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