]> granicus.if.org Git - postgresql/blob - src/backend/parser/gram.y
Here's the Create/Alter/Drop Group stuff that's been really overdue. I
[postgresql] / src / backend / parser / gram.y
1 %{ /* -*-text-*- */
2
3 /*#define YYDEBUG 1*/
4 /*-------------------------------------------------------------------------
5  *
6  * gram.y
7  *        POSTGRES SQL YACC rules/actions
8  *
9  * Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  *        $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.123 1999/12/16 17:24:14 momjian Exp $
14  *
15  * HISTORY
16  *        AUTHOR                        DATE                    MAJOR EVENT
17  *        Andrew Yu                     Sept, 1994              POSTQUEL to SQL conversion
18  *        Andrew Yu                     Oct, 1994               lispy code conversion
19  *
20  * NOTES
21  *        CAPITALS are used to represent terminal symbols.
22  *        non-capitals are used to represent non-terminals.
23  *        SQL92-specific syntax is separated from plain SQL/Postgres syntax
24  *        to help isolate the non-extensible portions of the parser.
25  *
26  *        if you use list, make sure the datum is a node so that the printing
27  *        routines work
28  *
29  * WARNING
30  *        sometimes we assign constants to makeStrings. Make sure we don't free
31  *        those.
32  *
33  *-------------------------------------------------------------------------
34  */
35 #include <ctype.h>
36
37 #include "postgres.h"
38 #include "access/htup.h"
39 #include "access/xact.h"
40 #include "catalog/catname.h"
41 #include "catalog/pg_type.h"
42 #include "nodes/parsenodes.h"
43 #include "nodes/print.h"
44 #include "parser/analyze.h"
45 #include "parser/gramparse.h"
46 #include "parser/parse_type.h"
47 #include "storage/bufpage.h"
48 #include "storage/lmgr.h"
49 #include "utils/acl.h"
50 #include "utils/numeric.h"
51
52 #ifdef MULTIBYTE
53 #include "mb/pg_wchar.h"
54 #endif
55
56 extern List *parsetree;                 /* final parse result is delivered here */
57
58 static char saved_relname[NAMEDATALEN];  /* need this for complex attributes */
59 static bool QueryIsRule = FALSE;
60 static Oid      *param_type_info;
61 static int      pfunc_num_args;
62
63
64 /*
65  * If you need access to certain yacc-generated variables and find that
66  * they're static by default, uncomment the next line.  (this is not a
67  * problem, yet.)
68  */
69 /*#define __YYSCLASS*/
70
71 static char *xlateSqlFunc(char *);
72 static char *xlateSqlType(char *);
73 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
74 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
75 static void mapTargetColumns(List *source, List *target);
76 static void param_type_init(Oid *typev, int nargs);
77 static Node *doNegate(Node *n);
78
79 /* old versions of flex define this as a macro */
80 #if defined(yywrap)
81 #undef yywrap
82 #endif /* yywrap */
83 %}
84
85
86 %union
87 {
88         double                          dval;
89         int                                     ival;
90         char                            chr;
91         char                            *str;
92         bool                            boolean;
93         bool*                           pboolean;       /* for pg_shadow privileges */
94         List                            *list;
95         Node                            *node;
96         Value                           *value;
97
98         Attr                            *attr;
99
100         TypeName                        *typnam;
101         DefElem                         *defelt;
102         SortGroupBy                     *sortgroupby;
103         JoinExpr                        *joinexpr;
104         IndexElem                       *ielem;
105         RangeVar                        *range;
106         RelExpr                         *relexp;
107         A_Indices                       *aind;
108         ResTarget                       *target;
109         ParamNo                         *paramno;
110
111         VersionStmt                     *vstmt;
112         DefineStmt                      *dstmt;
113         RuleStmt                        *rstmt;
114         InsertStmt                      *astmt;
115 }
116
117 %type <node>    stmt,
118                 AddAttrStmt, ClosePortalStmt,
119                 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DropStmt,
120                 TruncateStmt, CommentStmt,
121                 ExtendStmt, FetchStmt,  GrantStmt, CreateTrigStmt, DropTrigStmt,
122                 CreatePLangStmt, DropPLangStmt,
123                 IndexStmt, ListenStmt, UnlistenStmt, LockStmt, OptimizableStmt,
124                 ProcedureStmt, RemoveAggrStmt, RemoveOperStmt,
125                 RemoveFuncStmt, RemoveStmt,
126                 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
127                 CreatedbStmt, DropdbStmt, VacuumStmt, CursorStmt, SubSelect,
128                 UpdateStmt, InsertStmt, select_clause, SelectStmt, NotifyStmt, DeleteStmt, 
129                 ClusterStmt, ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
130                 CreateUserStmt, AlterUserStmt, DropUserStmt, RuleActionStmt,
131                 RuleActionStmtOrEmpty, ConstraintsSetStmt,
132                 CreateGroupStmt, AlterGroupStmt, DropGroupStmt
133
134 %type <str>             opt_database1, opt_database2, location, encoding
135
136 %type <ival>    opt_lock, lock_type
137 %type <boolean> opt_lmode
138
139 %type <pboolean> user_createdb_clause, user_createuser_clause
140 %type <str>             user_passwd_clause
141 %type <ival>            sysid_clause
142 %type <str>             user_valid_clause
143 %type <list>    user_group_list, user_group_clause, users_in_new_group_clause
144
145 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
146
147 %type <str>             OptConstrFromTable
148
149 %type <str>             TriggerEvents, TriggerFuncArg
150
151 %type <str>             relation_name, copy_file_name, copy_delimiter, copy_null, def_name,
152                 database_name, access_method_clause, access_method, attr_name,
153                 class, index_name, name, func_name, file_name, aggr_argtype
154
155 %type <str>             opt_id, opt_portal_name,
156                 all_Op, MathOp, opt_name, opt_unique,
157                 OptUseOp, opt_class, SpecialRuleRelation
158
159 %type <str>             opt_level
160 %type <str>             privileges, operation_commalist, grantee
161 %type <chr>             operation, TriggerOneEvent
162
163 %type <list>    stmtblock, stmtmulti,
164                 result, relation_name_list, OptTableElementList,
165                 OptInherit, definition,
166                 opt_with, func_args, func_args_list, func_as,
167                 oper_argtypes, RuleActionList, RuleActionMulti,
168                 opt_column_list, columnList, opt_va_list, va_list,
169                 sort_clause, sortby_list, index_params, index_list, name_list,
170                 from_clause, from_expr, table_list, opt_array_bounds,
171                 expr_list, attrs, target_list, update_target_list,
172                 def_list, opt_indirection, group_clause, TriggerFuncArgs,
173                 opt_select_limit
174
175 %type <node>    func_return
176 %type <boolean> set_opt
177
178 %type <boolean> TriggerForOpt, TriggerForType, OptTemp, OptTempType, OptTempScope
179
180 %type <list>    for_update_clause, update_list
181 %type <boolean> opt_all
182 %type <boolean> opt_table
183 %type <boolean> opt_trans
184
185 %type <list>    join_clause_with_union, join_clause, join_list, join_qual, using_list
186 %type <node>    join_expr, using_expr
187 %type <str>             join_outer
188 %type <ival>    join_type
189
190 %type <list>    extract_list, position_list
191 %type <list>    substr_list, substr_from, substr_for, trim_list
192 %type <list>    opt_interval
193
194 %type <boolean> opt_inh_star, opt_binary, opt_using, opt_instead,
195                                 opt_with_copy, index_opt_unique, opt_verbose, opt_analyze
196 %type <boolean> opt_cursor
197
198 %type <ival>    copy_dirn, def_type, opt_direction, remove_type,
199                 opt_column, event, comment_type, comment_cl,
200                 comment_ag, comment_fn, comment_op, comment_tg
201
202 %type <ival>    fetch_how_many
203
204 %type <node>    select_limit_value, select_offset_value
205
206 %type <list>    OptSeqList
207 %type <defelt>  OptSeqElem
208
209 %type <dstmt>   def_rest
210 %type <astmt>   insert_rest
211
212 %type <node>    OptTableElement, ConstraintElem
213 %type <node>    columnDef, alter_clause
214 %type <defelt>  def_elem
215 %type <node>    def_arg, columnElem, where_clause,
216                                 a_expr, a_expr_or_null, b_expr, com_expr, AexprConst,
217                                 in_expr, having_clause
218 %type <list>    row_descriptor, row_list, in_expr_nodes
219 %type <node>    row_expr
220 %type <node>    case_expr, case_arg, when_clause, case_default
221 %type <list>    when_clause_list
222 %type <ival>    sub_type
223 %type <list>    OptCreateAs, CreateAsList
224 %type <node>    CreateAsElement
225 %type <value>   NumericOnly, FloatOnly, IntegerOnly
226 %type <attr>    event_object, attr
227 %type <sortgroupby>             sortby
228 %type <ielem>   index_elem, func_index
229 %type <range>   table_expr
230 %type <relexp>  relation_expr
231 %type <target>  target_el, update_target_el
232 %type <paramno> ParamNo
233
234 %type <typnam>  Typename, opt_type, SimpleTypename,
235                                 Generic, Numeric, Character, Datetime
236 %type <str>             generic, numeric, character, datetime
237 %type <str>             extract_arg
238 %type <str>             opt_charset, opt_collate
239 %type <str>             opt_float
240 %type <ival>    opt_numeric, opt_decimal
241 %type <boolean> opt_varying, opt_timezone
242
243 %type <ival>    Iconst
244 %type <str>             Sconst, comment_text
245 %type <str>             UserId, var_value, zone_value
246 %type <str>             ColId, ColLabel
247 %type <str>             TypeId
248
249 %type <node>    TableConstraint
250 %type <list>    ColPrimaryKey, ColConstraintList
251 %type <node>    ColConstraint, ColConstraintElem
252 %type <ival>    key_actions, key_action, key_reference
253 %type <str>             key_match
254 %type <ival>    ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
255                                 ConstraintTimeSpec
256
257 %type <list>    constraints_set_list
258 %type <list>    constraints_set_namelist
259 %type <boolean> constraints_set_mode
260
261 /*
262  * If you make any token changes, remember to:
263  *              - use "yacc -d" and update parse.h
264  *              - update the keyword table in parser/keywords.c
265  */
266
267 /* Reserved word tokens
268  * SQL92 syntax has many type-specific constructs.
269  * So, go ahead and make these types reserved words,
270  *  and call-out the syntax explicitly.
271  * This gets annoying when trying to also retain Postgres' nice
272  *  type-extensible features, but we don't really have a choice.
273  * - thomas 1997-10-11
274  */
275
276 /* Keywords (in SQL92 reserved words) */
277 %token  ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
278                 BEGIN_TRANS, BETWEEN, BOTH, BY,
279                 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
280                 COALESCE, COLLATE, COLUMN, COMMIT,
281                 CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
282                 CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
283                 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
284                 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
285                 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
286                 GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
287                 IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
288                 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
289                 MATCH, MINUTE_P, MONTH_P, NAMES,
290                 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
291                 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
292                 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
293                 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
294                 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
295                 TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
296                 TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
297                 UNION, UNIQUE, UPDATE, USER, USING,
298                 VALUES, VARCHAR, VARYING, VIEW,
299                 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
300
301
302 /* Keywords (in SQL3 reserved words) */
303 %token  DEFERRABLE, DEFERRED,
304                 IMMEDIATE, INITIALLY,
305                 PENDANT,
306                 RESTRICT,
307                 TRIGGER
308
309 /* Keywords (in SQL92 non-reserved words) */
310 %token  COMMITTED, SERIALIZABLE, TYPE_P
311
312 /* Keywords for Postgres support (not in SQL92 reserved words)
313  *
314  * The CREATEDB and CREATEUSER tokens should go away
315  * when some sort of pg_privileges relation is introduced.
316  * - Todd A. Brandys 1998-01-01?
317  */
318 %token  ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
319                 BACKWARD, BEFORE, BINARY, 
320                 CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
321                 DATABASE, DELIMITERS, DO,
322                 EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
323                 FORWARD, FUNCTION, HANDLER,
324                 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
325                 LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
326                 MAXVALUE, MINVALUE, MODE, MOVE,
327                 NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
328                 OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
329                 RENAME, RESET, RETURNS, ROW, RULE,
330                 SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID,
331                 TRUNCATE, TRUSTED, 
332                 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
333
334 /* Special keywords, not in the query language - see the "lex" file */
335 %token <str>    IDENT, SCONST, Op
336 %token <ival>   ICONST, PARAM
337 %token <dval>   FCONST
338
339 /* these are not real. they are here so that they get generated as #define's*/
340 %token                  OP
341
342 /* precedence */
343 %left           OR
344 %left           AND
345 %right          NOT
346 %right          '='
347 %nonassoc       '<' '>'
348 %nonassoc       LIKE
349 %nonassoc       BETWEEN
350 %nonassoc       IN
351 %left           Op                              /* multi-character ops and user-defined operators */
352 %nonassoc       NOTNULL
353 %nonassoc       ISNULL
354 %nonassoc       NULL_P
355 %nonassoc       IS
356 %left           '+' '-'
357 %left           '*' '/' '%'
358 %left           '^'
359 %left           '|'                             /* this is the relation union op, not logical or */
360 /* Unary Operators */
361 %right          ':'
362 %left           ';'                             /* end of statement or natural log */
363 %right          UMINUS
364 %left           '.'
365 %left           '[' ']'
366 %left           TYPECAST
367 %left           UNION INTERSECT EXCEPT
368 %%
369
370 /*
371  *      Handle comment-only lines, and ;; SELECT * FROM pg_class ;;;
372  *      psql already handles such cases, but other interfaces don't.
373  *      bjm 1999/10/05
374  */
375 stmtblock:  stmtmulti
376                                 { parsetree = $1; }
377                 ;
378
379 /* the thrashing around here is to discard "empty" statements... */
380 stmtmulti:  stmtmulti ';' stmt
381                                 { if ($3 != (Node *)NULL)
382                                         $$ = lappend($1, $3);
383                                   else
384                                         $$ = $1;
385                                 }
386                 | stmt
387                                 { if ($1 != (Node *)NULL)
388                                         $$ = lcons($1,NIL);
389                                   else
390                                         $$ = NIL;
391                                 }
392                 ;
393
394 stmt :    AddAttrStmt
395                 | AlterGroupStmt
396                 | AlterUserStmt
397                 | ClosePortalStmt
398                 | CopyStmt
399                 | CreateStmt
400                 | CreateAsStmt
401                 | CreateGroupStmt
402                 | CreateSeqStmt
403                 | CreatePLangStmt
404                 | CreateTrigStmt
405                 | CreateUserStmt
406                 | ClusterStmt
407                 | DefineStmt
408                 | DropStmt              
409                 | TruncateStmt
410                 | CommentStmt
411                 | DropGroupStmt
412                 | DropPLangStmt
413                 | DropTrigStmt
414                 | DropUserStmt
415                 | ExtendStmt
416                 | ExplainStmt
417                 | FetchStmt
418                 | GrantStmt
419                 | IndexStmt
420                 | ListenStmt
421                 | UnlistenStmt
422                 | LockStmt
423                 | ProcedureStmt
424                 | RemoveAggrStmt
425                 | RemoveOperStmt
426                 | RemoveFuncStmt
427                 | RemoveStmt
428                 | RenameStmt
429                 | RevokeStmt
430                 | OptimizableStmt
431                 | RuleStmt
432                 | TransactionStmt
433                 | ViewStmt
434                 | LoadStmt
435                 | CreatedbStmt
436                 | DropdbStmt
437                 | VacuumStmt
438                 | VariableSetStmt
439                 | VariableShowStmt
440                 | VariableResetStmt
441                 | ConstraintsSetStmt
442                 |       /*EMPTY*/
443                                 { $$ = (Node *)NULL; }
444                 ;
445
446 /*****************************************************************************
447  *
448  * Create a new Postgres DBMS user
449  *
450  *
451  *****************************************************************************/
452
453 CreateUserStmt:  CREATE USER UserId
454                  user_createdb_clause user_createuser_clause user_group_clause
455                  user_valid_clause
456                                 {
457                                         CreateUserStmt *n = makeNode(CreateUserStmt);
458                                         n->user = $3;
459                     n->sysid = -1;
460                                         n->password = NULL;
461                                         n->createdb = $4;
462                                         n->createuser = $5;
463                                         n->groupElts = $6;
464                                         n->validUntil = $7;
465                                         $$ = (Node *)n;
466                                 }
467                 | CREATE USER UserId WITH sysid_clause user_passwd_clause
468                 user_createdb_clause user_createuser_clause user_group_clause
469                 user_valid_clause
470                {
471                                         CreateUserStmt *n = makeNode(CreateUserStmt);
472                                         n->user = $3;
473                     n->sysid = $5;
474                                         n->password = $6;
475                                         n->createdb = $7;
476                                         n->createuser = $8;
477                                         n->groupElts = $9;
478                                         n->validUntil = $10;
479                                         $$ = (Node *)n;
480                }                   
481                 ;
482
483 /*****************************************************************************
484  *
485  * Alter a postresql DBMS user
486  *
487  *
488  *****************************************************************************/
489
490 AlterUserStmt:  ALTER USER UserId user_createdb_clause
491                 user_createuser_clause user_group_clause user_valid_clause
492                                 {
493                                         AlterUserStmt *n = makeNode(AlterUserStmt);
494                                         n->user = $3;
495                     n->sysid = -1;
496                                         n->password = NULL;
497                                         n->createdb = $4;
498                                         n->createuser = $5;
499                                         n->groupElts = $6;
500                                         n->validUntil = $7;
501                                         $$ = (Node *)n;
502                                 }
503               | ALTER USER UserId WITH sysid_clause user_passwd_clause
504                 user_createdb_clause
505                 user_createuser_clause user_group_clause user_valid_clause
506                                 {
507                                         AlterUserStmt *n = makeNode(AlterUserStmt);
508                                         n->user = $3;
509                     n->sysid = $5;
510                                         n->password = $6;
511                                         n->createdb = $7;
512                                         n->createuser = $8;
513                                         n->groupElts = $9;
514                                         n->validUntil = $10;
515                                         $$ = (Node *)n;
516                                 }
517                 ;
518
519 /*****************************************************************************
520  *
521  * Drop a postresql DBMS user
522  *
523  *
524  *****************************************************************************/
525
526 DropUserStmt:  DROP USER UserId
527                                 {
528                                         DropUserStmt *n = makeNode(DropUserStmt);
529                                         n->user = $3;
530                                         $$ = (Node *)n;
531                                 }
532                 ;
533
534 user_passwd_clause:  PASSWORD UserId                    { $$ = $2; }
535                         | /*EMPTY*/                                     { $$ = NULL; }
536                 ;
537
538 sysid_clause: SYSID Iconst                              { $$ = $2; }
539                         | /*EMPTY*/                     { $$ = -1; }
540         ;
541
542 user_createdb_clause:  CREATEDB
543                                 {
544                                         bool*  b;
545                                         $$ = (b = (bool*)palloc(sizeof(bool)));
546                                         *b = true;
547                                 }
548                         | NOCREATEDB
549                                 {
550                                         bool*  b;
551                                         $$ = (b = (bool*)palloc(sizeof(bool)));
552                                         *b = false;
553                                 }
554                         | /*EMPTY*/                                                     { $$ = NULL; }
555                 ;
556
557 user_createuser_clause:  CREATEUSER
558                                 {
559                                         bool*  b;
560                                         $$ = (b = (bool*)palloc(sizeof(bool)));
561                                         *b = true;
562                                 }
563                         | NOCREATEUSER
564                                 {
565                                         bool*  b;
566                                         $$ = (b = (bool*)palloc(sizeof(bool)));
567                                         *b = false;
568                                 }
569                         | /*EMPTY*/                                                     { $$ = NULL; }
570                 ;
571
572 user_group_list:  user_group_list ',' UserId
573                                 {
574                                         $$ = lcons((void*)makeString($3), $1);
575                                 }
576                         | UserId
577                                 {
578                                         $$ = lcons((void*)makeString($1), NIL);
579                                 }
580                 ;
581
582 user_group_clause:  IN GROUP user_group_list    { $$ = $3; }
583                         | /*EMPTY*/             { $$ = NULL; }
584                 ;
585
586 user_valid_clause:  VALID UNTIL SCONST                  { $$ = $3; }
587                         | /*EMPTY*/                                                     { $$ = NULL; }
588                 ;
589
590
591 /*****************************************************************************
592  *
593  * Create a postresql group
594  *
595  *
596  *****************************************************************************/
597
598 CreateGroupStmt:  CREATE GROUP UserId 
599                   {
600                         CreateGroupStmt *n = makeNode(CreateGroupStmt);
601                         n->name = $3;
602                         n->sysid = -1;
603                         n->initUsers = NULL;
604                         $$ = (Node *)n;
605                   }
606                   |
607                   CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
608                   {
609                         CreateGroupStmt *n = makeNode(CreateGroupStmt);
610                         n->name = $3;
611                         n->sysid = $5;
612                         n->initUsers = $6;
613                         $$ = (Node *)n;
614                   }
615                 ;
616
617 users_in_new_group_clause:  USER user_group_list   { $$ = $2; }
618                             | /* EMPTY */          { $$ = NULL; }
619                 ;                         
620
621 /*****************************************************************************
622  *
623  * Alter a postresql group
624  *
625  *
626  *****************************************************************************/
627
628 AlterGroupStmt: ALTER GROUP UserId WITH SYSID Iconst
629                 {
630                         AlterGroupStmt *n = makeNode(AlterGroupStmt);
631                         n->name = $3;
632                         n->sysid = $6;
633                         n->action = 0;
634                         n->listUsers = NULL;
635                         $$ = (Node *)n;
636                 }
637                 |
638                 ALTER GROUP UserId ADD USER user_group_list
639                 {
640                         AlterGroupStmt *n = makeNode(AlterGroupStmt);
641                         n->name = $3;
642                         n->sysid = -1;
643                         n->action = +1;
644                         n->listUsers = $6;
645                         $$ = (Node *)n;
646                 }
647                 |
648                 ALTER GROUP UserId DROP USER user_group_list
649                 {
650                         AlterGroupStmt *n = makeNode(AlterGroupStmt);
651                         n->name = $3;
652                         n->sysid = -1;
653                         n->action = -1;
654                         n->listUsers = $6;
655                         $$ = (Node *)n;
656                 }
657                 ;
658
659 /*****************************************************************************
660  *
661  * Drop a postresql group
662  *
663  *
664  *****************************************************************************/
665
666 DropGroupStmt: DROP GROUP UserId
667                {
668                         DropGroupStmt *n = makeNode(DropGroupStmt);
669                         n->name = $3;
670                         $$ = (Node *)n;
671                }
672                 ;
673
674
675 /*****************************************************************************
676  *
677  * Set PG internal variable
678  *        SET name TO 'var_value'
679  * Include SQL92 syntax (thomas 1997-10-22):
680  *    SET TIME ZONE 'var_value'
681  *
682  *****************************************************************************/
683
684 VariableSetStmt:  SET ColId TO var_value
685                                 {
686                                         VariableSetStmt *n = makeNode(VariableSetStmt);
687                                         n->name  = $2;
688                                         n->value = $4;
689                                         $$ = (Node *) n;
690                                 }
691                 | SET ColId '=' var_value
692                                 {
693                                         VariableSetStmt *n = makeNode(VariableSetStmt);
694                                         n->name  = $2;
695                                         n->value = $4;
696                                         $$ = (Node *) n;
697                                 }
698                 | SET TIME ZONE zone_value
699                                 {
700                                         VariableSetStmt *n = makeNode(VariableSetStmt);
701                                         n->name  = "timezone";
702                                         n->value = $4;
703                                         $$ = (Node *) n;
704                                 }
705                 | SET TRANSACTION ISOLATION LEVEL opt_level
706                                 {
707                                         VariableSetStmt *n = makeNode(VariableSetStmt);
708                                         n->name  = "XactIsoLevel";
709                                         n->value = $5;
710                                         $$ = (Node *) n;
711                                 }
712                 | SET NAMES encoding
713                                 {
714 #ifdef MULTIBYTE
715                                         VariableSetStmt *n = makeNode(VariableSetStmt);
716                                         n->name  = "client_encoding";
717                                         n->value = $3;
718                                         $$ = (Node *) n;
719 #else
720                                         elog(ERROR, "SET NAMES is not supported");
721 #endif
722                                 }
723                 ;
724
725 opt_level:  READ COMMITTED                                      { $$ = "committed"; }
726                 | SERIALIZABLE                                          { $$ = "serializable"; }
727                 ;
728
729 var_value:  Sconst                      { $$ = $1; }
730                 | DEFAULT                       { $$ = NULL; }
731                 ;
732
733 zone_value:  Sconst                     { $$ = $1; }
734                 | DEFAULT                       { $$ = NULL; }
735                 | LOCAL                         { $$ = NULL; }
736                 ;
737
738 VariableShowStmt:  SHOW ColId
739                                 {
740                                         VariableShowStmt *n = makeNode(VariableShowStmt);
741                                         n->name  = $2;
742                                         $$ = (Node *) n;
743                                 }
744                 | SHOW TIME ZONE
745                                 {
746                                         VariableShowStmt *n = makeNode(VariableShowStmt);
747                                         n->name  = "timezone";
748                                         $$ = (Node *) n;
749                                 }
750                 | SHOW TRANSACTION ISOLATION LEVEL
751                                 {
752                                         VariableShowStmt *n = makeNode(VariableShowStmt);
753                                         n->name  = "XactIsoLevel";
754                                         $$ = (Node *) n;
755                                 }
756                 ;
757
758 VariableResetStmt:      RESET ColId
759                                 {
760                                         VariableResetStmt *n = makeNode(VariableResetStmt);
761                                         n->name  = $2;
762                                         $$ = (Node *) n;
763                                 }
764                 | RESET TIME ZONE
765                                 {
766                                         VariableResetStmt *n = makeNode(VariableResetStmt);
767                                         n->name  = "timezone";
768                                         $$ = (Node *) n;
769                                 }
770                 | RESET TRANSACTION ISOLATION LEVEL
771                                 {
772                                         VariableResetStmt *n = makeNode(VariableResetStmt);
773                                         n->name  = "XactIsoLevel";
774                                         $$ = (Node *) n;
775                                 }
776                 ;
777
778
779 ConstraintsSetStmt:     SET CONSTRAINTS constraints_set_list constraints_set_mode
780                                 {
781                                         ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
782                                         n->constraints = $3;
783                                         n->deferred    = $4;
784                                         $$ = (Node *) n;
785                                 }
786                 ;
787
788
789 constraints_set_list:   ALL
790                                 {
791                                         $$ = NIL;
792                                 }
793                 | constraints_set_namelist
794                                 {
795                                         $$ = $1;
796                                 }
797                 ;
798
799
800 constraints_set_namelist:       IDENT
801                                 {
802                                         $$ = lappend(NIL, $1);
803                                 }
804                 | constraints_set_namelist ',' IDENT
805                                 {
806                                         $$ = lappend($1, $3);
807                                 }
808                 ;
809
810
811 constraints_set_mode:   DEFERRED
812                                 {
813                                         $$ = true;
814                                 }
815                 | IMMEDIATE
816                                 {
817                                         $$ = false;
818                                 }
819                 ;
820
821
822 /*****************************************************************************
823  *
824  *              QUERY :
825  *                              addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
826  *
827  *****************************************************************************/
828
829 AddAttrStmt:  ALTER TABLE relation_name opt_inh_star alter_clause
830                                 {
831                                         AddAttrStmt *n = makeNode(AddAttrStmt);
832                                         n->relname = $3;
833                                         n->inh = $4;
834                                         n->colDef = $5;
835                                         $$ = (Node *)n;
836                                 }
837                 ;
838
839 alter_clause:  ADD opt_column columnDef
840                                 {
841                                         $$ = $3;
842                                 }
843                         | ADD '(' OptTableElementList ')'
844                                 {
845                                         if (length($3) != 1)
846                                                 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
847                                         $$ = (Node *) lfirst($3);
848                                 }
849                         | DROP opt_column ColId
850                                 {       elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
851                         | ALTER opt_column ColId SET DEFAULT a_expr
852                                 {       elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
853                         | ALTER opt_column ColId DROP DEFAULT
854                                 {       elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
855                         | ADD ConstraintElem
856                                 {       elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
857                 ;
858
859
860 /*****************************************************************************
861  *
862  *              QUERY :
863  *                              close <optname>
864  *
865  *****************************************************************************/
866
867 ClosePortalStmt:  CLOSE opt_id
868                                 {
869                                         ClosePortalStmt *n = makeNode(ClosePortalStmt);
870                                         n->portalname = $2;
871                                         $$ = (Node *)n;
872                                 }
873                 ;
874
875 opt_id:  ColId                                                                  { $$ = $1; }
876                 | /*EMPTY*/                                                             { $$ = NULL; }
877                 ;
878
879
880 /*****************************************************************************
881  *
882  *              QUERY :
883  *                              COPY [BINARY] <relname> FROM/TO
884  *                              [USING DELIMITERS <delimiter>]
885  *
886  *****************************************************************************/
887
888 CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
889                                 {
890                                         CopyStmt *n = makeNode(CopyStmt);
891                                         n->binary = $2;
892                                         n->relname = $3;
893                                         n->oids = $4;
894                                         n->direction = $5;
895                                         n->filename = $6;
896                                         n->delimiter = $7;
897                                         n->null_print = $8;
898                                         $$ = (Node *)n;
899                                 }
900                 ;
901
902 copy_dirn:      TO
903                                 { $$ = TO; }
904                 | FROM
905                                 { $$ = FROM; }
906                 ;
907
908 /*
909  * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
910  * used depends on the direction. (It really doesn't make sense to copy from
911  * stdout. We silently correct the "typo".               - AY 9/94
912  */
913 copy_file_name:  Sconst                                                 { $$ = $1; }
914                 | STDIN                                                                 { $$ = NULL; }
915                 | STDOUT                                                                { $$ = NULL; }
916                 ;
917
918 opt_binary:  BINARY                                                             { $$ = TRUE; }
919                 | /*EMPTY*/                                                             { $$ = FALSE; }
920                 ;
921
922 opt_with_copy:  WITH OIDS                                               { $$ = TRUE; }
923                 | /*EMPTY*/                                                             { $$ = FALSE; }
924                 ;
925
926 /*
927  * the default copy delimiter is tab but the user can configure it
928  */
929 copy_delimiter:  opt_using DELIMITERS Sconst    { $$ = $3; }
930                 | /*EMPTY*/                                                             { $$ = "\t"; }
931                 ;
932
933 opt_using:      USING                                                           { $$ = TRUE; }
934                 | /*EMPTY*/                                                             { $$ = TRUE; }
935                 ;
936
937 copy_null:      WITH NULL_P AS Sconst { $$ = $4; }
938                 | /*EMPTY*/         { $$ = "\\N"; }
939
940 /*****************************************************************************
941  *
942  *              QUERY :
943  *                              CREATE relname
944  *
945  *****************************************************************************/
946
947 CreateStmt:  CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
948                                 OptInherit
949                                 {
950                                         CreateStmt *n = makeNode(CreateStmt);
951                                         n->istemp = $2;
952                                         n->relname = $4;
953                                         n->tableElts = $6;
954                                         n->inhRelnames = $8;
955                                         n->constraints = NIL;
956                                         $$ = (Node *)n;
957                                 }
958                 ;
959
960 OptTemp:  OptTempType                                           { $$ = $1; }
961                         | OptTempScope OptTempType              { $$ = $2; }
962                 ;
963
964 OptTempType:  TEMP                                                      { $$ = TRUE; }
965                         | TEMPORARY                                             { $$ = TRUE; }
966                         | /*EMPTY*/                                             { $$ = FALSE; }
967                 ;
968
969 OptTempScope:  GLOBAL
970                                 {
971                                         elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
972                                         $$ = TRUE;
973                                 }
974                         | LOCAL
975                                 {
976                                          $$ = FALSE;
977                                 }
978                 ;
979
980 OptTableElementList:  OptTableElementList ',' OptTableElement
981                                 {
982                                         if ($3 != NULL)
983                                                 $$ = lappend($1, $3);
984                                         else
985                                                 $$ = $1;
986                                 }
987                         | OptTableElement
988                                 {
989                                         if ($1 != NULL)
990                                                 $$ = lcons($1, NIL);
991                                         else
992                                                 $$ = NULL;
993                                 }
994                         | /*EMPTY*/                                                     { $$ = NULL; }
995                 ;
996
997 OptTableElement:  columnDef                                             { $$ = $1; }
998                         | TableConstraint                                       { $$ = $1; }
999                 ;
1000
1001 columnDef:  ColId Typename ColConstraintList
1002                                 {
1003                                         ColumnDef *n = makeNode(ColumnDef);
1004                                         n->colname = $1;
1005                                         n->typename = $2;
1006                                         n->raw_default = NULL;
1007                                         n->cooked_default = NULL;
1008                                         n->is_not_null = FALSE;
1009                                         n->constraints = $3;
1010                                         $$ = (Node *)n;
1011                                 }
1012                         | ColId SERIAL ColPrimaryKey
1013                                 {
1014                                         ColumnDef *n = makeNode(ColumnDef);
1015                                         n->colname = $1;
1016                                         n->typename = makeNode(TypeName);
1017                                         n->typename->name = xlateSqlType("integer");
1018                                         n->raw_default = NULL;
1019                                         n->cooked_default = NULL;
1020                                         n->is_not_null = TRUE;
1021                                         n->is_sequence = TRUE;
1022                                         n->constraints = $3;
1023
1024                                         $$ = (Node *)n;
1025                                 }
1026                 ;
1027
1028 ColConstraintList:  ColConstraintList ColConstraint
1029                                 {
1030                                         if ($2 != NULL)
1031                                                 $$ = lappend($1, $2);
1032                                         else
1033                                                 $$ = $1;
1034                                 }
1035                         | /*EMPTY*/
1036                                 { $$ = NIL; }
1037                 ;
1038
1039 ColPrimaryKey:  PRIMARY KEY
1040                                 {
1041                                         Constraint *n = makeNode(Constraint);
1042                                         n->contype = CONSTR_PRIMARY;
1043                                         n->name = NULL;
1044                                         n->raw_expr = NULL;
1045                                         n->cooked_expr = NULL;
1046                                         n->keys = NULL;
1047                                         $$ = lcons((Node *)n, NIL);
1048                                 }
1049                         | /*EMPTY*/                                                     { $$ = NULL; }
1050                 ;
1051
1052 ColConstraint:
1053                 CONSTRAINT name ColConstraintElem
1054                                 {
1055                                         switch (nodeTag($3))
1056                                         {
1057                                                 case T_Constraint:
1058                                                         {
1059                                                                 Constraint *n = (Constraint *)$3;
1060                                                                 if (n != NULL) n->name = $2;
1061                                                         }
1062                                                         break;
1063                                                 case T_FkConstraint:
1064                                                         {
1065                                                                 FkConstraint *n = (FkConstraint *)$3;
1066                                                                 if (n != NULL) n->constr_name = $2;
1067                                                         }
1068                                                         break;
1069                                                 default:
1070                                                         break;
1071                                         }
1072                                         $$ = $3;
1073                                 }
1074                 | ColConstraintElem
1075                                 { $$ = $1; }
1076                 ;
1077
1078 /*
1079  * DEFAULT NULL is already the default for Postgres.
1080  * But define it here and carry it forward into the system
1081  * to make it explicit.
1082  * - thomas 1998-09-13
1083  *
1084  * WITH NULL and NULL are not SQL92-standard syntax elements,
1085  * so leave them out. Use DEFAULT NULL to explicitly indicate
1086  * that a column may have that value. WITH NULL leads to
1087  * shift/reduce conflicts with WITH TIME ZONE anyway.
1088  * - thomas 1999-01-08
1089  *
1090  * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
1091  * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
1092  * or be part of a_expr NOT LIKE or similar constructs).
1093  */
1094 ColConstraintElem:  CHECK '(' a_expr ')'
1095                                 {
1096                                         Constraint *n = makeNode(Constraint);
1097                                         n->contype = CONSTR_CHECK;
1098                                         n->name = NULL;
1099                                         n->raw_expr = $3;
1100                                         n->cooked_expr = NULL;
1101                                         n->keys = NULL;
1102                                         $$ = (Node *)n;
1103                                 }
1104                         | DEFAULT NULL_P
1105                                 {
1106                                         Constraint *n = makeNode(Constraint);
1107                                         n->contype = CONSTR_DEFAULT;
1108                                         n->name = NULL;
1109                                         n->raw_expr = NULL;
1110                                         n->cooked_expr = NULL;
1111                                         n->keys = NULL;
1112                                         $$ = (Node *)n;
1113                                 }
1114                         | DEFAULT b_expr
1115                                 {
1116                                         Constraint *n = makeNode(Constraint);
1117                                         n->contype = CONSTR_DEFAULT;
1118                                         n->name = NULL;
1119                                         n->raw_expr = $2;
1120                                         n->cooked_expr = NULL;
1121                                         n->keys = NULL;
1122                                         $$ = (Node *)n;
1123                                 }
1124                         | NOT NULL_P
1125                                 {
1126                                         Constraint *n = makeNode(Constraint);
1127                                         n->contype = CONSTR_NOTNULL;
1128                                         n->name = NULL;
1129                                         n->raw_expr = NULL;
1130                                         n->cooked_expr = NULL;
1131                                         n->keys = NULL;
1132                                         $$ = (Node *)n;
1133                                 }
1134                         | UNIQUE
1135                                 {
1136                                         Constraint *n = makeNode(Constraint);
1137                                         n->contype = CONSTR_UNIQUE;
1138                                         n->name = NULL;
1139                                         n->raw_expr = NULL;
1140                                         n->cooked_expr = NULL;
1141                                         n->keys = NULL;
1142                                         $$ = (Node *)n;
1143                                 }
1144                         | PRIMARY KEY
1145                                 {
1146                                         Constraint *n = makeNode(Constraint);
1147                                         n->contype = CONSTR_PRIMARY;
1148                                         n->name = NULL;
1149                                         n->raw_expr = NULL;
1150                                         n->cooked_expr = NULL;
1151                                         n->keys = NULL;
1152                                         $$ = (Node *)n;
1153                                 }
1154                         | REFERENCES ColId opt_column_list key_match key_actions 
1155                                 {
1156                                         /* XXX
1157                                          *      Need ConstraintAttributeSpec as $6 -- Jan
1158                                          */
1159                                         FkConstraint *n = makeNode(FkConstraint);
1160                                         n->constr_name          = NULL;
1161                                         n->pktable_name         = $2;
1162                                         n->fk_attrs                     = NIL;
1163                                         n->pk_attrs                     = $3;
1164                                         n->match_type           = $4;
1165                                         n->actions                      = $5;
1166                                         n->deferrable           = true;
1167                                         n->initdeferred         = false;
1168                                         /*
1169                                         n->deferrable           = ($6 & 1) != 0;
1170                                         n->initdeferred         = ($6 & 2) != 0;
1171                                         */
1172                                         $$ = (Node *)n;
1173                                 }
1174                 ;
1175
1176 /* ConstraintElem specifies constraint syntax which is not embedded into
1177  *  a column definition. ColConstraintElem specifies the embedded form.
1178  * - thomas 1997-12-03
1179  */
1180 TableConstraint:  CONSTRAINT name ConstraintElem
1181                                 {
1182                                         switch (nodeTag($3))
1183                                         {
1184                                                 case T_Constraint:
1185                                                         {
1186                                                                 Constraint *n = (Constraint *)$3;
1187                                                                 if (n != NULL) n->name = $2;
1188                                                         }
1189                                                         break;
1190                                                 case T_FkConstraint:
1191                                                         {
1192                                                                 FkConstraint *n = (FkConstraint *)$3;
1193                                                                 if (n != NULL) n->constr_name = $2;
1194                                                         }
1195                                                         break;
1196                                                 default:
1197                                                         break;
1198                                         }
1199                                         $$ = $3;
1200                                 }
1201                 | ConstraintElem
1202                                 { $$ = $1; }
1203                 ;
1204
1205 ConstraintElem:  CHECK '(' a_expr ')'
1206                                 {
1207                                         Constraint *n = makeNode(Constraint);
1208                                         n->contype = CONSTR_CHECK;
1209                                         n->name = NULL;
1210                                         n->raw_expr = $3;
1211                                         n->cooked_expr = NULL;
1212                                         $$ = (Node *)n;
1213                                 }
1214                 | UNIQUE '(' columnList ')'
1215                                 {
1216                                         Constraint *n = makeNode(Constraint);
1217                                         n->contype = CONSTR_UNIQUE;
1218                                         n->name = NULL;
1219                                         n->raw_expr = NULL;
1220                                         n->cooked_expr = NULL;
1221                                         n->keys = $3;
1222                                         $$ = (Node *)n;
1223                                 }
1224                 | PRIMARY KEY '(' columnList ')'
1225                                 {
1226                                         Constraint *n = makeNode(Constraint);
1227                                         n->contype = CONSTR_PRIMARY;
1228                                         n->name = NULL;
1229                                         n->raw_expr = NULL;
1230                                         n->cooked_expr = NULL;
1231                                         n->keys = $4;
1232                                         $$ = (Node *)n;
1233                                 }
1234                 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions ConstraintAttributeSpec
1235                                 {
1236                                         FkConstraint *n = makeNode(FkConstraint);
1237                                         n->constr_name          = NULL;
1238                                         n->pktable_name         = $7;
1239                                         n->fk_attrs                     = $4;
1240                                         n->pk_attrs                     = $8;
1241                                         n->match_type           = $9;
1242                                         n->actions                      = $10;
1243                                         n->deferrable           = ($11 & 1) != 0;
1244                                         n->initdeferred         = ($11 & 2) != 0;
1245                                         $$ = (Node *)n;
1246                                 }
1247                 ;
1248
1249 key_match:  MATCH FULL
1250                         {
1251                                 $$ = "FULL";
1252                         }
1253                 | MATCH PARTIAL
1254                         {
1255                                 elog(ERROR, "FOREIGN KEY match type PARTIAL not implemented yet");
1256                                 $$ = "PARTIAL";
1257                         }
1258                 | /*EMPTY*/
1259                         {
1260                                 elog(ERROR, "FOREIGN KEY match type UNSPECIFIED not implemented yet");
1261                                 $$ = "UNSPECIFIED";
1262                         }
1263                 ;
1264
1265 key_actions:  key_action key_action             { $$ = $1 | $2; }
1266                 | key_action                                    { $$ = $1; }
1267                 | /*EMPTY*/                                             { $$ = 0; }
1268                 ;
1269
1270 key_action:  ON DELETE key_reference    { $$ = $3 << FKCONSTR_ON_DELETE_SHIFT; }
1271                 | ON UPDATE key_reference               { $$ = $3 << FKCONSTR_ON_UPDATE_SHIFT; }
1272                 ;
1273
1274 key_reference:  NO ACTION                               { $$ = FKCONSTR_ON_KEY_NOACTION; }
1275                 | RESTRICT                                              { $$ = FKCONSTR_ON_KEY_RESTRICT; }
1276                 | CASCADE                                               { $$ = FKCONSTR_ON_KEY_CASCADE; }
1277                 | SET NULL_P                                    { $$ = FKCONSTR_ON_KEY_SETNULL; }
1278                 | SET DEFAULT                                   { $$ = FKCONSTR_ON_KEY_SETDEFAULT; }
1279                 ;
1280
1281 OptInherit:  INHERITS '(' relation_name_list ')'                { $$ = $3; }
1282                 | /*EMPTY*/                                                                             { $$ = NIL; }
1283                 ;
1284
1285 /*
1286  * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1287  * SELECT ... INTO.
1288  */
1289
1290 CreateAsStmt:  CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
1291                                 {
1292                                         SelectStmt *n = (SelectStmt *)$7;
1293                                         if ($5 != NIL)
1294                                                 mapTargetColumns($5, n->targetList);
1295                                         if (n->into != NULL)
1296                                                 elog(ERROR,"CREATE TABLE/AS SELECT may not specify INTO");
1297                                         n->istemp = $2;
1298                                         n->into = $4;
1299                                         $$ = (Node *)n;
1300                                 }
1301                 ;
1302
1303 OptCreateAs:  '(' CreateAsList ')'                              { $$ = $2; }
1304                         | /*EMPTY*/                                                     { $$ = NULL; }
1305                 ;
1306
1307 CreateAsList:  CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1308                         | CreateAsElement                                       { $$ = lcons($1, NIL); }
1309                 ;
1310
1311 CreateAsElement:  ColId
1312                                 {
1313                                         ColumnDef *n = makeNode(ColumnDef);
1314                                         n->colname = $1;
1315                                         n->typename = NULL;
1316                                         n->raw_default = NULL;
1317                                         n->cooked_default = NULL;
1318                                         n->is_not_null = FALSE;
1319                                         n->constraints = NULL;
1320                                         $$ = (Node *)n;
1321                                 }
1322                 ;
1323
1324
1325 /*****************************************************************************
1326  *
1327  *              QUERY :
1328  *                              CREATE SEQUENCE seqname
1329  *
1330  *****************************************************************************/
1331
1332 CreateSeqStmt:  CREATE SEQUENCE relation_name OptSeqList
1333                                 {
1334                                         CreateSeqStmt *n = makeNode(CreateSeqStmt);
1335                                         n->seqname = $3;
1336                                         n->options = $4;
1337                                         $$ = (Node *)n;
1338                                 }
1339                 ;
1340
1341 OptSeqList:  OptSeqList OptSeqElem
1342                                 { $$ = lappend($1, $2); }
1343                         |       { $$ = NIL; }
1344                 ;
1345
1346 OptSeqElem:  CACHE IntegerOnly
1347                                 {
1348                                         $$ = makeNode(DefElem);
1349                                         $$->defname = "cache";
1350                                         $$->arg = (Node *)$2;
1351                                 }
1352                         | CYCLE
1353                                 {
1354                                         $$ = makeNode(DefElem);
1355                                         $$->defname = "cycle";
1356                                         $$->arg = (Node *)NULL;
1357                                 }
1358                         | INCREMENT IntegerOnly
1359                                 {
1360                                         $$ = makeNode(DefElem);
1361                                         $$->defname = "increment";
1362                                         $$->arg = (Node *)$2;
1363                                 }
1364                         | MAXVALUE IntegerOnly
1365                                 {
1366                                         $$ = makeNode(DefElem);
1367                                         $$->defname = "maxvalue";
1368                                         $$->arg = (Node *)$2;
1369                                 }
1370                         | MINVALUE IntegerOnly
1371                                 {
1372                                         $$ = makeNode(DefElem);
1373                                         $$->defname = "minvalue";
1374                                         $$->arg = (Node *)$2;
1375                                 }
1376                         | START IntegerOnly
1377                                 {
1378                                         $$ = makeNode(DefElem);
1379                                         $$->defname = "start";
1380                                         $$->arg = (Node *)$2;
1381                                 }
1382                 ;
1383
1384 NumericOnly:  FloatOnly                                 { $$ = $1; }
1385                         | IntegerOnly                           { $$ = $1; }
1386
1387 FloatOnly:  FCONST
1388                                 {
1389                                         $$ = makeFloat($1);
1390                                 }
1391                         | '-' FCONST
1392                                 {
1393                                         $$ = makeFloat($2);
1394                                         $$->val.dval = - $$->val.dval;
1395                                 }
1396                 ;
1397
1398 IntegerOnly:  Iconst
1399                                 {
1400                                         $$ = makeInteger($1);
1401                                 }
1402                         | '-' Iconst
1403                                 {
1404                                         $$ = makeInteger($2);
1405                                         $$->val.ival = - $$->val.ival;
1406                                 }
1407                 ;
1408
1409 /*****************************************************************************
1410  *
1411  *              QUERIES :
1412  *                              CREATE PROCEDURAL LANGUAGE ...
1413  *                              DROP PROCEDURAL LANGUAGE ...
1414  *
1415  *****************************************************************************/
1416
1417 CreatePLangStmt:  CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst 
1418                         HANDLER def_name LANCOMPILER Sconst
1419                         {
1420                                 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1421                                 n->plname = $5;
1422                                 n->plhandler = $7;
1423                                 n->plcompiler = $9;
1424                                 n->pltrusted = $2;
1425                                 $$ = (Node *)n;
1426                         }
1427                 ;
1428
1429 PLangTrusted:           TRUSTED { $$ = TRUE; }
1430                         |       { $$ = FALSE; }
1431
1432 DropPLangStmt:  DROP PROCEDURAL LANGUAGE Sconst
1433                         {
1434                                 DropPLangStmt *n = makeNode(DropPLangStmt);
1435                                 n->plname = $4;
1436                                 $$ = (Node *)n;
1437                         }
1438                 ;
1439
1440 /*****************************************************************************
1441  *
1442  *              QUERIES :
1443  *                              CREATE TRIGGER ...
1444  *                              DROP TRIGGER ...
1445  *
1446  *****************************************************************************/
1447
1448 CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1449                                 relation_name TriggerForSpec EXECUTE PROCEDURE
1450                                 name '(' TriggerFuncArgs ')'
1451                                 {
1452                                         CreateTrigStmt *n = makeNode(CreateTrigStmt);
1453                                         n->trigname = $3;
1454                                         n->relname = $7;
1455                                         n->funcname = $11;
1456                                         n->args = $13;
1457                                         n->before = $4;
1458                                         n->row = $8;
1459                                         memcpy (n->actions, $5, 4);
1460                                         n->lang = NULL;         /* unused */
1461                                         n->text = NULL;         /* unused */
1462                                         n->attr = NULL;         /* unused */
1463                                         n->when = NULL;         /* unused */
1464
1465                                         n->isconstraint  = false;
1466                                         n->deferrable    = false;
1467                                         n->initdeferred  = false;
1468                                         n->constrrelname = NULL;
1469                                         $$ = (Node *)n;
1470                                 }
1471                 | CREATE CONSTRAINT TRIGGER name AFTER TriggerOneEvent ON
1472                                 relation_name OptConstrFromTable 
1473                                 ConstraintAttributeSpec
1474                                 FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')'
1475                                 {
1476                                         CreateTrigStmt *n = makeNode(CreateTrigStmt);
1477                                         n->trigname = $4;
1478                                         n->relname = $8;
1479                                         n->funcname = $16;
1480                                         n->args = $18;
1481                                         n->before = false;
1482                                         n->row = true;
1483                                         n->actions[0] = $6;
1484                                         n->actions[1] = '\0';
1485                                         n->lang = NULL;         /* unused */
1486                                         n->text = NULL;         /* unused */
1487                                         n->attr = NULL;         /* unused */
1488                                         n->when = NULL;         /* unused */
1489
1490                                         n->isconstraint  = true;
1491                                         n->deferrable = ($10 & 1) != 0;
1492                                         n->initdeferred = ($10 & 2) != 0;
1493
1494                                         n->constrrelname = $9;
1495                                         $$ = (Node *)n;
1496                                 }
1497                 ;
1498
1499 TriggerActionTime:  BEFORE                                              { $$ = TRUE; }
1500                         | AFTER                                                         { $$ = FALSE; }
1501                 ;
1502
1503 TriggerEvents:  TriggerOneEvent
1504                                 {
1505                                         char *e = palloc (4);
1506                                         e[0] = $1; e[1] = 0; $$ = e;
1507                                 }
1508                         | TriggerOneEvent OR TriggerOneEvent
1509                                 {
1510                                         char *e = palloc (4);
1511                                         e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1512                                 }
1513                         | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1514                                 {
1515                                         char *e = palloc (4);
1516                                         e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1517                                         $$ = e;
1518                                 }
1519                 ;
1520
1521 TriggerOneEvent:  INSERT                                        { $$ = 'i'; }
1522                         | DELETE                                                { $$ = 'd'; }
1523                         | UPDATE                                                { $$ = 'u'; }
1524                 ;
1525
1526 TriggerForSpec:  FOR TriggerForOpt TriggerForType
1527                                 {
1528                                         $$ = $3;
1529                                 }
1530                 ;
1531
1532 TriggerForOpt:  EACH                                            { $$ = TRUE; }
1533                         | /*EMPTY*/                                             { $$ = FALSE; }
1534                 ;
1535
1536 TriggerForType:  ROW                                            { $$ = TRUE; }
1537                         | STATEMENT                                             { $$ = FALSE; }
1538                 ;
1539
1540 TriggerFuncArgs:  TriggerFuncArg
1541                                 { $$ = lcons($1, NIL); }
1542                         | TriggerFuncArgs ',' TriggerFuncArg
1543                                 { $$ = lappend($1, $3); }
1544                         | /*EMPTY*/
1545                                 { $$ = NIL; }
1546                 ;
1547
1548 TriggerFuncArg:  ICONST
1549                                 {
1550                                         char *s = (char *) palloc (256);
1551                                         sprintf (s, "%d", $1);
1552                                         $$ = s;
1553                                 }
1554                         | FCONST
1555                                 {
1556                                         char *s = (char *) palloc (256);
1557                                         sprintf (s, "%g", $1);
1558                                         $$ = s;
1559                                 }
1560                         | Sconst                                                {  $$ = $1; }
1561                         | IDENT                                                 {  $$ = $1; }
1562                 ;
1563
1564 OptConstrFromTable:                     /* Empty */
1565                                 {
1566                                         $$ = "";
1567                                 }
1568                 | FROM relation_name
1569                                 {
1570                                         $$ = $2;
1571                                 }
1572                 ;
1573
1574 ConstraintAttributeSpec: /* Empty */
1575                         { $$ = 0; }
1576                 | ConstraintDeferrabilitySpec
1577                         { $$ = $1; }
1578                 | ConstraintDeferrabilitySpec ConstraintTimeSpec
1579                         {
1580                                 if ($1 == 0 && $2 != 0)
1581                                         elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1582                                 $$ = $1 | $2;
1583                         }
1584                 | ConstraintTimeSpec
1585                         {
1586                                 if ($1 != 0)
1587                                         $$ = 3;
1588                                 else
1589                                         $$ = 0;
1590                         }
1591                 | ConstraintTimeSpec ConstraintDeferrabilitySpec
1592                         {
1593                                 if ($2 == 0 && $1 != 0)
1594                                         elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1595                                 $$ = $1 | $2;
1596                         }
1597                 ;
1598
1599 ConstraintDeferrabilitySpec: NOT DEFERRABLE
1600                         { $$ = 0; }
1601                 | DEFERRABLE
1602                         { $$ = 1; }
1603                 ;
1604
1605 ConstraintTimeSpec: INITIALLY IMMEDIATE
1606                         { $$ = 0; }
1607                 | INITIALLY DEFERRED
1608                         { $$ = 2; }
1609                 ;
1610
1611
1612 DropTrigStmt:  DROP TRIGGER name ON relation_name
1613                                 {
1614                                         DropTrigStmt *n = makeNode(DropTrigStmt);
1615                                         n->trigname = $3;
1616                                         n->relname = $5;
1617                                         $$ = (Node *) n;
1618                                 }
1619                 ;
1620
1621
1622 /*****************************************************************************
1623  *
1624  *              QUERY :
1625  *                              define (type,operator,aggregate)
1626  *
1627  *****************************************************************************/
1628
1629 DefineStmt:  CREATE def_type def_rest
1630                                 {
1631                                         $3->defType = $2;
1632                                         $$ = (Node *)$3;
1633                                 }
1634                 ;
1635
1636 def_rest:  def_name definition
1637                                 {
1638                                         $$ = makeNode(DefineStmt);
1639                                         $$->defname = $1;
1640                                         $$->definition = $2;
1641                                 }
1642                 ;
1643
1644 def_type:  OPERATOR                                                     { $$ = OPERATOR; }
1645                 | TYPE_P                                                        { $$ = TYPE_P; }
1646                 | AGGREGATE                                                     { $$ = AGGREGATE; }
1647                 ;
1648
1649 def_name:  PROCEDURE                                            { $$ = "procedure"; }
1650                 | JOIN                                                          { $$ = "join"; }
1651                 | ColId                                                         { $$ = $1; }
1652                 | all_Op                                                        { $$ = $1; }
1653                 ;
1654
1655 definition:  '(' def_list ')'                           { $$ = $2; }
1656                 ;
1657
1658 def_list:  def_elem                                                     { $$ = lcons($1, NIL); }
1659                 | def_list ',' def_elem                         { $$ = lappend($1, $3); }
1660                 ;
1661
1662 def_elem:  def_name '=' def_arg
1663                                 {
1664                                         $$ = makeNode(DefElem);
1665                                         $$->defname = $1;
1666                                         $$->arg = (Node *)$3;
1667                                 }
1668                 | def_name
1669                                 {
1670                                         $$ = makeNode(DefElem);
1671                                         $$->defname = $1;
1672                                         $$->arg = (Node *)NULL;
1673                                 }
1674                 | DEFAULT '=' def_arg
1675                                 {
1676                                         $$ = makeNode(DefElem);
1677                                         $$->defname = "default";
1678                                         $$->arg = (Node *)$3;
1679                                 }
1680                 ;
1681
1682 def_arg:  ColId                                                 {  $$ = (Node *)makeString($1); }
1683                 | all_Op                                                {  $$ = (Node *)makeString($1); }
1684                 | NumericOnly                                   {  $$ = (Node *)$1; }
1685                 | Sconst                                                {  $$ = (Node *)makeString($1); }
1686                 | SETOF ColId
1687                                 {
1688                                         TypeName *n = makeNode(TypeName);
1689                                         n->name = $2;
1690                                         n->setof = TRUE;
1691                                         n->arrayBounds = NULL;
1692                                         n->typmod = -1;
1693                                         $$ = (Node *)n;
1694                                 }
1695                 ;
1696
1697
1698 /*****************************************************************************
1699  *
1700  *              QUERY:
1701  *                              drop <relname1> [, <relname2> .. <relnameN> ]
1702  *
1703  *****************************************************************************/
1704
1705 DropStmt:  DROP TABLE relation_name_list
1706                                 {
1707                                         DropStmt *n = makeNode(DropStmt);
1708                                         n->relNames = $3;
1709                                         n->sequence = FALSE;
1710                                         $$ = (Node *)n;
1711                                 }
1712                 | DROP SEQUENCE relation_name_list
1713                                 {
1714                                         DropStmt *n = makeNode(DropStmt);
1715                                         n->relNames = $3;
1716                                         n->sequence = TRUE;
1717                                         $$ = (Node *)n;
1718                                 }
1719                 ;
1720
1721 /*****************************************************************************
1722  *
1723  *              QUERY:
1724  *                              truncate table relname
1725  *
1726  *****************************************************************************/
1727
1728 TruncateStmt:  TRUNCATE TABLE relation_name
1729                                 {
1730                                         TruncateStmt *n = makeNode(TruncateStmt);
1731                                         n->relName = $3;
1732                                         $$ = (Node *)n;
1733                                 }
1734                         ;
1735
1736 /*****************************************************************************
1737  *
1738  *  The COMMENT ON statement can take different forms based upon the type of
1739  *  the object associated with the comment. The form of the statement is:
1740  *
1741  *  COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ] 
1742  *               <objname> | AGGREGATE <aggname> <aggtype> | FUNCTION 
1743  *               <funcname> (arg1, arg2, ...) | OPERATOR <op> 
1744  *               (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
1745  *               <relname> ] IS 'text'
1746  *
1747  *****************************************************************************/
1748  
1749 CommentStmt:    COMMENT ON comment_type name IS comment_text
1750                         {
1751                                 CommentStmt *n = makeNode(CommentStmt);
1752                                 n->objtype = $3;
1753                                 n->objname = $4;
1754                                 n->objproperty = NULL;
1755                                 n->objlist = NULL;
1756                                 n->comment = $6;
1757                                 $$ = (Node *) n;
1758                         }
1759                 | COMMENT ON comment_cl relation_name '.' attr_name IS comment_text
1760                         {
1761                                 CommentStmt *n = makeNode(CommentStmt);
1762                                 n->objtype = $3;
1763                                 n->objname = $4;
1764                                 n->objproperty = $6;
1765                                 n->objlist = NULL;
1766                                 n->comment = $8;
1767                                 $$ = (Node *) n;
1768                         }
1769                 | COMMENT ON comment_ag name aggr_argtype IS comment_text
1770                         {
1771                                 CommentStmt *n = makeNode(CommentStmt);
1772                                 n->objtype = $3;
1773                                 n->objname = $4;
1774                                 n->objproperty = $5;
1775                                 n->objlist = NULL;
1776                                 n->comment = $7;
1777                                 $$ = (Node *) n;
1778                         }
1779                 | COMMENT ON comment_fn func_name func_args IS comment_text
1780                         {
1781                                 CommentStmt *n = makeNode(CommentStmt);
1782                                 n->objtype = $3;
1783                                 n->objname = $4;
1784                                 n->objproperty = NULL;
1785                                 n->objlist = $5;
1786                                 n->comment = $7;
1787                                 $$ = (Node *) n;
1788                         }
1789                 | COMMENT ON comment_op all_Op '(' oper_argtypes ')' IS comment_text
1790                         {
1791                                 CommentStmt *n = makeNode(CommentStmt);
1792                                 n->objtype = $3;
1793                                 n->objname = $4;
1794                                 n->objproperty = NULL;
1795                                 n->objlist = $6;
1796                                 n->comment = $9;
1797                                 $$ = (Node *) n;
1798                         }
1799                 | COMMENT ON comment_tg name ON relation_name IS comment_text
1800                         {
1801                                 CommentStmt *n = makeNode(CommentStmt);
1802                                 n->objtype = $3;
1803                                 n->objname = $4;
1804                                 n->objproperty = $6;
1805                                 n->objlist = NULL;
1806                                 n->comment = $8;
1807                                 $$ = (Node *) n;
1808                         }
1809                 ;
1810
1811 comment_type:   DATABASE { $$ = DATABASE; }
1812                 | INDEX { $$ = INDEX; }
1813                 | RULE { $$ = RULE; }
1814                 | SEQUENCE { $$ = SEQUENCE; }
1815                 | TABLE { $$ = TABLE; }
1816                 | TYPE_P { $$ = TYPE_P; }
1817                 | VIEW { $$ = VIEW; }
1818                 ;               
1819
1820 comment_cl:     COLUMN { $$ = COLUMN; }
1821                 ;
1822
1823 comment_ag:     AGGREGATE { $$ = AGGREGATE; }
1824                 ;
1825
1826 comment_fn:     FUNCTION { $$ = FUNCTION; }
1827                 ;
1828
1829 comment_op:     OPERATOR { $$ = OPERATOR; }
1830                 ;
1831
1832 comment_tg:     TRIGGER { $$ = TRIGGER; }
1833                 ; 
1834
1835 comment_text:   Sconst { $$ = $1; }
1836                 | NULL_P { $$ = NULL; }
1837                 ;
1838                 
1839 /*****************************************************************************
1840  *
1841  *              QUERY:
1842  *                      fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1843  *                      fetch [ forward | backward | absolute | relative ]
1844  *                            [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1845  *
1846  *****************************************************************************/
1847
1848 FetchStmt:      FETCH opt_direction fetch_how_many opt_portal_name
1849                                 {
1850                                         FetchStmt *n = makeNode(FetchStmt);
1851                                         if ($2 == RELATIVE)
1852                                         {
1853                                                 if ($3 == 0)
1854                                                         elog(ERROR,"FETCH/RELATIVE at current position is not supported");
1855                                                 $2 = FORWARD;
1856                                         }
1857                                         if ($3 < 0)
1858                                         {
1859                                                 $3 = -$3;
1860                                                 $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
1861                                         }
1862                                         n->direction = $2;
1863                                         n->howMany = $3;
1864                                         n->portalname = $4;
1865                                         n->ismove = false;
1866                                         $$ = (Node *)n;
1867                                 }
1868                 |       MOVE opt_direction fetch_how_many opt_portal_name
1869                                 {
1870                                         FetchStmt *n = makeNode(FetchStmt);
1871                                         if ($3 < 0)
1872                                         {
1873                                                 $3 = -$3;
1874                                                 $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
1875                                         }
1876                                         n->direction = $2;
1877                                         n->howMany = $3;
1878                                         n->portalname = $4;
1879                                         n->ismove = TRUE;
1880                                         $$ = (Node *)n;
1881                                 }
1882                 ;
1883
1884 opt_direction:  FORWARD                                 { $$ = FORWARD; }
1885                 | BACKWARD                                              { $$ = BACKWARD; }
1886                 | RELATIVE                                              { $$ = RELATIVE; }
1887                 | ABSOLUTE
1888                         {
1889                                 elog(NOTICE,"FETCH/ABSOLUTE not supported, using RELATIVE");
1890                                 $$ = RELATIVE;
1891                         }
1892                 | /*EMPTY*/                                             { $$ = FORWARD; /* default */ }
1893                 ;
1894
1895 fetch_how_many:  Iconst                                 { $$ = $1; }
1896                 | '-' Iconst                                    { $$ = - $2; }
1897                 | ALL                                                   { $$ = 0; /* 0 means fetch all tuples*/ }
1898                 | NEXT                                                  { $$ = 1; }
1899                 | PRIOR                                                 { $$ = -1; }
1900                 | /*EMPTY*/                                             { $$ = 1; /*default*/ }
1901                 ;
1902
1903 opt_portal_name:  IN name                               { $$ = $2; }
1904                 | FROM name                                             { $$ = $2; }
1905                 | /*EMPTY*/                                             { $$ = NULL; }
1906                 ;
1907
1908
1909 /*****************************************************************************
1910  *
1911  *              QUERY:
1912  *                              GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1913  *
1914  *****************************************************************************/
1915
1916 GrantStmt:  GRANT privileges ON relation_name_list TO grantee opt_with_grant
1917                                 {
1918                                         $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1919                                 }
1920                 ;
1921
1922 privileges:  ALL PRIVILEGES
1923                                 {
1924                                  $$ = aclmakepriv("rwaR",0);
1925                                 }
1926                 | ALL
1927                                 {
1928                                  $$ = aclmakepriv("rwaR",0);
1929                                 }
1930                 | operation_commalist
1931                                 {
1932                                  $$ = $1;
1933                                 }
1934                 ;
1935
1936 operation_commalist:  operation
1937                                 {
1938                                                 $$ = aclmakepriv("",$1);
1939                                 }
1940                 | operation_commalist ',' operation
1941                                 {
1942                                                 $$ = aclmakepriv($1,$3);
1943                                 }
1944                 ;
1945
1946 operation:  SELECT
1947                                 {
1948                                                 $$ = ACL_MODE_RD_CHR;
1949                                 }
1950                 | INSERT
1951                                 {
1952                                                 $$ = ACL_MODE_AP_CHR;
1953                                 }
1954                 | UPDATE
1955                                 {
1956                                                 $$ = ACL_MODE_WR_CHR;
1957                                 }
1958                 | DELETE
1959                                 {
1960                                                 $$ = ACL_MODE_WR_CHR;
1961                                 }
1962                 | RULE
1963                                 {
1964                                                 $$ = ACL_MODE_RU_CHR;
1965                                 }
1966                 ;
1967
1968 grantee:  PUBLIC
1969                                 {
1970                                                 $$ = aclmakeuser("A","");
1971                                 }
1972                 | GROUP ColId
1973                                 {
1974                                                 $$ = aclmakeuser("G",$2);
1975                                 }
1976                 | ColId
1977                                 {
1978                                                 $$ = aclmakeuser("U",$1);
1979                                 }
1980                 ;
1981
1982 opt_with_grant:  WITH GRANT OPTION
1983                                 {
1984                                         yyerror("WITH GRANT OPTION is not supported.  Only relation owners can set privileges");
1985                                  }
1986                 | /*EMPTY*/
1987                 ;
1988
1989
1990 /*****************************************************************************
1991  *
1992  *              QUERY:
1993  *                              REVOKE [privileges] ON [relation_name] FROM [user]
1994  *
1995  *****************************************************************************/
1996
1997 RevokeStmt:  REVOKE privileges ON relation_name_list FROM grantee
1998                                 {
1999                                         $$ = (Node*)makeAclStmt($2,$4,$6,'-');
2000                                 }
2001                 ;
2002
2003
2004 /*****************************************************************************
2005  *
2006  *              QUERY:
2007  *                              create index <indexname> on <relname>
2008  *                                using <access> "(" (<col> with <op>)+ ")" [with
2009  *                                <target_list>]
2010  *
2011  *      [where <qual>] is not supported anymore
2012  *****************************************************************************/
2013
2014 IndexStmt:      CREATE index_opt_unique INDEX index_name ON relation_name
2015                         access_method_clause '(' index_params ')' opt_with
2016                                 {
2017                                         /* should check that access_method is valid,
2018                                            etc ... but doesn't */
2019                                         IndexStmt *n = makeNode(IndexStmt);
2020                                         n->unique = $2;
2021                                         n->idxname = $4;
2022                                         n->relname = $6;
2023                                         n->accessMethod = $7;
2024                                         n->indexParams = $9;
2025                                         n->withClause = $11;
2026                                         n->whereClause = NULL;
2027                                         $$ = (Node *)n;
2028                                 }
2029                 ;
2030
2031 index_opt_unique:  UNIQUE                                               { $$ = TRUE; }
2032                 | /*EMPTY*/                                                             { $$ = FALSE; }
2033                 ;
2034
2035 access_method_clause:  USING access_method              { $$ = $2; }
2036                 | /*EMPTY*/                                                             { $$ = "btree"; }
2037                 ;
2038
2039 index_params:  index_list                                               { $$ = $1; }
2040                 | func_index                                                    { $$ = lcons($1,NIL); }
2041                 ;
2042
2043 index_list:  index_list ',' index_elem                  { $$ = lappend($1, $3); }
2044                 | index_elem                                                    { $$ = lcons($1, NIL); }
2045                 ;
2046
2047 func_index:  func_name '(' name_list ')' opt_type opt_class
2048                                 {
2049                                         $$ = makeNode(IndexElem);
2050                                         $$->name = $1;
2051                                         $$->args = $3;
2052                                         $$->class = $6;
2053                                         $$->typename = $5;
2054                                 }
2055                   ;
2056
2057 index_elem:  attr_name opt_type opt_class
2058                                 {
2059                                         $$ = makeNode(IndexElem);
2060                                         $$->name = $1;
2061                                         $$->args = NIL;
2062                                         $$->class = $3;
2063                                         $$->typename = $2;
2064                                 }
2065                 ;
2066
2067 opt_type:  ':' Typename                                                 { $$ = $2; }
2068                 | FOR Typename                                                  { $$ = $2; }
2069                 | /*EMPTY*/                                                             { $$ = NULL; }
2070                 ;
2071
2072 /* opt_class "WITH class" conflicts with preceeding opt_type
2073  *  for Typename of "TIMESTAMP WITH TIME ZONE"
2074  * So, remove "WITH class" from the syntax. OK??
2075  * - thomas 1997-10-12
2076  *              | WITH class                                                    { $$ = $2; }
2077  */
2078 opt_class:  class                                                               { $$ = $1; }
2079                 | USING class                                                   { $$ = $2; }
2080                 | /*EMPTY*/                                                             { $$ = NULL; }
2081                 ;
2082
2083
2084 /*****************************************************************************
2085  *
2086  *              QUERY:
2087  *                              extend index <indexname> [where <qual>]
2088  *
2089  *****************************************************************************/
2090
2091 ExtendStmt:  EXTEND INDEX index_name where_clause
2092                                 {
2093                                         ExtendStmt *n = makeNode(ExtendStmt);
2094                                         n->idxname = $3;
2095                                         n->whereClause = $4;
2096                                         $$ = (Node *)n;
2097                                 }
2098                 ;
2099
2100 /*****************************************************************************
2101  *
2102  *              QUERY:
2103  *                              execute recipe <recipeName>
2104  *
2105  *****************************************************************************/
2106
2107 /* NOT USED
2108 RecipeStmt:  EXECUTE RECIPE recipe_name
2109                                 {
2110                                         RecipeStmt *n;
2111                                         if (!IsTransactionBlock())
2112                                                 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
2113
2114                                         n = makeNode(RecipeStmt);
2115                                         n->recipeName = $3;
2116                                         $$ = (Node *)n;
2117                                 }
2118                 ;
2119 */
2120
2121 /*****************************************************************************
2122  *
2123  *              QUERY:
2124  *                              define function <fname>
2125  *                                         (language = <lang>, returntype = <typename>
2126  *                                              [, arch_pct = <percentage | pre-defined>]
2127  *                                              [, disk_pct = <percentage | pre-defined>]
2128  *                                              [, byte_pct = <percentage | pre-defined>]
2129  *                                              [, perbyte_cpu = <int | pre-defined>]
2130  *                                              [, percall_cpu = <int | pre-defined>]
2131  *                                              [, iscachable])
2132  *                                              [arg is (<type-1> { , <type-n>})]
2133  *                                              as <filename or code in language as appropriate>
2134  *
2135  *****************************************************************************/
2136
2137 ProcedureStmt:  CREATE FUNCTION func_name func_args
2138                          RETURNS func_return opt_with AS func_as LANGUAGE Sconst
2139                                 {
2140                                         ProcedureStmt *n = makeNode(ProcedureStmt);
2141                                         n->funcname = $3;
2142                                         n->defArgs = $4;
2143                                         n->returnType = $6;
2144                                         n->withClause = $7;
2145                                         n->as = $9;
2146                                         n->language = $11;
2147                                         $$ = (Node *)n;
2148                                 };
2149
2150 opt_with:  WITH definition                                              { $$ = $2; }
2151                 | /*EMPTY*/                                                             { $$ = NIL; }
2152                 ;
2153
2154 func_args:  '(' func_args_list ')'                              { $$ = $2; }
2155                 | '(' ')'                                                               { $$ = NIL; }
2156                 ;
2157
2158 func_args_list:  TypeId
2159                                 {       $$ = lcons(makeString($1),NIL); }
2160                 | func_args_list ',' TypeId
2161                                 {       $$ = lappend($1,makeString($3)); }
2162                 ;
2163
2164 func_as: Sconst 
2165                                 {   $$ = lcons(makeString($1),NIL); }
2166                 | Sconst ',' Sconst
2167                                 {       $$ = lappend(lcons(makeString($1),NIL), makeString($3)); }
2168                 ;
2169
2170 func_return:  set_opt TypeId
2171                                 {
2172                                         TypeName *n = makeNode(TypeName);
2173                                         n->name = $2;
2174                                         n->setof = $1;
2175                                         n->arrayBounds = NULL;
2176                                         $$ = (Node *)n;
2177                                 }
2178                 ;
2179
2180 set_opt:  SETOF                                                                 { $$ = TRUE; }
2181                 | /*EMPTY*/                                                             { $$ = FALSE; }
2182                 ;
2183
2184 /*****************************************************************************
2185  *
2186  *              QUERY:
2187  *
2188  *              remove function <funcname>
2189  *                              (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
2190  *              remove aggregate <aggname>
2191  *                              (REMOVE AGGREGATE "aggname" "aggtype")
2192  *              remove operator <opname>
2193  *                              (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
2194  *              remove type <typename>
2195  *                              (REMOVE TYPE "typename")
2196  *              remove rule <rulename>
2197  *                              (REMOVE RULE "rulename")
2198  *
2199  *****************************************************************************/
2200
2201 RemoveStmt:  DROP remove_type name
2202                                 {
2203                                         RemoveStmt *n = makeNode(RemoveStmt);
2204                                         n->removeType = $2;
2205                                         n->name = $3;
2206                                         $$ = (Node *)n;
2207                                 }
2208                 ;
2209
2210 remove_type:  TYPE_P                                                    {  $$ = TYPE_P; }
2211                 | INDEX                                                                 {  $$ = INDEX; }
2212                 | RULE                                                                  {  $$ = RULE; }
2213                 | VIEW                                                                  {  $$ = VIEW; }
2214                 ;
2215
2216
2217 RemoveAggrStmt:  DROP AGGREGATE name aggr_argtype
2218                                 {
2219                                                 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
2220                                                 n->aggname = $3;
2221                                                 n->aggtype = $4;
2222                                                 $$ = (Node *)n;
2223                                 }
2224                 ;
2225
2226 aggr_argtype:  name                                                             { $$ = $1; }
2227                 | '*'                                                                   { $$ = NULL; }
2228                 ;
2229
2230
2231 RemoveFuncStmt:  DROP FUNCTION func_name func_args
2232                                 {
2233                                         RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
2234                                         n->funcname = $3;
2235                                         n->args = $4;
2236                                         $$ = (Node *)n;
2237                                 }
2238                 ;
2239
2240
2241 RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')'
2242                                 {
2243                                         RemoveOperStmt *n = makeNode(RemoveOperStmt);
2244                                         n->opname = $3;
2245                                         n->args = $5;
2246                                         $$ = (Node *)n;
2247                                 }
2248                 ;
2249
2250 oper_argtypes:  name
2251                                 {
2252                                    elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
2253                                 }
2254                 | name ',' name
2255                                 { $$ = makeList(makeString($1), makeString($3), -1); }
2256                 | NONE ',' name                 /* left unary */
2257                                 { $$ = makeList(NULL, makeString($3), -1); }
2258                 | name ',' NONE                 /* right unary */
2259                                 { $$ = makeList(makeString($1), NULL, -1); }
2260                 ;
2261
2262
2263 /*****************************************************************************
2264  *
2265  *              QUERY:
2266  *                              rename <attrname1> in <relname> [*] to <attrname2>
2267  *                              rename <relname1> to <relname2>
2268  *
2269  *****************************************************************************/
2270
2271 RenameStmt:  ALTER TABLE relation_name opt_inh_star
2272                                   RENAME opt_column opt_name TO name
2273                                 {
2274                                         RenameStmt *n = makeNode(RenameStmt);
2275                                         n->relname = $3;
2276                                         n->inh = $4;
2277                                         n->column = $7;
2278                                         n->newname = $9;
2279                                         $$ = (Node *)n;
2280                                 }
2281                 ;
2282
2283 opt_name:  name                                                 { $$ = $1; }
2284                 | /*EMPTY*/                                             { $$ = NULL; }
2285                 ;
2286
2287 opt_column:  COLUMN                                             { $$ = COLUMN; }
2288                 | /*EMPTY*/                                             { $$ = 0; }
2289                 ;
2290
2291
2292 /*****************************************************************************
2293  *
2294  *              QUERY:  Define Rewrite Rule , Define Tuple Rule
2295  *                              Define Rule <old rules >
2296  *
2297  *              only rewrite rule is supported -- ay 9/94
2298  *
2299  *****************************************************************************/
2300
2301 RuleStmt:  CREATE RULE name AS
2302                    { QueryIsRule=TRUE; }
2303                    ON event TO event_object where_clause
2304                    DO opt_instead RuleActionList
2305                                 {
2306                                         RuleStmt *n = makeNode(RuleStmt);
2307                                         n->rulename = $3;
2308                                         n->event = $7;
2309                                         n->object = $9;
2310                                         n->whereClause = $10;
2311                                         n->instead = $12;
2312                                         n->actions = $13;
2313                                         $$ = (Node *)n;
2314                                 }
2315                 ;
2316
2317 RuleActionList:  NOTHING                                { $$ = NIL; }
2318                 | SelectStmt                                    { $$ = lcons($1, NIL); }
2319                 | RuleActionStmt                                { $$ = lcons($1, NIL); }
2320                 | '[' RuleActionMulti ']'               { $$ = $2; }
2321                 | '(' RuleActionMulti ')'               { $$ = $2; } 
2322                 ;
2323
2324 /* the thrashing around here is to discard "empty" statements... */
2325 RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
2326                                 { if ($3 != (Node *)NULL)
2327                                         $$ = lappend($1, $3);
2328                                   else
2329                                         $$ = $1;
2330                                 }
2331                 | RuleActionStmtOrEmpty
2332                                 { if ($1 != (Node *)NULL)
2333                                         $$ = lcons($1,NIL);
2334                                   else
2335                                         $$ = NIL;
2336                                 }
2337                 ;
2338
2339 RuleActionStmt: InsertStmt
2340                 | UpdateStmt
2341                 | DeleteStmt
2342                 | NotifyStmt
2343                 ;
2344
2345 RuleActionStmtOrEmpty:  RuleActionStmt
2346                 |       /*EMPTY*/
2347                                 { $$ = (Node *)NULL; }
2348                 ;
2349
2350 event_object:  relation_name '.' attr_name
2351                                 {
2352                                         $$ = makeNode(Attr);
2353                                         $$->relname = $1;
2354                                         $$->paramNo = NULL;
2355                                         $$->attrs = lcons(makeString($3), NIL);
2356                                         $$->indirection = NIL;
2357                                 }
2358                 | relation_name
2359                                 {
2360                                         $$ = makeNode(Attr);
2361                                         $$->relname = $1;
2362                                         $$->paramNo = NULL;
2363                                         $$->attrs = NIL;
2364                                         $$->indirection = NIL;
2365                                 }
2366                 ;
2367
2368 /* change me to select, update, etc. some day */
2369 event:  SELECT                                                  { $$ = CMD_SELECT; }
2370                 | UPDATE                                                { $$ = CMD_UPDATE; }
2371                 | DELETE                                                { $$ = CMD_DELETE; }
2372                 | INSERT                                                { $$ = CMD_INSERT; }
2373                  ;
2374
2375 opt_instead:  INSTEAD                                   { $$ = TRUE; }
2376                 | /*EMPTY*/                                             { $$ = FALSE; }
2377                 ;
2378
2379
2380 /*****************************************************************************
2381  *
2382  *              QUERY:
2383  *                              NOTIFY <relation_name>  can appear both in rule bodies and
2384  *                              as a query-level command
2385  *
2386  *****************************************************************************/
2387
2388 NotifyStmt:  NOTIFY relation_name
2389                                 {
2390                                         NotifyStmt *n = makeNode(NotifyStmt);
2391                                         n->relname = $2;
2392                                         $$ = (Node *)n;
2393                                 }
2394                 ;
2395
2396 ListenStmt:  LISTEN relation_name
2397                                 {
2398                                         ListenStmt *n = makeNode(ListenStmt);
2399                                         n->relname = $2;
2400                                         $$ = (Node *)n;
2401                                 }
2402 ;
2403
2404 UnlistenStmt:  UNLISTEN relation_name
2405                                 {
2406                                         UnlistenStmt *n = makeNode(UnlistenStmt);
2407                                         n->relname = $2;
2408                                         $$ = (Node *)n;
2409                                 }
2410                 | UNLISTEN '*'
2411                                 {
2412                                         UnlistenStmt *n = makeNode(UnlistenStmt);
2413                                         n->relname = "*";
2414                                         $$ = (Node *)n;
2415                                 }
2416 ;
2417
2418
2419 /*****************************************************************************
2420  *
2421  *              Transactions:
2422  *
2423  *              abort transaction
2424  *                              (ABORT)
2425  *              begin transaction
2426  *                              (BEGIN)
2427  *              end transaction
2428  *                              (END)
2429  *
2430  *****************************************************************************/
2431
2432 TransactionStmt: ABORT_TRANS opt_trans
2433                                 {
2434                                         TransactionStmt *n = makeNode(TransactionStmt);
2435                                         n->command = ABORT_TRANS;
2436                                         $$ = (Node *)n;
2437                                 }
2438                 | BEGIN_TRANS opt_trans
2439                                 {
2440                                         TransactionStmt *n = makeNode(TransactionStmt);
2441                                         n->command = BEGIN_TRANS;
2442                                         $$ = (Node *)n;
2443                                 }
2444                 | COMMIT opt_trans
2445                                 {
2446                                         TransactionStmt *n = makeNode(TransactionStmt);
2447                                         n->command = END_TRANS;
2448                                         $$ = (Node *)n;
2449                                 }
2450                 | END_TRANS opt_trans
2451                                 {
2452                                         TransactionStmt *n = makeNode(TransactionStmt);
2453                                         n->command = END_TRANS;
2454                                         $$ = (Node *)n;
2455                                 }
2456                 | ROLLBACK opt_trans
2457                                 {
2458                                         TransactionStmt *n = makeNode(TransactionStmt);
2459                                         n->command = ABORT_TRANS;
2460                                         $$ = (Node *)n;
2461                                 }
2462                 ;
2463
2464 opt_trans: WORK                                                                 { $$ = TRUE; }
2465                 | TRANSACTION                                                   { $$ = TRUE; }
2466                 | /*EMPTY*/                                                             { $$ = TRUE; }
2467                 ;
2468
2469
2470 /*****************************************************************************
2471  *
2472  *              QUERY:
2473  *                              define view <viewname> '('target-list ')' [where <quals> ]
2474  *
2475  *****************************************************************************/
2476
2477 ViewStmt:  CREATE VIEW name AS SelectStmt
2478                                 {
2479                                         ViewStmt *n = makeNode(ViewStmt);
2480                                         n->viewname = $3;
2481                                         n->query = (Query *)$5;
2482                                         if (((SelectStmt *)n->query)->sortClause != NULL)
2483                                                 elog(ERROR,"Order by and Distinct on views is not implemented.");
2484                                         if (((SelectStmt *)n->query)->unionClause != NULL)
2485                                                 elog(ERROR,"Views on unions not implemented.");
2486                                         if (((SelectStmt *)n->query)->forUpdate != NULL)
2487                                                 elog(ERROR, "SELECT FOR UPDATE is not allowed in CREATE VIEW");
2488                                         $$ = (Node *)n;
2489                                 }
2490                 ;
2491
2492
2493 /*****************************************************************************
2494  *
2495  *              QUERY:
2496  *                              load "filename"
2497  *
2498  *****************************************************************************/
2499
2500 LoadStmt:  LOAD file_name
2501                                 {
2502                                         LoadStmt *n = makeNode(LoadStmt);
2503                                         n->filename = $2;
2504                                         $$ = (Node *)n;
2505                                 }
2506                 ;
2507
2508
2509 /*****************************************************************************
2510  *
2511  *              QUERY:
2512  *                              createdb dbname
2513  *
2514  *****************************************************************************/
2515
2516 CreatedbStmt:  CREATE DATABASE database_name WITH opt_database1 opt_database2
2517                                 {
2518                                         CreatedbStmt *n = makeNode(CreatedbStmt);
2519                                         if ($5 == NULL && $6 == NULL) {
2520                                                 elog(ERROR, "CREATE DATABASE WITH requires at least an option");
2521                                         }
2522                                         n->dbname = $3;
2523                                         n->dbpath = $5;
2524 #ifdef MULTIBYTE
2525                                         if ($6 != NULL) {
2526                                                 n->encoding = pg_char_to_encoding($6);
2527                                                 if (n->encoding < 0) {
2528                                                         elog(ERROR, "invalid encoding name %s", $6);
2529                                                 }
2530                                         } else {
2531                                                 n->encoding = GetTemplateEncoding();
2532                                         }
2533 #else
2534                                         if ($6 != NULL)
2535                                                 elog(ERROR, "WITH ENCODING is not supported");
2536                                         n->encoding = 0;
2537 #endif
2538                                         $$ = (Node *)n;
2539                                 }
2540                 | CREATE DATABASE database_name
2541                                 {
2542                                         CreatedbStmt *n = makeNode(CreatedbStmt);
2543                                         n->dbname = $3;
2544                                         n->dbpath = NULL;
2545 #ifdef MULTIBYTE
2546                                         n->encoding = GetTemplateEncoding();
2547 #else
2548                                         n->encoding = 0;
2549 #endif
2550                                         $$ = (Node *)n;
2551                                 }
2552                 ;
2553
2554 opt_database1:  LOCATION '=' location                   { $$ = $3; }
2555                 | /*EMPTY*/                                                             { $$ = NULL; }
2556                 ;
2557
2558 opt_database2:  ENCODING '=' encoding                   { $$ = $3; }
2559                 | /*EMPTY*/                                                             { $$ = NULL; }
2560                 ;
2561
2562 location:  Sconst                                                               { $$ = $1; }
2563                 | DEFAULT                                                               { $$ = NULL; }
2564                 | /*EMPTY*/                                                             { $$ = NULL; }
2565                 ;
2566
2567 encoding:  Sconst                                                               { $$ = $1; }
2568                 | DEFAULT                                                               { $$ = NULL; }
2569                 | /*EMPTY*/                                                             { $$ = NULL; }
2570                 ;
2571
2572 /*****************************************************************************
2573  *
2574  *              QUERY:
2575  *                              dropdb dbname
2576  *
2577  *****************************************************************************/
2578
2579 DropdbStmt:     DROP DATABASE database_name
2580                                 {
2581                                         DropdbStmt *n = makeNode(DropdbStmt);
2582                                         n->dbname = $3;
2583                                         $$ = (Node *)n;
2584                                 }
2585                 ;
2586
2587
2588 /*****************************************************************************
2589  *
2590  *              QUERY:
2591  *                              cluster <index_name> on <relation_name>
2592  *
2593  *****************************************************************************/
2594
2595 ClusterStmt:  CLUSTER index_name ON relation_name
2596                                 {
2597                                    ClusterStmt *n = makeNode(ClusterStmt);
2598                                    n->relname = $4;
2599                                    n->indexname = $2;
2600                                    $$ = (Node*)n;
2601                                 }
2602                 ;
2603
2604 /*****************************************************************************
2605  *
2606  *              QUERY:
2607  *                              vacuum
2608  *
2609  *****************************************************************************/
2610
2611 VacuumStmt:  VACUUM opt_verbose opt_analyze
2612                                 {
2613                                         VacuumStmt *n = makeNode(VacuumStmt);
2614                                         n->verbose = $2;
2615                                         n->analyze = $3;
2616                                         n->vacrel = NULL;
2617                                         n->va_spec = NIL;
2618                                         $$ = (Node *)n;
2619                                 }
2620                 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2621                                 {
2622                                         VacuumStmt *n = makeNode(VacuumStmt);
2623                                         n->verbose = $2;
2624                                         n->analyze = $3;
2625                                         n->vacrel = $4;
2626                                         n->va_spec = $5;
2627                                         if ( $5 != NIL && !$4 )
2628                                                 elog(ERROR,"parser: syntax error at or near \"(\"");
2629                                         $$ = (Node *)n;
2630                                 }
2631                 ;
2632
2633 opt_verbose:  VERBOSE                                                   { $$ = TRUE; }
2634                 | /*EMPTY*/                                                             { $$ = FALSE; }
2635                 ;
2636
2637 opt_analyze:  ANALYZE                                                   { $$ = TRUE; }
2638                 | /*EMPTY*/                                                             { $$ = FALSE; }
2639                 ;
2640
2641 opt_va_list:  '(' va_list ')'                                   { $$ = $2; }
2642                 | /*EMPTY*/                                                             { $$ = NIL; }
2643                 ;
2644
2645 va_list:  name
2646                                 { $$=lcons($1,NIL); }
2647                 | va_list ',' name
2648                                 { $$=lappend($1,$3); }
2649                 ;
2650
2651
2652 /*****************************************************************************
2653  *
2654  *              QUERY:
2655  *                              EXPLAIN query
2656  *
2657  *****************************************************************************/
2658
2659 ExplainStmt:  EXPLAIN opt_verbose OptimizableStmt
2660                                 {
2661                                         ExplainStmt *n = makeNode(ExplainStmt);
2662                                         n->verbose = $2;
2663                                         n->query = (Query*)$3;
2664                                         $$ = (Node *)n;
2665                                 }
2666                 ;
2667
2668
2669 /*****************************************************************************
2670  *                                                                                                                                                       *
2671  *              Optimizable Stmts:                                                                                                       *
2672  *                                                                                                                                                       *
2673  *              one of the five queries processed by the planner                                         *
2674  *                                                                                                                                                       *
2675  *              [ultimately] produces query-trees as specified                                           *
2676  *              in the query-spec document in ~postgres/ref                                                      *
2677  *                                                                                                                                                       *
2678  *****************************************************************************/
2679
2680 OptimizableStmt:  SelectStmt
2681                 | CursorStmt
2682                 | UpdateStmt
2683                 | InsertStmt
2684                 | NotifyStmt
2685                 | DeleteStmt                                    /* by default all are $$=$1 */
2686                 ;
2687
2688
2689 /*****************************************************************************
2690  *
2691  *              QUERY:
2692  *                              INSERT STATEMENTS
2693  *
2694  *****************************************************************************/
2695
2696 /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
2697  * originally. When the second rule of 'insert_rest' was changed to use the
2698  * new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
2699  * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to
2700  * accept the same statements without any shift/reduce conflicts
2701  */
2702 InsertStmt:  INSERT INTO relation_name insert_rest
2703                                 {
2704                                         $4->relname = $3;
2705                                         $$ = (Node *) $4;
2706                                 }
2707                 ;
2708
2709 insert_rest:  VALUES '(' target_list ')'
2710                                 {
2711                                         $$ = makeNode(InsertStmt);
2712                                         $$->cols = NULL;
2713                                         $$->unique = NULL;
2714                                         $$->targetList = $3;
2715                                         $$->fromClause = NIL;
2716                                         $$->whereClause = NULL;
2717                                         $$->groupClause = NIL;
2718                                         $$->havingClause = NULL;
2719                                         $$->unionClause = NIL;
2720                                 }
2721                 | DEFAULT VALUES
2722                                 {
2723                                         $$ = makeNode(InsertStmt);
2724                                         $$->unique = NULL;
2725                                         $$->targetList = NIL;
2726                                         $$->fromClause = NIL;
2727                                         $$->whereClause = NULL;
2728                                         $$->groupClause = NIL;
2729                                         $$->havingClause = NULL;
2730                                         $$->unionClause = NIL;
2731                                         $$->intersectClause = NIL;
2732                                 }
2733 /* We want the full power of SelectStatements including INTERSECT and EXCEPT
2734  * for insertion.  However, we can't support sort or limit clauses.
2735  */
2736                 | SelectStmt
2737                                 {
2738                                         SelectStmt *n = (SelectStmt *) $1;
2739                                         if (n->sortClause)
2740                                                 elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
2741                                         $$ = makeNode(InsertStmt);
2742                                         $$->cols = NIL;
2743                                         $$->unique = n->unique;
2744                                         $$->targetList = n->targetList;
2745                                         $$->fromClause = n->fromClause;
2746                                         $$->whereClause = n->whereClause;
2747                                         $$->groupClause = n->groupClause;
2748                                         $$->havingClause = n->havingClause;
2749                                         $$->unionClause = n->unionClause;
2750                                         $$->intersectClause = n->intersectClause;
2751                                         $$->unionall = n->unionall;
2752                                         $$->forUpdate = n->forUpdate;
2753                                 }
2754                 | '(' columnList ')' VALUES '(' target_list ')'
2755                                 {
2756                                         $$ = makeNode(InsertStmt);
2757                                         $$->cols = $2;
2758                                         $$->unique = NULL;
2759                                         $$->targetList = $6;
2760                                         $$->fromClause = NIL;
2761                                         $$->whereClause = NULL;
2762                                         $$->groupClause = NIL;
2763                                         $$->havingClause = NULL;
2764                                         $$->unionClause = NIL; 
2765                                         $$->intersectClause = NIL;
2766                                 }
2767                 | '(' columnList ')' SelectStmt
2768                                 {
2769                                         SelectStmt *n = (SelectStmt *) $4;
2770                                         if (n->sortClause)
2771                                                 elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
2772                                         $$ = makeNode(InsertStmt);
2773                                         $$->cols = $2;
2774                                         $$->unique = n->unique;
2775                                         $$->targetList = n->targetList;
2776                                         $$->fromClause = n->fromClause;
2777                                         $$->whereClause = n->whereClause;
2778                                         $$->groupClause = n->groupClause;
2779                                         $$->havingClause = n->havingClause;
2780                                         $$->unionClause = n->unionClause;
2781                                         $$->intersectClause = n->intersectClause;
2782                                         $$->unionall = n->unionall;
2783                                         $$->forUpdate = n->forUpdate;
2784                                 }
2785                 ;
2786
2787 opt_column_list:  '(' columnList ')'                    { $$ = $2; }
2788                 | /*EMPTY*/                                                             { $$ = NIL; }
2789                 ;
2790
2791 columnList:
2792                   columnList ',' columnElem
2793                                 { $$ = lappend($1, $3); }
2794                 | columnElem
2795                                 { $$ = lcons($1, NIL); }
2796                 ;
2797
2798 columnElem:  ColId opt_indirection
2799                                 {
2800                                         Ident *id = makeNode(Ident);
2801                                         id->name = $1;
2802                                         id->indirection = $2;
2803                                         $$ = (Node *)id;
2804                                 }
2805                 ;
2806
2807
2808 /*****************************************************************************
2809  *
2810  *              QUERY:
2811  *                              DELETE STATEMENTS
2812  *
2813  *****************************************************************************/
2814
2815 DeleteStmt:  DELETE FROM relation_name
2816                          where_clause
2817                                 {
2818                                         DeleteStmt *n = makeNode(DeleteStmt);
2819                                         n->relname = $3;
2820                                         n->whereClause = $4;
2821                                         $$ = (Node *)n;
2822                                 }
2823                 ;
2824
2825 LockStmt:       LOCK_P opt_table relation_name opt_lock
2826                                 {
2827                                         LockStmt *n = makeNode(LockStmt);
2828
2829                                         n->relname = $3;
2830                                         n->mode = $4;
2831                                         $$ = (Node *)n;
2832                                 }
2833                 ;
2834
2835 opt_lock:  IN lock_type MODE            { $$ = $2; }
2836                 | /*EMPTY*/                             { $$ = AccessExclusiveLock; }
2837                 ;
2838
2839 lock_type:  SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; }
2840                 | ROW opt_lmode                 { $$ = ($2? RowShareLock: RowExclusiveLock); }
2841                 | ACCESS opt_lmode              { $$ = ($2? AccessShareLock: AccessExclusiveLock); }
2842                 | opt_lmode                             { $$ = ($1? ShareLock: ExclusiveLock); }
2843                 ;
2844
2845 opt_lmode:      SHARE                           { $$ = TRUE; }
2846                 | EXCLUSIVE                             { $$ = FALSE; }
2847                 ;
2848
2849
2850 /*****************************************************************************
2851  *
2852  *              QUERY:
2853  *                              UpdateStmt (UPDATE)
2854  *
2855  *****************************************************************************/
2856
2857 UpdateStmt:  UPDATE relation_name
2858                           SET update_target_list
2859                           from_clause
2860                           where_clause
2861                                 {
2862                                         UpdateStmt *n = makeNode(UpdateStmt);
2863                                         n->relname = $2;
2864                                         n->targetList = $4;
2865                                         n->fromClause = $5;
2866                                         n->whereClause = $6;
2867                                         $$ = (Node *)n;
2868                                 }
2869                 ;
2870
2871
2872 /*****************************************************************************
2873  *
2874  *              QUERY:
2875  *                              CURSOR STATEMENTS
2876  *
2877  *****************************************************************************/
2878 CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
2879                                 {
2880                                         SelectStmt *n;
2881   
2882                                         n= (SelectStmt *)$6;
2883                                         /* from PORTAL name */
2884                                         /*
2885                                          *      15 august 1991 -- since 3.0 postgres does locking
2886                                          *      right, we discovered that portals were violating
2887                                          *      locking protocol.  portal locks cannot span xacts.
2888                                          *      as a short-term fix, we installed the check here.
2889                                          *                                                      -- mao
2890                                          */
2891                                         if (!IsTransactionBlock())
2892                                                 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2893
2894                                         n->portalname = $2;
2895                                         n->binary = $3;
2896                                         if (n->forUpdate != NULL)
2897                                                         elog(ERROR,"DECLARE/UPDATE not supported;"
2898                                                                                 " Cursors must be READ ONLY.");
2899                                         $$ = (Node *)n;
2900                                 }
2901                 ;
2902
2903 opt_cursor:  BINARY                                             { $$ = TRUE; }
2904                 | INSENSITIVE                                   { $$ = FALSE; }
2905                 | SCROLL                                                { $$ = FALSE; }
2906                 | INSENSITIVE SCROLL                    { $$ = FALSE; }
2907                 | /*EMPTY*/                                             { $$ = FALSE; }
2908                 ;
2909
2910 /*****************************************************************************
2911  *
2912  *              QUERY:
2913  *                              SELECT STATEMENTS
2914  *
2915  *****************************************************************************/
2916
2917 /* A complete SELECT statement looks like this.  Note sort, for_update,
2918  * and limit clauses can only appear once, not in each subselect.
2919  * 
2920  * The rule returns a SelectStmt Node having the set operations attached to 
2921  * unionClause and intersectClause (NIL if no set operations were present)
2922  */
2923
2924 SelectStmt:       select_clause sort_clause for_update_clause opt_select_limit
2925                         {
2926                                 if IsA($1, SelectStmt)
2927                                 {
2928                                         /* There were no set operations, so just attach the
2929                                          * one-time clauses.
2930                                          */
2931                                         SelectStmt *n = (SelectStmt *) $1;
2932                                         n->sortClause = $2;
2933                                         n->forUpdate = $3;
2934                                         n->limitOffset = nth(0, $4);
2935                                         n->limitCount = nth(1, $4);
2936                                         $$ = (Node *) n;
2937                 }
2938                                 else
2939                                 {
2940                                         /* There were set operations.  The root of the operator
2941                                          * tree is delivered by $1, but we must hand back a
2942                                          * SelectStmt node not an A_Expr Node.
2943                                          * So we find the leftmost 'SelectStmt' in the operator
2944                                          * tree $1 (which is the first Select Statement in the
2945                                          * query), which will be the returned node.
2946                                          * Then we attach the whole operator tree to that node's
2947                                          * 'intersectClause', and a list of all 'SelectStmt' Nodes
2948                                          * in the tree to its 'unionClause'. (NOTE that this means
2949                                          * the top node has indirect recursive pointers to itself!
2950                                          * This would cause trouble if we tried copyObject!!)
2951                                          * The intersectClause and unionClause subtrees will be
2952                                          * left untouched by the main parser, and will only be
2953                                          * processed when control gets to the function
2954                                          * Except_Intersect_Rewrite() (in rewriteHandler.c).
2955                                          */
2956                                         Node *op = (Node *) $1;
2957                                         List *select_list = NIL;
2958                                         SelectStmt *first_select;
2959                                         bool    intersect_present = false,
2960                                                         unionall_present = false;
2961
2962                                         /* Take the operator tree as an argument and create a
2963                                          * list of all SelectStmt Nodes found in the tree.
2964                                          *
2965                                          * If one of the SelectStmt Nodes has the 'unionall' flag
2966                                          * set to true the 'unionall_present' flag is also set to
2967                                          * true.
2968                                          */
2969                                         create_select_list(op, &select_list, &unionall_present);
2970
2971                                         /* Replace all the A_Expr Nodes in the operator tree by
2972                                          * Expr Nodes.
2973                                          *
2974                                          * If an INTERSECT or an EXCEPT is present, the 
2975                                          * 'intersect_present' flag is set to true
2976                                          */
2977                                         op = A_Expr_to_Expr(op, &intersect_present);
2978
2979                                         /* If both flags are set to true we have a UNION ALL
2980                                          * statement mixed up with INTERSECT or EXCEPT 
2981                                          * which can not be handled at the moment.
2982                                          */
2983                                         if (intersect_present && unionall_present)
2984                                                 elog(ERROR, "UNION ALL not allowed in mixed set operations");
2985
2986                                         /* Get the leftmost SeletStmt Node (which automatically
2987                                          * represents the first Select Statement of the query!)
2988                                          */
2989                                         first_select = (SelectStmt *) lfirst(select_list);
2990
2991                                         /* Attach the list of all SeletStmt Nodes to unionClause */
2992                                         first_select->unionClause = select_list;
2993
2994                                         /* Attach the whole operator tree to intersectClause */
2995                                         first_select->intersectClause = (List *) op;
2996
2997                                         /* finally attach the sort clause &etc */
2998                                         first_select->sortClause = $2;
2999                                         first_select->forUpdate = $3;
3000                                         first_select->limitOffset = nth(0, $4);
3001                                         first_select->limitCount = nth(1, $4);
3002                                         $$ = (Node *) first_select;
3003                                 }               
3004                                 if (((SelectStmt *)$$)->forUpdate != NULL && QueryIsRule)
3005                                         elog(ERROR, "SELECT FOR UPDATE is not allowed in RULES");
3006                         }
3007                 ;
3008
3009 /* This rule parses Select statements that can appear within set operations,
3010  * including UNION, INTERSECT and EXCEPT.  '(' and ')' can be used to specify
3011  * the ordering of the set operations.  Without '(' and ')' we want the
3012  * operations to be left associative.
3013  *
3014  * Note that sort clauses cannot be included at this level --- a sort clause
3015  * can only appear at the end of the complete Select, and it will be handled
3016  * by the topmost SelectStmt rule.  Likewise FOR UPDATE and LIMIT.
3017  * 
3018  * The rule builds up an operator tree using A_Expr Nodes. AND Nodes represent
3019  * INTERSECTs, OR Nodes represent UNIONs, and AND NOT nodes represent EXCEPTs. 
3020  * The SelectStatements to be connected are the left and right arguments to
3021  * the A_Expr Nodes.
3022  * If no set operations appear in the query, the tree consists only of one
3023  * SelectStmt Node.
3024  */
3025 select_clause: '(' select_clause ')'
3026                         {
3027                                 $$ = $2; 
3028                         }
3029                 | SubSelect
3030                         {
3031                                 $$ = $1; 
3032                         }
3033                 | select_clause EXCEPT select_clause
3034                         {
3035                                 $$ = (Node *)makeA_Expr(AND,NULL,$1,
3036                                                         makeA_Expr(NOT,NULL,NULL,$3));
3037                         }
3038                 | select_clause UNION opt_all select_clause
3039                         {       
3040                                 if (IsA($4, SelectStmt))
3041                                   {
3042                                      SelectStmt *n = (SelectStmt *)$4;
3043                                      n->unionall = $3;
3044                                          /* NOTE: if UNION ALL appears with a parenthesized set
3045                                           * operation to its right, the ALL is silently discarded.
3046                                           * Should we generate an error instead?  I think it may
3047                                           * be OK since ALL with UNION to its right is ignored
3048                                           * anyway...
3049                                           */
3050                                   }
3051                                 $$ = (Node *)makeA_Expr(OR,NULL,$1,$4);
3052                         }
3053                 | select_clause INTERSECT select_clause
3054                         {
3055                                 $$ = (Node *)makeA_Expr(AND,NULL,$1,$3);
3056                         }
3057                 ; 
3058
3059 SubSelect:      SELECT opt_unique target_list
3060                          result from_clause where_clause
3061                          group_clause having_clause
3062                                 {
3063                                         SelectStmt *n = makeNode(SelectStmt);
3064                                         n->unique = $2;
3065                                         n->unionall = FALSE;
3066                                         n->targetList = $3;
3067                                         /* This is new: Subselects support the INTO clause
3068                                          * which allows queries that are not part of the
3069                                          * SQL92 standard and should not be formulated!
3070                                          * We need it for INTERSECT and EXCEPT and I did not
3071                                          * want to create a new rule 'SubSelect1' including the
3072                                          * feature. If it makes troubles we will have to add 
3073                                          * a new rule and change this to prevent INTOs in 
3074                                          * Subselects again.
3075                                          */
3076                                         n->istemp = (bool) ((Value *) lfirst($4))->val.ival;
3077                                         n->into = (char *) lnext($4);
3078
3079                                         n->fromClause = $5;
3080                                         n->whereClause = $6;
3081                                         n->groupClause = $7;
3082                                         n->havingClause = $8;
3083                                         $$ = (Node *)n;
3084                                 }
3085                 ;
3086
3087                 /* easy way to return two values. Can someone improve this?  bjm */
3088 result:  INTO OptTemp opt_table relation_name   { $$ = lcons(makeInteger($2), (List *)$4); }
3089                 | /*EMPTY*/                                                             { $$ = lcons(makeInteger(false), NIL); }
3090                 ;
3091
3092 opt_table:  TABLE                                                               { $$ = TRUE; }
3093                 | /*EMPTY*/                                                             { $$ = FALSE; }
3094                 ;
3095
3096 opt_all:  ALL                                                                   { $$ = TRUE; }
3097                 | /*EMPTY*/                                                             { $$ = FALSE; }
3098                 ;
3099
3100 opt_unique:  DISTINCT                                                   { $$ = "*"; }
3101                 | DISTINCT ON ColId                                             { $$ = $3; }
3102                 | ALL                                                                   { $$ = NULL; }
3103                 | /*EMPTY*/                                                             { $$ = NULL; }
3104                 ;
3105
3106 sort_clause:  ORDER BY sortby_list                              { $$ = $3; }
3107                 | /*EMPTY*/                                                             { $$ = NIL; }
3108                 ;
3109
3110 sortby_list:  sortby                                                    { $$ = lcons($1, NIL); }
3111                 | sortby_list ',' sortby                                { $$ = lappend($1, $3); }
3112                 ;
3113
3114 sortby: a_expr OptUseOp
3115                                 {
3116                                         $$ = makeNode(SortGroupBy);
3117                                         $$->node = $1;
3118                                         $$->useOp = $2;
3119                                 }
3120                 ;
3121
3122 OptUseOp:  USING all_Op                                                 { $$ = $2; }
3123                 | ASC                                                                   { $$ = "<"; }
3124                 | DESC                                                                  { $$ = ">"; }
3125                 | /*EMPTY*/                                                             { $$ = "<"; /*default*/ }
3126                 ;
3127
3128
3129 opt_select_limit:       LIMIT select_limit_value ',' select_offset_value
3130                         { $$ = lappend(lappend(NIL, $4), $2); }
3131                 | LIMIT select_limit_value OFFSET select_offset_value
3132                         { $$ = lappend(lappend(NIL, $4), $2); }
3133                 | LIMIT select_limit_value
3134                         { $$ = lappend(lappend(NIL, NULL), $2); }
3135                 | OFFSET select_offset_value LIMIT select_limit_value
3136                         { $$ = lappend(lappend(NIL, $2), $4); }
3137                 | OFFSET select_offset_value
3138                         { $$ = lappend(lappend(NIL, $2), NULL); }
3139                 | /* EMPTY */
3140                         { $$ = lappend(lappend(NIL, NULL), NULL); }
3141                 ;
3142
3143 select_limit_value:             Iconst
3144                         {
3145                                 Const   *n = makeNode(Const);
3146
3147                                 if ($1 < 1)
3148                                         elog(ERROR, "selection limit must be ALL or a positive integer value > 0");
3149
3150                                 n->consttype    = INT4OID;
3151                                 n->constlen             = sizeof(int4);
3152                                 n->constvalue   = (Datum)$1;
3153                                 n->constisnull  = FALSE;
3154                                 n->constbyval   = TRUE;
3155                                 n->constisset   = FALSE;
3156                                 n->constiscast  = FALSE;
3157                                 $$ = (Node *)n;
3158                         }
3159                 | ALL
3160                         {
3161                                 Const   *n = makeNode(Const);
3162
3163                                 n->consttype    = INT4OID;
3164                                 n->constlen             = sizeof(int4);
3165                                 n->constvalue   = (Datum)0;
3166                                 n->constisnull  = FALSE;
3167                                 n->constbyval   = TRUE;
3168                                 n->constisset   = FALSE;
3169                                 n->constiscast  = FALSE;
3170                                 $$ = (Node *)n;
3171                         }
3172                 | PARAM
3173                         {
3174                                 Param   *n = makeNode(Param);
3175
3176                                 n->paramkind    = PARAM_NUM;
3177                                 n->paramid              = $1;
3178                                 n->paramtype    = INT4OID;
3179                                 $$ = (Node *)n;
3180                         }
3181                 ;
3182
3183 select_offset_value:    Iconst
3184                         {
3185                                 Const   *n = makeNode(Const);
3186
3187                                 n->consttype    = INT4OID;
3188                                 n->constlen             = sizeof(int4);
3189                                 n->constvalue   = (Datum)$1;
3190                                 n->constisnull  = FALSE;
3191                                 n->constbyval   = TRUE;
3192                                 n->constisset   = FALSE;
3193                                 n->constiscast  = FALSE;
3194                                 $$ = (Node *)n;
3195                         }
3196                 | PARAM
3197                         {
3198                                 Param   *n = makeNode(Param);
3199
3200                                 n->paramkind    = PARAM_NUM;
3201                                 n->paramid              = $1;
3202                                 n->paramtype    = INT4OID;
3203                                 $$ = (Node *)n;
3204                         }
3205                 ;
3206 /*
3207  *      jimmy bell-style recursive queries aren't supported in the
3208  *      current system.
3209  *
3210  *      ...however, recursive addattr and rename supported.  make special
3211  *      cases for these.
3212  */
3213 opt_inh_star:  '*'                                                              { $$ = TRUE; }
3214                 | /*EMPTY*/                                                             { $$ = FALSE; }
3215                 ;
3216
3217 relation_name_list:  name_list;
3218
3219 name_list:  name
3220                                 {       $$ = lcons(makeString($1),NIL); }
3221                 | name_list ',' name
3222                                 {       $$ = lappend($1,makeString($3)); }
3223                 ;
3224
3225 group_clause:  GROUP BY expr_list                               { $$ = $3; }
3226                 | /*EMPTY*/                                                             { $$ = NIL; }
3227                 ;
3228
3229 having_clause:  HAVING a_expr
3230                                 {
3231                                         $$ = $2;
3232                                 }
3233                 | /*EMPTY*/                                                             { $$ = NULL; }
3234                 ;
3235
3236 for_update_clause:  FOR UPDATE update_list              { $$ = $3; }
3237                 | FOR READ ONLY                                                 { $$ = NULL; }
3238                 | /* EMPTY */                                                   { $$ = NULL; }
3239                 ;
3240
3241 update_list:  OF va_list                                                { $$ = $2; }
3242                 | /* EMPTY */                                                   { $$ = lcons(NULL, NULL); }
3243                 ;
3244
3245 /*****************************************************************************
3246  *
3247  *      clauses common to all Optimizable Stmts:
3248  *              from_clause             -
3249  *              where_clause    -
3250  *
3251  *****************************************************************************/
3252
3253 from_clause:  FROM from_expr                                    { $$ = $2; }
3254                 | /*EMPTY*/                                                             { $$ = NIL; }
3255                 ;
3256
3257 from_expr:  '(' join_clause_with_union ')'
3258                                 { $$ = $2; }
3259                 | join_clause
3260                                 { $$ = $1; }
3261                 | table_list
3262                                 { $$ = $1; }
3263                 ;
3264
3265 table_list:  table_list ',' table_expr
3266                                 { $$ = lappend($1, $3); }
3267                 | table_expr
3268                                 { $$ = lcons($1, NIL); }
3269                 ;
3270
3271 table_expr:  relation_expr AS ColLabel
3272                                 {
3273                                         $$ = makeNode(RangeVar);
3274                                         $$->relExpr = $1;
3275                                         $$->name = $3;
3276                                 }
3277                 | relation_expr ColId
3278                                 {
3279                                         $$ = makeNode(RangeVar);
3280                                         $$->relExpr = $1;
3281                                         $$->name = $2;
3282                                 }
3283                 | relation_expr
3284                                 {
3285                                         $$ = makeNode(RangeVar);
3286                                         $$->relExpr = $1;
3287                                         $$->name = NULL;
3288                                 }
3289                 ;
3290
3291 /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
3292  * all result rows which would have matched on an INNER JOIN.
3293  * Let's reject this for now. - thomas 1999-01-08
3294  */
3295 join_clause_with_union:  join_clause
3296                                 {       $$ = $1; }
3297                 | table_expr UNION JOIN table_expr
3298                                 {       elog(ERROR,"UNION JOIN not yet implemented"); }
3299                 ;
3300
3301 join_clause:  table_expr join_list
3302                                 {
3303                                         Node *n = lfirst($2);
3304
3305                                         /* JoinExpr came back? then it is a join of some sort...
3306                                          */
3307                                         if (IsA(n, JoinExpr))
3308                                         {
3309                                                 JoinExpr *j = (JoinExpr *)n;
3310                                                 j->larg = $1;
3311                                                 $$ = $2;
3312                                         }
3313                                         /* otherwise, it was a cross join,
3314                                          * which we just represent as an inner join...
3315                                          */
3316                                         else
3317                                                 $$ = lcons($1, $2);
3318                                 }
3319                 ;
3320
3321 join_list:  join_list join_expr
3322                                 {
3323                                         $$ = lappend($1, $2);
3324                                 }
3325                 | join_expr
3326                                 {
3327                                         $$ = lcons($1, NIL);
3328                                 }
3329                 ;
3330
3331 /* This is everything but the left side of a join.
3332  * Note that a CROSS JOIN is the same as an unqualified
3333  * inner join, so just pass back the right-side table.
3334  * A NATURAL JOIN implicitly matches column names between
3335  * tables, so we'll collect those during the later transformation.
3336  */
3337 join_expr:  join_type JOIN table_expr join_qual
3338                                 {
3339                                         JoinExpr *n = makeNode(JoinExpr);
3340                                         n->jointype = $1;
3341                                         n->rarg = (Node *)$3;
3342                                         n->quals = $4;
3343                                         $$ = (Node *)n;
3344                                 }
3345                 | NATURAL join_type JOIN table_expr
3346                                 {
3347                                         JoinExpr *n = makeNode(JoinExpr);
3348                                         n->jointype = $2;
3349                                         n->rarg = (Node *)$4;
3350                                         n->quals = NULL; /* figure out which columns later... */
3351                                         $$ = (Node *)n;
3352                                 }
3353                 | CROSS JOIN table_expr
3354                                 { $$ = (Node *)$3; }
3355                 ;
3356
3357 /* OUTER is just noise... */
3358 join_type:  FULL join_outer
3359                                 {
3360                                         $$ = FULL;
3361                                         elog(NOTICE,"FULL OUTER JOIN not yet implemented");
3362                                 }
3363                 | LEFT join_outer
3364                                 {
3365                                         $$ = LEFT;
3366                                         elog(NOTICE,"LEFT OUTER JOIN not yet implemented");
3367                                 }
3368                 | RIGHT join_outer
3369                                 {
3370                                         $$ = RIGHT;
3371                                         elog(NOTICE,"RIGHT OUTER JOIN not yet implemented");
3372                                 }
3373                 | OUTER_P
3374                                 {
3375                                         $$ = LEFT;
3376                                         elog(NOTICE,"OUTER JOIN not yet implemented");
3377                                 }
3378                 | INNER_P
3379                                 {
3380                                         $$ = INNER_P;
3381                                 }
3382                 | /*EMPTY*/
3383                                 {
3384                                         $$ = INNER_P;
3385                                 }
3386                 ;
3387
3388 join_outer:  OUTER_P                                                    { $$ = NULL; }
3389                 | /*EMPTY*/                                                             { $$ = NULL;  /* no qualifiers */ }
3390                 ;
3391
3392 /* JOIN qualification clauses
3393  * Possibilities are:
3394  *  USING ( column list ) allows only unqualified column names,
3395  *                        which must match between tables.
3396  *  ON expr allows more general qualifications.
3397  * - thomas 1999-01-07
3398  */
3399
3400 join_qual:  USING '(' using_list ')'                    { $$ = $3; }
3401                 | ON a_expr                                                             { $$ = lcons($2, NIL); }
3402                 ;
3403
3404 using_list:  using_list ',' using_expr                  { $$ = lappend($1, $3); }
3405                 | using_expr                                                    { $$ = lcons($1, NIL); }
3406                 ;
3407
3408 using_expr:  ColId
3409                                 {
3410                                         /* could be a column name or a relation_name */
3411                                         Ident *n = makeNode(Ident);
3412                                         n->name = $1;
3413                                         n->indirection = NULL;
3414                                         $$ = (Node *)n;
3415                                 }
3416                 ;
3417
3418 where_clause:  WHERE a_expr                                             { $$ = $2; }
3419                 | /*EMPTY*/                                                             { $$ = NULL;  /* no qualifiers */ }
3420                 ;
3421
3422 relation_expr:  relation_name
3423                                 {
3424                                         /* normal relations */
3425                                         $$ = makeNode(RelExpr);
3426                                         $$->relname = $1;
3427                                         $$->inh = FALSE;
3428                                 }
3429                 | relation_name '*'                               %prec '='
3430                                 {
3431                                         /* inheritance query */
3432                                         $$ = makeNode(RelExpr);
3433                                         $$->relname = $1;
3434                                         $$->inh = TRUE;
3435                                 }
3436
3437 opt_array_bounds:       '[' ']' opt_array_bounds
3438                                 {  $$ = lcons(makeInteger(-1), $3); }
3439                 | '[' Iconst ']' opt_array_bounds
3440                                 {  $$ = lcons(makeInteger($2), $4); }
3441                 | /*EMPTY*/
3442                                 {  $$ = NIL; }
3443                 ;
3444
3445
3446 /*****************************************************************************
3447  *
3448  *      Type syntax
3449  *              SQL92 introduces a large amount of type-specific syntax.
3450  *              Define individual clauses to handle these cases, and use
3451  *               the generic case to handle regular type-extensible Postgres syntax.
3452  *              - thomas 1997-10-10
3453  *
3454  *****************************************************************************/
3455
3456 Typename:  SimpleTypename opt_array_bounds
3457                                 {
3458                                         $$ = $1;
3459                                         $$->arrayBounds = $2;
3460
3461                                         /* Is this the name of a complex type? If so, implement
3462                                          * it as a set.
3463                                          */
3464                                         if (!strcmp(saved_relname, $$->name))
3465                                                 /* This attr is the same type as the relation
3466                                                  * being defined. The classic example: create
3467                                                  * emp(name=text,mgr=emp)
3468                                                  */
3469                                                 $$->setof = TRUE;
3470                                         else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
3471                                                  /* (Eventually add in here that the set can only
3472                                                   * contain one element.)
3473                                                   */
3474                                                 $$->setof = TRUE;
3475                                         else
3476                                                 $$->setof = FALSE;
3477                                 }
3478                 | SETOF SimpleTypename
3479                                 {
3480                                         $$ = $2;
3481                                         $$->setof = TRUE;
3482                                 }
3483                 ;
3484
3485 SimpleTypename:  Generic
3486                 | Numeric
3487                 | Character
3488                 | Datetime
3489                 ;
3490
3491 Generic:  generic
3492                                 {
3493                                         $$ = makeNode(TypeName);
3494                                         $$->name = xlateSqlType($1);
3495                                         $$->typmod = -1;
3496                                 }
3497                 ;
3498
3499 generic:  IDENT                                                                 { $$ = $1; }
3500                 | TYPE_P                                                                { $$ = "type"; }
3501                 ;
3502
3503 /* SQL92 numeric data types
3504  * Check FLOAT() precision limits assuming IEEE floating types.
3505  * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3506  * - thomas 1997-09-18
3507  */
3508 Numeric:  FLOAT opt_float
3509                                 {
3510                                         $$ = makeNode(TypeName);
3511                                         $$->name = xlateSqlType($2);
3512                                         $$->typmod = -1;
3513                                 }
3514                 | DOUBLE PRECISION
3515                                 {
3516                                         $$ = makeNode(TypeName);
3517                                         $$->name = xlateSqlType("float");
3518                                 }
3519                 | DECIMAL opt_decimal
3520                                 {
3521                                         $$ = makeNode(TypeName);
3522                                         $$->name = xlateSqlType("numeric");
3523                                         $$->typmod = $2;
3524                                 }
3525                 | NUMERIC opt_numeric
3526                                 {
3527                                         $$ = makeNode(TypeName);
3528                                         $$->name = xlateSqlType("numeric");
3529                                         $$->typmod = $2;
3530                                 }
3531                 ;
3532
3533 numeric:  FLOAT
3534                                 {       $$ = xlateSqlType("float8"); }
3535                 | DOUBLE PRECISION
3536                                 {       $$ = xlateSqlType("float8"); }
3537                 | DECIMAL
3538                                 {       $$ = xlateSqlType("numeric"); }
3539                 | NUMERIC
3540                                 {       $$ = xlateSqlType("numeric"); }
3541                 ;
3542
3543 opt_float:  '(' Iconst ')'
3544                                 {
3545                                         if ($2 < 1)
3546                                                 elog(ERROR,"precision for FLOAT must be at least 1");
3547                                         else if ($2 < 7)
3548                                                 $$ = xlateSqlType("float4");
3549                                         else if ($2 < 16)
3550                                                 $$ = xlateSqlType("float8");
3551                                         else
3552                                                 elog(ERROR,"precision for FLOAT must be less than 16");
3553                                 }
3554                 | /*EMPTY*/
3555                                 {
3556                                         $$ = xlateSqlType("float8");
3557                                 }
3558                 ;
3559
3560 opt_numeric:  '(' Iconst ',' Iconst ')'
3561                                 {
3562                                         if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3563                                                 elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
3564                                                                         $2, NUMERIC_MAX_PRECISION);
3565                                         if ($4 < 0 || $4 > $2)
3566                                                 elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
3567                                                                         $4,$2);
3568
3569                                         $$ = (($2 << 16) | $4) + VARHDRSZ;
3570                                 }
3571                 | '(' Iconst ')'
3572                                 {
3573                                         if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3574                                                 elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
3575                                                                         $2, NUMERIC_MAX_PRECISION);
3576
3577                                         $$ = ($2 << 16) + VARHDRSZ;
3578                                 }
3579                 | /*EMPTY*/
3580                                 {
3581                                         $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
3582                                 }
3583                 ;
3584
3585 opt_decimal:  '(' Iconst ',' Iconst ')'
3586                                 {
3587                                         if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3588                                                 elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
3589                                                                         $2, NUMERIC_MAX_PRECISION);
3590                                         if ($4 < 0 || $4 > $2)
3591                                                 elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d",
3592                                                                         $4,$2);
3593
3594                                         $$ = (($2 << 16) | $4) + VARHDRSZ;
3595                                 }
3596                 | '(' Iconst ')'
3597                                 {
3598                                         if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3599                                                 elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
3600                                                                         $2, NUMERIC_MAX_PRECISION);
3601
3602                                         $$ = ($2 << 16) + VARHDRSZ;
3603                                 }
3604                 | /*EMPTY*/
3605                                 {
3606                                         $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
3607                                 }
3608                 ;
3609
3610
3611 /* SQL92 character data types
3612  * The following implements CHAR() and VARCHAR().
3613  */
3614 Character:  character '(' Iconst ')'
3615                                 {
3616                                         $$ = makeNode(TypeName);
3617                                         if (strcasecmp($1, "char") == 0)
3618                                                 $$->name = xlateSqlType("bpchar");
3619                                         else if (strcasecmp($1, "varchar") == 0)
3620                                                 $$->name = xlateSqlType("varchar");
3621                                         else
3622                                                 yyerror("internal parsing error; unrecognized character type");
3623
3624                                         if ($3 < 1)
3625                                                 elog(ERROR,"length for '%s' type must be at least 1",$1);
3626                                         else if ($3 > MaxAttrSize)
3627                                                 elog(ERROR,"length for type '%s' cannot exceed %d",$1,
3628                                                         MaxAttrSize);
3629
3630                                         /* we actually implement this sort of like a varlen, so
3631                                          * the first 4 bytes is the length. (the difference
3632                                          * between this and "text" is that we blank-pad and
3633                                          * truncate where necessary
3634                                          */
3635                                         $$->typmod = VARHDRSZ + $3;
3636                                 }
3637                 | character
3638                                 {
3639                                         $$ = makeNode(TypeName);
3640                                         /* Let's try to make all single-character types into bpchar(1)
3641                                          * - thomas 1998-05-07
3642                                          */
3643                                         if (strcasecmp($1, "char") == 0)
3644                                         {
3645                                                 $$->name = xlateSqlType("bpchar");
3646                                                 $$->typmod = VARHDRSZ + 1;
3647                                         }
3648                                         else
3649                                         {
3650                                                 $$->name = xlateSqlType($1);
3651                                                 $$->typmod = -1;
3652                                         }
3653                                 }
3654                 ;
3655
3656 character:  CHARACTER opt_varying opt_charset opt_collate
3657                                 {
3658                                         char *type, *c;
3659                                         if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
3660                                                 if ($2) type = xlateSqlType("varchar");
3661                                                 else type = xlateSqlType("char");
3662                                         } else {
3663                                                 if ($2) {
3664                                                         c = palloc(strlen("var") + strlen($3) + 1);
3665                                                         strcpy(c, "var");
3666                                                         strcat(c, $3);
3667                                                         type = xlateSqlType(c);
3668                                                 } else {
3669                                                         type = xlateSqlType($3);
3670                                                 }
3671                                         };
3672                                         if ($4 != NULL)
3673                                                 elog(NOTICE,"COLLATE %s not yet implemented; clause ignored",$4);
3674                                         $$ = type;
3675                                 }
3676                 | CHAR opt_varying                                              { $$ = xlateSqlType($2? "varchar": "char"); }
3677                 | VARCHAR                                                               { $$ = xlateSqlType("varchar"); }
3678                 | NATIONAL CHARACTER opt_varying                { $$ = xlateSqlType($3? "varchar": "char"); }
3679                 | NCHAR opt_varying                                             { $$ = xlateSqlType($2? "varchar": "char"); }
3680                 ;
3681
3682 opt_varying:  VARYING                                                   { $$ = TRUE; }
3683                 | /*EMPTY*/                                                             { $$ = FALSE; }
3684                 ;
3685
3686 opt_charset:  CHARACTER SET ColId                               { $$ = $3; }
3687                 | /*EMPTY*/                                                             { $$ = NULL; }
3688                 ;
3689
3690 opt_collate:  COLLATE ColId                                             { $$ = $2; }
3691                 | /*EMPTY*/                                                             { $$ = NULL; }
3692                 ;
3693
3694 Datetime:  datetime
3695                                 {
3696                                         $$ = makeNode(TypeName);
3697                                         $$->name = xlateSqlType($1);
3698                                         $$->typmod = -1;
3699                                 }
3700                 | TIMESTAMP opt_timezone
3701                                 {
3702                                         $$ = makeNode(TypeName);
3703                                         $$->name = xlateSqlType("timestamp");
3704                                         $$->timezone = $2;
3705                                         $$->typmod = -1;
3706                                 }
3707                 | TIME
3708                                 {
3709                                         $$ = makeNode(TypeName);
3710                                         $$->name = xlateSqlType("time");
3711                                         $$->typmod = -1;
3712                                 }
3713                 | INTERVAL opt_interval
3714                                 {
3715                                         $$ = makeNode(TypeName);
3716                                         $$->name = xlateSqlType("interval");
3717                                         $$->typmod = -1;
3718                                 }
3719                 ;
3720
3721 datetime:  YEAR_P                                                               { $$ = "year"; }
3722                 | MONTH_P                                                               { $$ = "month"; }
3723                 | DAY_P                                                                 { $$ = "day"; }
3724                 | HOUR_P                                                                { $$ = "hour"; }
3725                 | MINUTE_P                                                              { $$ = "minute"; }
3726                 | SECOND_P                                                              { $$ = "second"; }
3727                 ;
3728
3729 opt_timezone:  WITH TIME ZONE                                   { $$ = TRUE; }
3730                 | /*EMPTY*/                                                             { $$ = FALSE; }
3731                 ;
3732
3733 opt_interval:  datetime                                                 { $$ = lcons($1, NIL); }
3734                 | YEAR_P TO MONTH_P                                             { $$ = NIL; }
3735                 | DAY_P TO HOUR_P                                               { $$ = NIL; }
3736                 | DAY_P TO MINUTE_P                                             { $$ = NIL; }
3737                 | DAY_P TO SECOND_P                                             { $$ = NIL; }
3738                 | HOUR_P TO MINUTE_P                                    { $$ = NIL; }
3739                 | HOUR_P TO SECOND_P                                    { $$ = NIL; }
3740                 | MINUTE_P TO SECOND_P                                  { $$ = NIL; }
3741                 | /*EMPTY*/                                                             { $$ = NIL; }
3742                 ;
3743
3744
3745 /*****************************************************************************
3746  *
3747  *      expression grammar
3748  *
3749  *****************************************************************************/
3750
3751 a_expr_or_null:  a_expr
3752                                 { $$ = $1; }
3753                 | NULL_P
3754                                 {
3755                                         A_Const *n = makeNode(A_Const);
3756                                         n->val.type = T_Null;
3757                                         $$ = (Node *)n;
3758                                 }
3759                 ;
3760
3761 /* Expressions using row descriptors
3762  * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3763  *  with singleton expressions.
3764  */
3765 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3766                                 {
3767                                         SubLink *n = makeNode(SubLink);
3768                                         n->lefthand = $2;
3769                                         n->oper = lcons("=", NIL);
3770                                         n->useor = false;
3771                                         n->subLinkType = ANY_SUBLINK;
3772                                         n->subselect = $6;
3773                                         $$ = (Node *)n;
3774                                 }
3775                 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3776                                 {
3777                                         SubLink *n = makeNode(SubLink);
3778                                         n->lefthand = $2;
3779                                         n->oper = lcons("<>", NIL);
3780                                         n->useor = true;
3781                                         n->subLinkType = ALL_SUBLINK;
3782                                         n->subselect = $7;
3783                                         $$ = (Node *)n;
3784                                 }
3785                 | '(' row_descriptor ')' all_Op sub_type '(' SubSelect ')'
3786                                 {
3787                                         SubLink *n = makeNode(SubLink);
3788                                         n->lefthand = $2;
3789                                         n->oper = lcons($4, NIL);
3790                                         if (strcmp($4,"<>") == 0)
3791                                                 n->useor = true;
3792                                         else
3793                                                 n->useor = false;
3794                                         n->subLinkType = $5;
3795                                         n->subselect = $7;
3796                                         $$ = (Node *)n;
3797                                 }
3798                 | '(' row_descriptor ')' all_Op '(' SubSelect ')'
3799                                 {
3800                                         SubLink *n = makeNode(SubLink);
3801                                         n->lefthand = $2;
3802                                         n->oper = lcons($4, NIL);
3803                                         if (strcmp($4,"<>") == 0)
3804                                                 n->useor = true;
3805                                         else
3806                                                 n->useor = false;
3807                                         n->subLinkType = MULTIEXPR_SUBLINK;
3808                                         n->subselect = $6;
3809                                         $$ = (Node *)n;
3810                                 }
3811                 | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
3812                                 {
3813                                         $$ = makeRowExpr($4, $2, $6);
3814                                 }
3815                 ;
3816
3817 row_descriptor:  row_list ',' a_expr
3818                                 {
3819                                         $$ = lappend($1, $3);
3820                                 }
3821                 ;
3822
3823 row_list:  row_list ',' a_expr
3824                                 {
3825                                         $$ = lappend($1, $3);
3826                                 }
3827                 | a_expr
3828                                 {
3829                                         $$ = lcons($1, NIL);
3830                                 }
3831                 ;
3832
3833 sub_type:  ANY                                                          { $$ = ANY_SUBLINK; }
3834                 | ALL                                                           { $$ = ALL_SUBLINK; }
3835                 ;
3836
3837 all_Op:  Op | MathOp;
3838
3839 MathOp: '+'                             { $$ = "+"; }
3840                 | '-'                   { $$ = "-"; }
3841                 | '*'                   { $$ = "*"; }
3842                 | '/'                   { $$ = "/"; }
3843                 | '%'                   { $$ = "%"; }
3844                 | '^'                   { $$ = "^"; }
3845                 | '|'                   { $$ = "|"; }
3846                 | '<'                   { $$ = "<"; }
3847                 | '>'                   { $$ = ">"; }
3848                 | '='                   { $$ = "="; }
3849                 ;
3850
3851 /*
3852  * General expressions
3853  * This is the heart of the expression syntax.
3854  *
3855  * We have two expression types: a_expr is the unrestricted kind, and
3856  * b_expr is a subset that must be used in some places to avoid shift/reduce
3857  * conflicts.  For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
3858  * because that use of AND conflicts with AND as a boolean operator.  So,
3859  * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
3860  *
3861  * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
3862  * always be used by surrounding it with parens.
3863  *
3864  * com_expr is all the productions that are common to a_expr and b_expr;
3865  * it's factored out just to eliminate redundant coding.
3866  */
3867 a_expr:  com_expr
3868                                 {       $$ = $1;  }
3869                 | a_expr TYPECAST Typename
3870                                 {
3871                                         $$ = (Node *)$1;
3872                                         /* AexprConst can be either A_Const or ParamNo */
3873                                         if (nodeTag($1) == T_A_Const) {
3874                                                 ((A_Const *)$1)->typename = $3;
3875                                         } else if (nodeTag($1) == T_ParamNo) {
3876                                                 ((ParamNo *)$1)->typename = $3;
3877                                         /* otherwise, try to transform to a function call */
3878                                         } else {
3879                                                 FuncCall *n = makeNode(FuncCall);
3880                                                 n->funcname = $3->name;
3881                                                 n->args = lcons($1,NIL);
3882                                                 n->agg_star = false;
3883                                                 n->agg_distinct = false;
3884                                                 $$ = (Node *)n;
3885                                         }
3886                                 }
3887                 /*
3888                  * Can't collapse this into prior rule by using a_expr_or_null;
3889                  * that creates reduce/reduce conflicts.  Grumble.
3890                  */
3891                 | NULL_P TYPECAST Typename
3892                                 {
3893                                         A_Const *n = makeNode(A_Const);
3894                                         n->val.type = T_Null;
3895                                         n->typename = $3;
3896                                         $$ = (Node *)n;
3897                                 }
3898                 /*
3899                  * These operators must be called out explicitly in order to make use
3900                  * of yacc/bison's automatic operator-precedence handling.  All other
3901                  * operator names are handled by the generic productions using "Op",
3902                  * below; and all those operators will have the same precedence.
3903                  *
3904                  * If you add more explicitly-known operators, be sure to add them
3905                  * also to b_expr and to the MathOp list above.
3906                  */
3907                 | '-' a_expr %prec UMINUS
3908                                 {       $$ = doNegate($2); }
3909                 | '%' a_expr
3910                                 {       $$ = makeA_Expr(OP, "%", NULL, $2); }
3911                 | '^' a_expr
3912                                 {       $$ = makeA_Expr(OP, "^", NULL, $2); }
3913                 | '|' a_expr
3914                                 {       $$ = makeA_Expr(OP, "|", NULL, $2); }
3915                 | ':' a_expr
3916                                 {       $$ = makeA_Expr(OP, ":", NULL, $2); }
3917                 | ';' a_expr
3918                                 {       $$ = makeA_Expr(OP, ";", NULL, $2); }
3919                 | a_expr '%'
3920                                 {       $$ = makeA_Expr(OP, "%", $1, NULL); }
3921                 | a_expr '^'
3922                                 {       $$ = makeA_Expr(OP, "^", $1, NULL); }
3923                 | a_expr '|'
3924                                 {       $$ = makeA_Expr(OP, "|", $1, NULL); }
3925                 | a_expr '+' a_expr
3926                                 {       $$ = makeA_Expr(OP, "+", $1, $3); }
3927                 | a_expr '-' a_expr
3928                                 {       $$ = makeA_Expr(OP, "-", $1, $3); }
3929                 | a_expr '*' a_expr
3930                                 {       $$ = makeA_Expr(OP, "*", $1, $3); }
3931                 | a_expr '/' a_expr
3932                                 {       $$ = makeA_Expr(OP, "/", $1, $3); }
3933                 | a_expr '%' a_expr
3934                                 {       $$ = makeA_Expr(OP, "%", $1, $3); }
3935                 | a_expr '^' a_expr
3936                                 {       $$ = makeA_Expr(OP, "^", $1, $3); }
3937                 | a_expr '|' a_expr
3938                                 {       $$ = makeA_Expr(OP, "|", $1, $3); }
3939                 | a_expr '<' a_expr
3940                                 {       $$ = makeA_Expr(OP, "<", $1, $3); }
3941                 | a_expr '>' a_expr
3942                                 {       $$ = makeA_Expr(OP, ">", $1, $3); }
3943
3944                 | a_expr '=' NULL_P
3945                                 {       $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3946                 /* We allow this for standards-broken SQL products, like MS stuff */
3947                 | NULL_P '=' a_expr
3948                                 {       $$ = makeA_Expr(ISNULL, NULL, $3, NULL); }
3949
3950                 | a_expr '=' a_expr
3951                                 {       $$ = makeA_Expr(OP, "=", $1, $3); }
3952
3953                 | a_expr Op a_expr
3954                                 {       $$ = makeA_Expr(OP, $2, $1, $3); }
3955                 | Op a_expr
3956                                 {       $$ = makeA_Expr(OP, $1, NULL, $2); }
3957                 | a_expr Op
3958                                 {       $$ = makeA_Expr(OP, $2, $1, NULL); }
3959
3960                 | a_expr AND a_expr
3961                                 {       $$ = makeA_Expr(AND, NULL, $1, $3); }
3962                 | a_expr OR a_expr
3963                                 {       $$ = makeA_Expr(OR, NULL, $1, $3); }
3964                 | NOT a_expr
3965                                 {       $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3966
3967                 | a_expr LIKE a_expr
3968                                 {       $$ = makeA_Expr(OP, "~~", $1, $3); }
3969                 | a_expr NOT LIKE a_expr
3970                                 {       $$ = makeA_Expr(OP, "!~~", $1, $4); }
3971
3972                 | a_expr ISNULL
3973                                 {       $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3974                 | a_expr IS NULL_P
3975                                 {       $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3976                 | a_expr NOTNULL
3977                                 {       $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3978                 | a_expr IS NOT NULL_P
3979                                 {       $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3980                 /* IS TRUE, IS FALSE, etc used to be function calls
3981                  *  but let's make them expressions to allow the optimizer
3982                  *  a chance to eliminate them if a_expr is a constant string.
3983                  * - thomas 1997-12-22
3984                  */
3985                 | a_expr IS TRUE_P
3986                                 {
3987                                         A_Const *n = makeNode(A_Const);
3988                                         n->val.type = T_String;
3989                                         n->val.val.str = "t";
3990                                         n->typename = makeNode(TypeName);
3991                                         n->typename->name = xlateSqlType("bool");
3992                                         n->typename->typmod = -1;
3993                                         $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3994                                 }
3995                 | a_expr IS NOT FALSE_P
3996                                 {
3997                                         A_Const *n = makeNode(A_Const);
3998                                         n->val.type = T_String;
3999                                         n->val.val.str = "t";
4000                                         n->typename = makeNode(TypeName);
4001                                         n->typename->name = xlateSqlType("bool");
4002                                         n->typename->typmod = -1;
4003                                         $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4004                                 }
4005                 | a_expr IS FALSE_P
4006                                 {
4007                                         A_Const *n = makeNode(A_Const);
4008                                         n->val.type = T_String;
4009                                         n->val.val.str = "f";
4010                                         n->typename = makeNode(TypeName);
4011                                         n->typename->name = xlateSqlType("bool");
4012                                         n->typename->typmod = -1;
4013                                         $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4014                                 }
4015                 | a_expr IS NOT TRUE_P
4016                                 {
4017                                         A_Const *n = makeNode(A_Const);
4018                                         n->val.type = T_String;
4019                                         n->val.val.str = "f";
4020                                         n->typename = makeNode(TypeName);
4021                                         n->typename->name = xlateSqlType("bool");
4022                                         n->typename->typmod = -1;
4023                                         $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4024                                 }
4025                 | a_expr BETWEEN b_expr AND b_expr
4026                                 {
4027                                         $$ = makeA_Expr(AND, NULL,
4028                                                 makeA_Expr(OP, ">=", $1, $3),
4029                                                 makeA_Expr(OP, "<=", $1, $5));
4030                                 }
4031                 | a_expr NOT BETWEEN b_expr AND b_expr
4032                                 {
4033                                         $$ = makeA_Expr(OR, NULL,
4034                                                 makeA_Expr(OP, "<", $1, $4),
4035                                                 makeA_Expr(OP, ">", $1, $6));
4036                                 }
4037                 | a_expr IN '(' in_expr ')'
4038                                 {
4039                                         /* in_expr returns a SubLink or a list of a_exprs */
4040                                         if (IsA($4, SubLink))
4041                                         {
4042                                                         SubLink *n = (SubLink *)$4;
4043                                                         n->lefthand = lcons($1, NIL);
4044                                                         n->oper = lcons("=", NIL);
4045                                                         n->useor = false;
4046                                                         n->subLinkType = ANY_SUBLINK;
4047                                                         $$ = (Node *)n;
4048                                         }
4049                                         else
4050                                         {
4051                                                 Node *n = NULL;
4052                                                 List *l;
4053                                                 foreach(l, (List *) $4)
4054                                                 {
4055                                                         Node *cmp = makeA_Expr(OP, "=", $1, lfirst(l));
4056                                                         if (n == NULL)
4057                                                                 n = cmp;
4058                                                         else
4059                                                                 n = makeA_Expr(OR, NULL, n, cmp);
4060                                                 }
4061                                                 $$ = n;
4062                                         }
4063                                 }
4064                 | a_expr NOT IN '(' in_expr ')'
4065                                 {
4066                                         /* in_expr returns a SubLink or a list of a_exprs */
4067                                         if (IsA($5, SubLink))
4068                                         {
4069                                                 SubLink *n = (SubLink *)$5;
4070                                                 n->lefthand = lcons($1, NIL);
4071                                                 n->oper = lcons("<>", NIL);
4072                                                 n->useor = false;
4073                                                 n->subLinkType = ALL_SUBLINK;
4074                                                 $$ = (Node *)n;
4075                                         }
4076                                         else
4077                                         {
4078                                                 Node *n = NULL;
4079                                                 List *l;
4080                                                 foreach(l, (List *) $5)
4081                                                 {
4082                                                         Node *cmp = makeA_Expr(OP, "<>", $1, lfirst(l));
4083                                                         if (n == NULL)
4084                                                                 n = cmp;
4085                                                         else
4086                                                                 n = makeA_Expr(AND, NULL, n, cmp);
4087                                                 }
4088                                                 $$ = n;
4089                                         }
4090                                 }
4091                 | a_expr all_Op sub_type '(' SubSelect ')'
4092                                 {
4093                                         SubLink *n = makeNode(SubLink);
4094                                         n->lefthand = lcons($1, NIL);
4095                                         n->oper = lcons($2, NIL);
4096                                         n->useor = false; /* doesn't matter since only one col */
4097                                         n->subLinkType = $3;
4098                                         n->subselect = $5;
4099                                         $$ = (Node *)n;
4100                                 }
4101                 | row_expr
4102                                 {       $$ = $1;  }
4103                 ;
4104
4105 /*
4106  * Restricted expressions
4107  *
4108  * b_expr is a subset of the complete expression syntax defined by a_expr.
4109  *
4110  * Presently, AND, NOT, IS, IN, and NULL are the a_expr keywords that would
4111  * cause trouble in the places where b_expr is used.  For simplicity, we
4112  * just eliminate all the boolean-keyword-operator productions from b_expr.
4113  */
4114 b_expr:  com_expr
4115                                 {       $$ = $1;  }
4116                 | b_expr TYPECAST Typename
4117                                 {
4118                                         $$ = (Node *)$1;
4119                                         /* AexprConst can be either A_Const or ParamNo */
4120                                         if (nodeTag($1) == T_A_Const) {
4121                                                 ((A_Const *)$1)->typename = $3;
4122                                         } else if (nodeTag($1) == T_ParamNo) {
4123                                                 ((ParamNo *)$1)->typename = $3;
4124                                         /* otherwise, try to transform to a function call */
4125                                         } else {
4126                                                 FuncCall *n = makeNode(FuncCall);
4127                                                 n->funcname = $3->name;
4128                                                 n->args = lcons($1,NIL);
4129                                                 n->agg_star = false;
4130                                                 n->agg_distinct = false;
4131                                                 $$ = (Node *)n;
4132                                         }
4133                                 }
4134                 | NULL_P TYPECAST Typename
4135                                 {
4136                                         A_Const *n = makeNode(A_Const);
4137                                         n->val.type = T_Null;
4138                                         n->typename = $3;
4139                                         $$ = (Node *)n;
4140                                 }
4141                 | '-' b_expr %prec UMINUS
4142                                 {       $$ = doNegate($2); }
4143                 | '%' b_expr
4144                                 {       $$ = makeA_Expr(OP, "%", NULL, $2); }
4145                 | '^' b_expr
4146                                 {       $$ = makeA_Expr(OP, "^", NULL, $2); }
4147                 | '|' b_expr
4148                                 {       $$ = makeA_Expr(OP, "|", NULL, $2); }
4149                 | ':' b_expr
4150                                 {       $$ = makeA_Expr(OP, ":", NULL, $2); }
4151                 | ';' b_expr
4152                                 {       $$ = makeA_Expr(OP, ";", NULL, $2); }
4153                 | b_expr '%'
4154                                 {       $$ = makeA_Expr(OP, "%", $1, NULL); }
4155                 | b_expr '^'
4156                                 {       $$ = makeA_Expr(OP, "^", $1, NULL); }
4157                 | b_expr '|'
4158                                 {       $$ = makeA_Expr(OP, "|", $1, NULL); }
4159                 | b_expr '+' b_expr
4160                                 {       $$ = makeA_Expr(OP, "+", $1, $3); }
4161                 | b_expr '-' b_expr
4162                                 {       $$ = makeA_Expr(OP, "-", $1, $3); }
4163                 | b_expr '*' b_expr
4164                                 {       $$ = makeA_Expr(OP, "*", $1, $3); }
4165                 | b_expr '/' b_expr
4166                                 {       $$ = makeA_Expr(OP, "/", $1, $3); }
4167                 | b_expr '%' b_expr
4168                                 {       $$ = makeA_Expr(OP, "%", $1, $3); }
4169                 | b_expr '^' b_expr
4170                                 {       $$ = makeA_Expr(OP, "^", $1, $3); }
4171                 | b_expr '|' b_expr
4172                                 {       $$ = makeA_Expr(OP, "|", $1, $3); }
4173                 | b_expr '<' b_expr
4174                                 {       $$ = makeA_Expr(OP, "<", $1, $3); }
4175                 | b_expr '>' b_expr
4176                                 {       $$ = makeA_Expr(OP, ">", $1, $3); }
4177                 | b_expr '=' b_expr
4178                                 {       $$ = makeA_Expr(OP, "=", $1, $3); }
4179
4180                 | b_expr Op b_expr
4181                                 {       $$ = makeA_Expr(OP, $2, $1, $3); }
4182                 | Op b_expr
4183                                 {       $$ = makeA_Expr(OP, $1, NULL, $2); }
4184                 | b_expr Op
4185                                 {       $$ = makeA_Expr(OP, $2, $1, NULL); }
4186                 ;
4187
4188 /*
4189  * Productions that can be used in both a_expr and b_expr.
4190  *
4191  * Note: productions that refer recursively to a_expr or b_expr mostly
4192  * cannot appear here.  However, it's OK to refer to a_exprs that occur
4193  * inside parentheses, such as function arguments; that cannot introduce
4194  * ambiguity to the b_expr syntax.
4195  */
4196 com_expr:  attr
4197                                 {       $$ = (Node *) $1;  }
4198                 | ColId opt_indirection
4199                                 {
4200                                         /* could be a column name or a relation_name */
4201                                         Ident *n = makeNode(Ident);
4202                                         n->name = $1;
4203                                         n->indirection = $2;
4204                                         $$ = (Node *)n;
4205                                 }
4206                 | AexprConst
4207                                 {       $$ = $1;  }
4208                 | '(' a_expr_or_null ')'
4209                                 {       $$ = $2; }
4210                 | CAST '(' a_expr_or_null AS Typename ')'
4211                                 {
4212                                         $$ = (Node *)$3;
4213                                         /* AexprConst can be either A_Const or ParamNo */
4214                                         if (nodeTag($3) == T_A_Const) {
4215                                                 ((A_Const *)$3)->typename = $5;
4216                                         } else if (nodeTag($3) == T_ParamNo) {
4217                                                 ((ParamNo *)$3)->typename = $5;
4218                                         /* otherwise, try to transform to a function call */
4219                                         } else {
4220                                                 FuncCall *n = makeNode(FuncCall);
4221                                                 n->funcname = $5->name;
4222                                                 n->args = lcons($3,NIL);
4223                                                 n->agg_star = false;
4224                                                 n->agg_distinct = false;
4225                                                 $$ = (Node *)n;
4226                                         }
4227                                 }
4228                 | case_expr
4229                                 {       $$ = $1; }
4230                 | func_name '(' ')'
4231                                 {
4232                                         FuncCall *n = makeNode(FuncCall);
4233                                         n->funcname = $1;
4234                                         n->args = NIL;
4235                                         n->agg_star = false;
4236                                         n->agg_distinct = false;
4237                                         $$ = (Node *)n;
4238                                 }
4239                 | func_name '(' expr_list ')'
4240                                 {
4241                                         FuncCall *n = makeNode(FuncCall);
4242                                         n->funcname = $1;
4243                                         n->args = $3;
4244                                         n->agg_star = false;
4245                                         n->agg_distinct = false;
4246                                         $$ = (Node *)n;
4247                                 }
4248                 | func_name '(' DISTINCT expr_list ')'
4249                                 {
4250                                         FuncCall *n = makeNode(FuncCall);
4251                                         n->funcname = $1;
4252                                         n->args = $4;
4253                                         n->agg_star = false;
4254                                         n->agg_distinct = true;
4255                                         $$ = (Node *)n;
4256                                 }
4257                 | func_name '(' '*' ')'
4258                                 {
4259                                         /*
4260                                          * For now, we transform AGGREGATE(*) into AGGREGATE(1).
4261                                          *
4262                                          * This does the right thing for COUNT(*) (in fact,
4263                                          * any certainly-non-null expression would do for COUNT),
4264                                          * and there are no other aggregates in SQL92 that accept
4265                                          * '*' as parameter.
4266                                          *
4267                                          * The FuncCall node is also marked agg_star = true,
4268                                          * so that later processing can detect what the argument
4269                                          * really was.
4270                                          */
4271                                         FuncCall *n = makeNode(FuncCall);
4272                                         A_Const *star = makeNode(A_Const);
4273
4274                                         star->val.type = T_Integer;
4275                                         star->val.val.ival = 1;
4276                                         n->funcname = $1;
4277                                         n->args = lcons(star, NIL);
4278                                         n->agg_star = true;
4279                                         n->agg_distinct = false;
4280                                         $$ = (Node *)n;
4281                                 }
4282                 | CURRENT_DATE
4283                                 {
4284                                         /*
4285                                          * Translate as "date('now'::text)".
4286                                          *
4287                                          * We cannot use "'now'::date" because coerce_type() will
4288                                          * immediately reduce that to a constant representing
4289                                          * today's date.  We need to delay the conversion until
4290                                          * runtime, else the wrong things will happen when
4291                                          * CURRENT_DATE is used in a column default value or rule.
4292                                          *
4293                                          * This could be simplified if we had a way to generate
4294                                          * an expression tree representing runtime application
4295                                          * of type-input conversion functions...
4296                                          */
4297                                         A_Const *s = makeNode(A_Const);
4298                                         TypeName *t = makeNode(TypeName);
4299                                         FuncCall *n = makeNode(FuncCall);
4300
4301                                         s->val.type = T_String;
4302                                         s->val.val.str = "now";
4303                                         s->typename = t;
4304
4305                                         t->name = xlateSqlType("text");
4306                                         t->setof = FALSE;
4307                                         t->typmod = -1;
4308
4309                                         n->funcname = xlateSqlType("date");
4310                                         n->args = lcons(s, NIL);
4311                                         n->agg_star = false;
4312                                         n->agg_distinct = false;
4313
4314                                         $$ = (Node *)n;
4315                                 }
4316                 | CURRENT_TIME
4317                                 {
4318                                         /*
4319                                          * Translate as "time('now'::text)".
4320                                          * See comments for CURRENT_DATE.
4321                                          */
4322                                         A_Const *s = makeNode(A_Const);
4323                                         TypeName *t = makeNode(TypeName);
4324                                         FuncCall *n = makeNode(FuncCall);
4325
4326                                         s->val.type = T_String;
4327                                         s->val.val.str = "now";
4328                                         s->typename = t;
4329
4330                                         t->name = xlateSqlType("text");
4331                                         t->setof = FALSE;
4332                                         t->typmod = -1;
4333
4334                                         n->funcname = xlateSqlType("time");
4335                                         n->args = lcons(s, NIL);
4336                                         n->agg_star = false;
4337                                         n->agg_distinct = false;
4338
4339                                         $$ = (Node *)n;
4340                                 }
4341                 | CURRENT_TIME '(' Iconst ')'
4342                                 {
4343                                         /*
4344                                          * Translate as "time('now'::text)".
4345                                          * See comments for CURRENT_DATE.
4346                                          */
4347                                         A_Const *s = makeNode(A_Const);
4348                                         TypeName *t = makeNode(TypeName);
4349                                         FuncCall *n = makeNode(FuncCall);
4350
4351                                         s->val.type = T_String;
4352                                         s->val.val.str = "now";
4353                                         s->typename = t;
4354
4355                                         t->name = xlateSqlType("text");
4356                                         t->setof = FALSE;
4357                                         t->typmod = -1;
4358
4359                                         n->funcname = xlateSqlType("time");
4360                                         n->args = lcons(s, NIL);
4361                                         n->agg_star = false;
4362                                         n->agg_distinct = false;
4363
4364                                         if ($3 != 0)
4365                                                 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4366
4367                                         $$ = (Node *)n;
4368                                 }
4369                 | CURRENT_TIMESTAMP
4370                                 {
4371                                         /*
4372                                          * Translate as "timestamp('now'::text)".
4373                                          * See comments for CURRENT_DATE.
4374                                          */
4375                                         A_Const *s = makeNode(A_Const);
4376                                         TypeName *t = makeNode(TypeName);
4377                                         FuncCall *n = makeNode(FuncCall);
4378
4379                                         s->val.type = T_String;
4380                                         s->val.val.str = "now";
4381                                         s->typename = t;
4382
4383                                         t->name = xlateSqlType("text");
4384                                         t->setof = FALSE;
4385                                         t->typmod = -1;
4386
4387                                         n->funcname = xlateSqlType("timestamp");
4388                                         n->args = lcons(s, NIL);
4389                                         n->agg_star = false;
4390                                         n->agg_distinct = false;
4391
4392                                         $$ = (Node *)n;
4393                                 }
4394                 | CURRENT_TIMESTAMP '(' Iconst ')'
4395                                 {
4396                                         /*
4397                                          * Translate as "timestamp('now'::text)".
4398                                          * See comments for CURRENT_DATE.
4399                                          */
4400                                         A_Const *s = makeNode(A_Const);
4401                                         TypeName *t = makeNode(TypeName);
4402                                         FuncCall *n = makeNode(FuncCall);
4403
4404                                         s->val.type = T_String;
4405                                         s->val.val.str = "now";
4406                                         s->typename = t;
4407
4408                                         t->name = xlateSqlType("text");
4409                                         t->setof = FALSE;
4410                                         t->typmod = -1;
4411
4412                                         n->funcname = xlateSqlType("timestamp");
4413                                         n->args = lcons(s, NIL);
4414                                         n->agg_star = false;
4415                                         n->agg_distinct = false;
4416
4417                                         if ($3 != 0)
4418                                                 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4419
4420                                         $$ = (Node *)n;
4421                                 }
4422                 | CURRENT_USER
4423                                 {
4424                                         FuncCall *n = makeNode(FuncCall);
4425                                         n->funcname = "getpgusername";
4426                                         n->args = NIL;
4427                                         n->agg_star = false;
4428                                         n->agg_distinct = false;
4429                                         $$ = (Node *)n;
4430                                 }
4431                 | USER
4432                                 {
4433                                         FuncCall *n = makeNode(FuncCall);
4434                                         n->funcname = "getpgusername";
4435                                         n->args = NIL;
4436                                         n->agg_star = false;
4437                                         n->agg_distinct = false;
4438                                         $$ = (Node *)n;
4439                                 }
4440                 | EXTRACT '(' extract_list ')'
4441                                 {
4442                                         FuncCall *n = makeNode(FuncCall);
4443                                         n->funcname = "date_part";
4444                                         n->args = $3;
4445                                         n->agg_star = false;
4446                                         n->agg_distinct = false;
4447                                         $$ = (Node *)n;
4448                                 }
4449                 | POSITION '(' position_list ')'
4450                                 {
4451                                         FuncCall *n = makeNode(FuncCall);
4452                                         n->funcname = "strpos";
4453                                         n->args = $3;
4454                                         n->agg_star = false;
4455                                         n->agg_distinct = false;
4456                                         $$ = (Node *)n;
4457                                 }
4458                 | SUBSTRING '(' substr_list ')'
4459                                 {
4460                                         FuncCall *n = makeNode(FuncCall);
4461                                         n->funcname = "substr";
4462                                         n->args = $3;
4463                                         n->agg_star = false;
4464                                         n->agg_distinct = false;
4465                                         $$ = (Node *)n;
4466                                 }
4467                 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4468                 | TRIM '(' BOTH trim_list ')'
4469                                 {
4470                                         FuncCall *n = makeNode(FuncCall);
4471                                         n->funcname = "btrim";
4472                                         n->args = $4;
4473                                         n->agg_star = false;
4474                                         n->agg_distinct = false;
4475                                         $$ = (Node *)n;
4476                                 }
4477                 | TRIM '(' LEADING trim_list ')'
4478                                 {
4479                                         FuncCall *n = makeNode(FuncCall);
4480                                         n->funcname = "ltrim";
4481                                         n->args = $4;
4482                                         n->agg_star = false;
4483                                         n->agg_distinct = false;
4484                                         $$ = (Node *)n;
4485                                 }
4486                 | TRIM '(' TRAILING trim_list ')'
4487                                 {
4488                                         FuncCall *n = makeNode(FuncCall);
4489                                         n->funcname = "rtrim";
4490                                         n->args = $4;
4491                                         n->agg_star = false;
4492                                         n->agg_distinct = false;
4493                                         $$ = (Node *)n;
4494                                 }
4495                 | TRIM '(' trim_list ')'
4496                                 {
4497                                         FuncCall *n = makeNode(FuncCall);
4498                                         n->funcname = "btrim";
4499                                         n->args = $3;
4500                                         n->agg_star = false;
4501                                         n->agg_distinct = false;
4502                                         $$ = (Node *)n;
4503                                 }
4504                 | '(' SubSelect ')'
4505                                 {
4506                                         SubLink *n = makeNode(SubLink);
4507                                         n->lefthand = NIL;
4508                                         n->oper = NIL;
4509                                         n->useor = false;
4510                                         n->subLinkType = EXPR_SUBLINK;
4511                                         n->subselect = $2;
4512                                         $$ = (Node *)n;
4513                                 }
4514                 | EXISTS '(' SubSelect ')'
4515                                 {
4516                                         SubLink *n = makeNode(SubLink);
4517                                         n->lefthand = NIL;
4518                                         n->oper = NIL;
4519                                         n->useor = false;
4520                                         n->subLinkType = EXISTS_SUBLINK;
4521                                         n->subselect = $3;
4522                                         $$ = (Node *)n;
4523                                 }
4524                 ;
4525
4526 /*
4527  * Supporting nonterminals for expressions.
4528  */
4529
4530 opt_indirection:  '[' a_expr ']' opt_indirection
4531                                 {
4532                                         A_Indices *ai = makeNode(A_Indices);
4533                                         ai->lidx = NULL;
4534                                         ai->uidx = $2;
4535                                         $$ = lcons(ai, $4);
4536                                 }
4537                 | '[' a_expr ':' a_expr ']' opt_indirection
4538                                 {
4539                                         A_Indices *ai = makeNode(A_Indices);
4540                                         ai->lidx = $2;
4541                                         ai->uidx = $4;
4542                                         $$ = lcons(ai, $6);
4543                                 }
4544                 | /*EMPTY*/
4545                                 {       $$ = NIL; }
4546                 ;
4547
4548 expr_list:  a_expr_or_null
4549                                 { $$ = lcons($1, NIL); }
4550                 | expr_list ',' a_expr_or_null
4551                                 { $$ = lappend($1, $3); }
4552                 | expr_list USING a_expr
4553                                 { $$ = lappend($1, $3); }
4554                 ;
4555
4556 extract_list:  extract_arg FROM a_expr
4557                                 {
4558                                         A_Const *n = makeNode(A_Const);
4559                                         n->val.type = T_String;
4560                                         n->val.val.str = $1;
4561                                         $$ = lappend(lcons((Node *)n,NIL), $3);
4562                                 }
4563                 | /*EMPTY*/
4564                                 {       $$ = NIL; }
4565                 ;
4566
4567 extract_arg:  datetime                                          { $$ = $1; }
4568                 | TIMEZONE_HOUR                                         { $$ = "tz_hour"; }
4569                 | TIMEZONE_MINUTE                                       { $$ = "tz_minute"; }
4570                 ;
4571
4572 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
4573
4574 position_list:  b_expr IN b_expr
4575                                 {       $$ = makeList($3, $1, -1); }
4576                 | /*EMPTY*/
4577                                 {       $$ = NIL; }
4578                 ;
4579
4580 substr_list:  expr_list substr_from substr_for
4581                                 {
4582                                         $$ = nconc(nconc($1,$2),$3);
4583                                 }
4584                 | /*EMPTY*/
4585                                 {       $$ = NIL; }
4586                 ;
4587
4588 substr_from:  FROM expr_list
4589                                 {       $$ = $2; }
4590                 | /*EMPTY*/
4591                                 {
4592                                         A_Const *n = makeNode(A_Const);
4593                                         n->val.type = T_Integer;
4594                                         n->val.val.ival = 1;
4595                                         $$ = lcons((Node *)n,NIL);
4596                                 }
4597                 ;
4598
4599 substr_for:  FOR expr_list
4600                                 {       $$ = $2; }
4601                 | /*EMPTY*/
4602                                 {       $$ = NIL; }
4603                 ;
4604
4605 trim_list:  a_expr FROM expr_list
4606                                 { $$ = lappend($3, $1); }
4607                 | FROM expr_list
4608                                 { $$ = $2; }
4609                 | expr_list
4610                                 { $$ = $1; }
4611                 ;
4612
4613 in_expr:  SubSelect
4614                                 {
4615                                         SubLink *n = makeNode(SubLink);
4616                                         n->subselect = $1;
4617                                         $$ = (Node *)n;
4618                                 }
4619                 | in_expr_nodes
4620                                 {       $$ = (Node *)$1; }
4621                 ;
4622
4623 in_expr_nodes:  a_expr
4624                                 {       $$ = lcons($1, NIL); }
4625                 | in_expr_nodes ',' a_expr
4626                                 {       $$ = lappend($1, $3); }
4627                 ;
4628
4629 /* Case clause
4630  * Define SQL92-style case clause.
4631  * Allow all four forms described in the standard:
4632  * - Full specification
4633  *  CASE WHEN a = b THEN c ... ELSE d END
4634  * - Implicit argument
4635  *  CASE a WHEN b THEN c ... ELSE d END
4636  * - Conditional NULL
4637  *  NULLIF(x,y)
4638  *  same as CASE WHEN x = y THEN NULL ELSE x END
4639  * - Conditional substitution from list, use first non-null argument
4640  *  COALESCE(a,b,...)
4641  * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
4642  * - thomas 1998-11-09
4643  */
4644 case_expr:  CASE case_arg when_clause_list case_default END_TRANS
4645                                 {
4646                                         CaseExpr *c = makeNode(CaseExpr);
4647                                         c->arg = $2;
4648                                         c->args = $3;
4649                                         c->defresult = $4;
4650                                         $$ = (Node *)c;
4651                                 }
4652                 | NULLIF '(' a_expr ',' a_expr ')'
4653                                 {
4654                                         CaseExpr *c = makeNode(CaseExpr);
4655                                         CaseWhen *w = makeNode(CaseWhen);
4656 /*
4657                                         A_Const *n = makeNode(A_Const);
4658                                         n->val.type = T_Null;
4659                                         w->result = (Node *)n;
4660 */
4661                                         w->expr = makeA_Expr(OP, "=", $3, $5);
4662                                         c->args = lcons(w, NIL);
4663                                         c->defresult = $3;
4664                                         $$ = (Node *)c;
4665                                 }
4666                 | COALESCE '(' expr_list ')'
4667                                 {
4668                                         CaseExpr *c = makeNode(CaseExpr);
4669                                         CaseWhen *w;
4670                                         List *l;
4671                                         foreach (l,$3)
4672                                         {
4673                                                 w = makeNode(CaseWhen);
4674                                                 w->expr = makeA_Expr(NOTNULL, NULL, lfirst(l), NULL);
4675                                                 w->result = lfirst(l);
4676                                                 c->args = lappend(c->args, w);
4677                                         }
4678                                         $$ = (Node *)c;
4679                                 }
4680                 ;
4681
4682 when_clause_list:  when_clause_list when_clause
4683                                 { $$ = lappend($1, $2); }
4684                 | when_clause
4685                                 { $$ = lcons($1, NIL); }
4686                 ;
4687
4688 when_clause:  WHEN a_expr THEN a_expr_or_null
4689                                 {
4690                                         CaseWhen *w = makeNode(CaseWhen);
4691                                         w->expr = $2;
4692                                         w->result = $4;
4693                                         $$ = (Node *)w;
4694                                 }
4695                 ;
4696
4697 case_default:  ELSE a_expr_or_null                              { $$ = $2; }
4698                 | /*EMPTY*/                                                             { $$ = NULL; }
4699                 ;
4700
4701 case_arg:  a_expr
4702                                 {       $$ = $1; }
4703                 | /*EMPTY*/
4704                                 {       $$ = NULL; }
4705                 ;
4706
4707 attr:  relation_name '.' attrs opt_indirection
4708                                 {
4709                                         $$ = makeNode(Attr);
4710                                         $$->relname = $1;
4711                                         $$->paramNo = NULL;
4712                                         $$->attrs = $3;
4713                                         $$->indirection = $4;
4714                                 }
4715                 | ParamNo '.' attrs opt_indirection
4716                                 {
4717                                         $$ = makeNode(Attr);
4718                                         $$->relname = NULL;
4719                                         $$->paramNo = $1;
4720                                         $$->attrs = $3;
4721                                         $$->indirection = $4;
4722                                 }
4723                 ;
4724
4725 attrs:    attr_name
4726                                 { $$ = lcons(makeString($1), NIL); }
4727                 | attrs '.' attr_name
4728                                 { $$ = lappend($1, makeString($3)); }
4729                 | attrs '.' '*'
4730                                 { $$ = lappend($1, makeString("*")); }
4731                 ;
4732
4733
4734 /*****************************************************************************
4735  *
4736  *      target lists
4737  *
4738  *****************************************************************************/
4739
4740 /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
4741
4742 target_list:  target_list ',' target_el
4743                                 {       $$ = lappend($1, $3);  }
4744                 | target_el
4745                                 {       $$ = lcons($1, NIL);  }
4746                 ;
4747
4748 /* AS is not optional because shift/red conflict with unary ops */
4749 target_el:  a_expr_or_null AS ColLabel
4750                                 {
4751                                         $$ = makeNode(ResTarget);
4752                                         $$->name = $3;
4753                                         $$->indirection = NULL;
4754                                         $$->val = (Node *)$1;
4755                                 }
4756                 | a_expr_or_null
4757                                 {
4758                                         $$ = makeNode(ResTarget);
4759                                         $$->name = NULL;
4760                                         $$->indirection = NULL;
4761                                         $$->val = (Node *)$1;
4762                                 }
4763                 | relation_name '.' '*'
4764                                 {
4765                                         Attr *att = makeNode(Attr);
4766                                         att->relname = $1;
4767                                         att->paramNo = NULL;
4768                                         att->attrs = lcons(makeString("*"), NIL);
4769                                         att->indirection = NIL;
4770                                         $$ = makeNode(ResTarget);
4771                                         $$->name = NULL;
4772                                         $$->indirection = NULL;
4773                                         $$->val = (Node *)att;
4774                                 }
4775                 | '*'
4776                                 {
4777                                         Attr *att = makeNode(Attr);
4778                                         att->relname = "*";
4779                                         att->paramNo = NULL;
4780                                         att->attrs = NULL;
4781                                         att->indirection = NIL;
4782                                         $$ = makeNode(ResTarget);
4783                                         $$->name = NULL;
4784                                         $$->indirection = NULL;
4785                                         $$->val = (Node *)att;
4786                                 }
4787                 ;
4788
4789 /* Target list as found in UPDATE table SET ... */
4790
4791 update_target_list:  update_target_list ',' update_target_el
4792                                 {       $$ = lappend($1,$3);  }
4793                 | update_target_el
4794                                 {       $$ = lcons($1, NIL);  }
4795                 ;
4796
4797 update_target_el:  ColId opt_indirection '=' a_expr_or_null
4798                                 {
4799                                         $$ = makeNode(ResTarget);
4800                                         $$->name = $1;
4801                                         $$->indirection = $2;
4802                                         $$->val = (Node *)$4;
4803                                 }
4804                 ;
4805
4806 /*****************************************************************************
4807  *
4808  *      Names and constants
4809  *
4810  *****************************************************************************/
4811
4812 relation_name:  SpecialRuleRelation
4813                                 {
4814                                         $$ = $1;
4815                                         StrNCpy(saved_relname, $1, NAMEDATALEN);
4816                                 }
4817                 | ColId
4818                                 {
4819                                         /* disallow refs to variable system tables */
4820                                         if (strcmp(LogRelationName, $1) == 0
4821                                            || strcmp(VariableRelationName, $1) == 0)
4822                                                 elog(ERROR,"%s cannot be accessed by users",$1);
4823                                         else
4824                                                 $$ = $1;
4825                                         StrNCpy(saved_relname, $1, NAMEDATALEN);
4826                                 }
4827                 ;
4828
4829 database_name:                  ColId                   { $$ = $1; };
4830 access_method:                  IDENT                   { $$ = $1; };
4831 attr_name:                              ColId                   { $$ = $1; };
4832 class:                                  IDENT                   { $$ = $1; };
4833 index_name:                             ColId                   { $$ = $1; };
4834
4835 /* Functions
4836  * Include date/time keywords as SQL92 extension.
4837  * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4838  */
4839 name:                                   ColId                   { $$ = $1; };
4840 func_name:                              ColId                   { $$ = xlateSqlFunc($1); };
4841
4842 file_name:                              Sconst                  { $$ = $1; };
4843 /* NOT USED recipe_name:                        IDENT                   { $$ = $1; };*/
4844
4845 /* Constants
4846  * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4847  */
4848 AexprConst:  Iconst
4849                                 {
4850                                         A_Const *n = makeNode(A_Const);
4851                                         n->val.type = T_Integer;
4852                                         n->val.val.ival = $1;
4853                                         $$ = (Node *)n;
4854                                 }
4855                 | FCONST
4856                                 {
4857                                         A_Const *n = makeNode(A_Const);
4858                                         n->val.type = T_Float;
4859                                         n->val.val.dval = $1;
4860                                         $$ = (Node *)n;
4861                                 }
4862                 | Sconst
4863                                 {
4864                                         A_Const *n = makeNode(A_Const);
4865                                         n->val.type = T_String;
4866                                         n->val.val.str = $1;
4867                                         $$ = (Node *)n;
4868                                 }
4869                 /* this rule formerly used Typename, but that causes reduce conflicts
4870                  * with subscripted column names ...
4871                  */
4872                 | SimpleTypename Sconst
4873                                 {
4874                                         A_Const *n = makeNode(A_Const);
4875                                         n->typename = $1;
4876                                         n->val.type = T_String;
4877                                         n->val.val.str = $2;
4878                                         $$ = (Node *)n;
4879                                 }
4880                 | ParamNo
4881                                 {       $$ = (Node *)$1;  }
4882                 | TRUE_P
4883                                 {
4884                                         A_Const *n = makeNode(A_Const);
4885                                         n->val.type = T_String;
4886                                         n->val.val.str = "t";
4887                                         n->typename = makeNode(TypeName);
4888                                         n->typename->name = xlateSqlType("bool");
4889                                         n->typename->typmod = -1;
4890                                         $$ = (Node *)n;
4891                                 }
4892                 | FALSE_P
4893                                 {
4894                                         A_Const *n = makeNode(A_Const);
4895                                         n->val.type = T_String;
4896                                         n->val.val.str = "f";
4897                                         n->typename = makeNode(TypeName);
4898                                         n->typename->name = xlateSqlType("bool");
4899                                         n->typename->typmod = -1;
4900                                         $$ = (Node *)n;
4901                                 }
4902                 ;
4903
4904 ParamNo:  PARAM opt_indirection
4905                                 {
4906                                         $$ = makeNode(ParamNo);
4907                                         $$->number = $1;
4908                                         $$->indirection = $2;
4909                                 }
4910                 ;
4911
4912 Iconst:  ICONST                                                 { $$ = $1; };
4913 Sconst:  SCONST                                                 { $$ = $1; };
4914 UserId:  IDENT                                                  { $$ = $1; };
4915
4916 /* Column and type identifier
4917  * Does not include explicit datetime types
4918  *  since these must be decoupled in Typename syntax.
4919  * Use ColId for most identifiers. - thomas 1997-10-21
4920  */
4921 TypeId:  ColId
4922                         {       $$ = xlateSqlType($1); }
4923                 | numeric
4924                         {       $$ = xlateSqlType($1); }
4925                 | character
4926                         {       $$ = xlateSqlType($1); }
4927                 ;
4928 /* Column identifier
4929  * Include date/time keywords as SQL92 extension.
4930  * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4931  * Add other keywords. Note that as the syntax expands,
4932  *  some of these keywords will have to be removed from this
4933  *  list due to shift/reduce conflicts in yacc. If so, move
4934  *  down to the ColLabel entity. - thomas 1997-11-06
4935  */
4936 ColId:  IDENT                                                   { $$ = $1; }
4937                 | datetime                                              { $$ = $1; }
4938                 | ABSOLUTE                                              { $$ = "absolute"; }
4939                 | ACCESS                                                { $$ = "access"; }
4940                 | ACTION                                                { $$ = "action"; }
4941                 | AFTER                                                 { $$ = "after"; }
4942                 | AGGREGATE                                             { $$ = "aggregate"; }
4943                 | BACKWARD                                              { $$ = "backward"; }
4944                 | BEFORE                                                { $$ = "before"; }
4945                 | CACHE                                                 { $$ = "cache"; }
4946                 | COMMENT                                               { $$ = "comment"; }
4947                 | COMMITTED                                             { $$ = "committed"; }
4948                 | CONSTRAINTS                                   { $$ = "constraints"; }
4949                 | CREATEDB                                              { $$ = "createdb"; }
4950                 | CREATEUSER                                    { $$ = "createuser"; }
4951                 | CYCLE                                                 { $$ = "cycle"; }
4952                 | DATABASE                                              { $$ = "database"; }
4953                 | DEFERRABLE                                    { $$ = "deferrable"; }
4954                 | DEFERRED                                              { $$ = "deferred"; }
4955                 | DELIMITERS                                    { $$ = "delimiters"; }
4956                 | DOUBLE                                                { $$ = "double"; }
4957                 | EACH                                                  { $$ = "each"; }
4958                 | ENCODING                                              { $$ = "encoding"; }
4959                 | EXCLUSIVE                                             { $$ = "exclusive"; }
4960                 | FORWARD                                               { $$ = "forward"; }
4961                 | FUNCTION                                              { $$ = "function"; }
4962                 | HANDLER                                               { $$ = "handler"; }
4963                 | IMMEDIATE                                             { $$ = "immediate"; }
4964                 | INCREMENT                                             { $$ = "increment"; }
4965                 | INDEX                                                 { $$ = "index"; }
4966                 | INHERITS                                              { $$ = "inherits"; }
4967                 | INITIALLY                                             { $$ = "initially"; }
4968                 | INSENSITIVE                                   { $$ = "insensitive"; }
4969                 | INSTEAD                                               { $$ = "instead"; }
4970                 | ISNULL                                                { $$ = "isnull"; }
4971                 | ISOLATION                                             { $$ = "isolation"; }
4972                 | KEY                                                   { $$ = "key"; }
4973                 | LANGUAGE                                              { $$ = "language"; }
4974                 | LANCOMPILER                                   { $$ = "lancompiler"; }
4975                 | LEVEL                                                 { $$ = "level"; }
4976                 | LOCATION                                              { $$ = "location"; }
4977                 | MATCH                                                 { $$ = "match"; }
4978                 | MAXVALUE                                              { $$ = "maxvalue"; }
4979                 | MINVALUE                                              { $$ = "minvalue"; }
4980                 | MODE                                                  { $$ = "mode"; }
4981                 | NEXT                                                  { $$ = "next"; }
4982                 | NOCREATEDB                                    { $$ = "nocreatedb"; }
4983                 | NOCREATEUSER                                  { $$ = "nocreateuser"; }
4984                 | NOTHING                                               { $$ = "nothing"; }
4985                 | NOTNULL                                               { $$ = "notnull"; }
4986                 | OF                                                    { $$ = "of"; }
4987                 | OIDS                                                  { $$ = "oids"; }
4988                 | ONLY                                                  { $$ = "only"; }
4989                 | OPERATOR                                              { $$ = "operator"; }
4990                 | OPTION                                                { $$ = "option"; }
4991                 | PASSWORD                                              { $$ = "password"; }
4992                 | PENDANT                                               { $$ = "pendant"; }
4993                 | PRIOR                                                 { $$ = "prior"; }
4994                 | PRIVILEGES                                    { $$ = "privileges"; }
4995                 | PROCEDURAL                                    { $$ = "procedural"; }
4996                 | READ                                                  { $$ = "read"; }
4997                 | RELATIVE                                              { $$ = "relative"; }
4998                 | RENAME                                                { $$ = "rename"; }
4999                 | RESTRICT                                              { $$ = "restrict"; }
5000                 | RETURNS                                               { $$ = "returns"; }
5001                 | ROW                                                   { $$ = "row"; }
5002                 | RULE                                                  { $$ = "rule"; }
5003                 | SCROLL                                                { $$ = "scroll"; }
5004                 | SEQUENCE                                              { $$ = "sequence"; }
5005                 | SERIAL                                                { $$ = "serial"; }
5006                 | SERIALIZABLE                                  { $$ = "serializable"; }
5007                 | SHARE                                                 { $$ = "share"; }
5008                 | START                                                 { $$ = "start"; }
5009                 | STATEMENT                                             { $$ = "statement"; }
5010                 | STDIN                                                 { $$ = "stdin"; }
5011                 | STDOUT                                                { $$ = "stdout"; }
5012                 | SYSID                                                 { $$ = "sysid"; }
5013                 | TIME                                                  { $$ = "time"; }
5014                 | TIMESTAMP                                             { $$ = "timestamp"; }
5015                 | TIMEZONE_HOUR                                 { $$ = "timezone_hour"; }
5016                 | TIMEZONE_MINUTE                               { $$ = "timezone_minute"; }
5017                 | TRIGGER                                               { $$ = "trigger"; }
5018                 | TRUNCATE                                              { $$ = "truncate"; }
5019                 | TRUSTED                                               { $$ = "trusted"; }
5020                 | TYPE_P                                                { $$ = "type"; }
5021                 | VALID                                                 { $$ = "valid"; }
5022                 | VERSION                                               { $$ = "version"; }
5023                 | ZONE                                                  { $$ = "zone"; }
5024                 ;
5025
5026 /* Column label
5027  * Allowed labels in "AS" clauses.
5028  * Include TRUE/FALSE SQL3 reserved words for Postgres backward
5029  *  compatibility. Cannot allow this for column names since the
5030  *  syntax would not distinguish between the constant value and
5031  *  a column name. - thomas 1997-10-24
5032  * Add other keywords to this list. Note that they appear here
5033  *  rather than in ColId if there was a shift/reduce conflict
5034  *  when used as a full identifier. - thomas 1997-11-06
5035  */
5036 ColLabel:  ColId                                                { $$ = $1; }
5037                 | ABORT_TRANS                                   { $$ = "abort"; }
5038                 | ANALYZE                                               { $$ = "analyze"; }
5039                 | BINARY                                                { $$ = "binary"; }
5040                 | CASE                                                  { $$ = "case"; }
5041                 | CLUSTER                                               { $$ = "cluster"; }
5042                 | COALESCE                                              { $$ = "coalesce"; }
5043                 | CONSTRAINT                                    { $$ = "constraint"; }
5044                 | COPY                                                  { $$ = "copy"; }
5045                 | CURRENT                                               { $$ = "current"; }
5046                 | DO                                                    { $$ = "do"; }
5047                 | ELSE                                                  { $$ = "else"; }
5048                 | END_TRANS                                             { $$ = "end"; }
5049                 | EXPLAIN                                               { $$ = "explain"; }
5050                 | EXTEND                                                { $$ = "extend"; }
5051                 | FALSE_P                                               { $$ = "false"; }
5052                 | FOREIGN                                               { $$ = "foreign"; }
5053                 | GLOBAL                                                { $$ = "global"; }
5054                 | GROUP                                                 { $$ = "group"; }
5055                 | LISTEN                                                { $$ = "listen"; }
5056                 | LOAD                                                  { $$ = "load"; }
5057                 | LOCAL                                                 { $$ = "local"; }
5058                 | LOCK_P                                                { $$ = "lock"; }
5059                 | MOVE                                                  { $$ = "move"; }
5060                 | NEW                                                   { $$ = "new"; }
5061                 | NONE                                                  { $$ = "none"; }
5062                 | NULLIF                                                { $$ = "nullif"; }
5063                 | ORDER                                                 { $$ = "order"; }
5064                 | POSITION                                              { $$ = "position"; }
5065                 | PRECISION                                             { $$ = "precision"; }
5066                 | RESET                                                 { $$ = "reset"; }
5067                 | SETOF                                                 { $$ = "setof"; }
5068                 | SHOW                                                  { $$ = "show"; }
5069                 | TABLE                                                 { $$ = "table"; }
5070                 | THEN                                                  { $$ = "then"; }
5071                 | TRANSACTION                                   { $$ = "transaction"; }
5072                 | TRUE_P                                                { $$ = "true"; }
5073                 | VACUUM                                                { $$ = "vacuum"; }
5074                 | VERBOSE                                               { $$ = "verbose"; }
5075                 | WHEN                                                  { $$ = "when"; }
5076                 ;
5077
5078 SpecialRuleRelation:  CURRENT
5079                                 {
5080                                         if (QueryIsRule)
5081                                                 $$ = "*CURRENT*";
5082                                         else
5083                                                 elog(ERROR,"CURRENT used in non-rule query");
5084                                 }
5085                 | NEW
5086                                 {
5087                                         if (QueryIsRule)
5088                                                 $$ = "*NEW*";
5089                                         else
5090                                                 elog(ERROR,"NEW used in non-rule query");
5091                                 }
5092                 ;
5093
5094 %%
5095
5096 static Node *
5097 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
5098 {
5099         A_Expr *a = makeNode(A_Expr);
5100         a->oper = oper;
5101         a->opname = opname;
5102         a->lexpr = lexpr;
5103         a->rexpr = rexpr;
5104         return (Node *)a;
5105 }
5106
5107 /* makeRowExpr()
5108  * Generate separate operator nodes for a single row descriptor expression.
5109  * Perhaps this should go deeper in the parser someday...
5110  * - thomas 1997-12-22
5111  */
5112 static Node *
5113 makeRowExpr(char *opr, List *largs, List *rargs)
5114 {
5115         Node *expr = NULL;
5116         Node *larg, *rarg;
5117
5118         if (length(largs) != length(rargs))
5119                 elog(ERROR,"Unequal number of entries in row expression");
5120
5121         if (lnext(largs) != NIL)
5122                 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
5123
5124         larg = lfirst(largs);
5125         rarg = lfirst(rargs);
5126
5127         if ((strcmp(opr, "=") == 0)
5128          || (strcmp(opr, "<") == 0)
5129          || (strcmp(opr, "<=") == 0)
5130          || (strcmp(opr, ">") == 0)
5131          || (strcmp(opr, ">=") == 0))
5132         {
5133                 if (expr == NULL)
5134                         expr = makeA_Expr(OP, opr, larg, rarg);
5135                 else
5136                         expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
5137         }
5138         else if (strcmp(opr, "<>") == 0)
5139         {
5140                 if (expr == NULL)
5141                         expr = makeA_Expr(OP, opr, larg, rarg);
5142                 else
5143                         expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
5144         }
5145         else
5146         {
5147                 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
5148         }
5149
5150         return expr;
5151 }
5152
5153 static void
5154 mapTargetColumns(List *src, List *dst)
5155 {
5156         ColumnDef *s;
5157         ResTarget *d;
5158
5159         if (length(src) != length(dst))
5160                 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
5161
5162         while ((src != NIL) && (dst != NIL))
5163         {
5164                 s = (ColumnDef *)lfirst(src);
5165                 d = (ResTarget *)lfirst(dst);
5166
5167                 d->name = s->colname;
5168
5169                 src = lnext(src);
5170                 dst = lnext(dst);
5171         }
5172 } /* mapTargetColumns() */
5173
5174
5175 /* xlateSqlFunc()
5176  * Convert alternate type names to internal Postgres types.
5177  * Do not convert "float", since that is handled elsewhere
5178  *  for FLOAT(p) syntax.
5179  */
5180 static char *
5181 xlateSqlFunc(char *name)
5182 {
5183         if (!strcasecmp(name,"character_length")
5184          || !strcasecmp(name,"char_length"))
5185                 return "length";
5186         else
5187                 return name;
5188 } /* xlateSqlFunc() */
5189
5190 /* xlateSqlType()
5191  * Convert alternate type names to internal Postgres types.
5192  */
5193 static char *
5194 xlateSqlType(char *name)
5195 {
5196         if (!strcasecmp(name,"int")
5197          || !strcasecmp(name,"integer"))
5198                 return "int4";
5199         else if (!strcasecmp(name, "smallint"))
5200                 return "int2";
5201         else if (!strcasecmp(name, "real")
5202          || !strcasecmp(name, "float"))
5203                 return "float8";
5204         else if (!strcasecmp(name, "interval"))
5205                 return "timespan";
5206         else if (!strcasecmp(name, "boolean"))
5207                 return "bool";
5208         else
5209                 return name;
5210 } /* xlateSqlType() */
5211
5212
5213 void parser_init(Oid *typev, int nargs)
5214 {
5215         QueryIsRule = FALSE;
5216         saved_relname[0]= '\0';
5217
5218         param_type_init(typev, nargs);
5219 }
5220
5221
5222 /*
5223  * param_type_init()
5224  *
5225  * keep enough information around fill out the type of param nodes
5226  * used in postquel functions
5227  */
5228 static void
5229 param_type_init(Oid *typev, int nargs)
5230 {
5231         pfunc_num_args = nargs;
5232         param_type_info = typev;
5233 }
5234
5235 Oid param_type(int t)
5236 {
5237         if ((t > pfunc_num_args) || (t == 0))
5238                 return InvalidOid;
5239         return param_type_info[t - 1];
5240 }
5241
5242 /*
5243  *      The optimizer doesn't like '-' 4 for index use.  It only checks for
5244  *      Var '=' Const.  It wants an integer of -4, so we try to merge the
5245  *      minus into the constant.
5246  *
5247  *      This code is no longer essential as of 10/1999, since the optimizer
5248  *      now has a constant-subexpression simplifier.  However, we can save
5249  *      a few cycles throughout the parse and rewrite stages if we collapse
5250  *      the minus into the constant sooner rather than later...
5251  */
5252 static Node *doNegate(Node *n)
5253 {
5254         if (IsA(n, A_Const))
5255         {
5256                 A_Const *con = (A_Const *)n;
5257
5258                 if (con->val.type == T_Integer)
5259                 {
5260                         con->val.val.ival = -con->val.val.ival;
5261                         return n;
5262                 }
5263                 if (con->val.type == T_Float)
5264                 {
5265                         con->val.val.dval = -con->val.val.dval;
5266                         return n;
5267                 }
5268         }
5269
5270         return makeA_Expr(OP, "-", NULL, n);
5271 }