4 /*-------------------------------------------------------------------------
7 * POSTGRES SQL YACC rules/actions
9 * Copyright (c) 1994, Regents of the University of California
13 * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.10 1998/04/13 21:07:15 momjian Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
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.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlFunc(char *);
65 static char *xlateSqlType(char *);
66 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
67 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
68 void mapTargetColumns(List *source, List *target);
69 static List *makeConstantList( A_Const *node);
70 static char *FlattenStringList(List *list);
71 static char *fmtId(char *rawid);
72 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
73 static void param_type_init(Oid *typev, int nargs);
75 Oid param_type(int t); /* used in parse_expr.c */
77 /* old versions of flex define this as a macro */
91 bool* pboolean; /* for pg_shadow privileges */
101 SortGroupBy *sortgroupby;
116 AddAttrStmt, ClosePortalStmt,
117 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
118 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
119 CreatePLangStmt, DropPLangStmt,
120 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
121 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
122 RemoveFuncStmt, RemoveStmt,
123 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
124 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
125 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
126 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
127 CreateUserStmt, AlterUserStmt, DropUserStmt
129 %type <str> opt_database, location
131 %type <pboolean> user_createdb_clause, user_createuser_clause
132 %type <str> user_passwd_clause
133 %type <str> user_valid_clause
134 %type <list> user_group_list, user_group_clause
136 %type <str> join_expr, join_outer, join_spec
137 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
139 %type <str> TriggerEvents, TriggerFuncArg
141 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
142 database_name, access_method_clause, access_method, attr_name,
143 class, index_name, name, func_name, file_name, recipe_name, aggr_argtype
145 %type <str> opt_id, opt_portal_name,
146 all_Op, MathOp, opt_name, opt_unique,
147 result, OptUseOp, opt_class, SpecialRuleRelation
149 %type <str> privileges, operation_commalist, grantee
150 %type <chr> operation, TriggerOneEvent
152 %type <list> stmtblock, stmtmulti,
153 relation_name_list, OptTableElementList,
154 OptInherit, definition,
155 opt_with, func_args, func_args_list,
156 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
157 opt_column_list, columnList, opt_va_list, va_list,
158 sort_clause, sortby_list, index_params, index_list, name_list,
159 from_clause, from_list, opt_array_bounds, nest_array_bounds,
160 expr_list, attrs, res_target_list, res_target_list2,
161 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
163 %type <node> func_return
164 %type <boolean> set_opt
166 %type <boolean> TriggerForOpt, TriggerForType
168 %type <list> union_clause, select_list
169 %type <list> join_list
172 %type <boolean> opt_union
173 %type <boolean> opt_table
175 %type <node> position_expr
176 %type <list> extract_list, position_list
177 %type <list> substr_list, substr_from, substr_for, trim_list
178 %type <list> opt_interval
180 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
181 index_opt_unique, opt_verbose, opt_analyze
183 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
186 %type <ival> fetch_how_many
188 %type <list> OptSeqList
189 %type <defelt> OptSeqElem
191 %type <dstmt> def_rest
192 %type <astmt> insert_rest
194 %type <node> OptTableElement, ConstraintElem
195 %type <node> columnDef, alter_clause
196 %type <defelt> def_elem
197 %type <node> def_arg, columnElem, where_clause,
198 a_expr, a_expr_or_null, b_expr, AexprConst,
199 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
201 %type <list> row_descriptor, row_list
202 %type <node> row_expr
203 %type <list> OptCreateAs, CreateAsList
204 %type <node> CreateAsElement
205 %type <value> NumConst
206 %type <value> IntegerOnly
207 %type <attr> event_object, attr
208 %type <sortgroupby> groupby
209 %type <sortgroupby> sortby
210 %type <ielem> index_elem, func_index
211 %type <range> from_val
212 %type <relexp> relation_expr
213 %type <target> res_target_el, res_target_el2
214 %type <paramno> ParamNo
216 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
217 %type <str> generic, numeric, character, datetime
218 %type <str> extract_arg
219 %type <str> opt_charset, opt_collate
220 %type <str> opt_float, opt_numeric, opt_decimal
221 %type <boolean> opt_varying, opt_timezone
225 %type <str> UserId, var_value, zone_value
226 %type <str> ColId, ColLabel
229 %type <node> TableConstraint
230 %type <list> constraint_list, constraint_expr
231 %type <list> default_list, default_expr
232 %type <list> ColQualList, ColQualifier
233 %type <node> ColConstraint, ColConstraintElem
234 %type <list> key_actions, key_action
235 %type <str> key_match, key_reference
238 * If you make any token changes, remember to:
239 * - use "yacc -d" and update parse.h
240 * - update the keyword table in parser/keywords.c
243 /* Reserved word tokens
244 * SQL92 syntax has many type-specific constructs.
245 * So, go ahead and make these types reserved words,
246 * and call-out the syntax explicitly.
247 * This gets annoying when trying to also retain Postgres' nice
248 * type-extensible features, but we don't really have a choice.
249 * - thomas 1997-10-11
252 /* Keywords (in SQL92 reserved words) */
253 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
254 BEGIN_TRANS, BETWEEN, BOTH, BY,
255 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
256 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
257 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
258 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
259 END_TRANS, EXECUTE, EXISTS, EXTRACT,
260 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
261 GRANT, GROUP, HAVING, HOUR_P,
262 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
263 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
264 MATCH, MINUTE_P, MONTH_P,
265 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
266 ON, OPTION, OR, ORDER, OUTER_P,
267 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
268 REFERENCES, REVOKE, RIGHT, ROLLBACK,
269 SECOND_P, SELECT, SET, SUBSTRING,
270 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
271 UNION, UNIQUE, UPDATE, USING,
272 VALUES, VARCHAR, VARYING, VIEW,
273 WHERE, WITH, WORK, YEAR_P, ZONE
275 /* Keywords (in SQL3 reserved words) */
276 %token FALSE_P, TRIGGER, TRUE_P
278 /* Keywords (in SQL92 non-reserved words) */
281 /* Keywords for Postgres support (not in SQL92 reserved words) */
282 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
283 BACKWARD, BEFORE, BINARY, CACHE, CLUSTER, COPY, CYCLE,
284 DATABASE, DELIMITERS, DO, EACH, EXPLAIN, EXTEND,
285 FORWARD, FUNCTION, HANDLER,
286 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
287 LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MAXVALUE, MINVALUE, MOVE,
288 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
289 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
290 SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
291 VACUUM, VERBOSE, VERSION
293 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
297 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
298 * when some sort of pg_privileges relation is introduced.
302 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
304 /* Special keywords, not in the query language - see the "lex" file */
305 %token <str> IDENT, SCONST, Op
306 %token <ival> ICONST, PARAM
309 /* these are not real. they are here so that they get generated as #define's*/
321 %nonassoc Op /* multi-character ops and user-defined operators */
327 %left '|' /* this is the relation union op, not logical or */
328 /* Unary Operators */
330 %left ';' /* end of statement or natural log */
342 { parsetree = lcons($1,NIL); }
345 stmtmulti: stmtmulti stmt ';'
346 { $$ = lappend($1, $2); }
348 { $$ = lappend($1, $2); }
350 { $$ = lcons($1,NIL); }
397 /*****************************************************************************
399 * Create a new Postgres DBMS user
402 *****************************************************************************/
404 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
405 user_createuser_clause user_group_clause user_valid_clause
407 CreateUserStmt *n = makeNode(CreateUserStmt);
418 /*****************************************************************************
420 * Alter a postresql DBMS user
423 *****************************************************************************/
425 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
426 user_createuser_clause user_group_clause user_valid_clause
428 AlterUserStmt *n = makeNode(AlterUserStmt);
439 /*****************************************************************************
441 * Drop a postresql DBMS user
444 *****************************************************************************/
446 DropUserStmt: DROP USER UserId
448 DropUserStmt *n = makeNode(DropUserStmt);
454 user_passwd_clause: WITH PASSWORD UserId { $$ = $3; }
455 | /*EMPTY*/ { $$ = NULL; }
458 user_createdb_clause: CREATEDB
461 $$ = (b = (bool*)palloc(sizeof(bool)));
467 $$ = (b = (bool*)palloc(sizeof(bool)));
470 | /*EMPTY*/ { $$ = NULL; }
473 user_createuser_clause: CREATEUSER
476 $$ = (b = (bool*)palloc(sizeof(bool)));
482 $$ = (b = (bool*)palloc(sizeof(bool)));
485 | /*EMPTY*/ { $$ = NULL; }
488 user_group_list: user_group_list ',' UserId
490 $$ = lcons((void*)makeString($3), $1);
494 $$ = lcons((void*)makeString($1), NIL);
498 user_group_clause: IN GROUP user_group_list { $$ = $3; }
499 | /*EMPTY*/ { $$ = NULL; }
502 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
503 | /*EMPTY*/ { $$ = NULL; }
506 /*****************************************************************************
508 * Set PG internal variable
509 * SET name TO 'var_value'
510 * Include SQL92 syntax (thomas 1997-10-22):
511 * SET TIME ZONE 'var_value'
513 *****************************************************************************/
515 VariableSetStmt: SET ColId TO var_value
517 VariableSetStmt *n = makeNode(VariableSetStmt);
522 | SET ColId '=' var_value
524 VariableSetStmt *n = makeNode(VariableSetStmt);
529 | SET TIME ZONE zone_value
531 VariableSetStmt *n = makeNode(VariableSetStmt);
532 n->name = "timezone";
538 var_value: Sconst { $$ = $1; }
539 | DEFAULT { $$ = NULL; }
542 zone_value: Sconst { $$ = $1; }
543 | DEFAULT { $$ = NULL; }
544 | LOCAL { $$ = NULL; }
547 VariableShowStmt: SHOW ColId
549 VariableShowStmt *n = makeNode(VariableShowStmt);
555 VariableShowStmt *n = makeNode(VariableShowStmt);
556 n->name = "timezone";
561 VariableResetStmt: RESET ColId
563 VariableResetStmt *n = makeNode(VariableResetStmt);
569 VariableResetStmt *n = makeNode(VariableResetStmt);
570 n->name = "timezone";
576 /*****************************************************************************
579 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
581 *****************************************************************************/
583 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
585 AddAttrStmt *n = makeNode(AddAttrStmt);
593 alter_clause: ADD opt_column columnDef
597 | ADD '(' OptTableElementList ')'
599 Node *lp = lfirst($3);
602 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
605 | DROP opt_column ColId
606 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
607 | ALTER opt_column ColId SET DEFAULT default_expr
608 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
609 | ALTER opt_column ColId DROP DEFAULT
610 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
612 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
616 /*****************************************************************************
621 *****************************************************************************/
623 ClosePortalStmt: CLOSE opt_id
625 ClosePortalStmt *n = makeNode(ClosePortalStmt);
632 /*****************************************************************************
635 * COPY [BINARY] <relname> FROM/TO
636 * [USING DELIMITERS <delimiter>]
638 *****************************************************************************/
640 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
642 CopyStmt *n = makeNode(CopyStmt);
660 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
661 * used depends on the direction. (It really doesn't make sense to copy from
662 * stdout. We silently correct the "typo". - AY 9/94
664 copy_file_name: Sconst { $$ = $1; }
665 | STDIN { $$ = NULL; }
666 | STDOUT { $$ = NULL; }
669 opt_binary: BINARY { $$ = TRUE; }
670 | /*EMPTY*/ { $$ = FALSE; }
673 opt_with_copy: WITH OIDS { $$ = TRUE; }
674 | /*EMPTY*/ { $$ = FALSE; }
678 * the default copy delimiter is tab but the user can configure it
680 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
681 | /*EMPTY*/ { $$ = "\t"; }
685 /*****************************************************************************
690 *****************************************************************************/
692 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
693 OptInherit OptArchiveType
695 CreateStmt *n = makeNode(CreateStmt);
699 n->constraints = NIL;
704 OptTableElementList: OptTableElementList ',' OptTableElement
707 $$ = lappend($1, $3);
718 | /*EMPTY*/ { $$ = NULL; }
721 OptTableElement: columnDef { $$ = $1; }
722 | TableConstraint { $$ = $1; }
725 columnDef: ColId Typename ColQualifier
727 ColumnDef *n = makeNode(ColumnDef);
731 n->is_not_null = FALSE;
737 ColQualifier: ColQualList { $$ = $1; }
738 | /*EMPTY*/ { $$ = NULL; }
741 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
742 | ColConstraint { $$ = lcons($1, NIL); }
746 CONSTRAINT name ColConstraintElem
748 Constraint *n = (Constraint *)$3;
749 if (n != NULL) n->name = fmtId($2);
756 ColConstraintElem: CHECK '(' constraint_expr ')'
758 Constraint *n = makeNode(Constraint);
759 n->contype = CONSTR_CHECK;
761 n->def = FlattenStringList($3);
765 | DEFAULT default_expr
767 Constraint *n = makeNode(Constraint);
768 n->contype = CONSTR_DEFAULT;
770 n->def = FlattenStringList($2);
776 Constraint *n = makeNode(Constraint);
777 n->contype = CONSTR_NOTNULL;
785 Constraint *n = makeNode(Constraint);
786 n->contype = CONSTR_UNIQUE;
794 Constraint *n = makeNode(Constraint);
795 n->contype = CONSTR_PRIMARY;
801 | REFERENCES ColId opt_column_list key_match key_actions
803 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
808 default_list: default_list ',' default_expr
810 $$ = lappend($1,makeString(","));
819 default_expr: AexprConst
820 { $$ = makeConstantList((A_Const *) $1); }
822 { $$ = lcons( makeString("NULL"), NIL); }
823 | '-' default_expr %prec UMINUS
824 { $$ = lcons( makeString( "-"), $2); }
825 | default_expr '+' default_expr
826 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
827 | default_expr '-' default_expr
828 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
829 | default_expr '/' default_expr
830 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
831 | default_expr '*' default_expr
832 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
833 | default_expr '=' default_expr
834 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
835 | default_expr '<' default_expr
836 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
837 | default_expr '>' default_expr
838 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
840 { $$ = lcons( makeString( ":"), $2); }
842 { $$ = lcons( makeString( ";"), $2); }
844 { $$ = lcons( makeString( "|"), $2); }
845 | default_expr TYPECAST Typename
847 $3->name = fmtId($3->name);
848 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
850 | CAST '(' default_expr AS Typename ')'
852 $5->name = fmtId($5->name);
853 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
855 | '(' default_expr ')'
856 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
859 $$ = makeList( makeString($1), makeString("("), -1);
860 $$ = lappend( $$, makeString(")"));
862 | func_name '(' default_list ')'
864 $$ = makeList( makeString($1), makeString("("), -1);
866 $$ = lappend( $$, makeString(")"));
868 | default_expr Op default_expr
870 if (!strcmp("<=", $2) || !strcmp(">=", $2))
871 elog(ERROR,"boolean expressions not supported in DEFAULT");
872 $$ = nconc( $1, lcons( makeString( $2), $3));
875 { $$ = lcons( makeString( $1), $2); }
877 { $$ = lappend( $1, makeString( $2)); }
878 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
880 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
882 { $$ = lcons( makeString( "'now'::time"), NIL); }
883 | CURRENT_TIME '(' Iconst ')'
886 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
887 $$ = lcons( makeString( "'now'::time"), NIL);
890 { $$ = lcons( makeString( "now()"), NIL); }
891 | CURRENT_TIMESTAMP '(' Iconst ')'
894 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
895 $$ = lcons( makeString( "now()"), NIL);
898 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
901 /* ConstraintElem specifies constraint syntax which is not embedded into
902 * a column definition. ColConstraintElem specifies the embedded form.
903 * - thomas 1997-12-03
905 TableConstraint: CONSTRAINT name ConstraintElem
907 Constraint *n = (Constraint *)$3;
908 if (n != NULL) n->name = fmtId($2);
915 ConstraintElem: CHECK '(' constraint_expr ')'
917 Constraint *n = makeNode(Constraint);
918 n->contype = CONSTR_CHECK;
920 n->def = FlattenStringList($3);
923 | UNIQUE '(' columnList ')'
925 Constraint *n = makeNode(Constraint);
926 n->contype = CONSTR_UNIQUE;
932 | PRIMARY KEY '(' columnList ')'
934 Constraint *n = makeNode(Constraint);
935 n->contype = CONSTR_PRIMARY;
941 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
943 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
948 constraint_list: constraint_list ',' constraint_expr
950 $$ = lappend($1,makeString(","));
959 constraint_expr: AexprConst
960 { $$ = makeConstantList((A_Const *) $1); }
962 { $$ = lcons( makeString("NULL"), NIL); }
965 $$ = lcons( makeString(fmtId($1)), NIL);
967 | '-' constraint_expr %prec UMINUS
968 { $$ = lcons( makeString( "-"), $2); }
969 | constraint_expr '+' constraint_expr
970 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
971 | constraint_expr '-' constraint_expr
972 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
973 | constraint_expr '/' constraint_expr
974 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
975 | constraint_expr '*' constraint_expr
976 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
977 | constraint_expr '=' constraint_expr
978 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
979 | constraint_expr '<' constraint_expr
980 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
981 | constraint_expr '>' constraint_expr
982 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
983 | ':' constraint_expr
984 { $$ = lcons( makeString( ":"), $2); }
985 | ';' constraint_expr
986 { $$ = lcons( makeString( ";"), $2); }
987 | '|' constraint_expr
988 { $$ = lcons( makeString( "|"), $2); }
989 | constraint_expr TYPECAST Typename
991 $3->name = fmtId($3->name);
992 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
994 | CAST '(' constraint_expr AS Typename ')'
996 $5->name = fmtId($5->name);
997 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
999 | '(' constraint_expr ')'
1000 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
1003 $$ = makeList( makeString($1), makeString("("), -1);
1004 $$ = lappend( $$, makeString(")"));
1006 | func_name '(' constraint_list ')'
1008 $$ = makeList( makeString($1), makeString("("), -1);
1009 $$ = nconc( $$, $3);
1010 $$ = lappend( $$, makeString(")"));
1012 | constraint_expr Op constraint_expr
1013 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
1014 | constraint_expr LIKE constraint_expr
1015 { $$ = nconc( $1, lcons( makeString( "like"), $3)); }
1016 | constraint_expr AND constraint_expr
1017 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
1018 | constraint_expr OR constraint_expr
1019 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
1020 | NOT constraint_expr
1021 { $$ = lcons( makeString( "NOT"), $2); }
1022 | Op constraint_expr
1023 { $$ = lcons( makeString( $1), $2); }
1024 | constraint_expr Op
1025 { $$ = lappend( $1, makeString( $2)); }
1026 | constraint_expr ISNULL
1027 { $$ = lappend( $1, makeString( "IS NULL")); }
1028 | constraint_expr IS NULL_P
1029 { $$ = lappend( $1, makeString( "IS NULL")); }
1030 | constraint_expr NOTNULL
1031 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1032 | constraint_expr IS NOT NULL_P
1033 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1034 | constraint_expr IS TRUE_P
1035 { $$ = lappend( $1, makeString( "IS TRUE")); }
1036 | constraint_expr IS FALSE_P
1037 { $$ = lappend( $1, makeString( "IS FALSE")); }
1038 | constraint_expr IS NOT TRUE_P
1039 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1040 | constraint_expr IS NOT FALSE_P
1041 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1044 key_match: MATCH FULL { $$ = NULL; }
1045 | MATCH PARTIAL { $$ = NULL; }
1046 | /*EMPTY*/ { $$ = NULL; }
1049 key_actions: key_action key_action { $$ = NIL; }
1050 | key_action { $$ = NIL; }
1051 | /*EMPTY*/ { $$ = NIL; }
1054 key_action: ON DELETE key_reference { $$ = NIL; }
1055 | ON UPDATE key_reference { $$ = NIL; }
1058 key_reference: NO ACTION { $$ = NULL; }
1059 | CASCADE { $$ = NULL; }
1060 | SET DEFAULT { $$ = NULL; }
1061 | SET NULL_P { $$ = NULL; }
1064 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1065 | /*EMPTY*/ { $$ = NIL; }
1069 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1070 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1072 OptArchiveType: ARCHIVE '=' NONE { }
1076 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1078 SelectStmt *n = (SelectStmt *)$6;
1080 mapTargetColumns($4, n->targetList);
1086 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1087 | /*EMPTY*/ { $$ = NULL; }
1090 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1091 | CreateAsElement { $$ = lcons($1, NIL); }
1094 CreateAsElement: ColId
1096 ColumnDef *n = makeNode(ColumnDef);
1100 n->is_not_null = FALSE;
1101 n->constraints = NULL;
1107 /*****************************************************************************
1110 * CREATE SEQUENCE seqname
1112 *****************************************************************************/
1114 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1116 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1123 OptSeqList: OptSeqList OptSeqElem
1124 { $$ = lappend($1, $2); }
1128 OptSeqElem: CACHE IntegerOnly
1130 $$ = makeNode(DefElem);
1131 $$->defname = "cache";
1132 $$->arg = (Node *)$2;
1136 $$ = makeNode(DefElem);
1137 $$->defname = "cycle";
1138 $$->arg = (Node *)NULL;
1140 | INCREMENT IntegerOnly
1142 $$ = makeNode(DefElem);
1143 $$->defname = "increment";
1144 $$->arg = (Node *)$2;
1146 | MAXVALUE IntegerOnly
1148 $$ = makeNode(DefElem);
1149 $$->defname = "maxvalue";
1150 $$->arg = (Node *)$2;
1152 | MINVALUE IntegerOnly
1154 $$ = makeNode(DefElem);
1155 $$->defname = "minvalue";
1156 $$->arg = (Node *)$2;
1160 $$ = makeNode(DefElem);
1161 $$->defname = "start";
1162 $$->arg = (Node *)$2;
1168 $$ = makeInteger($1);
1172 $$ = makeInteger($2);
1173 $$->val.ival = - $$->val.ival;
1177 /*****************************************************************************
1180 * CREATE PROCEDURAL LANGUAGE ...
1181 * DROP PROCEDURAL LANGUAGE ...
1183 *****************************************************************************/
1185 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1186 HANDLER def_name LANCOMPILER Sconst
1188 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1197 PLangTrusted: TRUSTED { $$ = TRUE; }
1200 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1202 DropPLangStmt *n = makeNode(DropPLangStmt);
1208 /*****************************************************************************
1211 * CREATE TRIGGER ...
1214 *****************************************************************************/
1216 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1217 relation_name TriggerForSpec EXECUTE PROCEDURE
1218 name '(' TriggerFuncArgs ')'
1220 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1227 memcpy (n->actions, $5, 4);
1232 TriggerActionTime: BEFORE { $$ = TRUE; }
1233 | AFTER { $$ = FALSE; }
1236 TriggerEvents: TriggerOneEvent
1238 char *e = palloc (4);
1239 e[0] = $1; e[1] = 0; $$ = e;
1241 | TriggerOneEvent OR TriggerOneEvent
1243 char *e = palloc (4);
1244 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1246 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1248 char *e = palloc (4);
1249 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1254 TriggerOneEvent: INSERT { $$ = 'i'; }
1255 | DELETE { $$ = 'd'; }
1256 | UPDATE { $$ = 'u'; }
1259 TriggerForSpec: FOR TriggerForOpt TriggerForType
1265 TriggerForOpt: EACH { $$ = TRUE; }
1266 | /*EMPTY*/ { $$ = FALSE; }
1269 TriggerForType: ROW { $$ = TRUE; }
1270 | STATEMENT { $$ = FALSE; }
1273 TriggerFuncArgs: TriggerFuncArg
1274 { $$ = lcons($1, NIL); }
1275 | TriggerFuncArgs ',' TriggerFuncArg
1276 { $$ = lappend($1, $3); }
1281 TriggerFuncArg: ICONST
1283 char *s = (char *) palloc (256);
1284 sprintf (s, "%d", $1);
1289 char *s = (char *) palloc (256);
1290 sprintf (s, "%g", $1);
1293 | Sconst { $$ = $1; }
1294 | IDENT { $$ = $1; }
1297 DropTrigStmt: DROP TRIGGER name ON relation_name
1299 DropTrigStmt *n = makeNode(DropTrigStmt);
1307 /*****************************************************************************
1310 * define (type,operator,aggregate)
1312 *****************************************************************************/
1314 DefineStmt: CREATE def_type def_rest
1321 def_rest: def_name definition
1323 $$ = makeNode(DefineStmt);
1325 $$->definition = $2;
1329 def_type: OPERATOR { $$ = OPERATOR; }
1330 | TYPE_P { $$ = TYPE_P; }
1331 | AGGREGATE { $$ = AGGREGATE; }
1334 def_name: PROCEDURE { $$ = "procedure"; }
1335 | JOIN { $$ = "join"; }
1336 | ColId { $$ = $1; }
1337 | MathOp { $$ = $1; }
1341 definition: '(' def_list ')' { $$ = $2; }
1344 def_list: def_elem { $$ = lcons($1, NIL); }
1345 | def_list ',' def_elem { $$ = lappend($1, $3); }
1348 def_elem: def_name '=' def_arg
1350 $$ = makeNode(DefElem);
1352 $$->arg = (Node *)$3;
1356 $$ = makeNode(DefElem);
1358 $$->arg = (Node *)NULL;
1360 | DEFAULT '=' def_arg
1362 $$ = makeNode(DefElem);
1363 $$->defname = "default";
1364 $$->arg = (Node *)$3;
1368 def_arg: ColId { $$ = (Node *)makeString($1); }
1369 | all_Op { $$ = (Node *)makeString($1); }
1370 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1371 | Sconst { $$ = (Node *)makeString($1); }
1374 TypeName *n = makeNode(TypeName);
1377 n->arrayBounds = NULL;
1384 /*****************************************************************************
1387 * destroy <relname1> [, <relname2> .. <relnameN> ]
1389 *****************************************************************************/
1391 DestroyStmt: DROP TABLE relation_name_list
1393 DestroyStmt *n = makeNode(DestroyStmt);
1395 n->sequence = FALSE;
1398 | DROP SEQUENCE relation_name_list
1400 DestroyStmt *n = makeNode(DestroyStmt);
1408 /*****************************************************************************
1411 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1413 *****************************************************************************/
1415 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1417 FetchStmt *n = makeNode(FetchStmt);
1424 | MOVE opt_direction fetch_how_many opt_portal_name
1426 FetchStmt *n = makeNode(FetchStmt);
1435 opt_direction: FORWARD { $$ = FORWARD; }
1436 | BACKWARD { $$ = BACKWARD; }
1437 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1440 fetch_how_many: Iconst
1442 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1443 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1444 | /*EMPTY*/ { $$ = 1; /*default*/ }
1447 opt_portal_name: IN name { $$ = $2; }
1448 | /*EMPTY*/ { $$ = NULL; }
1452 /*****************************************************************************
1455 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1457 *****************************************************************************/
1459 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1461 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1465 privileges: ALL PRIVILEGES
1467 $$ = aclmakepriv("rwaR",0);
1471 $$ = aclmakepriv("rwaR",0);
1473 | operation_commalist
1479 operation_commalist: operation
1481 $$ = aclmakepriv("",$1);
1483 | operation_commalist ',' operation
1485 $$ = aclmakepriv($1,$3);
1491 $$ = ACL_MODE_RD_CHR;
1495 $$ = ACL_MODE_AP_CHR;
1499 $$ = ACL_MODE_WR_CHR;
1503 $$ = ACL_MODE_WR_CHR;
1507 $$ = ACL_MODE_RU_CHR;
1513 $$ = aclmakeuser("A","");
1517 $$ = aclmakeuser("G",$2);
1521 $$ = aclmakeuser("U",$1);
1525 opt_with_grant: WITH GRANT OPTION
1527 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1533 /*****************************************************************************
1536 * REVOKE [privileges] ON [relation_name] FROM [user]
1538 *****************************************************************************/
1540 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1542 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1547 /*****************************************************************************
1550 * create index <indexname> on <relname>
1551 * using <access> "(" (<col> with <op>)+ ")" [with
1554 * [where <qual>] is not supported anymore
1555 *****************************************************************************/
1557 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1558 access_method_clause '(' index_params ')' opt_with
1560 /* should check that access_method is valid,
1561 etc ... but doesn't */
1562 IndexStmt *n = makeNode(IndexStmt);
1566 n->accessMethod = $7;
1567 n->indexParams = $9;
1568 n->withClause = $11;
1569 n->whereClause = NULL;
1574 index_opt_unique: UNIQUE { $$ = TRUE; }
1575 | /*EMPTY*/ { $$ = FALSE; }
1578 access_method_clause: USING access_method { $$ = $2; }
1579 | /*EMPTY*/ { $$ = "btree"; }
1582 index_params: index_list { $$ = $1; }
1583 | func_index { $$ = lcons($1,NIL); }
1586 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1587 | index_elem { $$ = lcons($1, NIL); }
1590 func_index: func_name '(' name_list ')' opt_type opt_class
1592 $$ = makeNode(IndexElem);
1600 index_elem: attr_name opt_type opt_class
1602 $$ = makeNode(IndexElem);
1610 opt_type: ':' Typename { $$ = $2; }
1611 | FOR Typename { $$ = $2; }
1612 | /*EMPTY*/ { $$ = NULL; }
1615 /* opt_class "WITH class" conflicts with preceeding opt_type
1616 * for Typename of "TIMESTAMP WITH TIME ZONE"
1617 * So, remove "WITH class" from the syntax. OK??
1618 * - thomas 1997-10-12
1619 * | WITH class { $$ = $2; }
1621 opt_class: class { $$ = $1; }
1622 | USING class { $$ = $2; }
1623 | /*EMPTY*/ { $$ = NULL; }
1627 /*****************************************************************************
1630 * extend index <indexname> [where <qual>]
1632 *****************************************************************************/
1634 ExtendStmt: EXTEND INDEX index_name where_clause
1636 ExtendStmt *n = makeNode(ExtendStmt);
1638 n->whereClause = $4;
1644 /*****************************************************************************
1647 * execute recipe <recipeName>
1649 *****************************************************************************/
1651 RecipeStmt: EXECUTE RECIPE recipe_name
1654 if (!IsTransactionBlock())
1655 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1657 n = makeNode(RecipeStmt);
1664 /*****************************************************************************
1667 * define function <fname>
1668 * (language = <lang>, returntype = <typename>
1669 * [, arch_pct = <percentage | pre-defined>]
1670 * [, disk_pct = <percentage | pre-defined>]
1671 * [, byte_pct = <percentage | pre-defined>]
1672 * [, perbyte_cpu = <int | pre-defined>]
1673 * [, percall_cpu = <int | pre-defined>]
1675 * [arg is (<type-1> { , <type-n>})]
1676 * as <filename or code in language as appropriate>
1678 *****************************************************************************/
1680 ProcedureStmt: CREATE FUNCTION func_name func_args
1681 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
1683 ProcedureStmt *n = makeNode(ProcedureStmt);
1693 opt_with: WITH definition { $$ = $2; }
1694 | /*EMPTY*/ { $$ = NIL; }
1697 func_args: '(' func_args_list ')' { $$ = $2; }
1698 | '(' ')' { $$ = NIL; }
1701 func_args_list: TypeId
1702 { $$ = lcons(makeString($1),NIL); }
1703 | func_args_list ',' TypeId
1704 { $$ = lappend($1,makeString($3)); }
1707 func_return: set_opt TypeId
1709 TypeName *n = makeNode(TypeName);
1712 n->arrayBounds = NULL;
1717 set_opt: SETOF { $$ = TRUE; }
1718 | /*EMPTY*/ { $$ = FALSE; }
1721 /*****************************************************************************
1725 * remove function <funcname>
1726 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1727 * remove aggregate <aggname>
1728 * (REMOVE AGGREGATE "aggname" "aggtype")
1729 * remove operator <opname>
1730 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1731 * remove type <typename>
1732 * (REMOVE TYPE "typename")
1733 * remove rule <rulename>
1734 * (REMOVE RULE "rulename")
1736 *****************************************************************************/
1738 RemoveStmt: DROP remove_type name
1740 RemoveStmt *n = makeNode(RemoveStmt);
1747 remove_type: TYPE_P { $$ = TYPE_P; }
1748 | INDEX { $$ = INDEX; }
1749 | RULE { $$ = RULE; }
1750 | VIEW { $$ = VIEW; }
1754 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1756 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1763 aggr_argtype: name { $$ = $1; }
1764 | '*' { $$ = NULL; }
1768 RemoveFuncStmt: DROP FUNCTION func_name func_args
1770 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1778 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1780 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1787 all_Op: Op | MathOp;
1789 MathOp: '+' { $$ = "+"; }
1800 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1803 { $$ = makeList(makeString($1), makeString($3), -1); }
1804 | NONE ',' name /* left unary */
1805 { $$ = makeList(NULL, makeString($3), -1); }
1806 | name ',' NONE /* right unary */
1807 { $$ = makeList(makeString($1), NULL, -1); }
1811 /*****************************************************************************
1814 * rename <attrname1> in <relname> [*] to <attrname2>
1815 * rename <relname1> to <relname2>
1817 *****************************************************************************/
1819 RenameStmt: ALTER TABLE relation_name opt_inh_star
1820 RENAME opt_column opt_name TO name
1822 RenameStmt *n = makeNode(RenameStmt);
1831 opt_name: name { $$ = $1; }
1832 | /*EMPTY*/ { $$ = NULL; }
1835 opt_column: COLUMN { $$ = COLUMN; }
1836 | /*EMPTY*/ { $$ = 0; }
1840 /*****************************************************************************
1842 * QUERY: Define Rewrite Rule , Define Tuple Rule
1843 * Define Rule <old rules >
1845 * only rewrite rule is supported -- ay 9/94
1847 *****************************************************************************/
1849 RuleStmt: CREATE RULE name AS
1850 { QueryIsRule=TRUE; }
1851 ON event TO event_object where_clause
1852 DO opt_instead OptStmtList
1854 RuleStmt *n = makeNode(RuleStmt);
1858 n->whereClause = $10;
1865 OptStmtList: NOTHING { $$ = NIL; }
1866 | OptimizableStmt { $$ = lcons($1, NIL); }
1867 | '[' OptStmtBlock ']' { $$ = $2; }
1870 OptStmtBlock: OptStmtMulti
1873 { $$ = lcons($1, NIL); }
1876 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1877 { $$ = lappend($1, $2); }
1878 | OptStmtMulti OptimizableStmt
1879 { $$ = lappend($1, $2); }
1880 | OptimizableStmt ';'
1881 { $$ = lcons($1, NIL); }
1884 event_object: relation_name '.' attr_name
1886 $$ = makeNode(Attr);
1889 $$->attrs = lcons(makeString($3), NIL);
1890 $$->indirection = NIL;
1894 $$ = makeNode(Attr);
1898 $$->indirection = NIL;
1902 /* change me to select, update, etc. some day */
1903 event: SELECT { $$ = CMD_SELECT; }
1904 | UPDATE { $$ = CMD_UPDATE; }
1905 | DELETE { $$ = CMD_DELETE; }
1906 | INSERT { $$ = CMD_INSERT; }
1909 opt_instead: INSTEAD { $$ = TRUE; }
1910 | /*EMPTY*/ { $$ = FALSE; }
1914 /*****************************************************************************
1917 * NOTIFY <relation_name> can appear both in rule bodies and
1918 * as a query-level command
1920 *****************************************************************************/
1922 NotifyStmt: NOTIFY relation_name
1924 NotifyStmt *n = makeNode(NotifyStmt);
1930 ListenStmt: LISTEN relation_name
1932 ListenStmt *n = makeNode(ListenStmt);
1939 /*****************************************************************************
1950 *****************************************************************************/
1952 TransactionStmt: ABORT_TRANS TRANSACTION
1954 TransactionStmt *n = makeNode(TransactionStmt);
1955 n->command = ABORT_TRANS;
1958 | BEGIN_TRANS TRANSACTION
1960 TransactionStmt *n = makeNode(TransactionStmt);
1961 n->command = BEGIN_TRANS;
1966 TransactionStmt *n = makeNode(TransactionStmt);
1967 n->command = BEGIN_TRANS;
1972 TransactionStmt *n = makeNode(TransactionStmt);
1973 n->command = END_TRANS;
1976 | END_TRANS TRANSACTION
1978 TransactionStmt *n = makeNode(TransactionStmt);
1979 n->command = END_TRANS;
1984 TransactionStmt *n = makeNode(TransactionStmt);
1985 n->command = ABORT_TRANS;
1991 TransactionStmt *n = makeNode(TransactionStmt);
1992 n->command = ABORT_TRANS;
1997 TransactionStmt *n = makeNode(TransactionStmt);
1998 n->command = BEGIN_TRANS;
2003 TransactionStmt *n = makeNode(TransactionStmt);
2004 n->command = END_TRANS;
2010 TransactionStmt *n = makeNode(TransactionStmt);
2011 n->command = END_TRANS;
2016 TransactionStmt *n = makeNode(TransactionStmt);
2017 n->command = ABORT_TRANS;
2023 /*****************************************************************************
2026 * define view <viewname> '('target-list ')' [where <quals> ]
2028 *****************************************************************************/
2030 ViewStmt: CREATE VIEW name AS SelectStmt
2032 ViewStmt *n = makeNode(ViewStmt);
2034 n->query = (Query *)$5;
2035 if (((SelectStmt *)n->query)->sortClause != NULL)
2036 elog(ERROR,"Order by and Distinct on views is not implemented.");
2037 if (((SelectStmt *)n->query)->unionClause != NULL)
2038 elog(ERROR,"Views on unions not implemented.");
2044 /*****************************************************************************
2049 *****************************************************************************/
2051 LoadStmt: LOAD file_name
2053 LoadStmt *n = makeNode(LoadStmt);
2060 /*****************************************************************************
2065 *****************************************************************************/
2067 CreatedbStmt: CREATE DATABASE database_name opt_database
2069 CreatedbStmt *n = makeNode(CreatedbStmt);
2076 opt_database: WITH LOCATION '=' location { $$ = $4; }
2077 | /*EMPTY*/ { $$ = NULL; }
2080 location: Sconst { $$ = $1; }
2081 | DEFAULT { $$ = NULL; }
2082 | /*EMPTY*/ { $$ = NULL; }
2085 /*****************************************************************************
2090 *****************************************************************************/
2092 DestroydbStmt: DROP DATABASE database_name
2094 DestroydbStmt *n = makeNode(DestroydbStmt);
2101 /*****************************************************************************
2104 * cluster <index_name> on <relation_name>
2106 *****************************************************************************/
2108 ClusterStmt: CLUSTER index_name ON relation_name
2110 ClusterStmt *n = makeNode(ClusterStmt);
2118 /*****************************************************************************
2123 *****************************************************************************/
2125 VacuumStmt: VACUUM opt_verbose opt_analyze
2127 VacuumStmt *n = makeNode(VacuumStmt);
2134 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2136 VacuumStmt *n = makeNode(VacuumStmt);
2141 if ( $5 != NIL && !$4 )
2142 elog(ERROR,"parser: syntax error at or near \"(\"");
2147 opt_verbose: VERBOSE { $$ = TRUE; }
2148 | /*EMPTY*/ { $$ = FALSE; }
2151 opt_analyze: ANALYZE { $$ = TRUE; }
2152 | /*EMPTY*/ { $$ = FALSE; }
2155 opt_va_list: '(' va_list ')' { $$ = $2; }
2156 | /*EMPTY*/ { $$ = NIL; }
2160 { $$=lcons($1,NIL); }
2162 { $$=lappend($1,$3); }
2166 /*****************************************************************************
2171 *****************************************************************************/
2173 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2175 ExplainStmt *n = makeNode(ExplainStmt);
2177 n->query = (Query*)$3;
2183 /*****************************************************************************
2185 * Optimizable Stmts: *
2187 * one of the five queries processed by the planner *
2189 * [ultimately] produces query-trees as specified *
2190 * in the query-spec document in ~postgres/ref *
2192 *****************************************************************************/
2194 OptimizableStmt: SelectStmt
2199 | DeleteStmt /* by default all are $$=$1 */
2203 /*****************************************************************************
2208 *****************************************************************************/
2210 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2218 insert_rest: VALUES '(' res_target_list2 ')'
2220 $$ = makeNode(InsertStmt);
2222 $$->targetList = $3;
2223 $$->fromClause = NIL;
2224 $$->whereClause = NULL;
2225 $$->groupClause = NIL;
2226 $$->havingClause = NULL;
2227 $$->unionClause = NIL;
2229 | SELECT opt_unique res_target_list2
2230 from_clause where_clause
2231 group_clause having_clause
2234 $$ = makeNode(InsertStmt);
2236 $$->targetList = $3;
2237 $$->fromClause = $4;
2238 $$->whereClause = $5;
2239 $$->groupClause = $6;
2240 $$->havingClause = $7;
2241 $$->unionClause = $8;
2245 opt_column_list: '(' columnList ')' { $$ = $2; }
2246 | /*EMPTY*/ { $$ = NIL; }
2250 columnList ',' columnElem
2251 { $$ = lappend($1, $3); }
2253 { $$ = lcons($1, NIL); }
2256 columnElem: ColId opt_indirection
2258 Ident *id = makeNode(Ident);
2260 id->indirection = $2;
2266 /*****************************************************************************
2271 *****************************************************************************/
2273 DeleteStmt: DELETE FROM relation_name
2276 DeleteStmt *n = makeNode(DeleteStmt);
2278 n->whereClause = $4;
2284 * Total hack to just lock a table inside a transaction.
2285 * Is it worth making this a separate command, with
2286 * its own node type and file. I don't think so. bjm 1998/1/22
2288 LockStmt: LOCK_P opt_table relation_name
2290 DeleteStmt *n = makeNode(DeleteStmt);
2291 A_Const *c = makeNode(A_Const);
2293 c->val.type = T_String;
2294 c->val.val.str = "f";
2295 c->typename = makeNode(TypeName);
2296 c->typename->name = xlateSqlType("bool");
2297 c->typename->typmod = -1;
2300 n->whereClause = (Node *)c;
2306 /*****************************************************************************
2309 * UpdateStmt (UPDATE)
2311 *****************************************************************************/
2313 UpdateStmt: UPDATE relation_name
2318 UpdateStmt *n = makeNode(UpdateStmt);
2322 n->whereClause = $6;
2328 /*****************************************************************************
2333 *****************************************************************************/
2334 CursorStmt: DECLARE name opt_binary CURSOR FOR
2335 SELECT opt_unique res_target_list2
2336 from_clause where_clause
2337 group_clause having_clause
2338 union_clause sort_clause
2340 SelectStmt *n = makeNode(SelectStmt);
2342 /* from PORTAL name */
2344 * 15 august 1991 -- since 3.0 postgres does locking
2345 * right, we discovered that portals were violating
2346 * locking protocol. portal locks cannot span xacts.
2347 * as a short-term fix, we installed the check here.
2350 if (!IsTransactionBlock())
2351 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2358 n->whereClause = $10;
2359 n->groupClause = $11;
2360 n->havingClause = $12;
2361 n->unionClause = $13;
2362 n->sortClause = $14;
2368 /*****************************************************************************
2373 *****************************************************************************/
2375 SelectStmt: SELECT opt_unique res_target_list2
2376 result from_clause where_clause
2377 group_clause having_clause
2378 union_clause sort_clause
2380 SelectStmt *n = makeNode(SelectStmt);
2385 n->whereClause = $6;
2386 n->groupClause = $7;
2387 n->havingClause = $8;
2388 n->unionClause = $9;
2389 n->sortClause = $10;
2394 union_clause: UNION opt_union select_list
2396 SelectStmt *n = (SelectStmt *)lfirst($3);
2404 select_list: select_list UNION opt_union SubSelect
2406 SelectStmt *n = (SelectStmt *)$4;
2408 $$ = lappend($1, $4);
2411 { $$ = lcons($1, NIL); }
2414 SubSelect: SELECT opt_unique res_target_list2
2415 from_clause where_clause
2416 group_clause having_clause
2418 SelectStmt *n = makeNode(SelectStmt);
2420 n->unionall = FALSE;
2423 n->whereClause = $5;
2424 n->groupClause = $6;
2425 n->havingClause = $7;
2430 result: INTO opt_table relation_name { $$= $3; }
2431 | /*EMPTY*/ { $$ = NULL; }
2434 opt_table: TABLE { $$ = TRUE; }
2435 | /*EMPTY*/ { $$ = FALSE; }
2438 opt_union: ALL { $$ = TRUE; }
2439 | /*EMPTY*/ { $$ = FALSE; }
2442 opt_unique: DISTINCT { $$ = "*"; }
2443 | DISTINCT ON ColId { $$ = $3; }
2444 | ALL { $$ = NULL; }
2445 | /*EMPTY*/ { $$ = NULL; }
2448 sort_clause: ORDER BY sortby_list { $$ = $3; }
2449 | /*EMPTY*/ { $$ = NIL; }
2452 sortby_list: sortby { $$ = lcons($1, NIL); }
2453 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2456 sortby: ColId OptUseOp
2458 $$ = makeNode(SortGroupBy);
2464 | ColId '.' ColId OptUseOp
2466 $$ = makeNode(SortGroupBy);
2474 $$ = makeNode(SortGroupBy);
2482 OptUseOp: USING Op { $$ = $2; }
2483 | USING '<' { $$ = "<"; }
2484 | USING '>' { $$ = ">"; }
2486 | DESC { $$ = ">"; }
2487 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2491 * jimmy bell-style recursive queries aren't supported in the
2494 * ...however, recursive addattr and rename supported. make special
2497 opt_inh_star: '*' { $$ = TRUE; }
2498 | /*EMPTY*/ { $$ = FALSE; }
2501 relation_name_list: name_list;
2504 { $$ = lcons(makeString($1),NIL); }
2505 | name_list ',' name
2506 { $$ = lappend($1,makeString($3)); }
2509 group_clause: GROUP BY groupby_list { $$ = $3; }
2510 | /*EMPTY*/ { $$ = NIL; }
2513 groupby_list: groupby { $$ = lcons($1, NIL); }
2514 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2519 $$ = makeNode(SortGroupBy);
2527 $$ = makeNode(SortGroupBy);
2535 $$ = makeNode(SortGroupBy);
2543 having_clause: HAVING a_expr
2547 | /*EMPTY*/ { $$ = NULL; }
2551 /*****************************************************************************
2553 * clauses common to all Optimizable Stmts:
2557 *****************************************************************************/
2559 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2562 elog(ERROR,"JOIN not yet implemented");
2564 | FROM from_list { $$ = $2; }
2565 | /*EMPTY*/ { $$ = NIL; }
2568 from_list: from_list ',' from_val
2569 { $$ = lappend($1, $3); }
2570 | from_val CROSS JOIN from_val
2571 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2573 { $$ = lcons($1, NIL); }
2576 from_val: relation_expr AS ColLabel
2578 $$ = makeNode(RangeVar);
2582 | relation_expr ColId
2584 $$ = makeNode(RangeVar);
2590 $$ = makeNode(RangeVar);
2596 join_expr: NATURAL join_expr { $$ = NULL; }
2598 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2600 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2602 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2604 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2606 { elog(ERROR,"INNER JOIN not yet implemented"); }
2608 { elog(ERROR,"UNION JOIN not yet implemented"); }
2610 { elog(ERROR,"INNER JOIN not yet implemented"); }
2613 join_outer: OUTER_P { $$ = NULL; }
2614 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2617 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2618 | USING '(' join_list ')' { $$ = NULL; }
2619 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2622 join_list: join_using { $$ = lcons($1, NIL); }
2623 | join_list ',' join_using { $$ = lappend($1, $3); }
2628 $$ = makeNode(SortGroupBy);
2636 $$ = makeNode(SortGroupBy);
2644 $$ = makeNode(SortGroupBy);
2652 where_clause: WHERE a_expr { $$ = $2; }
2653 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2656 relation_expr: relation_name
2658 /* normal relations */
2659 $$ = makeNode(RelExpr);
2663 | relation_name '*' %prec '='
2665 /* inheritance query */
2666 $$ = makeNode(RelExpr);
2671 opt_array_bounds: '[' ']' nest_array_bounds
2672 { $$ = lcons(makeInteger(-1), $3); }
2673 | '[' Iconst ']' nest_array_bounds
2674 { $$ = lcons(makeInteger($2), $4); }
2679 nest_array_bounds: '[' ']' nest_array_bounds
2680 { $$ = lcons(makeInteger(-1), $3); }
2681 | '[' Iconst ']' nest_array_bounds
2682 { $$ = lcons(makeInteger($2), $4); }
2688 /*****************************************************************************
2691 * SQL92 introduces a large amount of type-specific syntax.
2692 * Define individual clauses to handle these cases, and use
2693 * the generic case to handle regular type-extensible Postgres syntax.
2694 * - thomas 1997-10-10
2696 *****************************************************************************/
2698 Typename: Array opt_array_bounds
2701 $$->arrayBounds = $2;
2703 /* Is this the name of a complex type? If so, implement
2706 if (!strcmp(saved_relname, $$->name))
2707 /* This attr is the same type as the relation
2708 * being defined. The classic example: create
2709 * emp(name=text,mgr=emp)
2712 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2713 /* (Eventually add in here that the set can only
2714 * contain one element.)
2735 $$ = makeNode(TypeName);
2736 $$->name = xlateSqlType($1);
2741 generic: IDENT { $$ = $1; }
2742 | TYPE_P { $$ = xlateSqlType("type"); }
2745 /* SQL92 numeric data types
2746 * Check FLOAT() precision limits assuming IEEE floating types.
2747 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2748 * by checking parameters and making sure they match what is possible with INTEGER.
2749 * - thomas 1997-09-18
2751 Numeric: FLOAT opt_float
2753 $$ = makeNode(TypeName);
2754 $$->name = xlateSqlType($2);
2759 $$ = makeNode(TypeName);
2760 $$->name = xlateSqlType("float");
2762 | DECIMAL opt_decimal
2764 $$ = makeNode(TypeName);
2765 $$->name = xlateSqlType("integer");
2768 | NUMERIC opt_numeric
2770 $$ = makeNode(TypeName);
2771 $$->name = xlateSqlType("integer");
2777 { $$ = xlateSqlType("float8"); }
2779 { $$ = xlateSqlType("float8"); }
2781 { $$ = xlateSqlType("decimal"); }
2783 { $$ = xlateSqlType("numeric"); }
2786 opt_float: '(' Iconst ')'
2789 elog(ERROR,"precision for FLOAT must be at least 1");
2791 $$ = xlateSqlType("float4");
2793 $$ = xlateSqlType("float8");
2795 elog(ERROR,"precision for FLOAT must be less than 16");
2799 $$ = xlateSqlType("float8");
2803 opt_numeric: '(' Iconst ',' Iconst ')'
2806 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2808 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2813 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2821 opt_decimal: '(' Iconst ',' Iconst ')'
2824 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2826 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2832 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2841 /* SQL92 character data types
2842 * The following implements CHAR() and VARCHAR().
2843 * We do it here instead of the 'Generic' production
2844 * because we don't want to allow arrays of VARCHAR().
2845 * I haven't thought about whether that will work or not.
2848 Character: character '(' Iconst ')'
2850 $$ = makeNode(TypeName);
2851 if (!strcasecmp($1, "char"))
2852 $$->name = xlateSqlType("bpchar");
2853 else if (!strcasecmp($1, "varchar"))
2854 $$->name = xlateSqlType("varchar");
2856 yyerror("parse error");
2858 elog(ERROR,"length for '%s' type must be at least 1",$1);
2860 /* we can store a char() of length up to the size
2861 * of a page (8KB) - page headers and friends but
2862 * just to be safe here... - ay 6/95
2863 * XXX note this hardcoded limit - thomas 1997-07-13
2865 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2867 /* we actually implement this sort of like a varlen, so
2868 * the first 4 bytes is the length. (the difference
2869 * between this and "text" is that we blank-pad and
2870 * truncate where necessary
2872 $$->typmod = VARHDRSZ + $3;
2876 $$ = makeNode(TypeName);
2877 $$->name = xlateSqlType($1);
2882 character: CHARACTER opt_varying opt_charset opt_collate
2885 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2886 if ($2) type = xlateSqlType("varchar");
2887 else type = xlateSqlType("char");
2890 c = palloc(strlen("var") + strlen($3) + 1);
2893 type = xlateSqlType(c);
2895 type = xlateSqlType($3);
2899 elog(ERROR,"COLLATE %s not yet implemented",$4);
2902 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2903 | VARCHAR { $$ = xlateSqlType("varchar"); }
2904 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2905 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2908 opt_varying: VARYING { $$ = TRUE; }
2909 | /*EMPTY*/ { $$ = FALSE; }
2912 opt_charset: CHARACTER SET ColId { $$ = $3; }
2913 | /*EMPTY*/ { $$ = NULL; }
2916 opt_collate: COLLATE ColId { $$ = $2; }
2917 | /*EMPTY*/ { $$ = NULL; }
2922 $$ = makeNode(TypeName);
2923 $$->name = xlateSqlType($1);
2926 | TIMESTAMP opt_timezone
2928 $$ = makeNode(TypeName);
2929 $$->name = xlateSqlType("timestamp");
2935 $$ = makeNode(TypeName);
2936 $$->name = xlateSqlType("time");
2939 | INTERVAL opt_interval
2941 $$ = makeNode(TypeName);
2942 $$->name = xlateSqlType("interval");
2947 datetime: YEAR_P { $$ = "year"; }
2948 | MONTH_P { $$ = "month"; }
2949 | DAY_P { $$ = "day"; }
2950 | HOUR_P { $$ = "hour"; }
2951 | MINUTE_P { $$ = "minute"; }
2952 | SECOND_P { $$ = "second"; }
2955 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2956 | /*EMPTY*/ { $$ = FALSE; }
2959 opt_interval: datetime { $$ = lcons($1, NIL); }
2960 | YEAR_P TO MONTH_P { $$ = NIL; }
2961 | DAY_P TO HOUR_P { $$ = NIL; }
2962 | DAY_P TO MINUTE_P { $$ = NIL; }
2963 | DAY_P TO SECOND_P { $$ = NIL; }
2964 | HOUR_P TO MINUTE_P { $$ = NIL; }
2965 | HOUR_P TO SECOND_P { $$ = NIL; }
2966 | /*EMPTY*/ { $$ = NIL; }
2970 /*****************************************************************************
2972 * expression grammar, still needs some cleanup
2974 *****************************************************************************/
2976 a_expr_or_null: a_expr
2980 A_Const *n = makeNode(A_Const);
2981 n->val.type = T_Null;
2986 /* Expressions using row descriptors
2987 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2988 * with singleton expressions.
2990 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2992 SubLink *n = makeNode(SubLink);
2994 n->oper = lcons("=",NIL);
2996 n->subLinkType = ANY_SUBLINK;
3000 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3002 SubLink *n = makeNode(SubLink);
3004 n->oper = lcons("<>",NIL);
3006 n->subLinkType = ALL_SUBLINK;
3010 | '(' row_descriptor ')' Op '(' SubSelect ')'
3012 SubLink *n = makeNode(SubLink);
3014 n->oper = lcons($4, NIL);
3015 if (strcmp($4,"<>") == 0)
3019 n->subLinkType = EXPR_SUBLINK;
3023 | '(' row_descriptor ')' '+' '(' SubSelect ')'
3025 SubLink *n = makeNode(SubLink);
3027 n->oper = lcons("+", NIL);
3029 n->subLinkType = EXPR_SUBLINK;
3033 | '(' row_descriptor ')' '-' '(' SubSelect ')'
3035 SubLink *n = makeNode(SubLink);
3037 n->oper = lcons("-", NIL);
3039 n->subLinkType = EXPR_SUBLINK;
3043 | '(' row_descriptor ')' '/' '(' SubSelect ')'
3045 SubLink *n = makeNode(SubLink);
3047 n->oper = lcons("/", NIL);
3049 n->subLinkType = EXPR_SUBLINK;
3053 | '(' row_descriptor ')' '*' '(' SubSelect ')'
3055 SubLink *n = makeNode(SubLink);
3057 n->oper = lcons("*", NIL);
3059 n->subLinkType = EXPR_SUBLINK;
3063 | '(' row_descriptor ')' '<' '(' SubSelect ')'
3065 SubLink *n = makeNode(SubLink);
3067 n->oper = lcons("<", NIL);
3069 n->subLinkType = EXPR_SUBLINK;
3073 | '(' row_descriptor ')' '>' '(' SubSelect ')'
3075 SubLink *n = makeNode(SubLink);
3077 n->oper = lcons(">", NIL);
3079 n->subLinkType = EXPR_SUBLINK;
3083 | '(' row_descriptor ')' '=' '(' SubSelect ')'
3085 SubLink *n = makeNode(SubLink);
3087 n->oper = lcons("=", NIL);
3089 n->subLinkType = EXPR_SUBLINK;
3093 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
3095 SubLink *n = makeNode(SubLink);
3097 n->oper = lcons($4,NIL);
3098 if (strcmp($4,"<>") == 0)
3102 n->subLinkType = ANY_SUBLINK;
3106 | '(' row_descriptor ')' '+' ANY '(' SubSelect ')'
3108 SubLink *n = makeNode(SubLink);
3110 n->oper = lcons("+",NIL);
3112 n->subLinkType = ANY_SUBLINK;
3116 | '(' row_descriptor ')' '-' ANY '(' SubSelect ')'
3118 SubLink *n = makeNode(SubLink);
3120 n->oper = lcons("-",NIL);
3122 n->subLinkType = ANY_SUBLINK;
3126 | '(' row_descriptor ')' '/' ANY '(' SubSelect ')'
3128 SubLink *n = makeNode(SubLink);
3130 n->oper = lcons("/",NIL);
3132 n->subLinkType = ANY_SUBLINK;
3136 | '(' row_descriptor ')' '*' ANY '(' SubSelect ')'
3138 SubLink *n = makeNode(SubLink);
3140 n->oper = lcons("*",NIL);
3142 n->subLinkType = ANY_SUBLINK;
3146 | '(' row_descriptor ')' '<' ANY '(' SubSelect ')'
3148 SubLink *n = makeNode(SubLink);
3150 n->oper = lcons("<",NIL);
3152 n->subLinkType = ANY_SUBLINK;
3156 | '(' row_descriptor ')' '>' ANY '(' SubSelect ')'
3158 SubLink *n = makeNode(SubLink);
3160 n->oper = lcons(">",NIL);
3162 n->subLinkType = ANY_SUBLINK;
3166 | '(' row_descriptor ')' '=' ANY '(' SubSelect ')'
3168 SubLink *n = makeNode(SubLink);
3170 n->oper = lcons("=",NIL);
3172 n->subLinkType = ANY_SUBLINK;
3176 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
3178 SubLink *n = makeNode(SubLink);
3180 n->oper = lcons($4,NIL);
3181 if (strcmp($4,"<>") == 0)
3185 n->subLinkType = ALL_SUBLINK;
3189 | '(' row_descriptor ')' '+' ALL '(' SubSelect ')'
3191 SubLink *n = makeNode(SubLink);
3193 n->oper = lcons("+",NIL);
3195 n->subLinkType = ALL_SUBLINK;
3199 | '(' row_descriptor ')' '-' ALL '(' SubSelect ')'
3201 SubLink *n = makeNode(SubLink);
3203 n->oper = lcons("-",NIL);
3205 n->subLinkType = ALL_SUBLINK;
3209 | '(' row_descriptor ')' '/' ALL '(' SubSelect ')'
3211 SubLink *n = makeNode(SubLink);
3213 n->oper = lcons("/",NIL);
3215 n->subLinkType = ALL_SUBLINK;
3219 | '(' row_descriptor ')' '*' ALL '(' SubSelect ')'
3221 SubLink *n = makeNode(SubLink);
3223 n->oper = lcons("*",NIL);
3225 n->subLinkType = ALL_SUBLINK;
3229 | '(' row_descriptor ')' '<' ALL '(' SubSelect ')'
3231 SubLink *n = makeNode(SubLink);
3233 n->oper = lcons("<",NIL);
3235 n->subLinkType = ALL_SUBLINK;
3239 | '(' row_descriptor ')' '>' ALL '(' SubSelect ')'
3241 SubLink *n = makeNode(SubLink);
3243 n->oper = lcons(">",NIL);
3245 n->subLinkType = ALL_SUBLINK;
3249 | '(' row_descriptor ')' '=' ALL '(' SubSelect ')'
3251 SubLink *n = makeNode(SubLink);
3253 n->oper = lcons("=",NIL);
3255 n->subLinkType = ALL_SUBLINK;
3259 | '(' row_descriptor ')' Op '(' row_descriptor ')'
3261 $$ = makeRowExpr($4, $2, $6);
3263 | '(' row_descriptor ')' '+' '(' row_descriptor ')'
3265 $$ = makeRowExpr("+", $2, $6);
3267 | '(' row_descriptor ')' '-' '(' row_descriptor ')'
3269 $$ = makeRowExpr("-", $2, $6);
3271 | '(' row_descriptor ')' '/' '(' row_descriptor ')'
3273 $$ = makeRowExpr("/", $2, $6);
3275 | '(' row_descriptor ')' '*' '(' row_descriptor ')'
3277 $$ = makeRowExpr("*", $2, $6);
3279 | '(' row_descriptor ')' '<' '(' row_descriptor ')'
3281 $$ = makeRowExpr("<", $2, $6);
3283 | '(' row_descriptor ')' '>' '(' row_descriptor ')'
3285 $$ = makeRowExpr(">", $2, $6);
3287 | '(' row_descriptor ')' '=' '(' row_descriptor ')'
3289 $$ = makeRowExpr("=", $2, $6);
3293 row_descriptor: row_list ',' a_expr
3295 $$ = lappend($1, $3);
3299 row_list: row_list ',' a_expr
3301 $$ = lappend($1, $3);
3305 $$ = lcons($1, NIL);
3310 * This is the heart of the expression syntax.
3311 * Note that the BETWEEN clause looks similar to a boolean expression
3312 * and so we must define b_expr which is almost the same as a_expr
3313 * but without the boolean expressions.
3314 * All operations are allowed in a BETWEEN clause if surrounded by parens.
3317 a_expr: attr opt_indirection
3319 $1->indirection = $2;
3328 /* could be a column name or a relation_name */
3329 Ident *n = makeNode(Ident);
3331 n->indirection = NULL;
3334 | '-' a_expr %prec UMINUS
3335 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3337 { $$ = makeA_Expr(OP, "+", $1, $3); }
3339 { $$ = makeA_Expr(OP, "-", $1, $3); }
3341 { $$ = makeA_Expr(OP, "/", $1, $3); }
3343 { $$ = makeA_Expr(OP, "*", $1, $3); }
3345 { $$ = makeA_Expr(OP, "<", $1, $3); }
3347 { $$ = makeA_Expr(OP, ">", $1, $3); }
3349 { $$ = makeA_Expr(OP, "=", $1, $3); }
3351 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3353 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3355 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3356 | a_expr TYPECAST Typename
3359 /* AexprConst can be either A_Const or ParamNo */
3360 if (nodeTag($1) == T_A_Const) {
3361 ((A_Const *)$1)->typename = $3;
3362 } else if (nodeTag($1) == T_Param) {
3363 ((ParamNo *)$1)->typename = $3;
3364 /* otherwise, try to transform to a function call */
3366 FuncCall *n = makeNode(FuncCall);
3367 n->funcname = $3->name;
3368 n->args = lcons($1,NIL);
3372 | CAST '(' a_expr AS Typename ')'
3375 /* AexprConst can be either A_Const or ParamNo */
3376 if (nodeTag($3) == T_A_Const) {
3377 ((A_Const *)$3)->typename = $5;
3378 } else if (nodeTag($5) == T_Param) {
3379 ((ParamNo *)$3)->typename = $5;
3380 /* otherwise, try to transform to a function call */
3382 FuncCall *n = makeNode(FuncCall);
3383 n->funcname = $5->name;
3384 n->args = lcons($3,NIL);
3388 | '(' a_expr_or_null ')'
3391 { $$ = makeIndexable($2,$1,$3); }
3392 | a_expr LIKE a_expr
3393 { $$ = makeIndexable("~~", $1, $3); }
3394 | a_expr NOT LIKE a_expr
3395 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3397 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3399 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3400 | func_name '(' '*' ')'
3402 /* cheap hack for aggregate (eg. count) */
3403 FuncCall *n = makeNode(FuncCall);
3404 A_Const *star = makeNode(A_Const);
3406 star->val.type = T_String;
3407 star->val.val.str = "";
3409 n->args = lcons(star, NIL);
3414 FuncCall *n = makeNode(FuncCall);
3419 | func_name '(' expr_list ')'
3421 FuncCall *n = makeNode(FuncCall);
3428 A_Const *n = makeNode(A_Const);
3429 TypeName *t = makeNode(TypeName);
3431 n->val.type = T_String;
3432 n->val.val.str = "now";
3435 t->name = xlateSqlType("date");
3443 A_Const *n = makeNode(A_Const);
3444 TypeName *t = makeNode(TypeName);
3446 n->val.type = T_String;
3447 n->val.val.str = "now";
3450 t->name = xlateSqlType("time");
3456 | CURRENT_TIME '(' Iconst ')'
3458 FuncCall *n = makeNode(FuncCall);
3459 A_Const *s = makeNode(A_Const);
3460 TypeName *t = makeNode(TypeName);
3462 n->funcname = xlateSqlType("time");
3463 n->args = lcons(s, NIL);
3465 s->val.type = T_String;
3466 s->val.val.str = "now";
3469 t->name = xlateSqlType("time");
3474 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3480 A_Const *n = makeNode(A_Const);
3481 TypeName *t = makeNode(TypeName);
3483 n->val.type = T_String;
3484 n->val.val.str = "now";
3487 t->name = xlateSqlType("timestamp");
3493 | CURRENT_TIMESTAMP '(' Iconst ')'
3495 FuncCall *n = makeNode(FuncCall);
3496 A_Const *s = makeNode(A_Const);
3497 TypeName *t = makeNode(TypeName);
3499 n->funcname = xlateSqlType("timestamp");
3500 n->args = lcons(s, NIL);
3502 s->val.type = T_String;
3503 s->val.val.str = "now";
3506 t->name = xlateSqlType("timestamp");
3511 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3517 FuncCall *n = makeNode(FuncCall);
3518 n->funcname = "getpgusername";
3522 | EXISTS '(' SubSelect ')'
3524 SubLink *n = makeNode(SubLink);
3528 n->subLinkType = EXISTS_SUBLINK;
3532 | EXTRACT '(' extract_list ')'
3534 FuncCall *n = makeNode(FuncCall);
3535 n->funcname = "date_part";
3539 | POSITION '(' position_list ')'
3541 FuncCall *n = makeNode(FuncCall);
3542 n->funcname = "strpos";
3546 | SUBSTRING '(' substr_list ')'
3548 FuncCall *n = makeNode(FuncCall);
3549 n->funcname = "substr";
3553 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3554 | TRIM '(' BOTH trim_list ')'
3556 FuncCall *n = makeNode(FuncCall);
3557 n->funcname = "btrim";
3561 | TRIM '(' LEADING trim_list ')'
3563 FuncCall *n = makeNode(FuncCall);
3564 n->funcname = "ltrim";
3568 | TRIM '(' TRAILING trim_list ')'
3570 FuncCall *n = makeNode(FuncCall);
3571 n->funcname = "rtrim";
3575 | TRIM '(' trim_list ')'
3577 FuncCall *n = makeNode(FuncCall);
3578 n->funcname = "btrim";
3583 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3585 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3587 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3588 | a_expr IS NOT NULL_P
3589 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3590 /* IS TRUE, IS FALSE, etc used to be function calls
3591 * but let's make them expressions to allow the optimizer
3592 * a chance to eliminate them if a_expr is a constant string.
3593 * - thomas 1997-12-22
3597 A_Const *n = makeNode(A_Const);
3598 n->val.type = T_String;
3599 n->val.val.str = "t";
3600 n->typename = makeNode(TypeName);
3601 n->typename->name = xlateSqlType("bool");
3602 n->typename->typmod = -1;
3603 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3605 | a_expr IS NOT FALSE_P
3607 A_Const *n = makeNode(A_Const);
3608 n->val.type = T_String;
3609 n->val.val.str = "t";
3610 n->typename = makeNode(TypeName);
3611 n->typename->name = xlateSqlType("bool");
3612 n->typename->typmod = -1;
3613 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3617 A_Const *n = makeNode(A_Const);
3618 n->val.type = T_String;
3619 n->val.val.str = "f";
3620 n->typename = makeNode(TypeName);
3621 n->typename->name = xlateSqlType("bool");
3622 n->typename->typmod = -1;
3623 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3625 | a_expr IS NOT TRUE_P
3627 A_Const *n = makeNode(A_Const);
3628 n->val.type = T_String;
3629 n->val.val.str = "f";
3630 n->typename = makeNode(TypeName);
3631 n->typename->name = xlateSqlType("bool");
3632 n->typename->typmod = -1;
3633 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3635 | a_expr BETWEEN b_expr AND b_expr
3637 $$ = makeA_Expr(AND, NULL,
3638 makeA_Expr(OP, ">=", $1, $3),
3639 makeA_Expr(OP, "<=", $1, $5));
3641 | a_expr NOT BETWEEN b_expr AND b_expr
3643 $$ = makeA_Expr(OR, NULL,
3644 makeA_Expr(OP, "<", $1, $4),
3645 makeA_Expr(OP, ">", $1, $6));
3647 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3649 saved_In_Expr = lnext(saved_In_Expr);
3650 if (nodeTag($5) == T_SubLink)
3652 SubLink *n = (SubLink *)$5;
3653 n->lefthand = lcons($1, NIL);
3654 n->oper = lcons("=",NIL);
3656 n->subLinkType = ANY_SUBLINK;
3661 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
3663 saved_In_Expr = lnext(saved_In_Expr);
3664 if (nodeTag($6) == T_SubLink)
3666 SubLink *n = (SubLink *)$6;
3667 n->lefthand = lcons($1, NIL);
3668 n->oper = lcons("<>",NIL);
3670 n->subLinkType = ALL_SUBLINK;
3675 | a_expr Op '(' SubSelect ')'
3677 SubLink *n = makeNode(SubLink);
3678 n->lefthand = lcons($1, NULL);
3679 n->oper = lcons($2,NIL);
3681 n->subLinkType = EXPR_SUBLINK;
3685 | a_expr '+' '(' SubSelect ')'
3687 SubLink *n = makeNode(SubLink);
3688 n->lefthand = lcons($1, NULL);
3689 n->oper = lcons("+",NIL);
3691 n->subLinkType = EXPR_SUBLINK;
3695 | a_expr '-' '(' SubSelect ')'
3697 SubLink *n = makeNode(SubLink);
3698 n->lefthand = lcons($1, NULL);
3699 n->oper = lcons("-",NIL);
3701 n->subLinkType = EXPR_SUBLINK;
3705 | a_expr '/' '(' SubSelect ')'
3707 SubLink *n = makeNode(SubLink);
3708 n->lefthand = lcons($1, NULL);
3709 n->oper = lcons("/",NIL);
3711 n->subLinkType = EXPR_SUBLINK;
3715 | a_expr '*' '(' SubSelect ')'
3717 SubLink *n = makeNode(SubLink);
3718 n->lefthand = lcons($1, NULL);
3719 n->oper = lcons("*",NIL);
3721 n->subLinkType = EXPR_SUBLINK;
3725 | a_expr '<' '(' SubSelect ')'
3727 SubLink *n = makeNode(SubLink);
3728 n->lefthand = lcons($1, NULL);
3729 n->oper = lcons("<",NIL);
3731 n->subLinkType = EXPR_SUBLINK;
3735 | a_expr '>' '(' SubSelect ')'
3737 SubLink *n = makeNode(SubLink);
3738 n->lefthand = lcons($1, NULL);
3739 n->oper = lcons(">",NIL);
3741 n->subLinkType = EXPR_SUBLINK;
3745 | a_expr '=' '(' SubSelect ')'
3747 SubLink *n = makeNode(SubLink);
3748 n->lefthand = lcons($1, NULL);
3749 n->oper = lcons("=",NIL);
3751 n->subLinkType = EXPR_SUBLINK;
3755 | a_expr Op ANY '(' SubSelect ')'
3757 SubLink *n = makeNode(SubLink);
3758 n->lefthand = lcons($1,NIL);
3759 n->oper = lcons($2,NIL);
3761 n->subLinkType = ANY_SUBLINK;
3765 | a_expr '+' ANY '(' SubSelect ')'
3767 SubLink *n = makeNode(SubLink);
3768 n->lefthand = lcons($1,NIL);
3769 n->oper = lcons("+",NIL);
3771 n->subLinkType = ANY_SUBLINK;
3775 | a_expr '-' ANY '(' SubSelect ')'
3777 SubLink *n = makeNode(SubLink);
3778 n->lefthand = lcons($1,NIL);
3779 n->oper = lcons("-",NIL);
3781 n->subLinkType = ANY_SUBLINK;
3785 | a_expr '/' ANY '(' SubSelect ')'
3787 SubLink *n = makeNode(SubLink);
3788 n->lefthand = lcons($1,NIL);
3789 n->oper = lcons("/",NIL);
3791 n->subLinkType = ANY_SUBLINK;
3795 | a_expr '*' ANY '(' SubSelect ')'
3797 SubLink *n = makeNode(SubLink);
3798 n->lefthand = lcons($1,NIL);
3799 n->oper = lcons("*",NIL);
3801 n->subLinkType = ANY_SUBLINK;
3805 | a_expr '<' ANY '(' SubSelect ')'
3807 SubLink *n = makeNode(SubLink);
3808 n->lefthand = lcons($1,NIL);
3809 n->oper = lcons("<",NIL);
3811 n->subLinkType = ANY_SUBLINK;
3815 | a_expr '>' ANY '(' SubSelect ')'
3817 SubLink *n = makeNode(SubLink);
3818 n->lefthand = lcons($1,NIL);
3819 n->oper = lcons(">",NIL);
3821 n->subLinkType = ANY_SUBLINK;
3825 | a_expr '=' ANY '(' SubSelect ')'
3827 SubLink *n = makeNode(SubLink);
3828 n->lefthand = lcons($1,NIL);
3829 n->oper = lcons("=",NIL);
3831 n->subLinkType = ANY_SUBLINK;
3835 | a_expr Op ALL '(' SubSelect ')'
3837 SubLink *n = makeNode(SubLink);
3838 n->lefthand = lcons($1, NULL);
3839 n->oper = lcons($2,NIL);
3841 n->subLinkType = ALL_SUBLINK;
3845 | a_expr '+' ALL '(' SubSelect ')'
3847 SubLink *n = makeNode(SubLink);
3848 n->lefthand = lcons($1, NULL);
3849 n->oper = lcons("+",NIL);
3851 n->subLinkType = ALL_SUBLINK;
3855 | a_expr '-' ALL '(' SubSelect ')'
3857 SubLink *n = makeNode(SubLink);
3858 n->lefthand = lcons($1, NULL);
3859 n->oper = lcons("-",NIL);
3861 n->subLinkType = ALL_SUBLINK;
3865 | a_expr '/' ALL '(' SubSelect ')'
3867 SubLink *n = makeNode(SubLink);
3868 n->lefthand = lcons($1, NULL);
3869 n->oper = lcons("/",NIL);
3871 n->subLinkType = ALL_SUBLINK;
3875 | a_expr '*' ALL '(' SubSelect ')'
3877 SubLink *n = makeNode(SubLink);
3878 n->lefthand = lcons($1, NULL);
3879 n->oper = lcons("*",NIL);
3881 n->subLinkType = ALL_SUBLINK;
3885 | a_expr '<' ALL '(' SubSelect ')'
3887 SubLink *n = makeNode(SubLink);
3888 n->lefthand = lcons($1, NULL);
3889 n->oper = lcons("<",NIL);
3891 n->subLinkType = ALL_SUBLINK;
3895 | a_expr '>' ALL '(' SubSelect ')'
3897 SubLink *n = makeNode(SubLink);
3898 n->lefthand = lcons($1, NULL);
3899 n->oper = lcons(">",NIL);
3901 n->subLinkType = ALL_SUBLINK;
3905 | a_expr '=' ALL '(' SubSelect ')'
3907 SubLink *n = makeNode(SubLink);
3908 n->lefthand = lcons($1, NULL);
3909 n->oper = lcons("=",NIL);
3911 n->subLinkType = ALL_SUBLINK;
3916 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3918 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3920 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3924 * b_expr is a subset of the complete expression syntax
3925 * defined by a_expr. b_expr is used in BETWEEN clauses
3926 * to eliminate parser ambiguities stemming from the AND keyword.
3929 b_expr: attr opt_indirection
3931 $1->indirection = $2;
3938 /* could be a column name or a relation_name */
3939 Ident *n = makeNode(Ident);
3941 n->indirection = NULL;
3944 | '-' b_expr %prec UMINUS
3945 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3947 { $$ = makeA_Expr(OP, "+", $1, $3); }
3949 { $$ = makeA_Expr(OP, "-", $1, $3); }
3951 { $$ = makeA_Expr(OP, "/", $1, $3); }
3953 { $$ = makeA_Expr(OP, "*", $1, $3); }
3955 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3957 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3959 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3960 | b_expr TYPECAST Typename
3963 /* AexprConst can be either A_Const or ParamNo */
3964 if (nodeTag($1) == T_A_Const) {
3965 ((A_Const *)$1)->typename = $3;
3966 } else if (nodeTag($1) == T_Param) {
3967 ((ParamNo *)$1)->typename = $3;
3968 /* otherwise, try to transform to a function call */
3970 FuncCall *n = makeNode(FuncCall);
3971 n->funcname = $3->name;
3972 n->args = lcons($1,NIL);
3976 | CAST '(' b_expr AS Typename ')'
3979 /* AexprConst can be either A_Const or ParamNo */
3980 if (nodeTag($3) == T_A_Const) {
3981 ((A_Const *)$3)->typename = $5;
3982 } else if (nodeTag($3) == T_Param) {
3983 ((ParamNo *)$3)->typename = $5;
3984 /* otherwise, try to transform to a function call */
3986 FuncCall *n = makeNode(FuncCall);
3987 n->funcname = $5->name;
3988 n->args = lcons($3,NIL);
3995 { $$ = makeIndexable($2,$1,$3); }
3997 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3999 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4002 FuncCall *n = makeNode(FuncCall);
4007 | func_name '(' expr_list ')'
4009 FuncCall *n = makeNode(FuncCall);
4016 A_Const *n = makeNode(A_Const);
4017 TypeName *t = makeNode(TypeName);
4019 n->val.type = T_String;
4020 n->val.val.str = "now";
4023 t->name = xlateSqlType("date");
4031 A_Const *n = makeNode(A_Const);
4032 TypeName *t = makeNode(TypeName);
4034 n->val.type = T_String;
4035 n->val.val.str = "now";
4038 t->name = xlateSqlType("time");
4044 | CURRENT_TIME '(' Iconst ')'
4046 FuncCall *n = makeNode(FuncCall);
4047 A_Const *s = makeNode(A_Const);
4048 TypeName *t = makeNode(TypeName);
4050 n->funcname = xlateSqlType("time");
4051 n->args = lcons(s, NIL);
4053 s->val.type = T_String;
4054 s->val.val.str = "now";
4057 t->name = xlateSqlType("time");
4062 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4068 A_Const *n = makeNode(A_Const);
4069 TypeName *t = makeNode(TypeName);
4071 n->val.type = T_String;
4072 n->val.val.str = "now";
4075 t->name = xlateSqlType("timestamp");
4081 | CURRENT_TIMESTAMP '(' Iconst ')'
4083 FuncCall *n = makeNode(FuncCall);
4084 A_Const *s = makeNode(A_Const);
4085 TypeName *t = makeNode(TypeName);
4087 n->funcname = xlateSqlType("timestamp");
4088 n->args = lcons(s, NIL);
4090 s->val.type = T_String;
4091 s->val.val.str = "now";
4094 t->name = xlateSqlType("timestamp");
4099 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4105 FuncCall *n = makeNode(FuncCall);
4106 n->funcname = "getpgusername";
4110 | POSITION '(' position_list ')'
4112 FuncCall *n = makeNode(FuncCall);
4113 n->funcname = "strpos";
4117 | SUBSTRING '(' substr_list ')'
4119 FuncCall *n = makeNode(FuncCall);
4120 n->funcname = "substr";
4124 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4125 | TRIM '(' BOTH trim_list ')'
4127 FuncCall *n = makeNode(FuncCall);
4128 n->funcname = "btrim";
4132 | TRIM '(' LEADING trim_list ')'
4134 FuncCall *n = makeNode(FuncCall);
4135 n->funcname = "ltrim";
4139 | TRIM '(' TRAILING trim_list ')'
4141 FuncCall *n = makeNode(FuncCall);
4142 n->funcname = "rtrim";
4146 | TRIM '(' trim_list ')'
4148 FuncCall *n = makeNode(FuncCall);
4149 n->funcname = "btrim";
4155 opt_indirection: '[' a_expr ']' opt_indirection
4157 A_Indices *ai = makeNode(A_Indices);
4162 | '[' a_expr ':' a_expr ']' opt_indirection
4164 A_Indices *ai = makeNode(A_Indices);
4173 expr_list: a_expr_or_null
4174 { $$ = lcons($1, NIL); }
4175 | expr_list ',' a_expr_or_null
4176 { $$ = lappend($1, $3); }
4177 | expr_list USING a_expr
4178 { $$ = lappend($1, $3); }
4181 extract_list: extract_arg FROM a_expr
4183 A_Const *n = makeNode(A_Const);
4184 n->val.type = T_String;
4185 n->val.val.str = $1;
4186 $$ = lappend(lcons((Node *)n,NIL), $3);
4192 /* Add in TIMEZONE_HOUR and TIMEZONE_MINUTE for SQL92 compliance
4193 * for next release. Just set up extract_arg for now...
4194 * - thomas 1998-04-08
4196 extract_arg: datetime
4200 position_list: position_expr IN position_expr
4201 { $$ = makeList($3, $1, -1); }
4206 position_expr: attr opt_indirection
4208 $1->indirection = $2;
4213 | '-' position_expr %prec UMINUS
4214 { $$ = makeA_Expr(OP, "-", NULL, $2); }
4215 | position_expr '+' position_expr
4216 { $$ = makeA_Expr(OP, "+", $1, $3); }
4217 | position_expr '-' position_expr
4218 { $$ = makeA_Expr(OP, "-", $1, $3); }
4219 | position_expr '/' position_expr
4220 { $$ = makeA_Expr(OP, "/", $1, $3); }
4221 | position_expr '*' position_expr
4222 { $$ = makeA_Expr(OP, "*", $1, $3); }
4224 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4225 | position_expr TYPECAST Typename
4228 /* AexprConst can be either A_Const or ParamNo */
4229 if (nodeTag($1) == T_A_Const) {
4230 ((A_Const *)$1)->typename = $3;
4231 } else if (nodeTag($1) == T_Param) {
4232 ((ParamNo *)$1)->typename = $3;
4233 /* otherwise, try to transform to a function call */
4235 FuncCall *n = makeNode(FuncCall);
4236 n->funcname = $3->name;
4237 n->args = lcons($1,NIL);
4241 | CAST '(' position_expr AS Typename ')'
4244 /* AexprConst can be either A_Const or ParamNo */
4245 if (nodeTag($3) == T_A_Const) {
4246 ((A_Const *)$3)->typename = $5;
4247 } else if (nodeTag($3) == T_Param) {
4248 ((ParamNo *)$3)->typename = $5;
4249 /* otherwise, try to transform to a function call */
4251 FuncCall *n = makeNode(FuncCall);
4252 n->funcname = $5->name;
4253 n->args = lcons($3,NIL);
4257 | '(' position_expr ')'
4259 | position_expr Op position_expr
4260 { $$ = makeA_Expr(OP, $2, $1, $3); }
4262 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4264 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4267 /* could be a column name or a relation_name */
4268 Ident *n = makeNode(Ident);
4270 n->indirection = NULL;
4275 FuncCall *n = makeNode(FuncCall);
4280 | func_name '(' expr_list ')'
4282 FuncCall *n = makeNode(FuncCall);
4287 | POSITION '(' position_list ')'
4289 FuncCall *n = makeNode(FuncCall);
4290 n->funcname = "strpos";
4294 | SUBSTRING '(' substr_list ')'
4296 FuncCall *n = makeNode(FuncCall);
4297 n->funcname = "substr";
4301 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4302 | TRIM '(' BOTH trim_list ')'
4304 FuncCall *n = makeNode(FuncCall);
4305 n->funcname = "btrim";
4309 | TRIM '(' LEADING trim_list ')'
4311 FuncCall *n = makeNode(FuncCall);
4312 n->funcname = "ltrim";
4316 | TRIM '(' TRAILING trim_list ')'
4318 FuncCall *n = makeNode(FuncCall);
4319 n->funcname = "rtrim";
4323 | TRIM '(' trim_list ')'
4325 FuncCall *n = makeNode(FuncCall);
4326 n->funcname = "btrim";
4332 substr_list: expr_list substr_from substr_for
4334 $$ = nconc(nconc($1,$2),$3);
4340 substr_from: FROM expr_list
4344 A_Const *n = makeNode(A_Const);
4345 n->val.type = T_Integer;
4346 n->val.val.ival = 1;
4347 $$ = lcons((Node *)n,NIL);
4351 substr_for: FOR expr_list
4357 trim_list: a_expr FROM expr_list
4358 { $$ = lappend($3, $1); }
4367 SubLink *n = makeNode(SubLink);
4375 in_expr_nodes: AexprConst
4376 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4377 | in_expr_nodes ',' AexprConst
4378 { $$ = makeA_Expr(OR, NULL, $1,
4379 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4383 not_in_expr: SubSelect
4385 SubLink *n = makeNode(SubLink);
4393 not_in_expr_nodes: AexprConst
4394 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4395 | not_in_expr_nodes ',' AexprConst
4396 { $$ = makeA_Expr(AND, NULL, $1,
4397 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4401 attr: relation_name '.' attrs
4403 $$ = makeNode(Attr);
4407 $$->indirection = NULL;
4411 $$ = makeNode(Attr);
4415 $$->indirection = NULL;
4420 { $$ = lcons(makeString($1), NIL); }
4421 | attrs '.' attr_name
4422 { $$ = lappend($1, makeString($3)); }
4424 { $$ = lappend($1, makeString("*")); }
4428 /*****************************************************************************
4432 *****************************************************************************/
4434 res_target_list: res_target_list ',' res_target_el
4435 { $$ = lappend($1,$3); }
4437 { $$ = lcons($1, NIL); }
4440 ResTarget *rt = makeNode(ResTarget);
4441 Attr *att = makeNode(Attr);
4443 att->paramNo = NULL;
4445 att->indirection = NIL;
4447 rt->indirection = NULL;
4448 rt->val = (Node *)att;
4449 $$ = lcons(rt, NIL);
4453 res_target_el: ColId opt_indirection '=' a_expr_or_null
4455 $$ = makeNode(ResTarget);
4457 $$->indirection = $2;
4458 $$->val = (Node *)$4;
4460 | attr opt_indirection
4462 $$ = makeNode(ResTarget);
4464 $$->indirection = $2;
4465 $$->val = (Node *)$1;
4467 | relation_name '.' '*'
4469 Attr *att = makeNode(Attr);
4471 att->paramNo = NULL;
4472 att->attrs = lcons(makeString("*"), NIL);
4473 att->indirection = NIL;
4474 $$ = makeNode(ResTarget);
4476 $$->indirection = NULL;
4477 $$->val = (Node *)att;
4482 ** target list for select.
4483 ** should get rid of the other but is still needed by the defunct select into
4484 ** and update (uses a subset)
4486 res_target_list2: res_target_list2 ',' res_target_el2
4487 { $$ = lappend($1, $3); }
4489 { $$ = lcons($1, NIL); }
4492 /* AS is not optional because shift/red conflict with unary ops */
4493 res_target_el2: a_expr_or_null AS ColLabel
4495 $$ = makeNode(ResTarget);
4497 $$->indirection = NULL;
4498 $$->val = (Node *)$1;
4502 $$ = makeNode(ResTarget);
4504 $$->indirection = NULL;
4505 $$->val = (Node *)$1;
4507 | relation_name '.' '*'
4509 Attr *att = makeNode(Attr);
4511 att->paramNo = NULL;
4512 att->attrs = lcons(makeString("*"), NIL);
4513 att->indirection = NIL;
4514 $$ = makeNode(ResTarget);
4516 $$->indirection = NULL;
4517 $$->val = (Node *)att;
4521 Attr *att = makeNode(Attr);
4523 att->paramNo = NULL;
4525 att->indirection = NIL;
4526 $$ = makeNode(ResTarget);
4528 $$->indirection = NULL;
4529 $$->val = (Node *)att;
4533 opt_id: ColId { $$ = $1; }
4534 | /* EMPTY */ { $$ = NULL; }
4537 relation_name: SpecialRuleRelation
4540 StrNCpy(saved_relname, $1, NAMEDATALEN);
4544 /* disallow refs to variable system tables */
4545 if (strcmp(LogRelationName, $1) == 0
4546 || strcmp(VariableRelationName, $1) == 0)
4547 elog(ERROR,"%s cannot be accessed by users",$1);
4550 StrNCpy(saved_relname, $1, NAMEDATALEN);
4554 database_name: ColId { $$ = $1; };
4555 access_method: IDENT { $$ = $1; };
4556 attr_name: ColId { $$ = $1; };
4557 class: IDENT { $$ = $1; };
4558 index_name: ColId { $$ = $1; };
4561 * Include date/time keywords as SQL92 extension.
4562 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4564 name: ColId { $$ = $1; };
4565 func_name: ColId { $$ = xlateSqlFunc($1); };
4567 file_name: Sconst { $$ = $1; };
4568 recipe_name: IDENT { $$ = $1; };
4571 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4575 A_Const *n = makeNode(A_Const);
4576 n->val.type = T_Integer;
4577 n->val.val.ival = $1;
4582 A_Const *n = makeNode(A_Const);
4583 n->val.type = T_Float;
4584 n->val.val.dval = $1;
4589 A_Const *n = makeNode(A_Const);
4590 n->val.type = T_String;
4591 n->val.val.str = $1;
4596 A_Const *n = makeNode(A_Const);
4598 n->val.type = T_String;
4599 n->val.val.str = $2;
4603 { $$ = (Node *)$1; }
4606 A_Const *n = makeNode(A_Const);
4607 n->val.type = T_String;
4608 n->val.val.str = "t";
4609 n->typename = makeNode(TypeName);
4610 n->typename->name = xlateSqlType("bool");
4611 n->typename->typmod = -1;
4616 A_Const *n = makeNode(A_Const);
4617 n->val.type = T_String;
4618 n->val.val.str = "f";
4619 n->typename = makeNode(TypeName);
4620 n->typename->name = xlateSqlType("bool");
4621 n->typename->typmod = -1;
4628 $$ = makeNode(ParamNo);
4633 NumConst: Iconst { $$ = makeInteger($1); }
4634 | FCONST { $$ = makeFloat($1); }
4637 Iconst: ICONST { $$ = $1; };
4638 Sconst: SCONST { $$ = $1; };
4639 UserId: IDENT { $$ = $1; };
4641 /* Column and type identifier
4642 * Does not include explicit datetime types
4643 * since these must be decoupled in Typename syntax.
4644 * Use ColId for most identifiers. - thomas 1997-10-21
4647 { $$ = xlateSqlType($1); }
4649 { $$ = xlateSqlType($1); }
4651 { $$ = xlateSqlType($1); }
4653 /* Column identifier
4654 * Include date/time keywords as SQL92 extension.
4655 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4656 * Add other keywords. Note that as the syntax expands,
4657 * some of these keywords will have to be removed from this
4658 * list due to shift/reduce conflicts in yacc. If so, move
4659 * down to the ColLabel entity. - thomas 1997-11-06
4661 ColId: IDENT { $$ = $1; }
4662 | datetime { $$ = $1; }
4663 | ACTION { $$ = "action"; }
4664 | CACHE { $$ = "cache"; }
4665 | CYCLE { $$ = "cycle"; }
4666 | DATABASE { $$ = "database"; }
4667 | DELIMITERS { $$ = "delimiters"; }
4668 | DOUBLE { $$ = "double"; }
4669 | EACH { $$ = "each"; }
4670 | FUNCTION { $$ = "function"; }
4671 | INCREMENT { $$ = "increment"; }
4672 | INDEX { $$ = "index"; }
4673 | KEY { $$ = "key"; }
4674 | LANGUAGE { $$ = "language"; }
4675 | LOCATION { $$ = "location"; }
4676 | MATCH { $$ = "match"; }
4677 | MAXVALUE { $$ = "maxvalue"; }
4678 | MINVALUE { $$ = "minvalue"; }
4679 | OPERATOR { $$ = "operator"; }
4680 | OPTION { $$ = "option"; }
4681 | PASSWORD { $$ = "password"; }
4682 | PRIVILEGES { $$ = "privileges"; }
4683 | RECIPE { $$ = "recipe"; }
4684 | ROW { $$ = "row"; }
4685 | START { $$ = "start"; }
4686 | STATEMENT { $$ = "statement"; }
4687 | TIME { $$ = "time"; }
4688 | TRIGGER { $$ = "trigger"; }
4689 | TYPE_P { $$ = "type"; }
4690 | USER { $$ = "user"; }
4691 | VALID { $$ = "valid"; }
4692 | VERSION { $$ = "version"; }
4693 | ZONE { $$ = "zone"; }
4697 * Allowed labels in "AS" clauses.
4698 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4699 * compatibility. Cannot allow this for column names since the
4700 * syntax would not distinguish between the constant value and
4701 * a column name. - thomas 1997-10-24
4702 * Add other keywords to this list. Note that they appear here
4703 * rather than in ColId if there was a shift/reduce conflict
4704 * when used as a full identifier. - thomas 1997-11-06
4706 ColLabel: ColId { $$ = $1; }
4707 | ARCHIVE { $$ = "archive"; }
4708 | CLUSTER { $$ = "cluster"; }
4709 | CONSTRAINT { $$ = "constraint"; }
4710 | CROSS { $$ = "cross"; }
4711 | FOREIGN { $$ = "foreign"; }
4712 | GROUP { $$ = "group"; }
4713 | LOAD { $$ = "load"; }
4714 | ORDER { $$ = "order"; }
4715 | POSITION { $$ = "position"; }
4716 | PRECISION { $$ = "precision"; }
4717 | TABLE { $$ = "table"; }
4718 | TRANSACTION { $$ = "transaction"; }
4719 | TRUE_P { $$ = "true"; }
4720 | FALSE_P { $$ = "false"; }
4723 SpecialRuleRelation: CURRENT
4728 elog(ERROR,"CURRENT used in non-rule query");
4735 elog(ERROR,"NEW used in non-rule query");
4742 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
4744 A_Expr *a = makeNode(A_Expr);
4753 * Generate separate operator nodes for a single row descriptor expression.
4754 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
4757 makeRowExpr(char *opr, List *largs, List *rargs)
4762 if (length(largs) != length(rargs))
4763 elog(ERROR,"Unequal number of entries in row expression");
4765 if (lnext(largs) != NIL)
4766 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
4768 larg = lfirst(largs);
4769 rarg = lfirst(rargs);
4771 if ((strcmp(opr, "=") == 0)
4772 || (strcmp(opr, "<") == 0)
4773 || (strcmp(opr, "<=") == 0)
4774 || (strcmp(opr, ">") == 0)
4775 || (strcmp(opr, ">=") == 0))
4778 expr = makeA_Expr(OP, opr, larg, rarg);
4780 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4782 else if (strcmp(opr, "<>") == 0)
4785 expr = makeA_Expr(OP, opr, larg, rarg);
4787 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4791 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
4795 while ((largs != NIL) && (rargs != NIL))
4797 larg = lfirst(largs);
4798 rarg = lfirst(rargs);
4801 expr = makeA_Expr(OP, opr, larg, rarg);
4803 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4805 largs = lnext(largs);
4806 rargs = lnext(rargs);
4815 mapTargetColumns(List *src, List *dst)
4820 if (length(src) != length(dst))
4821 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
4823 while ((src != NIL) && (dst != NIL))
4825 s = (ColumnDef *)lfirst(src);
4826 d = (ResTarget *)lfirst(dst);
4828 d->name = s->colname;
4835 } /* mapTargetColumns() */
4837 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
4839 Node *result = NULL;
4841 /* we do this so indexes can be used */
4842 if (strcmp(opname,"~") == 0 ||
4843 strcmp(opname,"~*") == 0)
4845 if (nodeTag(rexpr) == T_A_Const &&
4846 ((A_Const *)rexpr)->val.type == T_String &&
4847 ((A_Const *)rexpr)->val.val.str[0] == '^')
4849 A_Const *n = (A_Const *)rexpr;
4850 char *match_least = palloc(strlen(n->val.val.str)+2);
4851 char *match_most = palloc(strlen(n->val.val.str)+2);
4852 int pos, match_pos=0;
4854 /* skip leading ^ */
4855 for (pos = 1; n->val.val.str[pos]; pos++)
4857 if (n->val.val.str[pos] == '.' ||
4858 n->val.val.str[pos] == '?' ||
4859 n->val.val.str[pos] == '*' ||
4860 n->val.val.str[pos] == '[' ||
4861 n->val.val.str[pos] == '$' ||
4862 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4864 if (n->val.val.str[pos] == '\\')
4866 match_least[match_pos] = n->val.val.str[pos];
4867 match_most[match_pos++] = n->val.val.str[pos];
4872 A_Const *least = makeNode(A_Const);
4873 A_Const *most = makeNode(A_Const);
4875 /* make strings to be used in index use */
4876 match_least[match_pos] = '\0';
4877 match_most[match_pos] = '\377';
4878 match_most[match_pos+1] = '\0';
4879 least->val.type = T_String;
4880 least->val.val.str = match_least;
4881 most->val.type = T_String;
4882 most->val.val.str = match_most;
4883 result = makeA_Expr(AND, NULL,
4884 makeA_Expr(OP, "~", lexpr, rexpr),
4885 makeA_Expr(AND, NULL,
4886 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4887 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4891 else if (strcmp(opname,"~~") == 0)
4893 if (nodeTag(rexpr) == T_A_Const &&
4894 ((A_Const *)rexpr)->val.type == T_String)
4896 A_Const *n = (A_Const *)rexpr;
4897 char *match_least = palloc(strlen(n->val.val.str)+2);
4898 char *match_most = palloc(strlen(n->val.val.str)+2);
4899 int pos, match_pos=0;
4901 for (pos = 0; n->val.val.str[pos]; pos++)
4903 if (n->val.val.str[pos] == '%' &&
4904 n->val.val.str[pos+1] != '%')
4906 if(n->val.val.str[pos] == '_')
4908 if (n->val.val.str[pos] == '\\' ||
4909 n->val.val.str[pos] == '%')
4911 if (n->val.val.str[pos] == '\0')
4913 match_least[match_pos] = n->val.val.str[pos];
4914 match_most[match_pos++] = n->val.val.str[pos];
4919 A_Const *least = makeNode(A_Const);
4920 A_Const *most = makeNode(A_Const);
4922 /* make strings to be used in index use */
4923 match_least[match_pos] = '\0';
4924 match_most[match_pos] = '\377';
4925 match_most[match_pos+1] = '\0';
4926 least->val.type = T_String;
4927 least->val.val.str = match_least;
4928 most->val.type = T_String;
4929 most->val.val.str = match_most;
4930 result = makeA_Expr(AND, NULL,
4931 makeA_Expr(OP, "~~", lexpr, rexpr),
4932 makeA_Expr(AND, NULL,
4933 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4934 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4940 result = makeA_Expr(OP, opname, lexpr, rexpr);
4942 } /* makeIndexable() */
4946 * Convert alternate type names to internal Postgres types.
4947 * Do not convert "float", since that is handled elsewhere
4948 * for FLOAT(p) syntax.
4951 xlateSqlFunc(char *name)
4953 if (!strcasecmp(name,"character_length")
4954 || !strcasecmp(name,"char_length"))
4958 } /* xlateSqlFunc() */
4961 * Convert alternate type names to internal Postgres types.
4964 xlateSqlType(char *name)
4966 if (!strcasecmp(name,"int")
4967 || !strcasecmp(name,"integer"))
4969 else if (!strcasecmp(name, "smallint"))
4971 else if (!strcasecmp(name, "real")
4972 || !strcasecmp(name, "float"))
4974 else if (!strcasecmp(name, "interval"))
4976 else if (!strcasecmp(name, "boolean"))
4980 } /* xlateSqlType() */
4983 void parser_init(Oid *typev, int nargs)
4985 QueryIsRule = FALSE;
4986 saved_relname[0]= '\0';
4987 saved_In_Expr = NULL;
4989 param_type_init(typev, nargs);
4993 /* FlattenStringList()
4994 * Traverse list of string nodes and convert to a single string.
4995 * Used for reconstructing string form of complex expressions.
4997 * Allocate at least one byte for terminator.
5000 FlattenStringList(List *list)
5008 nlist = length(list);
5011 v = (Value *)lfirst(l);
5018 s = (char*) palloc(len+1);
5023 v = (Value *)lfirst(l);
5027 if (l != NIL) strcat(s," ");
5032 printf( "flattened string is \"%s\"\n", s);
5036 } /* FlattenStringList() */
5039 /* makeConstantList()
5040 * Convert constant value node into string node.
5043 makeConstantList( A_Const *n)
5045 char *defval = NULL;
5046 if (nodeTag(n) != T_A_Const) {
5047 elog(ERROR,"Cannot handle non-constant parameter");
5049 } else if (n->val.type == T_Float) {
5050 defval = (char*) palloc(20+1);
5051 sprintf( defval, "%g", n->val.val.dval);
5053 } else if (n->val.type == T_Integer) {
5054 defval = (char*) palloc(20+1);
5055 sprintf( defval, "%ld", n->val.val.ival);
5057 } else if (n->val.type == T_String) {
5058 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
5059 strcpy( defval, "'");
5060 strcat( defval, ((A_Const *) n)->val.val.str);
5061 strcat( defval, "'");
5064 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
5068 printf( "AexprConst argument is \"%s\"\n", defval);
5071 return( lcons( makeString(defval), NIL));
5072 } /* makeConstantList() */
5076 * Check input string for non-lowercase/non-numeric characters.
5077 * Returns either input string or input surrounded by double quotes.
5084 for (cp = rawid; *cp != '\0'; cp++)
5085 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
5088 cp = palloc(strlen(rawid)+1);
5097 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
5106 * keep enough information around fill out the type of param nodes
5107 * used in postquel functions
5110 param_type_init(Oid *typev, int nargs)
5112 pfunc_num_args = nargs;
5113 param_type_info = typev;
5116 Oid param_type(int t)
5118 if ((t > pfunc_num_args) || (t == 0))
5120 return param_type_info[t - 1];