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.123 1999/12/16 17:24:14 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 *-------------------------------------------------------------------------
38 #include "access/htup.h"
39 #include "access/xact.h"
40 #include "catalog/catname.h"
41 #include "catalog/pg_type.h"
42 #include "nodes/parsenodes.h"
43 #include "nodes/print.h"
44 #include "parser/analyze.h"
45 #include "parser/gramparse.h"
46 #include "parser/parse_type.h"
47 #include "storage/bufpage.h"
48 #include "storage/lmgr.h"
49 #include "utils/acl.h"
50 #include "utils/numeric.h"
53 #include "mb/pg_wchar.h"
56 extern List *parsetree; /* final parse result is delivered here */
58 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
59 static bool QueryIsRule = FALSE;
60 static Oid *param_type_info;
61 static int pfunc_num_args;
65 * If you need access to certain yacc-generated variables and find that
66 * they're static by default, uncomment the next line. (this is not a
69 /*#define __YYSCLASS*/
71 static char *xlateSqlFunc(char *);
72 static char *xlateSqlType(char *);
73 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
74 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
75 static void mapTargetColumns(List *source, List *target);
76 static void param_type_init(Oid *typev, int nargs);
77 static Node *doNegate(Node *n);
79 /* old versions of flex define this as a macro */
93 bool* pboolean; /* for pg_shadow privileges */
102 SortGroupBy *sortgroupby;
118 AddAttrStmt, ClosePortalStmt,
119 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DropStmt,
120 TruncateStmt, CommentStmt,
121 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
122 CreatePLangStmt, DropPLangStmt,
123 IndexStmt, ListenStmt, UnlistenStmt, LockStmt, OptimizableStmt,
124 ProcedureStmt, RemoveAggrStmt, RemoveOperStmt,
125 RemoveFuncStmt, RemoveStmt,
126 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
127 CreatedbStmt, DropdbStmt, VacuumStmt, CursorStmt, SubSelect,
128 UpdateStmt, InsertStmt, select_clause, SelectStmt, NotifyStmt, DeleteStmt,
129 ClusterStmt, ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
130 CreateUserStmt, AlterUserStmt, DropUserStmt, RuleActionStmt,
131 RuleActionStmtOrEmpty, ConstraintsSetStmt,
132 CreateGroupStmt, AlterGroupStmt, DropGroupStmt
134 %type <str> opt_database1, opt_database2, location, encoding
136 %type <ival> opt_lock, lock_type
137 %type <boolean> opt_lmode
139 %type <pboolean> user_createdb_clause, user_createuser_clause
140 %type <str> user_passwd_clause
141 %type <ival> sysid_clause
142 %type <str> user_valid_clause
143 %type <list> user_group_list, user_group_clause, users_in_new_group_clause
145 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
147 %type <str> OptConstrFromTable
149 %type <str> TriggerEvents, TriggerFuncArg
151 %type <str> relation_name, copy_file_name, copy_delimiter, copy_null, def_name,
152 database_name, access_method_clause, access_method, attr_name,
153 class, index_name, name, func_name, file_name, aggr_argtype
155 %type <str> opt_id, opt_portal_name,
156 all_Op, MathOp, opt_name, opt_unique,
157 OptUseOp, opt_class, SpecialRuleRelation
159 %type <str> opt_level
160 %type <str> privileges, operation_commalist, grantee
161 %type <chr> operation, TriggerOneEvent
163 %type <list> stmtblock, stmtmulti,
164 result, relation_name_list, OptTableElementList,
165 OptInherit, definition,
166 opt_with, func_args, func_args_list, func_as,
167 oper_argtypes, RuleActionList, RuleActionMulti,
168 opt_column_list, columnList, opt_va_list, va_list,
169 sort_clause, sortby_list, index_params, index_list, name_list,
170 from_clause, from_expr, table_list, opt_array_bounds,
171 expr_list, attrs, target_list, update_target_list,
172 def_list, opt_indirection, group_clause, TriggerFuncArgs,
175 %type <node> func_return
176 %type <boolean> set_opt
178 %type <boolean> TriggerForOpt, TriggerForType, OptTemp, OptTempType, OptTempScope
180 %type <list> for_update_clause, update_list
181 %type <boolean> opt_all
182 %type <boolean> opt_table
183 %type <boolean> opt_trans
185 %type <list> join_clause_with_union, join_clause, join_list, join_qual, using_list
186 %type <node> join_expr, using_expr
187 %type <str> join_outer
188 %type <ival> join_type
190 %type <list> extract_list, position_list
191 %type <list> substr_list, substr_from, substr_for, trim_list
192 %type <list> opt_interval
194 %type <boolean> opt_inh_star, opt_binary, opt_using, opt_instead,
195 opt_with_copy, index_opt_unique, opt_verbose, opt_analyze
196 %type <boolean> opt_cursor
198 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
199 opt_column, event, comment_type, comment_cl,
200 comment_ag, comment_fn, comment_op, comment_tg
202 %type <ival> fetch_how_many
204 %type <node> select_limit_value, select_offset_value
206 %type <list> OptSeqList
207 %type <defelt> OptSeqElem
209 %type <dstmt> def_rest
210 %type <astmt> insert_rest
212 %type <node> OptTableElement, ConstraintElem
213 %type <node> columnDef, alter_clause
214 %type <defelt> def_elem
215 %type <node> def_arg, columnElem, where_clause,
216 a_expr, a_expr_or_null, b_expr, com_expr, AexprConst,
217 in_expr, having_clause
218 %type <list> row_descriptor, row_list, in_expr_nodes
219 %type <node> row_expr
220 %type <node> case_expr, case_arg, when_clause, case_default
221 %type <list> when_clause_list
222 %type <ival> sub_type
223 %type <list> OptCreateAs, CreateAsList
224 %type <node> CreateAsElement
225 %type <value> NumericOnly, FloatOnly, IntegerOnly
226 %type <attr> event_object, attr
227 %type <sortgroupby> sortby
228 %type <ielem> index_elem, func_index
229 %type <range> table_expr
230 %type <relexp> relation_expr
231 %type <target> target_el, update_target_el
232 %type <paramno> ParamNo
234 %type <typnam> Typename, opt_type, SimpleTypename,
235 Generic, Numeric, Character, Datetime
236 %type <str> generic, numeric, character, datetime
237 %type <str> extract_arg
238 %type <str> opt_charset, opt_collate
239 %type <str> opt_float
240 %type <ival> opt_numeric, opt_decimal
241 %type <boolean> opt_varying, opt_timezone
244 %type <str> Sconst, comment_text
245 %type <str> UserId, var_value, zone_value
246 %type <str> ColId, ColLabel
249 %type <node> TableConstraint
250 %type <list> ColPrimaryKey, ColConstraintList
251 %type <node> ColConstraint, ColConstraintElem
252 %type <ival> key_actions, key_action, key_reference
253 %type <str> key_match
254 %type <ival> ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
257 %type <list> constraints_set_list
258 %type <list> constraints_set_namelist
259 %type <boolean> constraints_set_mode
262 * If you make any token changes, remember to:
263 * - use "yacc -d" and update parse.h
264 * - update the keyword table in parser/keywords.c
267 /* Reserved word tokens
268 * SQL92 syntax has many type-specific constructs.
269 * So, go ahead and make these types reserved words,
270 * and call-out the syntax explicitly.
271 * This gets annoying when trying to also retain Postgres' nice
272 * type-extensible features, but we don't really have a choice.
273 * - thomas 1997-10-11
276 /* Keywords (in SQL92 reserved words) */
277 %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
278 BEGIN_TRANS, BETWEEN, BOTH, BY,
279 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
280 COALESCE, COLLATE, COLUMN, COMMIT,
281 CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
282 CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
283 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
284 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
285 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
286 GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
287 IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
288 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
289 MATCH, MINUTE_P, MONTH_P, NAMES,
290 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
291 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
292 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
293 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
294 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
295 TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
296 TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
297 UNION, UNIQUE, UPDATE, USER, USING,
298 VALUES, VARCHAR, VARYING, VIEW,
299 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
302 /* Keywords (in SQL3 reserved words) */
303 %token DEFERRABLE, DEFERRED,
304 IMMEDIATE, INITIALLY,
309 /* Keywords (in SQL92 non-reserved words) */
310 %token COMMITTED, SERIALIZABLE, TYPE_P
312 /* Keywords for Postgres support (not in SQL92 reserved words)
314 * The CREATEDB and CREATEUSER tokens should go away
315 * when some sort of pg_privileges relation is introduced.
316 * - Todd A. Brandys 1998-01-01?
318 %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
319 BACKWARD, BEFORE, BINARY,
320 CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
321 DATABASE, DELIMITERS, DO,
322 EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
323 FORWARD, FUNCTION, HANDLER,
324 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
325 LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
326 MAXVALUE, MINVALUE, MODE, MOVE,
327 NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
328 OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
329 RENAME, RESET, RETURNS, ROW, RULE,
330 SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID,
332 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
334 /* Special keywords, not in the query language - see the "lex" file */
335 %token <str> IDENT, SCONST, Op
336 %token <ival> ICONST, PARAM
339 /* these are not real. they are here so that they get generated as #define's*/
351 %left Op /* multi-character ops and user-defined operators */
359 %left '|' /* this is the relation union op, not logical or */
360 /* Unary Operators */
362 %left ';' /* end of statement or natural log */
367 %left UNION INTERSECT EXCEPT
371 * Handle comment-only lines, and ;; SELECT * FROM pg_class ;;;
372 * psql already handles such cases, but other interfaces don't.
379 /* the thrashing around here is to discard "empty" statements... */
380 stmtmulti: stmtmulti ';' stmt
381 { if ($3 != (Node *)NULL)
382 $$ = lappend($1, $3);
387 { if ($1 != (Node *)NULL)
443 { $$ = (Node *)NULL; }
446 /*****************************************************************************
448 * Create a new Postgres DBMS user
451 *****************************************************************************/
453 CreateUserStmt: CREATE USER UserId
454 user_createdb_clause user_createuser_clause user_group_clause
457 CreateUserStmt *n = makeNode(CreateUserStmt);
467 | CREATE USER UserId WITH sysid_clause user_passwd_clause
468 user_createdb_clause user_createuser_clause user_group_clause
471 CreateUserStmt *n = makeNode(CreateUserStmt);
483 /*****************************************************************************
485 * Alter a postresql DBMS user
488 *****************************************************************************/
490 AlterUserStmt: ALTER USER UserId user_createdb_clause
491 user_createuser_clause user_group_clause user_valid_clause
493 AlterUserStmt *n = makeNode(AlterUserStmt);
503 | ALTER USER UserId WITH sysid_clause user_passwd_clause
505 user_createuser_clause user_group_clause user_valid_clause
507 AlterUserStmt *n = makeNode(AlterUserStmt);
519 /*****************************************************************************
521 * Drop a postresql DBMS user
524 *****************************************************************************/
526 DropUserStmt: DROP USER UserId
528 DropUserStmt *n = makeNode(DropUserStmt);
534 user_passwd_clause: PASSWORD UserId { $$ = $2; }
535 | /*EMPTY*/ { $$ = NULL; }
538 sysid_clause: SYSID Iconst { $$ = $2; }
539 | /*EMPTY*/ { $$ = -1; }
542 user_createdb_clause: CREATEDB
545 $$ = (b = (bool*)palloc(sizeof(bool)));
551 $$ = (b = (bool*)palloc(sizeof(bool)));
554 | /*EMPTY*/ { $$ = NULL; }
557 user_createuser_clause: CREATEUSER
560 $$ = (b = (bool*)palloc(sizeof(bool)));
566 $$ = (b = (bool*)palloc(sizeof(bool)));
569 | /*EMPTY*/ { $$ = NULL; }
572 user_group_list: user_group_list ',' UserId
574 $$ = lcons((void*)makeString($3), $1);
578 $$ = lcons((void*)makeString($1), NIL);
582 user_group_clause: IN GROUP user_group_list { $$ = $3; }
583 | /*EMPTY*/ { $$ = NULL; }
586 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
587 | /*EMPTY*/ { $$ = NULL; }
591 /*****************************************************************************
593 * Create a postresql group
596 *****************************************************************************/
598 CreateGroupStmt: CREATE GROUP UserId
600 CreateGroupStmt *n = makeNode(CreateGroupStmt);
607 CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
609 CreateGroupStmt *n = makeNode(CreateGroupStmt);
617 users_in_new_group_clause: USER user_group_list { $$ = $2; }
618 | /* EMPTY */ { $$ = NULL; }
621 /*****************************************************************************
623 * Alter a postresql group
626 *****************************************************************************/
628 AlterGroupStmt: ALTER GROUP UserId WITH SYSID Iconst
630 AlterGroupStmt *n = makeNode(AlterGroupStmt);
638 ALTER GROUP UserId ADD USER user_group_list
640 AlterGroupStmt *n = makeNode(AlterGroupStmt);
648 ALTER GROUP UserId DROP USER user_group_list
650 AlterGroupStmt *n = makeNode(AlterGroupStmt);
659 /*****************************************************************************
661 * Drop a postresql group
664 *****************************************************************************/
666 DropGroupStmt: DROP GROUP UserId
668 DropGroupStmt *n = makeNode(DropGroupStmt);
675 /*****************************************************************************
677 * Set PG internal variable
678 * SET name TO 'var_value'
679 * Include SQL92 syntax (thomas 1997-10-22):
680 * SET TIME ZONE 'var_value'
682 *****************************************************************************/
684 VariableSetStmt: SET ColId TO var_value
686 VariableSetStmt *n = makeNode(VariableSetStmt);
691 | SET ColId '=' var_value
693 VariableSetStmt *n = makeNode(VariableSetStmt);
698 | SET TIME ZONE zone_value
700 VariableSetStmt *n = makeNode(VariableSetStmt);
701 n->name = "timezone";
705 | SET TRANSACTION ISOLATION LEVEL opt_level
707 VariableSetStmt *n = makeNode(VariableSetStmt);
708 n->name = "XactIsoLevel";
715 VariableSetStmt *n = makeNode(VariableSetStmt);
716 n->name = "client_encoding";
720 elog(ERROR, "SET NAMES is not supported");
725 opt_level: READ COMMITTED { $$ = "committed"; }
726 | SERIALIZABLE { $$ = "serializable"; }
729 var_value: Sconst { $$ = $1; }
730 | DEFAULT { $$ = NULL; }
733 zone_value: Sconst { $$ = $1; }
734 | DEFAULT { $$ = NULL; }
735 | LOCAL { $$ = NULL; }
738 VariableShowStmt: SHOW ColId
740 VariableShowStmt *n = makeNode(VariableShowStmt);
746 VariableShowStmt *n = makeNode(VariableShowStmt);
747 n->name = "timezone";
750 | SHOW TRANSACTION ISOLATION LEVEL
752 VariableShowStmt *n = makeNode(VariableShowStmt);
753 n->name = "XactIsoLevel";
758 VariableResetStmt: RESET ColId
760 VariableResetStmt *n = makeNode(VariableResetStmt);
766 VariableResetStmt *n = makeNode(VariableResetStmt);
767 n->name = "timezone";
770 | RESET TRANSACTION ISOLATION LEVEL
772 VariableResetStmt *n = makeNode(VariableResetStmt);
773 n->name = "XactIsoLevel";
779 ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode
781 ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
789 constraints_set_list: ALL
793 | constraints_set_namelist
800 constraints_set_namelist: IDENT
802 $$ = lappend(NIL, $1);
804 | constraints_set_namelist ',' IDENT
806 $$ = lappend($1, $3);
811 constraints_set_mode: DEFERRED
822 /*****************************************************************************
825 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
827 *****************************************************************************/
829 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
831 AddAttrStmt *n = makeNode(AddAttrStmt);
839 alter_clause: ADD opt_column columnDef
843 | ADD '(' OptTableElementList ')'
846 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
847 $$ = (Node *) lfirst($3);
849 | DROP opt_column ColId
850 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
851 | ALTER opt_column ColId SET DEFAULT a_expr
852 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
853 | ALTER opt_column ColId DROP DEFAULT
854 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
856 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
860 /*****************************************************************************
865 *****************************************************************************/
867 ClosePortalStmt: CLOSE opt_id
869 ClosePortalStmt *n = makeNode(ClosePortalStmt);
875 opt_id: ColId { $$ = $1; }
876 | /*EMPTY*/ { $$ = NULL; }
880 /*****************************************************************************
883 * COPY [BINARY] <relname> FROM/TO
884 * [USING DELIMITERS <delimiter>]
886 *****************************************************************************/
888 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
890 CopyStmt *n = makeNode(CopyStmt);
909 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
910 * used depends on the direction. (It really doesn't make sense to copy from
911 * stdout. We silently correct the "typo". - AY 9/94
913 copy_file_name: Sconst { $$ = $1; }
914 | STDIN { $$ = NULL; }
915 | STDOUT { $$ = NULL; }
918 opt_binary: BINARY { $$ = TRUE; }
919 | /*EMPTY*/ { $$ = FALSE; }
922 opt_with_copy: WITH OIDS { $$ = TRUE; }
923 | /*EMPTY*/ { $$ = FALSE; }
927 * the default copy delimiter is tab but the user can configure it
929 copy_delimiter: opt_using DELIMITERS Sconst { $$ = $3; }
930 | /*EMPTY*/ { $$ = "\t"; }
933 opt_using: USING { $$ = TRUE; }
934 | /*EMPTY*/ { $$ = TRUE; }
937 copy_null: WITH NULL_P AS Sconst { $$ = $4; }
938 | /*EMPTY*/ { $$ = "\\N"; }
940 /*****************************************************************************
945 *****************************************************************************/
947 CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
950 CreateStmt *n = makeNode(CreateStmt);
955 n->constraints = NIL;
960 OptTemp: OptTempType { $$ = $1; }
961 | OptTempScope OptTempType { $$ = $2; }
964 OptTempType: TEMP { $$ = TRUE; }
965 | TEMPORARY { $$ = TRUE; }
966 | /*EMPTY*/ { $$ = FALSE; }
971 elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
980 OptTableElementList: OptTableElementList ',' OptTableElement
983 $$ = lappend($1, $3);
994 | /*EMPTY*/ { $$ = NULL; }
997 OptTableElement: columnDef { $$ = $1; }
998 | TableConstraint { $$ = $1; }
1001 columnDef: ColId Typename ColConstraintList
1003 ColumnDef *n = makeNode(ColumnDef);
1006 n->raw_default = NULL;
1007 n->cooked_default = NULL;
1008 n->is_not_null = FALSE;
1009 n->constraints = $3;
1012 | ColId SERIAL ColPrimaryKey
1014 ColumnDef *n = makeNode(ColumnDef);
1016 n->typename = makeNode(TypeName);
1017 n->typename->name = xlateSqlType("integer");
1018 n->raw_default = NULL;
1019 n->cooked_default = NULL;
1020 n->is_not_null = TRUE;
1021 n->is_sequence = TRUE;
1022 n->constraints = $3;
1028 ColConstraintList: ColConstraintList ColConstraint
1031 $$ = lappend($1, $2);
1039 ColPrimaryKey: PRIMARY KEY
1041 Constraint *n = makeNode(Constraint);
1042 n->contype = CONSTR_PRIMARY;
1045 n->cooked_expr = NULL;
1047 $$ = lcons((Node *)n, NIL);
1049 | /*EMPTY*/ { $$ = NULL; }
1053 CONSTRAINT name ColConstraintElem
1055 switch (nodeTag($3))
1059 Constraint *n = (Constraint *)$3;
1060 if (n != NULL) n->name = $2;
1063 case T_FkConstraint:
1065 FkConstraint *n = (FkConstraint *)$3;
1066 if (n != NULL) n->constr_name = $2;
1079 * DEFAULT NULL is already the default for Postgres.
1080 * But define it here and carry it forward into the system
1081 * to make it explicit.
1082 * - thomas 1998-09-13
1084 * WITH NULL and NULL are not SQL92-standard syntax elements,
1085 * so leave them out. Use DEFAULT NULL to explicitly indicate
1086 * that a column may have that value. WITH NULL leads to
1087 * shift/reduce conflicts with WITH TIME ZONE anyway.
1088 * - thomas 1999-01-08
1090 * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
1091 * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
1092 * or be part of a_expr NOT LIKE or similar constructs).
1094 ColConstraintElem: CHECK '(' a_expr ')'
1096 Constraint *n = makeNode(Constraint);
1097 n->contype = CONSTR_CHECK;
1100 n->cooked_expr = NULL;
1106 Constraint *n = makeNode(Constraint);
1107 n->contype = CONSTR_DEFAULT;
1110 n->cooked_expr = NULL;
1116 Constraint *n = makeNode(Constraint);
1117 n->contype = CONSTR_DEFAULT;
1120 n->cooked_expr = NULL;
1126 Constraint *n = makeNode(Constraint);
1127 n->contype = CONSTR_NOTNULL;
1130 n->cooked_expr = NULL;
1136 Constraint *n = makeNode(Constraint);
1137 n->contype = CONSTR_UNIQUE;
1140 n->cooked_expr = NULL;
1146 Constraint *n = makeNode(Constraint);
1147 n->contype = CONSTR_PRIMARY;
1150 n->cooked_expr = NULL;
1154 | REFERENCES ColId opt_column_list key_match key_actions
1157 * Need ConstraintAttributeSpec as $6 -- Jan
1159 FkConstraint *n = makeNode(FkConstraint);
1160 n->constr_name = NULL;
1161 n->pktable_name = $2;
1166 n->deferrable = true;
1167 n->initdeferred = false;
1169 n->deferrable = ($6 & 1) != 0;
1170 n->initdeferred = ($6 & 2) != 0;
1176 /* ConstraintElem specifies constraint syntax which is not embedded into
1177 * a column definition. ColConstraintElem specifies the embedded form.
1178 * - thomas 1997-12-03
1180 TableConstraint: CONSTRAINT name ConstraintElem
1182 switch (nodeTag($3))
1186 Constraint *n = (Constraint *)$3;
1187 if (n != NULL) n->name = $2;
1190 case T_FkConstraint:
1192 FkConstraint *n = (FkConstraint *)$3;
1193 if (n != NULL) n->constr_name = $2;
1205 ConstraintElem: CHECK '(' a_expr ')'
1207 Constraint *n = makeNode(Constraint);
1208 n->contype = CONSTR_CHECK;
1211 n->cooked_expr = NULL;
1214 | UNIQUE '(' columnList ')'
1216 Constraint *n = makeNode(Constraint);
1217 n->contype = CONSTR_UNIQUE;
1220 n->cooked_expr = NULL;
1224 | PRIMARY KEY '(' columnList ')'
1226 Constraint *n = makeNode(Constraint);
1227 n->contype = CONSTR_PRIMARY;
1230 n->cooked_expr = NULL;
1234 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions ConstraintAttributeSpec
1236 FkConstraint *n = makeNode(FkConstraint);
1237 n->constr_name = NULL;
1238 n->pktable_name = $7;
1243 n->deferrable = ($11 & 1) != 0;
1244 n->initdeferred = ($11 & 2) != 0;
1249 key_match: MATCH FULL
1255 elog(ERROR, "FOREIGN KEY match type PARTIAL not implemented yet");
1260 elog(ERROR, "FOREIGN KEY match type UNSPECIFIED not implemented yet");
1265 key_actions: key_action key_action { $$ = $1 | $2; }
1266 | key_action { $$ = $1; }
1267 | /*EMPTY*/ { $$ = 0; }
1270 key_action: ON DELETE key_reference { $$ = $3 << FKCONSTR_ON_DELETE_SHIFT; }
1271 | ON UPDATE key_reference { $$ = $3 << FKCONSTR_ON_UPDATE_SHIFT; }
1274 key_reference: NO ACTION { $$ = FKCONSTR_ON_KEY_NOACTION; }
1275 | RESTRICT { $$ = FKCONSTR_ON_KEY_RESTRICT; }
1276 | CASCADE { $$ = FKCONSTR_ON_KEY_CASCADE; }
1277 | SET NULL_P { $$ = FKCONSTR_ON_KEY_SETNULL; }
1278 | SET DEFAULT { $$ = FKCONSTR_ON_KEY_SETDEFAULT; }
1281 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1282 | /*EMPTY*/ { $$ = NIL; }
1286 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1290 CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
1292 SelectStmt *n = (SelectStmt *)$7;
1294 mapTargetColumns($5, n->targetList);
1295 if (n->into != NULL)
1296 elog(ERROR,"CREATE TABLE/AS SELECT may not specify INTO");
1303 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1304 | /*EMPTY*/ { $$ = NULL; }
1307 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1308 | CreateAsElement { $$ = lcons($1, NIL); }
1311 CreateAsElement: ColId
1313 ColumnDef *n = makeNode(ColumnDef);
1316 n->raw_default = NULL;
1317 n->cooked_default = NULL;
1318 n->is_not_null = FALSE;
1319 n->constraints = NULL;
1325 /*****************************************************************************
1328 * CREATE SEQUENCE seqname
1330 *****************************************************************************/
1332 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1334 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1341 OptSeqList: OptSeqList OptSeqElem
1342 { $$ = lappend($1, $2); }
1346 OptSeqElem: CACHE IntegerOnly
1348 $$ = makeNode(DefElem);
1349 $$->defname = "cache";
1350 $$->arg = (Node *)$2;
1354 $$ = makeNode(DefElem);
1355 $$->defname = "cycle";
1356 $$->arg = (Node *)NULL;
1358 | INCREMENT IntegerOnly
1360 $$ = makeNode(DefElem);
1361 $$->defname = "increment";
1362 $$->arg = (Node *)$2;
1364 | MAXVALUE IntegerOnly
1366 $$ = makeNode(DefElem);
1367 $$->defname = "maxvalue";
1368 $$->arg = (Node *)$2;
1370 | MINVALUE IntegerOnly
1372 $$ = makeNode(DefElem);
1373 $$->defname = "minvalue";
1374 $$->arg = (Node *)$2;
1378 $$ = makeNode(DefElem);
1379 $$->defname = "start";
1380 $$->arg = (Node *)$2;
1384 NumericOnly: FloatOnly { $$ = $1; }
1385 | IntegerOnly { $$ = $1; }
1394 $$->val.dval = - $$->val.dval;
1400 $$ = makeInteger($1);
1404 $$ = makeInteger($2);
1405 $$->val.ival = - $$->val.ival;
1409 /*****************************************************************************
1412 * CREATE PROCEDURAL LANGUAGE ...
1413 * DROP PROCEDURAL LANGUAGE ...
1415 *****************************************************************************/
1417 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1418 HANDLER def_name LANCOMPILER Sconst
1420 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1429 PLangTrusted: TRUSTED { $$ = TRUE; }
1432 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1434 DropPLangStmt *n = makeNode(DropPLangStmt);
1440 /*****************************************************************************
1443 * CREATE TRIGGER ...
1446 *****************************************************************************/
1448 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1449 relation_name TriggerForSpec EXECUTE PROCEDURE
1450 name '(' TriggerFuncArgs ')'
1452 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1459 memcpy (n->actions, $5, 4);
1460 n->lang = NULL; /* unused */
1461 n->text = NULL; /* unused */
1462 n->attr = NULL; /* unused */
1463 n->when = NULL; /* unused */
1465 n->isconstraint = false;
1466 n->deferrable = false;
1467 n->initdeferred = false;
1468 n->constrrelname = NULL;
1471 | CREATE CONSTRAINT TRIGGER name AFTER TriggerOneEvent ON
1472 relation_name OptConstrFromTable
1473 ConstraintAttributeSpec
1474 FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')'
1476 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1484 n->actions[1] = '\0';
1485 n->lang = NULL; /* unused */
1486 n->text = NULL; /* unused */
1487 n->attr = NULL; /* unused */
1488 n->when = NULL; /* unused */
1490 n->isconstraint = true;
1491 n->deferrable = ($10 & 1) != 0;
1492 n->initdeferred = ($10 & 2) != 0;
1494 n->constrrelname = $9;
1499 TriggerActionTime: BEFORE { $$ = TRUE; }
1500 | AFTER { $$ = FALSE; }
1503 TriggerEvents: TriggerOneEvent
1505 char *e = palloc (4);
1506 e[0] = $1; e[1] = 0; $$ = e;
1508 | TriggerOneEvent OR TriggerOneEvent
1510 char *e = palloc (4);
1511 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1513 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1515 char *e = palloc (4);
1516 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1521 TriggerOneEvent: INSERT { $$ = 'i'; }
1522 | DELETE { $$ = 'd'; }
1523 | UPDATE { $$ = 'u'; }
1526 TriggerForSpec: FOR TriggerForOpt TriggerForType
1532 TriggerForOpt: EACH { $$ = TRUE; }
1533 | /*EMPTY*/ { $$ = FALSE; }
1536 TriggerForType: ROW { $$ = TRUE; }
1537 | STATEMENT { $$ = FALSE; }
1540 TriggerFuncArgs: TriggerFuncArg
1541 { $$ = lcons($1, NIL); }
1542 | TriggerFuncArgs ',' TriggerFuncArg
1543 { $$ = lappend($1, $3); }
1548 TriggerFuncArg: ICONST
1550 char *s = (char *) palloc (256);
1551 sprintf (s, "%d", $1);
1556 char *s = (char *) palloc (256);
1557 sprintf (s, "%g", $1);
1560 | Sconst { $$ = $1; }
1561 | IDENT { $$ = $1; }
1564 OptConstrFromTable: /* Empty */
1568 | FROM relation_name
1574 ConstraintAttributeSpec: /* Empty */
1576 | ConstraintDeferrabilitySpec
1578 | ConstraintDeferrabilitySpec ConstraintTimeSpec
1580 if ($1 == 0 && $2 != 0)
1581 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1584 | ConstraintTimeSpec
1591 | ConstraintTimeSpec ConstraintDeferrabilitySpec
1593 if ($2 == 0 && $1 != 0)
1594 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1599 ConstraintDeferrabilitySpec: NOT DEFERRABLE
1605 ConstraintTimeSpec: INITIALLY IMMEDIATE
1607 | INITIALLY DEFERRED
1612 DropTrigStmt: DROP TRIGGER name ON relation_name
1614 DropTrigStmt *n = makeNode(DropTrigStmt);
1622 /*****************************************************************************
1625 * define (type,operator,aggregate)
1627 *****************************************************************************/
1629 DefineStmt: CREATE def_type def_rest
1636 def_rest: def_name definition
1638 $$ = makeNode(DefineStmt);
1640 $$->definition = $2;
1644 def_type: OPERATOR { $$ = OPERATOR; }
1645 | TYPE_P { $$ = TYPE_P; }
1646 | AGGREGATE { $$ = AGGREGATE; }
1649 def_name: PROCEDURE { $$ = "procedure"; }
1650 | JOIN { $$ = "join"; }
1651 | ColId { $$ = $1; }
1652 | all_Op { $$ = $1; }
1655 definition: '(' def_list ')' { $$ = $2; }
1658 def_list: def_elem { $$ = lcons($1, NIL); }
1659 | def_list ',' def_elem { $$ = lappend($1, $3); }
1662 def_elem: def_name '=' def_arg
1664 $$ = makeNode(DefElem);
1666 $$->arg = (Node *)$3;
1670 $$ = makeNode(DefElem);
1672 $$->arg = (Node *)NULL;
1674 | DEFAULT '=' def_arg
1676 $$ = makeNode(DefElem);
1677 $$->defname = "default";
1678 $$->arg = (Node *)$3;
1682 def_arg: ColId { $$ = (Node *)makeString($1); }
1683 | all_Op { $$ = (Node *)makeString($1); }
1684 | NumericOnly { $$ = (Node *)$1; }
1685 | Sconst { $$ = (Node *)makeString($1); }
1688 TypeName *n = makeNode(TypeName);
1691 n->arrayBounds = NULL;
1698 /*****************************************************************************
1701 * drop <relname1> [, <relname2> .. <relnameN> ]
1703 *****************************************************************************/
1705 DropStmt: DROP TABLE relation_name_list
1707 DropStmt *n = makeNode(DropStmt);
1709 n->sequence = FALSE;
1712 | DROP SEQUENCE relation_name_list
1714 DropStmt *n = makeNode(DropStmt);
1721 /*****************************************************************************
1724 * truncate table relname
1726 *****************************************************************************/
1728 TruncateStmt: TRUNCATE TABLE relation_name
1730 TruncateStmt *n = makeNode(TruncateStmt);
1736 /*****************************************************************************
1738 * The COMMENT ON statement can take different forms based upon the type of
1739 * the object associated with the comment. The form of the statement is:
1741 * COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
1742 * <objname> | AGGREGATE <aggname> <aggtype> | FUNCTION
1743 * <funcname> (arg1, arg2, ...) | OPERATOR <op>
1744 * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
1745 * <relname> ] IS 'text'
1747 *****************************************************************************/
1749 CommentStmt: COMMENT ON comment_type name IS comment_text
1751 CommentStmt *n = makeNode(CommentStmt);
1754 n->objproperty = NULL;
1759 | COMMENT ON comment_cl relation_name '.' attr_name IS comment_text
1761 CommentStmt *n = makeNode(CommentStmt);
1764 n->objproperty = $6;
1769 | COMMENT ON comment_ag name aggr_argtype IS comment_text
1771 CommentStmt *n = makeNode(CommentStmt);
1774 n->objproperty = $5;
1779 | COMMENT ON comment_fn func_name func_args IS comment_text
1781 CommentStmt *n = makeNode(CommentStmt);
1784 n->objproperty = NULL;
1789 | COMMENT ON comment_op all_Op '(' oper_argtypes ')' IS comment_text
1791 CommentStmt *n = makeNode(CommentStmt);
1794 n->objproperty = NULL;
1799 | COMMENT ON comment_tg name ON relation_name IS comment_text
1801 CommentStmt *n = makeNode(CommentStmt);
1804 n->objproperty = $6;
1811 comment_type: DATABASE { $$ = DATABASE; }
1812 | INDEX { $$ = INDEX; }
1813 | RULE { $$ = RULE; }
1814 | SEQUENCE { $$ = SEQUENCE; }
1815 | TABLE { $$ = TABLE; }
1816 | TYPE_P { $$ = TYPE_P; }
1817 | VIEW { $$ = VIEW; }
1820 comment_cl: COLUMN { $$ = COLUMN; }
1823 comment_ag: AGGREGATE { $$ = AGGREGATE; }
1826 comment_fn: FUNCTION { $$ = FUNCTION; }
1829 comment_op: OPERATOR { $$ = OPERATOR; }
1832 comment_tg: TRIGGER { $$ = TRIGGER; }
1835 comment_text: Sconst { $$ = $1; }
1836 | NULL_P { $$ = NULL; }
1839 /*****************************************************************************
1842 * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1843 * fetch [ forward | backward | absolute | relative ]
1844 * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1846 *****************************************************************************/
1848 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1850 FetchStmt *n = makeNode(FetchStmt);
1854 elog(ERROR,"FETCH/RELATIVE at current position is not supported");
1860 $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
1868 | MOVE opt_direction fetch_how_many opt_portal_name
1870 FetchStmt *n = makeNode(FetchStmt);
1874 $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
1884 opt_direction: FORWARD { $$ = FORWARD; }
1885 | BACKWARD { $$ = BACKWARD; }
1886 | RELATIVE { $$ = RELATIVE; }
1889 elog(NOTICE,"FETCH/ABSOLUTE not supported, using RELATIVE");
1892 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1895 fetch_how_many: Iconst { $$ = $1; }
1896 | '-' Iconst { $$ = - $2; }
1897 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1899 | PRIOR { $$ = -1; }
1900 | /*EMPTY*/ { $$ = 1; /*default*/ }
1903 opt_portal_name: IN name { $$ = $2; }
1904 | FROM name { $$ = $2; }
1905 | /*EMPTY*/ { $$ = NULL; }
1909 /*****************************************************************************
1912 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1914 *****************************************************************************/
1916 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1918 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1922 privileges: ALL PRIVILEGES
1924 $$ = aclmakepriv("rwaR",0);
1928 $$ = aclmakepriv("rwaR",0);
1930 | operation_commalist
1936 operation_commalist: operation
1938 $$ = aclmakepriv("",$1);
1940 | operation_commalist ',' operation
1942 $$ = aclmakepriv($1,$3);
1948 $$ = ACL_MODE_RD_CHR;
1952 $$ = ACL_MODE_AP_CHR;
1956 $$ = ACL_MODE_WR_CHR;
1960 $$ = ACL_MODE_WR_CHR;
1964 $$ = ACL_MODE_RU_CHR;
1970 $$ = aclmakeuser("A","");
1974 $$ = aclmakeuser("G",$2);
1978 $$ = aclmakeuser("U",$1);
1982 opt_with_grant: WITH GRANT OPTION
1984 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1990 /*****************************************************************************
1993 * REVOKE [privileges] ON [relation_name] FROM [user]
1995 *****************************************************************************/
1997 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1999 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
2004 /*****************************************************************************
2007 * create index <indexname> on <relname>
2008 * using <access> "(" (<col> with <op>)+ ")" [with
2011 * [where <qual>] is not supported anymore
2012 *****************************************************************************/
2014 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
2015 access_method_clause '(' index_params ')' opt_with
2017 /* should check that access_method is valid,
2018 etc ... but doesn't */
2019 IndexStmt *n = makeNode(IndexStmt);
2023 n->accessMethod = $7;
2024 n->indexParams = $9;
2025 n->withClause = $11;
2026 n->whereClause = NULL;
2031 index_opt_unique: UNIQUE { $$ = TRUE; }
2032 | /*EMPTY*/ { $$ = FALSE; }
2035 access_method_clause: USING access_method { $$ = $2; }
2036 | /*EMPTY*/ { $$ = "btree"; }
2039 index_params: index_list { $$ = $1; }
2040 | func_index { $$ = lcons($1,NIL); }
2043 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
2044 | index_elem { $$ = lcons($1, NIL); }
2047 func_index: func_name '(' name_list ')' opt_type opt_class
2049 $$ = makeNode(IndexElem);
2057 index_elem: attr_name opt_type opt_class
2059 $$ = makeNode(IndexElem);
2067 opt_type: ':' Typename { $$ = $2; }
2068 | FOR Typename { $$ = $2; }
2069 | /*EMPTY*/ { $$ = NULL; }
2072 /* opt_class "WITH class" conflicts with preceeding opt_type
2073 * for Typename of "TIMESTAMP WITH TIME ZONE"
2074 * So, remove "WITH class" from the syntax. OK??
2075 * - thomas 1997-10-12
2076 * | WITH class { $$ = $2; }
2078 opt_class: class { $$ = $1; }
2079 | USING class { $$ = $2; }
2080 | /*EMPTY*/ { $$ = NULL; }
2084 /*****************************************************************************
2087 * extend index <indexname> [where <qual>]
2089 *****************************************************************************/
2091 ExtendStmt: EXTEND INDEX index_name where_clause
2093 ExtendStmt *n = makeNode(ExtendStmt);
2095 n->whereClause = $4;
2100 /*****************************************************************************
2103 * execute recipe <recipeName>
2105 *****************************************************************************/
2108 RecipeStmt: EXECUTE RECIPE recipe_name
2111 if (!IsTransactionBlock())
2112 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
2114 n = makeNode(RecipeStmt);
2121 /*****************************************************************************
2124 * define function <fname>
2125 * (language = <lang>, returntype = <typename>
2126 * [, arch_pct = <percentage | pre-defined>]
2127 * [, disk_pct = <percentage | pre-defined>]
2128 * [, byte_pct = <percentage | pre-defined>]
2129 * [, perbyte_cpu = <int | pre-defined>]
2130 * [, percall_cpu = <int | pre-defined>]
2132 * [arg is (<type-1> { , <type-n>})]
2133 * as <filename or code in language as appropriate>
2135 *****************************************************************************/
2137 ProcedureStmt: CREATE FUNCTION func_name func_args
2138 RETURNS func_return opt_with AS func_as LANGUAGE Sconst
2140 ProcedureStmt *n = makeNode(ProcedureStmt);
2150 opt_with: WITH definition { $$ = $2; }
2151 | /*EMPTY*/ { $$ = NIL; }
2154 func_args: '(' func_args_list ')' { $$ = $2; }
2155 | '(' ')' { $$ = NIL; }
2158 func_args_list: TypeId
2159 { $$ = lcons(makeString($1),NIL); }
2160 | func_args_list ',' TypeId
2161 { $$ = lappend($1,makeString($3)); }
2165 { $$ = lcons(makeString($1),NIL); }
2167 { $$ = lappend(lcons(makeString($1),NIL), makeString($3)); }
2170 func_return: set_opt TypeId
2172 TypeName *n = makeNode(TypeName);
2175 n->arrayBounds = NULL;
2180 set_opt: SETOF { $$ = TRUE; }
2181 | /*EMPTY*/ { $$ = FALSE; }
2184 /*****************************************************************************
2188 * remove function <funcname>
2189 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
2190 * remove aggregate <aggname>
2191 * (REMOVE AGGREGATE "aggname" "aggtype")
2192 * remove operator <opname>
2193 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
2194 * remove type <typename>
2195 * (REMOVE TYPE "typename")
2196 * remove rule <rulename>
2197 * (REMOVE RULE "rulename")
2199 *****************************************************************************/
2201 RemoveStmt: DROP remove_type name
2203 RemoveStmt *n = makeNode(RemoveStmt);
2210 remove_type: TYPE_P { $$ = TYPE_P; }
2211 | INDEX { $$ = INDEX; }
2212 | RULE { $$ = RULE; }
2213 | VIEW { $$ = VIEW; }
2217 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
2219 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
2226 aggr_argtype: name { $$ = $1; }
2227 | '*' { $$ = NULL; }
2231 RemoveFuncStmt: DROP FUNCTION func_name func_args
2233 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
2241 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
2243 RemoveOperStmt *n = makeNode(RemoveOperStmt);
2252 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
2255 { $$ = makeList(makeString($1), makeString($3), -1); }
2256 | NONE ',' name /* left unary */
2257 { $$ = makeList(NULL, makeString($3), -1); }
2258 | name ',' NONE /* right unary */
2259 { $$ = makeList(makeString($1), NULL, -1); }
2263 /*****************************************************************************
2266 * rename <attrname1> in <relname> [*] to <attrname2>
2267 * rename <relname1> to <relname2>
2269 *****************************************************************************/
2271 RenameStmt: ALTER TABLE relation_name opt_inh_star
2272 RENAME opt_column opt_name TO name
2274 RenameStmt *n = makeNode(RenameStmt);
2283 opt_name: name { $$ = $1; }
2284 | /*EMPTY*/ { $$ = NULL; }
2287 opt_column: COLUMN { $$ = COLUMN; }
2288 | /*EMPTY*/ { $$ = 0; }
2292 /*****************************************************************************
2294 * QUERY: Define Rewrite Rule , Define Tuple Rule
2295 * Define Rule <old rules >
2297 * only rewrite rule is supported -- ay 9/94
2299 *****************************************************************************/
2301 RuleStmt: CREATE RULE name AS
2302 { QueryIsRule=TRUE; }
2303 ON event TO event_object where_clause
2304 DO opt_instead RuleActionList
2306 RuleStmt *n = makeNode(RuleStmt);
2310 n->whereClause = $10;
2317 RuleActionList: NOTHING { $$ = NIL; }
2318 | SelectStmt { $$ = lcons($1, NIL); }
2319 | RuleActionStmt { $$ = lcons($1, NIL); }
2320 | '[' RuleActionMulti ']' { $$ = $2; }
2321 | '(' RuleActionMulti ')' { $$ = $2; }
2324 /* the thrashing around here is to discard "empty" statements... */
2325 RuleActionMulti: RuleActionMulti ';' RuleActionStmtOrEmpty
2326 { if ($3 != (Node *)NULL)
2327 $$ = lappend($1, $3);
2331 | RuleActionStmtOrEmpty
2332 { if ($1 != (Node *)NULL)
2339 RuleActionStmt: InsertStmt
2345 RuleActionStmtOrEmpty: RuleActionStmt
2347 { $$ = (Node *)NULL; }
2350 event_object: relation_name '.' attr_name
2352 $$ = makeNode(Attr);
2355 $$->attrs = lcons(makeString($3), NIL);
2356 $$->indirection = NIL;
2360 $$ = makeNode(Attr);
2364 $$->indirection = NIL;
2368 /* change me to select, update, etc. some day */
2369 event: SELECT { $$ = CMD_SELECT; }
2370 | UPDATE { $$ = CMD_UPDATE; }
2371 | DELETE { $$ = CMD_DELETE; }
2372 | INSERT { $$ = CMD_INSERT; }
2375 opt_instead: INSTEAD { $$ = TRUE; }
2376 | /*EMPTY*/ { $$ = FALSE; }
2380 /*****************************************************************************
2383 * NOTIFY <relation_name> can appear both in rule bodies and
2384 * as a query-level command
2386 *****************************************************************************/
2388 NotifyStmt: NOTIFY relation_name
2390 NotifyStmt *n = makeNode(NotifyStmt);
2396 ListenStmt: LISTEN relation_name
2398 ListenStmt *n = makeNode(ListenStmt);
2404 UnlistenStmt: UNLISTEN relation_name
2406 UnlistenStmt *n = makeNode(UnlistenStmt);
2412 UnlistenStmt *n = makeNode(UnlistenStmt);
2419 /*****************************************************************************
2430 *****************************************************************************/
2432 TransactionStmt: ABORT_TRANS opt_trans
2434 TransactionStmt *n = makeNode(TransactionStmt);
2435 n->command = ABORT_TRANS;
2438 | BEGIN_TRANS opt_trans
2440 TransactionStmt *n = makeNode(TransactionStmt);
2441 n->command = BEGIN_TRANS;
2446 TransactionStmt *n = makeNode(TransactionStmt);
2447 n->command = END_TRANS;
2450 | END_TRANS opt_trans
2452 TransactionStmt *n = makeNode(TransactionStmt);
2453 n->command = END_TRANS;
2456 | ROLLBACK opt_trans
2458 TransactionStmt *n = makeNode(TransactionStmt);
2459 n->command = ABORT_TRANS;
2464 opt_trans: WORK { $$ = TRUE; }
2465 | TRANSACTION { $$ = TRUE; }
2466 | /*EMPTY*/ { $$ = TRUE; }
2470 /*****************************************************************************
2473 * define view <viewname> '('target-list ')' [where <quals> ]
2475 *****************************************************************************/
2477 ViewStmt: CREATE VIEW name AS SelectStmt
2479 ViewStmt *n = makeNode(ViewStmt);
2481 n->query = (Query *)$5;
2482 if (((SelectStmt *)n->query)->sortClause != NULL)
2483 elog(ERROR,"Order by and Distinct on views is not implemented.");
2484 if (((SelectStmt *)n->query)->unionClause != NULL)
2485 elog(ERROR,"Views on unions not implemented.");
2486 if (((SelectStmt *)n->query)->forUpdate != NULL)
2487 elog(ERROR, "SELECT FOR UPDATE is not allowed in CREATE VIEW");
2493 /*****************************************************************************
2498 *****************************************************************************/
2500 LoadStmt: LOAD file_name
2502 LoadStmt *n = makeNode(LoadStmt);
2509 /*****************************************************************************
2514 *****************************************************************************/
2516 CreatedbStmt: CREATE DATABASE database_name WITH opt_database1 opt_database2
2518 CreatedbStmt *n = makeNode(CreatedbStmt);
2519 if ($5 == NULL && $6 == NULL) {
2520 elog(ERROR, "CREATE DATABASE WITH requires at least an option");
2526 n->encoding = pg_char_to_encoding($6);
2527 if (n->encoding < 0) {
2528 elog(ERROR, "invalid encoding name %s", $6);
2531 n->encoding = GetTemplateEncoding();
2535 elog(ERROR, "WITH ENCODING is not supported");
2540 | CREATE DATABASE database_name
2542 CreatedbStmt *n = makeNode(CreatedbStmt);
2546 n->encoding = GetTemplateEncoding();
2554 opt_database1: LOCATION '=' location { $$ = $3; }
2555 | /*EMPTY*/ { $$ = NULL; }
2558 opt_database2: ENCODING '=' encoding { $$ = $3; }
2559 | /*EMPTY*/ { $$ = NULL; }
2562 location: Sconst { $$ = $1; }
2563 | DEFAULT { $$ = NULL; }
2564 | /*EMPTY*/ { $$ = NULL; }
2567 encoding: Sconst { $$ = $1; }
2568 | DEFAULT { $$ = NULL; }
2569 | /*EMPTY*/ { $$ = NULL; }
2572 /*****************************************************************************
2577 *****************************************************************************/
2579 DropdbStmt: DROP DATABASE database_name
2581 DropdbStmt *n = makeNode(DropdbStmt);
2588 /*****************************************************************************
2591 * cluster <index_name> on <relation_name>
2593 *****************************************************************************/
2595 ClusterStmt: CLUSTER index_name ON relation_name
2597 ClusterStmt *n = makeNode(ClusterStmt);
2604 /*****************************************************************************
2609 *****************************************************************************/
2611 VacuumStmt: VACUUM opt_verbose opt_analyze
2613 VacuumStmt *n = makeNode(VacuumStmt);
2620 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2622 VacuumStmt *n = makeNode(VacuumStmt);
2627 if ( $5 != NIL && !$4 )
2628 elog(ERROR,"parser: syntax error at or near \"(\"");
2633 opt_verbose: VERBOSE { $$ = TRUE; }
2634 | /*EMPTY*/ { $$ = FALSE; }
2637 opt_analyze: ANALYZE { $$ = TRUE; }
2638 | /*EMPTY*/ { $$ = FALSE; }
2641 opt_va_list: '(' va_list ')' { $$ = $2; }
2642 | /*EMPTY*/ { $$ = NIL; }
2646 { $$=lcons($1,NIL); }
2648 { $$=lappend($1,$3); }
2652 /*****************************************************************************
2657 *****************************************************************************/
2659 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2661 ExplainStmt *n = makeNode(ExplainStmt);
2663 n->query = (Query*)$3;
2669 /*****************************************************************************
2671 * Optimizable Stmts: *
2673 * one of the five queries processed by the planner *
2675 * [ultimately] produces query-trees as specified *
2676 * in the query-spec document in ~postgres/ref *
2678 *****************************************************************************/
2680 OptimizableStmt: SelectStmt
2685 | DeleteStmt /* by default all are $$=$1 */
2689 /*****************************************************************************
2694 *****************************************************************************/
2696 /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
2697 * originally. When the second rule of 'insert_rest' was changed to use the
2698 * new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
2699 * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to
2700 * accept the same statements without any shift/reduce conflicts
2702 InsertStmt: INSERT INTO relation_name insert_rest
2709 insert_rest: VALUES '(' target_list ')'
2711 $$ = makeNode(InsertStmt);
2714 $$->targetList = $3;
2715 $$->fromClause = NIL;
2716 $$->whereClause = NULL;
2717 $$->groupClause = NIL;
2718 $$->havingClause = NULL;
2719 $$->unionClause = NIL;
2723 $$ = makeNode(InsertStmt);
2725 $$->targetList = NIL;
2726 $$->fromClause = NIL;
2727 $$->whereClause = NULL;
2728 $$->groupClause = NIL;
2729 $$->havingClause = NULL;
2730 $$->unionClause = NIL;
2731 $$->intersectClause = NIL;
2733 /* We want the full power of SelectStatements including INTERSECT and EXCEPT
2734 * for insertion. However, we can't support sort or limit clauses.
2738 SelectStmt *n = (SelectStmt *) $1;
2740 elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
2741 $$ = makeNode(InsertStmt);
2743 $$->unique = n->unique;
2744 $$->targetList = n->targetList;
2745 $$->fromClause = n->fromClause;
2746 $$->whereClause = n->whereClause;
2747 $$->groupClause = n->groupClause;
2748 $$->havingClause = n->havingClause;
2749 $$->unionClause = n->unionClause;
2750 $$->intersectClause = n->intersectClause;
2751 $$->unionall = n->unionall;
2752 $$->forUpdate = n->forUpdate;
2754 | '(' columnList ')' VALUES '(' target_list ')'
2756 $$ = makeNode(InsertStmt);
2759 $$->targetList = $6;
2760 $$->fromClause = NIL;
2761 $$->whereClause = NULL;
2762 $$->groupClause = NIL;
2763 $$->havingClause = NULL;
2764 $$->unionClause = NIL;
2765 $$->intersectClause = NIL;
2767 | '(' columnList ')' SelectStmt
2769 SelectStmt *n = (SelectStmt *) $4;
2771 elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
2772 $$ = makeNode(InsertStmt);
2774 $$->unique = n->unique;
2775 $$->targetList = n->targetList;
2776 $$->fromClause = n->fromClause;
2777 $$->whereClause = n->whereClause;
2778 $$->groupClause = n->groupClause;
2779 $$->havingClause = n->havingClause;
2780 $$->unionClause = n->unionClause;
2781 $$->intersectClause = n->intersectClause;
2782 $$->unionall = n->unionall;
2783 $$->forUpdate = n->forUpdate;
2787 opt_column_list: '(' columnList ')' { $$ = $2; }
2788 | /*EMPTY*/ { $$ = NIL; }
2792 columnList ',' columnElem
2793 { $$ = lappend($1, $3); }
2795 { $$ = lcons($1, NIL); }
2798 columnElem: ColId opt_indirection
2800 Ident *id = makeNode(Ident);
2802 id->indirection = $2;
2808 /*****************************************************************************
2813 *****************************************************************************/
2815 DeleteStmt: DELETE FROM relation_name
2818 DeleteStmt *n = makeNode(DeleteStmt);
2820 n->whereClause = $4;
2825 LockStmt: LOCK_P opt_table relation_name opt_lock
2827 LockStmt *n = makeNode(LockStmt);
2835 opt_lock: IN lock_type MODE { $$ = $2; }
2836 | /*EMPTY*/ { $$ = AccessExclusiveLock; }
2839 lock_type: SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; }
2840 | ROW opt_lmode { $$ = ($2? RowShareLock: RowExclusiveLock); }
2841 | ACCESS opt_lmode { $$ = ($2? AccessShareLock: AccessExclusiveLock); }
2842 | opt_lmode { $$ = ($1? ShareLock: ExclusiveLock); }
2845 opt_lmode: SHARE { $$ = TRUE; }
2846 | EXCLUSIVE { $$ = FALSE; }
2850 /*****************************************************************************
2853 * UpdateStmt (UPDATE)
2855 *****************************************************************************/
2857 UpdateStmt: UPDATE relation_name
2858 SET update_target_list
2862 UpdateStmt *n = makeNode(UpdateStmt);
2866 n->whereClause = $6;
2872 /*****************************************************************************
2877 *****************************************************************************/
2878 CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
2882 n= (SelectStmt *)$6;
2883 /* from PORTAL name */
2885 * 15 august 1991 -- since 3.0 postgres does locking
2886 * right, we discovered that portals were violating
2887 * locking protocol. portal locks cannot span xacts.
2888 * as a short-term fix, we installed the check here.
2891 if (!IsTransactionBlock())
2892 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2896 if (n->forUpdate != NULL)
2897 elog(ERROR,"DECLARE/UPDATE not supported;"
2898 " Cursors must be READ ONLY.");
2903 opt_cursor: BINARY { $$ = TRUE; }
2904 | INSENSITIVE { $$ = FALSE; }
2905 | SCROLL { $$ = FALSE; }
2906 | INSENSITIVE SCROLL { $$ = FALSE; }
2907 | /*EMPTY*/ { $$ = FALSE; }
2910 /*****************************************************************************
2915 *****************************************************************************/
2917 /* A complete SELECT statement looks like this. Note sort, for_update,
2918 * and limit clauses can only appear once, not in each subselect.
2920 * The rule returns a SelectStmt Node having the set operations attached to
2921 * unionClause and intersectClause (NIL if no set operations were present)
2924 SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
2926 if IsA($1, SelectStmt)
2928 /* There were no set operations, so just attach the
2931 SelectStmt *n = (SelectStmt *) $1;
2934 n->limitOffset = nth(0, $4);
2935 n->limitCount = nth(1, $4);
2940 /* There were set operations. The root of the operator
2941 * tree is delivered by $1, but we must hand back a
2942 * SelectStmt node not an A_Expr Node.
2943 * So we find the leftmost 'SelectStmt' in the operator
2944 * tree $1 (which is the first Select Statement in the
2945 * query), which will be the returned node.
2946 * Then we attach the whole operator tree to that node's
2947 * 'intersectClause', and a list of all 'SelectStmt' Nodes
2948 * in the tree to its 'unionClause'. (NOTE that this means
2949 * the top node has indirect recursive pointers to itself!
2950 * This would cause trouble if we tried copyObject!!)
2951 * The intersectClause and unionClause subtrees will be
2952 * left untouched by the main parser, and will only be
2953 * processed when control gets to the function
2954 * Except_Intersect_Rewrite() (in rewriteHandler.c).
2956 Node *op = (Node *) $1;
2957 List *select_list = NIL;
2958 SelectStmt *first_select;
2959 bool intersect_present = false,
2960 unionall_present = false;
2962 /* Take the operator tree as an argument and create a
2963 * list of all SelectStmt Nodes found in the tree.
2965 * If one of the SelectStmt Nodes has the 'unionall' flag
2966 * set to true the 'unionall_present' flag is also set to
2969 create_select_list(op, &select_list, &unionall_present);
2971 /* Replace all the A_Expr Nodes in the operator tree by
2974 * If an INTERSECT or an EXCEPT is present, the
2975 * 'intersect_present' flag is set to true
2977 op = A_Expr_to_Expr(op, &intersect_present);
2979 /* If both flags are set to true we have a UNION ALL
2980 * statement mixed up with INTERSECT or EXCEPT
2981 * which can not be handled at the moment.
2983 if (intersect_present && unionall_present)
2984 elog(ERROR, "UNION ALL not allowed in mixed set operations");
2986 /* Get the leftmost SeletStmt Node (which automatically
2987 * represents the first Select Statement of the query!)
2989 first_select = (SelectStmt *) lfirst(select_list);
2991 /* Attach the list of all SeletStmt Nodes to unionClause */
2992 first_select->unionClause = select_list;
2994 /* Attach the whole operator tree to intersectClause */
2995 first_select->intersectClause = (List *) op;
2997 /* finally attach the sort clause &etc */
2998 first_select->sortClause = $2;
2999 first_select->forUpdate = $3;
3000 first_select->limitOffset = nth(0, $4);
3001 first_select->limitCount = nth(1, $4);
3002 $$ = (Node *) first_select;
3004 if (((SelectStmt *)$$)->forUpdate != NULL && QueryIsRule)
3005 elog(ERROR, "SELECT FOR UPDATE is not allowed in RULES");
3009 /* This rule parses Select statements that can appear within set operations,
3010 * including UNION, INTERSECT and EXCEPT. '(' and ')' can be used to specify
3011 * the ordering of the set operations. Without '(' and ')' we want the
3012 * operations to be left associative.
3014 * Note that sort clauses cannot be included at this level --- a sort clause
3015 * can only appear at the end of the complete Select, and it will be handled
3016 * by the topmost SelectStmt rule. Likewise FOR UPDATE and LIMIT.
3018 * The rule builds up an operator tree using A_Expr Nodes. AND Nodes represent
3019 * INTERSECTs, OR Nodes represent UNIONs, and AND NOT nodes represent EXCEPTs.
3020 * The SelectStatements to be connected are the left and right arguments to
3022 * If no set operations appear in the query, the tree consists only of one
3025 select_clause: '(' select_clause ')'
3033 | select_clause EXCEPT select_clause
3035 $$ = (Node *)makeA_Expr(AND,NULL,$1,
3036 makeA_Expr(NOT,NULL,NULL,$3));
3038 | select_clause UNION opt_all select_clause
3040 if (IsA($4, SelectStmt))
3042 SelectStmt *n = (SelectStmt *)$4;
3044 /* NOTE: if UNION ALL appears with a parenthesized set
3045 * operation to its right, the ALL is silently discarded.
3046 * Should we generate an error instead? I think it may
3047 * be OK since ALL with UNION to its right is ignored
3051 $$ = (Node *)makeA_Expr(OR,NULL,$1,$4);
3053 | select_clause INTERSECT select_clause
3055 $$ = (Node *)makeA_Expr(AND,NULL,$1,$3);
3059 SubSelect: SELECT opt_unique target_list
3060 result from_clause where_clause
3061 group_clause having_clause
3063 SelectStmt *n = makeNode(SelectStmt);
3065 n->unionall = FALSE;
3067 /* This is new: Subselects support the INTO clause
3068 * which allows queries that are not part of the
3069 * SQL92 standard and should not be formulated!
3070 * We need it for INTERSECT and EXCEPT and I did not
3071 * want to create a new rule 'SubSelect1' including the
3072 * feature. If it makes troubles we will have to add
3073 * a new rule and change this to prevent INTOs in
3076 n->istemp = (bool) ((Value *) lfirst($4))->val.ival;
3077 n->into = (char *) lnext($4);
3080 n->whereClause = $6;
3081 n->groupClause = $7;
3082 n->havingClause = $8;
3087 /* easy way to return two values. Can someone improve this? bjm */
3088 result: INTO OptTemp opt_table relation_name { $$ = lcons(makeInteger($2), (List *)$4); }
3089 | /*EMPTY*/ { $$ = lcons(makeInteger(false), NIL); }
3092 opt_table: TABLE { $$ = TRUE; }
3093 | /*EMPTY*/ { $$ = FALSE; }
3096 opt_all: ALL { $$ = TRUE; }
3097 | /*EMPTY*/ { $$ = FALSE; }
3100 opt_unique: DISTINCT { $$ = "*"; }
3101 | DISTINCT ON ColId { $$ = $3; }
3102 | ALL { $$ = NULL; }
3103 | /*EMPTY*/ { $$ = NULL; }
3106 sort_clause: ORDER BY sortby_list { $$ = $3; }
3107 | /*EMPTY*/ { $$ = NIL; }
3110 sortby_list: sortby { $$ = lcons($1, NIL); }
3111 | sortby_list ',' sortby { $$ = lappend($1, $3); }
3114 sortby: a_expr OptUseOp
3116 $$ = makeNode(SortGroupBy);
3122 OptUseOp: USING all_Op { $$ = $2; }
3124 | DESC { $$ = ">"; }
3125 | /*EMPTY*/ { $$ = "<"; /*default*/ }
3129 opt_select_limit: LIMIT select_limit_value ',' select_offset_value
3130 { $$ = lappend(lappend(NIL, $4), $2); }
3131 | LIMIT select_limit_value OFFSET select_offset_value
3132 { $$ = lappend(lappend(NIL, $4), $2); }
3133 | LIMIT select_limit_value
3134 { $$ = lappend(lappend(NIL, NULL), $2); }
3135 | OFFSET select_offset_value LIMIT select_limit_value
3136 { $$ = lappend(lappend(NIL, $2), $4); }
3137 | OFFSET select_offset_value
3138 { $$ = lappend(lappend(NIL, $2), NULL); }
3140 { $$ = lappend(lappend(NIL, NULL), NULL); }
3143 select_limit_value: Iconst
3145 Const *n = makeNode(Const);
3148 elog(ERROR, "selection limit must be ALL or a positive integer value > 0");
3150 n->consttype = INT4OID;
3151 n->constlen = sizeof(int4);
3152 n->constvalue = (Datum)$1;
3153 n->constisnull = FALSE;
3154 n->constbyval = TRUE;
3155 n->constisset = FALSE;
3156 n->constiscast = FALSE;
3161 Const *n = makeNode(Const);
3163 n->consttype = INT4OID;
3164 n->constlen = sizeof(int4);
3165 n->constvalue = (Datum)0;
3166 n->constisnull = FALSE;
3167 n->constbyval = TRUE;
3168 n->constisset = FALSE;
3169 n->constiscast = FALSE;
3174 Param *n = makeNode(Param);
3176 n->paramkind = PARAM_NUM;
3178 n->paramtype = INT4OID;
3183 select_offset_value: Iconst
3185 Const *n = makeNode(Const);
3187 n->consttype = INT4OID;
3188 n->constlen = sizeof(int4);
3189 n->constvalue = (Datum)$1;
3190 n->constisnull = FALSE;
3191 n->constbyval = TRUE;
3192 n->constisset = FALSE;
3193 n->constiscast = FALSE;
3198 Param *n = makeNode(Param);
3200 n->paramkind = PARAM_NUM;
3202 n->paramtype = INT4OID;
3207 * jimmy bell-style recursive queries aren't supported in the
3210 * ...however, recursive addattr and rename supported. make special
3213 opt_inh_star: '*' { $$ = TRUE; }
3214 | /*EMPTY*/ { $$ = FALSE; }
3217 relation_name_list: name_list;
3220 { $$ = lcons(makeString($1),NIL); }
3221 | name_list ',' name
3222 { $$ = lappend($1,makeString($3)); }
3225 group_clause: GROUP BY expr_list { $$ = $3; }
3226 | /*EMPTY*/ { $$ = NIL; }
3229 having_clause: HAVING a_expr
3233 | /*EMPTY*/ { $$ = NULL; }
3236 for_update_clause: FOR UPDATE update_list { $$ = $3; }
3237 | FOR READ ONLY { $$ = NULL; }
3238 | /* EMPTY */ { $$ = NULL; }
3241 update_list: OF va_list { $$ = $2; }
3242 | /* EMPTY */ { $$ = lcons(NULL, NULL); }
3245 /*****************************************************************************
3247 * clauses common to all Optimizable Stmts:
3251 *****************************************************************************/
3253 from_clause: FROM from_expr { $$ = $2; }
3254 | /*EMPTY*/ { $$ = NIL; }
3257 from_expr: '(' join_clause_with_union ')'
3265 table_list: table_list ',' table_expr
3266 { $$ = lappend($1, $3); }
3268 { $$ = lcons($1, NIL); }
3271 table_expr: relation_expr AS ColLabel
3273 $$ = makeNode(RangeVar);
3277 | relation_expr ColId
3279 $$ = makeNode(RangeVar);
3285 $$ = makeNode(RangeVar);
3291 /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
3292 * all result rows which would have matched on an INNER JOIN.
3293 * Let's reject this for now. - thomas 1999-01-08
3295 join_clause_with_union: join_clause
3297 | table_expr UNION JOIN table_expr
3298 { elog(ERROR,"UNION JOIN not yet implemented"); }
3301 join_clause: table_expr join_list
3303 Node *n = lfirst($2);
3305 /* JoinExpr came back? then it is a join of some sort...
3307 if (IsA(n, JoinExpr))
3309 JoinExpr *j = (JoinExpr *)n;
3313 /* otherwise, it was a cross join,
3314 * which we just represent as an inner join...
3321 join_list: join_list join_expr
3323 $$ = lappend($1, $2);
3327 $$ = lcons($1, NIL);
3331 /* This is everything but the left side of a join.
3332 * Note that a CROSS JOIN is the same as an unqualified
3333 * inner join, so just pass back the right-side table.
3334 * A NATURAL JOIN implicitly matches column names between
3335 * tables, so we'll collect those during the later transformation.
3337 join_expr: join_type JOIN table_expr join_qual
3339 JoinExpr *n = makeNode(JoinExpr);
3341 n->rarg = (Node *)$3;
3345 | NATURAL join_type JOIN table_expr
3347 JoinExpr *n = makeNode(JoinExpr);
3349 n->rarg = (Node *)$4;
3350 n->quals = NULL; /* figure out which columns later... */
3353 | CROSS JOIN table_expr
3354 { $$ = (Node *)$3; }
3357 /* OUTER is just noise... */
3358 join_type: FULL join_outer
3361 elog(NOTICE,"FULL OUTER JOIN not yet implemented");
3366 elog(NOTICE,"LEFT OUTER JOIN not yet implemented");
3371 elog(NOTICE,"RIGHT OUTER JOIN not yet implemented");
3376 elog(NOTICE,"OUTER JOIN not yet implemented");
3388 join_outer: OUTER_P { $$ = NULL; }
3389 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
3392 /* JOIN qualification clauses
3393 * Possibilities are:
3394 * USING ( column list ) allows only unqualified column names,
3395 * which must match between tables.
3396 * ON expr allows more general qualifications.
3397 * - thomas 1999-01-07
3400 join_qual: USING '(' using_list ')' { $$ = $3; }
3401 | ON a_expr { $$ = lcons($2, NIL); }
3404 using_list: using_list ',' using_expr { $$ = lappend($1, $3); }
3405 | using_expr { $$ = lcons($1, NIL); }
3410 /* could be a column name or a relation_name */
3411 Ident *n = makeNode(Ident);
3413 n->indirection = NULL;
3418 where_clause: WHERE a_expr { $$ = $2; }
3419 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
3422 relation_expr: relation_name
3424 /* normal relations */
3425 $$ = makeNode(RelExpr);
3429 | relation_name '*' %prec '='
3431 /* inheritance query */
3432 $$ = makeNode(RelExpr);
3437 opt_array_bounds: '[' ']' opt_array_bounds
3438 { $$ = lcons(makeInteger(-1), $3); }
3439 | '[' Iconst ']' opt_array_bounds
3440 { $$ = lcons(makeInteger($2), $4); }
3446 /*****************************************************************************
3449 * SQL92 introduces a large amount of type-specific syntax.
3450 * Define individual clauses to handle these cases, and use
3451 * the generic case to handle regular type-extensible Postgres syntax.
3452 * - thomas 1997-10-10
3454 *****************************************************************************/
3456 Typename: SimpleTypename opt_array_bounds
3459 $$->arrayBounds = $2;
3461 /* Is this the name of a complex type? If so, implement
3464 if (!strcmp(saved_relname, $$->name))
3465 /* This attr is the same type as the relation
3466 * being defined. The classic example: create
3467 * emp(name=text,mgr=emp)
3470 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
3471 /* (Eventually add in here that the set can only
3472 * contain one element.)
3478 | SETOF SimpleTypename
3485 SimpleTypename: Generic
3493 $$ = makeNode(TypeName);
3494 $$->name = xlateSqlType($1);
3499 generic: IDENT { $$ = $1; }
3500 | TYPE_P { $$ = "type"; }
3503 /* SQL92 numeric data types
3504 * Check FLOAT() precision limits assuming IEEE floating types.
3505 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3506 * - thomas 1997-09-18
3508 Numeric: FLOAT opt_float
3510 $$ = makeNode(TypeName);
3511 $$->name = xlateSqlType($2);
3516 $$ = makeNode(TypeName);
3517 $$->name = xlateSqlType("float");
3519 | DECIMAL opt_decimal
3521 $$ = makeNode(TypeName);
3522 $$->name = xlateSqlType("numeric");
3525 | NUMERIC opt_numeric
3527 $$ = makeNode(TypeName);
3528 $$->name = xlateSqlType("numeric");
3534 { $$ = xlateSqlType("float8"); }
3536 { $$ = xlateSqlType("float8"); }
3538 { $$ = xlateSqlType("numeric"); }
3540 { $$ = xlateSqlType("numeric"); }
3543 opt_float: '(' Iconst ')'
3546 elog(ERROR,"precision for FLOAT must be at least 1");
3548 $$ = xlateSqlType("float4");
3550 $$ = xlateSqlType("float8");
3552 elog(ERROR,"precision for FLOAT must be less than 16");
3556 $$ = xlateSqlType("float8");
3560 opt_numeric: '(' Iconst ',' Iconst ')'
3562 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3563 elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
3564 $2, NUMERIC_MAX_PRECISION);
3565 if ($4 < 0 || $4 > $2)
3566 elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
3569 $$ = (($2 << 16) | $4) + VARHDRSZ;
3573 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3574 elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
3575 $2, NUMERIC_MAX_PRECISION);
3577 $$ = ($2 << 16) + VARHDRSZ;
3581 $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
3585 opt_decimal: '(' Iconst ',' Iconst ')'
3587 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3588 elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
3589 $2, NUMERIC_MAX_PRECISION);
3590 if ($4 < 0 || $4 > $2)
3591 elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d",
3594 $$ = (($2 << 16) | $4) + VARHDRSZ;
3598 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3599 elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
3600 $2, NUMERIC_MAX_PRECISION);
3602 $$ = ($2 << 16) + VARHDRSZ;
3606 $$ = ((NUMERIC_DEFAULT_PRECISION << 16) | NUMERIC_DEFAULT_SCALE) + VARHDRSZ;
3611 /* SQL92 character data types
3612 * The following implements CHAR() and VARCHAR().
3614 Character: character '(' Iconst ')'
3616 $$ = makeNode(TypeName);
3617 if (strcasecmp($1, "char") == 0)
3618 $$->name = xlateSqlType("bpchar");
3619 else if (strcasecmp($1, "varchar") == 0)
3620 $$->name = xlateSqlType("varchar");
3622 yyerror("internal parsing error; unrecognized character type");
3625 elog(ERROR,"length for '%s' type must be at least 1",$1);
3626 else if ($3 > MaxAttrSize)
3627 elog(ERROR,"length for type '%s' cannot exceed %d",$1,
3630 /* we actually implement this sort of like a varlen, so
3631 * the first 4 bytes is the length. (the difference
3632 * between this and "text" is that we blank-pad and
3633 * truncate where necessary
3635 $$->typmod = VARHDRSZ + $3;
3639 $$ = makeNode(TypeName);
3640 /* Let's try to make all single-character types into bpchar(1)
3641 * - thomas 1998-05-07
3643 if (strcasecmp($1, "char") == 0)
3645 $$->name = xlateSqlType("bpchar");
3646 $$->typmod = VARHDRSZ + 1;
3650 $$->name = xlateSqlType($1);
3656 character: CHARACTER opt_varying opt_charset opt_collate
3659 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
3660 if ($2) type = xlateSqlType("varchar");
3661 else type = xlateSqlType("char");
3664 c = palloc(strlen("var") + strlen($3) + 1);
3667 type = xlateSqlType(c);
3669 type = xlateSqlType($3);
3673 elog(NOTICE,"COLLATE %s not yet implemented; clause ignored",$4);
3676 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
3677 | VARCHAR { $$ = xlateSqlType("varchar"); }
3678 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
3679 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
3682 opt_varying: VARYING { $$ = TRUE; }
3683 | /*EMPTY*/ { $$ = FALSE; }
3686 opt_charset: CHARACTER SET ColId { $$ = $3; }
3687 | /*EMPTY*/ { $$ = NULL; }
3690 opt_collate: COLLATE ColId { $$ = $2; }
3691 | /*EMPTY*/ { $$ = NULL; }
3696 $$ = makeNode(TypeName);
3697 $$->name = xlateSqlType($1);
3700 | TIMESTAMP opt_timezone
3702 $$ = makeNode(TypeName);
3703 $$->name = xlateSqlType("timestamp");
3709 $$ = makeNode(TypeName);
3710 $$->name = xlateSqlType("time");
3713 | INTERVAL opt_interval
3715 $$ = makeNode(TypeName);
3716 $$->name = xlateSqlType("interval");
3721 datetime: YEAR_P { $$ = "year"; }
3722 | MONTH_P { $$ = "month"; }
3723 | DAY_P { $$ = "day"; }
3724 | HOUR_P { $$ = "hour"; }
3725 | MINUTE_P { $$ = "minute"; }
3726 | SECOND_P { $$ = "second"; }
3729 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
3730 | /*EMPTY*/ { $$ = FALSE; }
3733 opt_interval: datetime { $$ = lcons($1, NIL); }
3734 | YEAR_P TO MONTH_P { $$ = NIL; }
3735 | DAY_P TO HOUR_P { $$ = NIL; }
3736 | DAY_P TO MINUTE_P { $$ = NIL; }
3737 | DAY_P TO SECOND_P { $$ = NIL; }
3738 | HOUR_P TO MINUTE_P { $$ = NIL; }
3739 | HOUR_P TO SECOND_P { $$ = NIL; }
3740 | MINUTE_P TO SECOND_P { $$ = NIL; }
3741 | /*EMPTY*/ { $$ = NIL; }
3745 /*****************************************************************************
3747 * expression grammar
3749 *****************************************************************************/
3751 a_expr_or_null: a_expr
3755 A_Const *n = makeNode(A_Const);
3756 n->val.type = T_Null;
3761 /* Expressions using row descriptors
3762 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3763 * with singleton expressions.
3765 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3767 SubLink *n = makeNode(SubLink);
3769 n->oper = lcons("=", NIL);
3771 n->subLinkType = ANY_SUBLINK;
3775 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3777 SubLink *n = makeNode(SubLink);
3779 n->oper = lcons("<>", NIL);
3781 n->subLinkType = ALL_SUBLINK;
3785 | '(' row_descriptor ')' all_Op sub_type '(' SubSelect ')'
3787 SubLink *n = makeNode(SubLink);
3789 n->oper = lcons($4, NIL);
3790 if (strcmp($4,"<>") == 0)
3794 n->subLinkType = $5;
3798 | '(' row_descriptor ')' all_Op '(' SubSelect ')'
3800 SubLink *n = makeNode(SubLink);
3802 n->oper = lcons($4, NIL);
3803 if (strcmp($4,"<>") == 0)
3807 n->subLinkType = MULTIEXPR_SUBLINK;
3811 | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
3813 $$ = makeRowExpr($4, $2, $6);
3817 row_descriptor: row_list ',' a_expr
3819 $$ = lappend($1, $3);
3823 row_list: row_list ',' a_expr
3825 $$ = lappend($1, $3);
3829 $$ = lcons($1, NIL);
3833 sub_type: ANY { $$ = ANY_SUBLINK; }
3834 | ALL { $$ = ALL_SUBLINK; }
3837 all_Op: Op | MathOp;
3839 MathOp: '+' { $$ = "+"; }
3852 * General expressions
3853 * This is the heart of the expression syntax.
3855 * We have two expression types: a_expr is the unrestricted kind, and
3856 * b_expr is a subset that must be used in some places to avoid shift/reduce
3857 * conflicts. For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
3858 * because that use of AND conflicts with AND as a boolean operator. So,
3859 * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
3861 * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
3862 * always be used by surrounding it with parens.
3864 * com_expr is all the productions that are common to a_expr and b_expr;
3865 * it's factored out just to eliminate redundant coding.
3869 | a_expr TYPECAST Typename
3872 /* AexprConst can be either A_Const or ParamNo */
3873 if (nodeTag($1) == T_A_Const) {
3874 ((A_Const *)$1)->typename = $3;
3875 } else if (nodeTag($1) == T_ParamNo) {
3876 ((ParamNo *)$1)->typename = $3;
3877 /* otherwise, try to transform to a function call */
3879 FuncCall *n = makeNode(FuncCall);
3880 n->funcname = $3->name;
3881 n->args = lcons($1,NIL);
3882 n->agg_star = false;
3883 n->agg_distinct = false;
3888 * Can't collapse this into prior rule by using a_expr_or_null;
3889 * that creates reduce/reduce conflicts. Grumble.
3891 | NULL_P TYPECAST Typename
3893 A_Const *n = makeNode(A_Const);
3894 n->val.type = T_Null;
3899 * These operators must be called out explicitly in order to make use
3900 * of yacc/bison's automatic operator-precedence handling. All other
3901 * operator names are handled by the generic productions using "Op",
3902 * below; and all those operators will have the same precedence.
3904 * If you add more explicitly-known operators, be sure to add them
3905 * also to b_expr and to the MathOp list above.
3907 | '-' a_expr %prec UMINUS
3908 { $$ = doNegate($2); }
3910 { $$ = makeA_Expr(OP, "%", NULL, $2); }
3912 { $$ = makeA_Expr(OP, "^", NULL, $2); }
3914 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3916 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3918 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3920 { $$ = makeA_Expr(OP, "%", $1, NULL); }
3922 { $$ = makeA_Expr(OP, "^", $1, NULL); }
3924 { $$ = makeA_Expr(OP, "|", $1, NULL); }
3926 { $$ = makeA_Expr(OP, "+", $1, $3); }
3928 { $$ = makeA_Expr(OP, "-", $1, $3); }
3930 { $$ = makeA_Expr(OP, "*", $1, $3); }
3932 { $$ = makeA_Expr(OP, "/", $1, $3); }
3934 { $$ = makeA_Expr(OP, "%", $1, $3); }
3936 { $$ = makeA_Expr(OP, "^", $1, $3); }
3938 { $$ = makeA_Expr(OP, "|", $1, $3); }
3940 { $$ = makeA_Expr(OP, "<", $1, $3); }
3942 { $$ = makeA_Expr(OP, ">", $1, $3); }
3945 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3946 /* We allow this for standards-broken SQL products, like MS stuff */
3948 { $$ = makeA_Expr(ISNULL, NULL, $3, NULL); }
3951 { $$ = makeA_Expr(OP, "=", $1, $3); }
3954 { $$ = makeA_Expr(OP, $2, $1, $3); }
3956 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3958 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3961 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3963 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3965 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3967 | a_expr LIKE a_expr
3968 { $$ = makeA_Expr(OP, "~~", $1, $3); }
3969 | a_expr NOT LIKE a_expr
3970 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3973 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3975 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3977 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3978 | a_expr IS NOT NULL_P
3979 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3980 /* IS TRUE, IS FALSE, etc used to be function calls
3981 * but let's make them expressions to allow the optimizer
3982 * a chance to eliminate them if a_expr is a constant string.
3983 * - thomas 1997-12-22
3987 A_Const *n = makeNode(A_Const);
3988 n->val.type = T_String;
3989 n->val.val.str = "t";
3990 n->typename = makeNode(TypeName);
3991 n->typename->name = xlateSqlType("bool");
3992 n->typename->typmod = -1;
3993 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3995 | a_expr IS NOT FALSE_P
3997 A_Const *n = makeNode(A_Const);
3998 n->val.type = T_String;
3999 n->val.val.str = "t";
4000 n->typename = makeNode(TypeName);
4001 n->typename->name = xlateSqlType("bool");
4002 n->typename->typmod = -1;
4003 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4007 A_Const *n = makeNode(A_Const);
4008 n->val.type = T_String;
4009 n->val.val.str = "f";
4010 n->typename = makeNode(TypeName);
4011 n->typename->name = xlateSqlType("bool");
4012 n->typename->typmod = -1;
4013 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4015 | a_expr IS NOT TRUE_P
4017 A_Const *n = makeNode(A_Const);
4018 n->val.type = T_String;
4019 n->val.val.str = "f";
4020 n->typename = makeNode(TypeName);
4021 n->typename->name = xlateSqlType("bool");
4022 n->typename->typmod = -1;
4023 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4025 | a_expr BETWEEN b_expr AND b_expr
4027 $$ = makeA_Expr(AND, NULL,
4028 makeA_Expr(OP, ">=", $1, $3),
4029 makeA_Expr(OP, "<=", $1, $5));
4031 | a_expr NOT BETWEEN b_expr AND b_expr
4033 $$ = makeA_Expr(OR, NULL,
4034 makeA_Expr(OP, "<", $1, $4),
4035 makeA_Expr(OP, ">", $1, $6));
4037 | a_expr IN '(' in_expr ')'
4039 /* in_expr returns a SubLink or a list of a_exprs */
4040 if (IsA($4, SubLink))
4042 SubLink *n = (SubLink *)$4;
4043 n->lefthand = lcons($1, NIL);
4044 n->oper = lcons("=", NIL);
4046 n->subLinkType = ANY_SUBLINK;
4053 foreach(l, (List *) $4)
4055 Node *cmp = makeA_Expr(OP, "=", $1, lfirst(l));
4059 n = makeA_Expr(OR, NULL, n, cmp);
4064 | a_expr NOT IN '(' in_expr ')'
4066 /* in_expr returns a SubLink or a list of a_exprs */
4067 if (IsA($5, SubLink))
4069 SubLink *n = (SubLink *)$5;
4070 n->lefthand = lcons($1, NIL);
4071 n->oper = lcons("<>", NIL);
4073 n->subLinkType = ALL_SUBLINK;
4080 foreach(l, (List *) $5)
4082 Node *cmp = makeA_Expr(OP, "<>", $1, lfirst(l));
4086 n = makeA_Expr(AND, NULL, n, cmp);
4091 | a_expr all_Op sub_type '(' SubSelect ')'
4093 SubLink *n = makeNode(SubLink);
4094 n->lefthand = lcons($1, NIL);
4095 n->oper = lcons($2, NIL);
4096 n->useor = false; /* doesn't matter since only one col */
4097 n->subLinkType = $3;
4106 * Restricted expressions
4108 * b_expr is a subset of the complete expression syntax defined by a_expr.
4110 * Presently, AND, NOT, IS, IN, and NULL are the a_expr keywords that would
4111 * cause trouble in the places where b_expr is used. For simplicity, we
4112 * just eliminate all the boolean-keyword-operator productions from b_expr.
4116 | b_expr TYPECAST Typename
4119 /* AexprConst can be either A_Const or ParamNo */
4120 if (nodeTag($1) == T_A_Const) {
4121 ((A_Const *)$1)->typename = $3;
4122 } else if (nodeTag($1) == T_ParamNo) {
4123 ((ParamNo *)$1)->typename = $3;
4124 /* otherwise, try to transform to a function call */
4126 FuncCall *n = makeNode(FuncCall);
4127 n->funcname = $3->name;
4128 n->args = lcons($1,NIL);
4129 n->agg_star = false;
4130 n->agg_distinct = false;
4134 | NULL_P TYPECAST Typename
4136 A_Const *n = makeNode(A_Const);
4137 n->val.type = T_Null;
4141 | '-' b_expr %prec UMINUS
4142 { $$ = doNegate($2); }
4144 { $$ = makeA_Expr(OP, "%", NULL, $2); }
4146 { $$ = makeA_Expr(OP, "^", NULL, $2); }
4148 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4150 { $$ = makeA_Expr(OP, ":", NULL, $2); }
4152 { $$ = makeA_Expr(OP, ";", NULL, $2); }
4154 { $$ = makeA_Expr(OP, "%", $1, NULL); }
4156 { $$ = makeA_Expr(OP, "^", $1, NULL); }
4158 { $$ = makeA_Expr(OP, "|", $1, NULL); }
4160 { $$ = makeA_Expr(OP, "+", $1, $3); }
4162 { $$ = makeA_Expr(OP, "-", $1, $3); }
4164 { $$ = makeA_Expr(OP, "*", $1, $3); }
4166 { $$ = makeA_Expr(OP, "/", $1, $3); }
4168 { $$ = makeA_Expr(OP, "%", $1, $3); }
4170 { $$ = makeA_Expr(OP, "^", $1, $3); }
4172 { $$ = makeA_Expr(OP, "|", $1, $3); }
4174 { $$ = makeA_Expr(OP, "<", $1, $3); }
4176 { $$ = makeA_Expr(OP, ">", $1, $3); }
4178 { $$ = makeA_Expr(OP, "=", $1, $3); }
4181 { $$ = makeA_Expr(OP, $2, $1, $3); }
4183 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4185 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4189 * Productions that can be used in both a_expr and b_expr.
4191 * Note: productions that refer recursively to a_expr or b_expr mostly
4192 * cannot appear here. However, it's OK to refer to a_exprs that occur
4193 * inside parentheses, such as function arguments; that cannot introduce
4194 * ambiguity to the b_expr syntax.
4197 { $$ = (Node *) $1; }
4198 | ColId opt_indirection
4200 /* could be a column name or a relation_name */
4201 Ident *n = makeNode(Ident);
4203 n->indirection = $2;
4208 | '(' a_expr_or_null ')'
4210 | CAST '(' a_expr_or_null AS Typename ')'
4213 /* AexprConst can be either A_Const or ParamNo */
4214 if (nodeTag($3) == T_A_Const) {
4215 ((A_Const *)$3)->typename = $5;
4216 } else if (nodeTag($3) == T_ParamNo) {
4217 ((ParamNo *)$3)->typename = $5;
4218 /* otherwise, try to transform to a function call */
4220 FuncCall *n = makeNode(FuncCall);
4221 n->funcname = $5->name;
4222 n->args = lcons($3,NIL);
4223 n->agg_star = false;
4224 n->agg_distinct = false;
4232 FuncCall *n = makeNode(FuncCall);
4235 n->agg_star = false;
4236 n->agg_distinct = false;
4239 | func_name '(' expr_list ')'
4241 FuncCall *n = makeNode(FuncCall);
4244 n->agg_star = false;
4245 n->agg_distinct = false;
4248 | func_name '(' DISTINCT expr_list ')'
4250 FuncCall *n = makeNode(FuncCall);
4253 n->agg_star = false;
4254 n->agg_distinct = true;
4257 | func_name '(' '*' ')'
4260 * For now, we transform AGGREGATE(*) into AGGREGATE(1).
4262 * This does the right thing for COUNT(*) (in fact,
4263 * any certainly-non-null expression would do for COUNT),
4264 * and there are no other aggregates in SQL92 that accept
4267 * The FuncCall node is also marked agg_star = true,
4268 * so that later processing can detect what the argument
4271 FuncCall *n = makeNode(FuncCall);
4272 A_Const *star = makeNode(A_Const);
4274 star->val.type = T_Integer;
4275 star->val.val.ival = 1;
4277 n->args = lcons(star, NIL);
4279 n->agg_distinct = false;
4285 * Translate as "date('now'::text)".
4287 * We cannot use "'now'::date" because coerce_type() will
4288 * immediately reduce that to a constant representing
4289 * today's date. We need to delay the conversion until
4290 * runtime, else the wrong things will happen when
4291 * CURRENT_DATE is used in a column default value or rule.
4293 * This could be simplified if we had a way to generate
4294 * an expression tree representing runtime application
4295 * of type-input conversion functions...
4297 A_Const *s = makeNode(A_Const);
4298 TypeName *t = makeNode(TypeName);
4299 FuncCall *n = makeNode(FuncCall);
4301 s->val.type = T_String;
4302 s->val.val.str = "now";
4305 t->name = xlateSqlType("text");
4309 n->funcname = xlateSqlType("date");
4310 n->args = lcons(s, NIL);
4311 n->agg_star = false;
4312 n->agg_distinct = false;
4319 * Translate as "time('now'::text)".
4320 * See comments for CURRENT_DATE.
4322 A_Const *s = makeNode(A_Const);
4323 TypeName *t = makeNode(TypeName);
4324 FuncCall *n = makeNode(FuncCall);
4326 s->val.type = T_String;
4327 s->val.val.str = "now";
4330 t->name = xlateSqlType("text");
4334 n->funcname = xlateSqlType("time");
4335 n->args = lcons(s, NIL);
4336 n->agg_star = false;
4337 n->agg_distinct = false;
4341 | CURRENT_TIME '(' Iconst ')'
4344 * Translate as "time('now'::text)".
4345 * See comments for CURRENT_DATE.
4347 A_Const *s = makeNode(A_Const);
4348 TypeName *t = makeNode(TypeName);
4349 FuncCall *n = makeNode(FuncCall);
4351 s->val.type = T_String;
4352 s->val.val.str = "now";
4355 t->name = xlateSqlType("text");
4359 n->funcname = xlateSqlType("time");
4360 n->args = lcons(s, NIL);
4361 n->agg_star = false;
4362 n->agg_distinct = false;
4365 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4372 * Translate as "timestamp('now'::text)".
4373 * See comments for CURRENT_DATE.
4375 A_Const *s = makeNode(A_Const);
4376 TypeName *t = makeNode(TypeName);
4377 FuncCall *n = makeNode(FuncCall);
4379 s->val.type = T_String;
4380 s->val.val.str = "now";
4383 t->name = xlateSqlType("text");
4387 n->funcname = xlateSqlType("timestamp");
4388 n->args = lcons(s, NIL);
4389 n->agg_star = false;
4390 n->agg_distinct = false;
4394 | CURRENT_TIMESTAMP '(' Iconst ')'
4397 * Translate as "timestamp('now'::text)".
4398 * See comments for CURRENT_DATE.
4400 A_Const *s = makeNode(A_Const);
4401 TypeName *t = makeNode(TypeName);
4402 FuncCall *n = makeNode(FuncCall);
4404 s->val.type = T_String;
4405 s->val.val.str = "now";
4408 t->name = xlateSqlType("text");
4412 n->funcname = xlateSqlType("timestamp");
4413 n->args = lcons(s, NIL);
4414 n->agg_star = false;
4415 n->agg_distinct = false;
4418 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4424 FuncCall *n = makeNode(FuncCall);
4425 n->funcname = "getpgusername";
4427 n->agg_star = false;
4428 n->agg_distinct = false;
4433 FuncCall *n = makeNode(FuncCall);
4434 n->funcname = "getpgusername";
4436 n->agg_star = false;
4437 n->agg_distinct = false;
4440 | EXTRACT '(' extract_list ')'
4442 FuncCall *n = makeNode(FuncCall);
4443 n->funcname = "date_part";
4445 n->agg_star = false;
4446 n->agg_distinct = false;
4449 | POSITION '(' position_list ')'
4451 FuncCall *n = makeNode(FuncCall);
4452 n->funcname = "strpos";
4454 n->agg_star = false;
4455 n->agg_distinct = false;
4458 | SUBSTRING '(' substr_list ')'
4460 FuncCall *n = makeNode(FuncCall);
4461 n->funcname = "substr";
4463 n->agg_star = false;
4464 n->agg_distinct = false;
4467 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4468 | TRIM '(' BOTH trim_list ')'
4470 FuncCall *n = makeNode(FuncCall);
4471 n->funcname = "btrim";
4473 n->agg_star = false;
4474 n->agg_distinct = false;
4477 | TRIM '(' LEADING trim_list ')'
4479 FuncCall *n = makeNode(FuncCall);
4480 n->funcname = "ltrim";
4482 n->agg_star = false;
4483 n->agg_distinct = false;
4486 | TRIM '(' TRAILING trim_list ')'
4488 FuncCall *n = makeNode(FuncCall);
4489 n->funcname = "rtrim";
4491 n->agg_star = false;
4492 n->agg_distinct = false;
4495 | TRIM '(' trim_list ')'
4497 FuncCall *n = makeNode(FuncCall);
4498 n->funcname = "btrim";
4500 n->agg_star = false;
4501 n->agg_distinct = false;
4506 SubLink *n = makeNode(SubLink);
4510 n->subLinkType = EXPR_SUBLINK;
4514 | EXISTS '(' SubSelect ')'
4516 SubLink *n = makeNode(SubLink);
4520 n->subLinkType = EXISTS_SUBLINK;
4527 * Supporting nonterminals for expressions.
4530 opt_indirection: '[' a_expr ']' opt_indirection
4532 A_Indices *ai = makeNode(A_Indices);
4537 | '[' a_expr ':' a_expr ']' opt_indirection
4539 A_Indices *ai = makeNode(A_Indices);
4548 expr_list: a_expr_or_null
4549 { $$ = lcons($1, NIL); }
4550 | expr_list ',' a_expr_or_null
4551 { $$ = lappend($1, $3); }
4552 | expr_list USING a_expr
4553 { $$ = lappend($1, $3); }
4556 extract_list: extract_arg FROM a_expr
4558 A_Const *n = makeNode(A_Const);
4559 n->val.type = T_String;
4560 n->val.val.str = $1;
4561 $$ = lappend(lcons((Node *)n,NIL), $3);
4567 extract_arg: datetime { $$ = $1; }
4568 | TIMEZONE_HOUR { $$ = "tz_hour"; }
4569 | TIMEZONE_MINUTE { $$ = "tz_minute"; }
4572 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
4574 position_list: b_expr IN b_expr
4575 { $$ = makeList($3, $1, -1); }
4580 substr_list: expr_list substr_from substr_for
4582 $$ = nconc(nconc($1,$2),$3);
4588 substr_from: FROM expr_list
4592 A_Const *n = makeNode(A_Const);
4593 n->val.type = T_Integer;
4594 n->val.val.ival = 1;
4595 $$ = lcons((Node *)n,NIL);
4599 substr_for: FOR expr_list
4605 trim_list: a_expr FROM expr_list
4606 { $$ = lappend($3, $1); }
4615 SubLink *n = makeNode(SubLink);
4620 { $$ = (Node *)$1; }
4623 in_expr_nodes: a_expr
4624 { $$ = lcons($1, NIL); }
4625 | in_expr_nodes ',' a_expr
4626 { $$ = lappend($1, $3); }
4630 * Define SQL92-style case clause.
4631 * Allow all four forms described in the standard:
4632 * - Full specification
4633 * CASE WHEN a = b THEN c ... ELSE d END
4634 * - Implicit argument
4635 * CASE a WHEN b THEN c ... ELSE d END
4636 * - Conditional NULL
4638 * same as CASE WHEN x = y THEN NULL ELSE x END
4639 * - Conditional substitution from list, use first non-null argument
4641 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
4642 * - thomas 1998-11-09
4644 case_expr: CASE case_arg when_clause_list case_default END_TRANS
4646 CaseExpr *c = makeNode(CaseExpr);
4652 | NULLIF '(' a_expr ',' a_expr ')'
4654 CaseExpr *c = makeNode(CaseExpr);
4655 CaseWhen *w = makeNode(CaseWhen);
4657 A_Const *n = makeNode(A_Const);
4658 n->val.type = T_Null;
4659 w->result = (Node *)n;
4661 w->expr = makeA_Expr(OP, "=", $3, $5);
4662 c->args = lcons(w, NIL);
4666 | COALESCE '(' expr_list ')'
4668 CaseExpr *c = makeNode(CaseExpr);
4673 w = makeNode(CaseWhen);
4674 w->expr = makeA_Expr(NOTNULL, NULL, lfirst(l), NULL);
4675 w->result = lfirst(l);
4676 c->args = lappend(c->args, w);
4682 when_clause_list: when_clause_list when_clause
4683 { $$ = lappend($1, $2); }
4685 { $$ = lcons($1, NIL); }
4688 when_clause: WHEN a_expr THEN a_expr_or_null
4690 CaseWhen *w = makeNode(CaseWhen);
4697 case_default: ELSE a_expr_or_null { $$ = $2; }
4698 | /*EMPTY*/ { $$ = NULL; }
4707 attr: relation_name '.' attrs opt_indirection
4709 $$ = makeNode(Attr);
4713 $$->indirection = $4;
4715 | ParamNo '.' attrs opt_indirection
4717 $$ = makeNode(Attr);
4721 $$->indirection = $4;
4726 { $$ = lcons(makeString($1), NIL); }
4727 | attrs '.' attr_name
4728 { $$ = lappend($1, makeString($3)); }
4730 { $$ = lappend($1, makeString("*")); }
4734 /*****************************************************************************
4738 *****************************************************************************/
4740 /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
4742 target_list: target_list ',' target_el
4743 { $$ = lappend($1, $3); }
4745 { $$ = lcons($1, NIL); }
4748 /* AS is not optional because shift/red conflict with unary ops */
4749 target_el: a_expr_or_null AS ColLabel
4751 $$ = makeNode(ResTarget);
4753 $$->indirection = NULL;
4754 $$->val = (Node *)$1;
4758 $$ = makeNode(ResTarget);
4760 $$->indirection = NULL;
4761 $$->val = (Node *)$1;
4763 | relation_name '.' '*'
4765 Attr *att = makeNode(Attr);
4767 att->paramNo = NULL;
4768 att->attrs = lcons(makeString("*"), NIL);
4769 att->indirection = NIL;
4770 $$ = makeNode(ResTarget);
4772 $$->indirection = NULL;
4773 $$->val = (Node *)att;
4777 Attr *att = makeNode(Attr);
4779 att->paramNo = NULL;
4781 att->indirection = NIL;
4782 $$ = makeNode(ResTarget);
4784 $$->indirection = NULL;
4785 $$->val = (Node *)att;
4789 /* Target list as found in UPDATE table SET ... */
4791 update_target_list: update_target_list ',' update_target_el
4792 { $$ = lappend($1,$3); }
4794 { $$ = lcons($1, NIL); }
4797 update_target_el: ColId opt_indirection '=' a_expr_or_null
4799 $$ = makeNode(ResTarget);
4801 $$->indirection = $2;
4802 $$->val = (Node *)$4;
4806 /*****************************************************************************
4808 * Names and constants
4810 *****************************************************************************/
4812 relation_name: SpecialRuleRelation
4815 StrNCpy(saved_relname, $1, NAMEDATALEN);
4819 /* disallow refs to variable system tables */
4820 if (strcmp(LogRelationName, $1) == 0
4821 || strcmp(VariableRelationName, $1) == 0)
4822 elog(ERROR,"%s cannot be accessed by users",$1);
4825 StrNCpy(saved_relname, $1, NAMEDATALEN);
4829 database_name: ColId { $$ = $1; };
4830 access_method: IDENT { $$ = $1; };
4831 attr_name: ColId { $$ = $1; };
4832 class: IDENT { $$ = $1; };
4833 index_name: ColId { $$ = $1; };
4836 * Include date/time keywords as SQL92 extension.
4837 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4839 name: ColId { $$ = $1; };
4840 func_name: ColId { $$ = xlateSqlFunc($1); };
4842 file_name: Sconst { $$ = $1; };
4843 /* NOT USED recipe_name: IDENT { $$ = $1; };*/
4846 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4850 A_Const *n = makeNode(A_Const);
4851 n->val.type = T_Integer;
4852 n->val.val.ival = $1;
4857 A_Const *n = makeNode(A_Const);
4858 n->val.type = T_Float;
4859 n->val.val.dval = $1;
4864 A_Const *n = makeNode(A_Const);
4865 n->val.type = T_String;
4866 n->val.val.str = $1;
4869 /* this rule formerly used Typename, but that causes reduce conflicts
4870 * with subscripted column names ...
4872 | SimpleTypename Sconst
4874 A_Const *n = makeNode(A_Const);
4876 n->val.type = T_String;
4877 n->val.val.str = $2;
4881 { $$ = (Node *)$1; }
4884 A_Const *n = makeNode(A_Const);
4885 n->val.type = T_String;
4886 n->val.val.str = "t";
4887 n->typename = makeNode(TypeName);
4888 n->typename->name = xlateSqlType("bool");
4889 n->typename->typmod = -1;
4894 A_Const *n = makeNode(A_Const);
4895 n->val.type = T_String;
4896 n->val.val.str = "f";
4897 n->typename = makeNode(TypeName);
4898 n->typename->name = xlateSqlType("bool");
4899 n->typename->typmod = -1;
4904 ParamNo: PARAM opt_indirection
4906 $$ = makeNode(ParamNo);
4908 $$->indirection = $2;
4912 Iconst: ICONST { $$ = $1; };
4913 Sconst: SCONST { $$ = $1; };
4914 UserId: IDENT { $$ = $1; };
4916 /* Column and type identifier
4917 * Does not include explicit datetime types
4918 * since these must be decoupled in Typename syntax.
4919 * Use ColId for most identifiers. - thomas 1997-10-21
4922 { $$ = xlateSqlType($1); }
4924 { $$ = xlateSqlType($1); }
4926 { $$ = xlateSqlType($1); }
4928 /* Column identifier
4929 * Include date/time keywords as SQL92 extension.
4930 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4931 * Add other keywords. Note that as the syntax expands,
4932 * some of these keywords will have to be removed from this
4933 * list due to shift/reduce conflicts in yacc. If so, move
4934 * down to the ColLabel entity. - thomas 1997-11-06
4936 ColId: IDENT { $$ = $1; }
4937 | datetime { $$ = $1; }
4938 | ABSOLUTE { $$ = "absolute"; }
4939 | ACCESS { $$ = "access"; }
4940 | ACTION { $$ = "action"; }
4941 | AFTER { $$ = "after"; }
4942 | AGGREGATE { $$ = "aggregate"; }
4943 | BACKWARD { $$ = "backward"; }
4944 | BEFORE { $$ = "before"; }
4945 | CACHE { $$ = "cache"; }
4946 | COMMENT { $$ = "comment"; }
4947 | COMMITTED { $$ = "committed"; }
4948 | CONSTRAINTS { $$ = "constraints"; }
4949 | CREATEDB { $$ = "createdb"; }
4950 | CREATEUSER { $$ = "createuser"; }
4951 | CYCLE { $$ = "cycle"; }
4952 | DATABASE { $$ = "database"; }
4953 | DEFERRABLE { $$ = "deferrable"; }
4954 | DEFERRED { $$ = "deferred"; }
4955 | DELIMITERS { $$ = "delimiters"; }
4956 | DOUBLE { $$ = "double"; }
4957 | EACH { $$ = "each"; }
4958 | ENCODING { $$ = "encoding"; }
4959 | EXCLUSIVE { $$ = "exclusive"; }
4960 | FORWARD { $$ = "forward"; }
4961 | FUNCTION { $$ = "function"; }
4962 | HANDLER { $$ = "handler"; }
4963 | IMMEDIATE { $$ = "immediate"; }
4964 | INCREMENT { $$ = "increment"; }
4965 | INDEX { $$ = "index"; }
4966 | INHERITS { $$ = "inherits"; }
4967 | INITIALLY { $$ = "initially"; }
4968 | INSENSITIVE { $$ = "insensitive"; }
4969 | INSTEAD { $$ = "instead"; }
4970 | ISNULL { $$ = "isnull"; }
4971 | ISOLATION { $$ = "isolation"; }
4972 | KEY { $$ = "key"; }
4973 | LANGUAGE { $$ = "language"; }
4974 | LANCOMPILER { $$ = "lancompiler"; }
4975 | LEVEL { $$ = "level"; }
4976 | LOCATION { $$ = "location"; }
4977 | MATCH { $$ = "match"; }
4978 | MAXVALUE { $$ = "maxvalue"; }
4979 | MINVALUE { $$ = "minvalue"; }
4980 | MODE { $$ = "mode"; }
4981 | NEXT { $$ = "next"; }
4982 | NOCREATEDB { $$ = "nocreatedb"; }
4983 | NOCREATEUSER { $$ = "nocreateuser"; }
4984 | NOTHING { $$ = "nothing"; }
4985 | NOTNULL { $$ = "notnull"; }
4987 | OIDS { $$ = "oids"; }
4988 | ONLY { $$ = "only"; }
4989 | OPERATOR { $$ = "operator"; }
4990 | OPTION { $$ = "option"; }
4991 | PASSWORD { $$ = "password"; }
4992 | PENDANT { $$ = "pendant"; }
4993 | PRIOR { $$ = "prior"; }
4994 | PRIVILEGES { $$ = "privileges"; }
4995 | PROCEDURAL { $$ = "procedural"; }
4996 | READ { $$ = "read"; }
4997 | RELATIVE { $$ = "relative"; }
4998 | RENAME { $$ = "rename"; }
4999 | RESTRICT { $$ = "restrict"; }
5000 | RETURNS { $$ = "returns"; }
5001 | ROW { $$ = "row"; }
5002 | RULE { $$ = "rule"; }
5003 | SCROLL { $$ = "scroll"; }
5004 | SEQUENCE { $$ = "sequence"; }
5005 | SERIAL { $$ = "serial"; }
5006 | SERIALIZABLE { $$ = "serializable"; }
5007 | SHARE { $$ = "share"; }
5008 | START { $$ = "start"; }
5009 | STATEMENT { $$ = "statement"; }
5010 | STDIN { $$ = "stdin"; }
5011 | STDOUT { $$ = "stdout"; }
5012 | SYSID { $$ = "sysid"; }
5013 | TIME { $$ = "time"; }
5014 | TIMESTAMP { $$ = "timestamp"; }
5015 | TIMEZONE_HOUR { $$ = "timezone_hour"; }
5016 | TIMEZONE_MINUTE { $$ = "timezone_minute"; }
5017 | TRIGGER { $$ = "trigger"; }
5018 | TRUNCATE { $$ = "truncate"; }
5019 | TRUSTED { $$ = "trusted"; }
5020 | TYPE_P { $$ = "type"; }
5021 | VALID { $$ = "valid"; }
5022 | VERSION { $$ = "version"; }
5023 | ZONE { $$ = "zone"; }
5027 * Allowed labels in "AS" clauses.
5028 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
5029 * compatibility. Cannot allow this for column names since the
5030 * syntax would not distinguish between the constant value and
5031 * a column name. - thomas 1997-10-24
5032 * Add other keywords to this list. Note that they appear here
5033 * rather than in ColId if there was a shift/reduce conflict
5034 * when used as a full identifier. - thomas 1997-11-06
5036 ColLabel: ColId { $$ = $1; }
5037 | ABORT_TRANS { $$ = "abort"; }
5038 | ANALYZE { $$ = "analyze"; }
5039 | BINARY { $$ = "binary"; }
5040 | CASE { $$ = "case"; }
5041 | CLUSTER { $$ = "cluster"; }
5042 | COALESCE { $$ = "coalesce"; }
5043 | CONSTRAINT { $$ = "constraint"; }
5044 | COPY { $$ = "copy"; }
5045 | CURRENT { $$ = "current"; }
5047 | ELSE { $$ = "else"; }
5048 | END_TRANS { $$ = "end"; }
5049 | EXPLAIN { $$ = "explain"; }
5050 | EXTEND { $$ = "extend"; }
5051 | FALSE_P { $$ = "false"; }
5052 | FOREIGN { $$ = "foreign"; }
5053 | GLOBAL { $$ = "global"; }
5054 | GROUP { $$ = "group"; }
5055 | LISTEN { $$ = "listen"; }
5056 | LOAD { $$ = "load"; }
5057 | LOCAL { $$ = "local"; }
5058 | LOCK_P { $$ = "lock"; }
5059 | MOVE { $$ = "move"; }
5060 | NEW { $$ = "new"; }
5061 | NONE { $$ = "none"; }
5062 | NULLIF { $$ = "nullif"; }
5063 | ORDER { $$ = "order"; }
5064 | POSITION { $$ = "position"; }
5065 | PRECISION { $$ = "precision"; }
5066 | RESET { $$ = "reset"; }
5067 | SETOF { $$ = "setof"; }
5068 | SHOW { $$ = "show"; }
5069 | TABLE { $$ = "table"; }
5070 | THEN { $$ = "then"; }
5071 | TRANSACTION { $$ = "transaction"; }
5072 | TRUE_P { $$ = "true"; }
5073 | VACUUM { $$ = "vacuum"; }
5074 | VERBOSE { $$ = "verbose"; }
5075 | WHEN { $$ = "when"; }
5078 SpecialRuleRelation: CURRENT
5083 elog(ERROR,"CURRENT used in non-rule query");
5090 elog(ERROR,"NEW used in non-rule query");
5097 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
5099 A_Expr *a = makeNode(A_Expr);
5108 * Generate separate operator nodes for a single row descriptor expression.
5109 * Perhaps this should go deeper in the parser someday...
5110 * - thomas 1997-12-22
5113 makeRowExpr(char *opr, List *largs, List *rargs)
5118 if (length(largs) != length(rargs))
5119 elog(ERROR,"Unequal number of entries in row expression");
5121 if (lnext(largs) != NIL)
5122 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
5124 larg = lfirst(largs);
5125 rarg = lfirst(rargs);
5127 if ((strcmp(opr, "=") == 0)
5128 || (strcmp(opr, "<") == 0)
5129 || (strcmp(opr, "<=") == 0)
5130 || (strcmp(opr, ">") == 0)
5131 || (strcmp(opr, ">=") == 0))
5134 expr = makeA_Expr(OP, opr, larg, rarg);
5136 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
5138 else if (strcmp(opr, "<>") == 0)
5141 expr = makeA_Expr(OP, opr, larg, rarg);
5143 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
5147 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
5154 mapTargetColumns(List *src, List *dst)
5159 if (length(src) != length(dst))
5160 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
5162 while ((src != NIL) && (dst != NIL))
5164 s = (ColumnDef *)lfirst(src);
5165 d = (ResTarget *)lfirst(dst);
5167 d->name = s->colname;
5172 } /* mapTargetColumns() */
5176 * Convert alternate type names to internal Postgres types.
5177 * Do not convert "float", since that is handled elsewhere
5178 * for FLOAT(p) syntax.
5181 xlateSqlFunc(char *name)
5183 if (!strcasecmp(name,"character_length")
5184 || !strcasecmp(name,"char_length"))
5188 } /* xlateSqlFunc() */
5191 * Convert alternate type names to internal Postgres types.
5194 xlateSqlType(char *name)
5196 if (!strcasecmp(name,"int")
5197 || !strcasecmp(name,"integer"))
5199 else if (!strcasecmp(name, "smallint"))
5201 else if (!strcasecmp(name, "real")
5202 || !strcasecmp(name, "float"))
5204 else if (!strcasecmp(name, "interval"))
5206 else if (!strcasecmp(name, "boolean"))
5210 } /* xlateSqlType() */
5213 void parser_init(Oid *typev, int nargs)
5215 QueryIsRule = FALSE;
5216 saved_relname[0]= '\0';
5218 param_type_init(typev, nargs);
5225 * keep enough information around fill out the type of param nodes
5226 * used in postquel functions
5229 param_type_init(Oid *typev, int nargs)
5231 pfunc_num_args = nargs;
5232 param_type_info = typev;
5235 Oid param_type(int t)
5237 if ((t > pfunc_num_args) || (t == 0))
5239 return param_type_info[t - 1];
5243 * The optimizer doesn't like '-' 4 for index use. It only checks for
5244 * Var '=' Const. It wants an integer of -4, so we try to merge the
5245 * minus into the constant.
5247 * This code is no longer essential as of 10/1999, since the optimizer
5248 * now has a constant-subexpression simplifier. However, we can save
5249 * a few cycles throughout the parse and rewrite stages if we collapse
5250 * the minus into the constant sooner rather than later...
5252 static Node *doNegate(Node *n)
5254 if (IsA(n, A_Const))
5256 A_Const *con = (A_Const *)n;
5258 if (con->val.type == T_Integer)
5260 con->val.val.ival = -con->val.val.ival;
5263 if (con->val.type == T_Float)
5265 con->val.val.dval = -con->val.val.dval;
5270 return makeA_Expr(OP, "-", NULL, n);