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