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