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.133 2000/01/22 14:20:46 petere 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 *makeTypeCast(Node *arg, TypeName *typename);
75 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
76 static void mapTargetColumns(List *source, List *target);
77 static void param_type_init(Oid *typev, int nargs);
78 static Node *doNegate(Node *n);
80 /* old versions of flex define this as a macro */
102 SortGroupBy *sortgroupby;
118 AlterTableStmt, ClosePortalStmt,
119 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DropStmt,
120 TruncateStmt, CommentStmt,
121 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
122 CreatePLangStmt, DropPLangStmt,
123 IndexStmt, ListenStmt, UnlistenStmt, LockStmt, OptimizableStmt,
124 ProcedureStmt, RemoveAggrStmt, RemoveOperStmt,
125 RemoveFuncStmt, RemoveStmt,
126 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
127 CreatedbStmt, DropdbStmt, VacuumStmt, CursorStmt, SubSelect,
128 UpdateStmt, InsertStmt, select_clause, SelectStmt, NotifyStmt, DeleteStmt,
129 ClusterStmt, ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
130 CreateUserStmt, AlterUserStmt, DropUserStmt, RuleActionStmt,
131 RuleActionStmtOrEmpty, ConstraintsSetStmt,
132 CreateGroupStmt, AlterGroupStmt, DropGroupStmt
134 %type <node> alter_column_action
135 %type <ival> drop_behavior
137 %type <str> createdb_opt_location
138 %type <ival> createdb_opt_encoding
140 %type <ival> opt_lock, lock_type
141 %type <boolean> opt_lmode
143 %type <ival> user_createdb_clause, user_createuser_clause
144 %type <str> user_passwd_clause
145 %type <ival> sysid_clause
146 %type <str> user_valid_clause
147 %type <list> user_list, user_group_clause, users_in_new_group_clause
149 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
151 %type <str> OptConstrFromTable
153 %type <str> TriggerEvents, TriggerFuncArg
155 %type <str> relation_name, copy_file_name, copy_delimiter, copy_null, def_name,
156 database_name, access_method_clause, access_method, attr_name,
157 class, index_name, name, func_name, file_name, aggr_argtype
160 all_Op, MathOp, opt_name, opt_unique,
161 OptUseOp, opt_class, SpecialRuleRelation
163 %type <str> opt_level, opt_encoding
164 %type <str> privileges, operation_commalist, grantee
165 %type <chr> operation, TriggerOneEvent
167 %type <list> stmtblock, stmtmulti,
168 result, relation_name_list, OptTableElementList,
169 OptInherit, definition,
170 opt_with, func_args, func_args_list, func_as,
171 oper_argtypes, RuleActionList, RuleActionMulti,
172 opt_column_list, columnList, opt_va_list, va_list,
173 sort_clause, sortby_list, index_params, index_list, name_list,
174 from_clause, from_expr, table_list, opt_array_bounds,
175 expr_list, attrs, target_list, update_target_list,
176 def_list, opt_indirection, group_clause, TriggerFuncArgs,
179 %type <node> func_return
180 %type <boolean> set_opt
182 %type <boolean> TriggerForOpt, TriggerForType, OptTemp, OptTempType, OptTempScope
184 %type <list> for_update_clause, update_list
185 %type <boolean> opt_all
186 %type <boolean> opt_table
187 %type <boolean> opt_trans
189 %type <list> join_clause_with_union, join_clause, join_list, join_qual, using_list
190 %type <node> join_expr, using_expr
191 %type <str> join_outer
192 %type <ival> join_type
194 %type <list> extract_list, position_list
195 %type <list> substr_list, substr_from, substr_for, trim_list
196 %type <list> opt_interval
198 %type <boolean> opt_inh_star, opt_binary, opt_using, opt_instead,
199 opt_with_copy, index_opt_unique, opt_verbose, opt_analyze
200 %type <boolean> opt_cursor
202 %type <ival> copy_dirn, def_type, direction, remove_type,
203 opt_column, event, comment_type, comment_cl,
204 comment_ag, comment_fn, comment_op, comment_tg
206 %type <ival> fetch_how_many
208 %type <node> select_limit_value, select_offset_value
210 %type <list> OptSeqList
211 %type <defelt> OptSeqElem
213 %type <dstmt> def_rest
214 %type <astmt> insert_rest
216 %type <node> OptTableElement, ConstraintElem
217 %type <node> columnDef
218 %type <defelt> def_elem
219 %type <node> def_arg, columnElem, where_clause,
220 a_expr, a_expr_or_null, b_expr, com_expr, AexprConst,
221 in_expr, having_clause
222 %type <list> row_descriptor, row_list, in_expr_nodes
223 %type <node> row_expr
224 %type <node> case_expr, case_arg, when_clause, case_default
225 %type <list> when_clause_list
226 %type <ival> sub_type
227 %type <list> OptCreateAs, CreateAsList
228 %type <node> CreateAsElement
229 %type <value> NumericOnly, FloatOnly, IntegerOnly
230 %type <attr> event_object, attr
231 %type <sortgroupby> sortby
232 %type <ielem> index_elem, func_index
233 %type <range> table_expr
234 %type <relexp> relation_expr
235 %type <target> target_el, update_target_el
236 %type <paramno> ParamNo
238 %type <typnam> Typename, opt_type, SimpleTypename,
239 Generic, Numeric, Character, Datetime
240 %type <str> generic, numeric, character, datetime
241 %type <str> extract_arg
242 %type <str> opt_charset, opt_collate
243 %type <str> opt_float
244 %type <ival> opt_numeric, opt_decimal
245 %type <boolean> opt_varying, opt_timezone
248 %type <str> Sconst, comment_text
249 %type <str> UserId, var_value, zone_value
250 %type <str> ColId, ColLabel
253 %type <node> TableConstraint
254 %type <list> ColPrimaryKey, ColConstraintList
255 %type <node> ColConstraint, ColConstraintElem
256 %type <ival> key_actions, key_action, key_reference
257 %type <str> key_match
258 %type <ival> ConstraintAttributeSpec, ConstraintDeferrabilitySpec,
261 %type <list> constraints_set_list
262 %type <list> constraints_set_namelist
263 %type <boolean> constraints_set_mode
266 * If you make any token changes, remember to:
267 * - use "yacc -d" and update parse.h
268 * - update the keyword table in parser/keywords.c
271 /* Reserved word tokens
272 * SQL92 syntax has many type-specific constructs.
273 * So, go ahead and make these types reserved words,
274 * and call-out the syntax explicitly.
275 * This gets annoying when trying to also retain Postgres' nice
276 * type-extensible features, but we don't really have a choice.
277 * - thomas 1997-10-11
278 * NOTE: Whenever possible, try to add new keywords to the ColId list,
279 * or failing that, at least to the ColLabel list.
282 /* Keywords (in SQL92 reserved words) */
283 %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
284 BEGIN_TRANS, BETWEEN, BOTH, BY,
285 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
286 COALESCE, COLLATE, COLUMN, COMMIT,
287 CONSTRAINT, CONSTRAINTS, CREATE, CROSS, CURRENT, CURRENT_DATE,
288 CURRENT_TIME, CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
289 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
290 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
291 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
292 GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
293 IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
294 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
295 MATCH, MINUTE_P, MONTH_P, NAMES,
296 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
297 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
298 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
299 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
300 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
301 TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
302 TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
303 UNION, UNIQUE, UPDATE, USER, USING,
304 VALUES, VARCHAR, VARYING, VIEW,
305 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
308 /* Keywords (in SQL3 reserved words) */
309 %token DEFERRABLE, DEFERRED,
310 IMMEDIATE, INITIALLY,
315 /* Keywords (in SQL92 non-reserved words) */
316 %token COMMITTED, SERIALIZABLE, TYPE_P
318 /* Keywords for Postgres support (not in SQL92 reserved words)
320 * The CREATEDB and CREATEUSER tokens should go away
321 * when some sort of pg_privileges relation is introduced.
322 * - Todd A. Brandys 1998-01-01?
324 %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
325 BACKWARD, BEFORE, BINARY,
326 CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE,
327 DATABASE, DELIMITERS, DO,
328 EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
329 FORWARD, FUNCTION, HANDLER,
330 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
331 LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
332 MAXVALUE, MINVALUE, MODE, MOVE,
333 NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
334 OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
335 RENAME, RESET, RETURNS, ROW, RULE,
336 SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID,
338 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
340 /* Special keywords, not in the query language - see the "lex" file */
341 %token <str> IDENT, SCONST, Op
342 %token <ival> ICONST, PARAM
345 /* these are not real. they are here so that they get generated as #define's*/
357 %left Op /* multi-character ops and user-defined operators */
365 %left '|' /* this is the relation union op, not logical or */
366 /* Unary Operators */
368 %left ';' /* end of statement or natural log */
373 %left UNION INTERSECT EXCEPT
377 * Handle comment-only lines, and ;; SELECT * FROM pg_class ;;;
378 * psql already handles such cases, but other interfaces don't.
385 /* the thrashing around here is to discard "empty" statements... */
386 stmtmulti: stmtmulti ';' stmt
387 { if ($3 != (Node *)NULL)
388 $$ = lappend($1, $3);
393 { if ($1 != (Node *)NULL)
400 stmt : AlterTableStmt
449 { $$ = (Node *)NULL; }
452 /*****************************************************************************
454 * Create a new Postgres DBMS user
457 *****************************************************************************/
459 CreateUserStmt: CREATE USER UserId
460 user_createdb_clause user_createuser_clause user_group_clause
463 CreateUserStmt *n = makeNode(CreateUserStmt);
467 n->createdb = $4 == +1 ? true : false;
468 n->createuser = $5 == +1 ? true : false;
473 | CREATE USER UserId WITH sysid_clause user_passwd_clause
474 user_createdb_clause user_createuser_clause user_group_clause
477 CreateUserStmt *n = makeNode(CreateUserStmt);
481 n->createdb = $7 == +1 ? true : false;
482 n->createuser = $8 == +1 ? true : false;
489 /*****************************************************************************
491 * Alter a postresql DBMS user
494 *****************************************************************************/
496 AlterUserStmt: ALTER USER UserId user_createdb_clause
497 user_createuser_clause user_valid_clause
499 AlterUserStmt *n = makeNode(AlterUserStmt);
507 | ALTER USER UserId WITH PASSWORD Sconst
509 user_createuser_clause user_valid_clause
511 AlterUserStmt *n = makeNode(AlterUserStmt);
521 /*****************************************************************************
523 * Drop a postresql DBMS user
526 *****************************************************************************/
528 DropUserStmt: DROP USER user_list
530 DropUserStmt *n = makeNode(DropUserStmt);
536 user_passwd_clause: PASSWORD Sconst { $$ = $2; }
537 | /*EMPTY*/ { $$ = NULL; }
540 sysid_clause: SYSID Iconst
543 elog(ERROR, "sysid must be positive");
546 | /*EMPTY*/ { $$ = -1; }
549 user_createdb_clause: CREATEDB { $$ = +1; }
550 | NOCREATEDB { $$ = -1; }
551 | /*EMPTY*/ { $$ = 0; }
554 user_createuser_clause: CREATEUSER { $$ = +1; }
555 | NOCREATEUSER { $$ = -1; }
556 | /*EMPTY*/ { $$ = 0; }
559 user_list: user_list ',' UserId
561 $$ = lcons((void*)makeString($3), $1);
565 $$ = lcons((void*)makeString($1), NIL);
569 user_group_clause: IN GROUP user_list { $$ = $3; }
570 | /*EMPTY*/ { $$ = NULL; }
573 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
574 | /*EMPTY*/ { $$ = NULL; }
578 /*****************************************************************************
580 * Create a postresql group
583 *****************************************************************************/
585 CreateGroupStmt: CREATE GROUP UserId
587 CreateGroupStmt *n = makeNode(CreateGroupStmt);
594 CREATE GROUP UserId WITH sysid_clause users_in_new_group_clause
596 CreateGroupStmt *n = makeNode(CreateGroupStmt);
604 users_in_new_group_clause: USER user_list { $$ = $2; }
605 | /* EMPTY */ { $$ = NULL; }
608 /*****************************************************************************
610 * Alter a postresql group
613 *****************************************************************************/
615 AlterGroupStmt: ALTER GROUP UserId ADD USER user_list
617 AlterGroupStmt *n = makeNode(AlterGroupStmt);
625 ALTER GROUP UserId DROP USER user_list
627 AlterGroupStmt *n = makeNode(AlterGroupStmt);
636 /*****************************************************************************
638 * Drop a postresql group
641 *****************************************************************************/
643 DropGroupStmt: DROP GROUP UserId
645 DropGroupStmt *n = makeNode(DropGroupStmt);
652 /*****************************************************************************
654 * Set PG internal variable
655 * SET name TO 'var_value'
656 * Include SQL92 syntax (thomas 1997-10-22):
657 * SET TIME ZONE 'var_value'
659 *****************************************************************************/
661 VariableSetStmt: SET ColId TO var_value
663 VariableSetStmt *n = makeNode(VariableSetStmt);
668 | SET ColId '=' var_value
670 VariableSetStmt *n = makeNode(VariableSetStmt);
675 | SET TIME ZONE zone_value
677 VariableSetStmt *n = makeNode(VariableSetStmt);
678 n->name = "timezone";
682 | SET TRANSACTION ISOLATION LEVEL opt_level
684 VariableSetStmt *n = makeNode(VariableSetStmt);
685 n->name = "XactIsoLevel";
689 | SET NAMES opt_encoding
692 VariableSetStmt *n = makeNode(VariableSetStmt);
693 n->name = "client_encoding";
697 elog(ERROR, "SET NAMES is not supported.");
702 opt_level: READ COMMITTED { $$ = "committed"; }
703 | SERIALIZABLE { $$ = "serializable"; }
706 var_value: Sconst { $$ = $1; }
707 | DEFAULT { $$ = NULL; }
710 zone_value: Sconst { $$ = $1; }
711 | DEFAULT { $$ = NULL; }
712 | LOCAL { $$ = NULL; }
715 opt_encoding: Sconst { $$ = $1; }
716 | DEFAULT { $$ = NULL; }
717 | /*EMPTY*/ { $$ = NULL; }
720 VariableShowStmt: SHOW ColId
722 VariableShowStmt *n = makeNode(VariableShowStmt);
728 VariableShowStmt *n = makeNode(VariableShowStmt);
729 n->name = "timezone";
732 | SHOW TRANSACTION ISOLATION LEVEL
734 VariableShowStmt *n = makeNode(VariableShowStmt);
735 n->name = "XactIsoLevel";
740 VariableResetStmt: RESET ColId
742 VariableResetStmt *n = makeNode(VariableResetStmt);
748 VariableResetStmt *n = makeNode(VariableResetStmt);
749 n->name = "timezone";
752 | RESET TRANSACTION ISOLATION LEVEL
754 VariableResetStmt *n = makeNode(VariableResetStmt);
755 n->name = "XactIsoLevel";
761 ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode
763 ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt);
771 constraints_set_list: ALL
775 | constraints_set_namelist
782 constraints_set_namelist: IDENT
784 $$ = lappend(NIL, $1);
786 | constraints_set_namelist ',' IDENT
788 $$ = lappend($1, $3);
793 constraints_set_mode: DEFERRED
804 /*****************************************************************************
806 * ALTER TABLE variations
808 *****************************************************************************/
811 /* ALTER TABLE <name> ADD [COLUMN] <coldef> */
812 ALTER TABLE relation_name opt_inh_star ADD opt_column columnDef
814 AlterTableStmt *n = makeNode(AlterTableStmt);
821 /* ALTER TABLE <name> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
822 | ALTER TABLE relation_name opt_inh_star ALTER opt_column ColId alter_column_action
824 AlterTableStmt *n = makeNode(AlterTableStmt);
832 /* ALTER TABLE <name> DROP [COLUMN] <name> {RESTRICT|CASCADE} */
833 | ALTER TABLE relation_name opt_inh_star DROP opt_column ColId /* drop_behavior */
835 AlterTableStmt *n = makeNode(AlterTableStmt);
840 /* n->behavior = $8; */
843 /* ALTER TABLE <name> ADD CONSTRAINT ... */
844 | ALTER TABLE relation_name opt_inh_star ADD TableConstraint
846 AlterTableStmt *n = makeNode(AlterTableStmt);
853 /* ALTER TABLE <name> DROP CONSTRAINT <name> {RESTRICT|CASCADE} */
854 | ALTER TABLE relation_name opt_inh_star DROP CONSTRAINT name drop_behavior
856 AlterTableStmt *n = makeNode(AlterTableStmt);
867 SET DEFAULT a_expr_or_null { $$ = $3; }
868 | DROP DEFAULT { $$ = NULL; }
871 drop_behavior: CASCADE { $$ = CASCADE; }
872 | RESTRICT { $$ = RESTRICT; }
877 /*****************************************************************************
882 *****************************************************************************/
884 ClosePortalStmt: CLOSE opt_id
886 ClosePortalStmt *n = makeNode(ClosePortalStmt);
892 opt_id: ColId { $$ = $1; }
893 | /*EMPTY*/ { $$ = NULL; }
897 /*****************************************************************************
900 * COPY [BINARY] <relname> FROM/TO
901 * [USING DELIMITERS <delimiter>]
903 *****************************************************************************/
905 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter copy_null
907 CopyStmt *n = makeNode(CopyStmt);
926 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
927 * used depends on the direction. (It really doesn't make sense to copy from
928 * stdout. We silently correct the "typo". - AY 9/94
930 copy_file_name: Sconst { $$ = $1; }
931 | STDIN { $$ = NULL; }
932 | STDOUT { $$ = NULL; }
935 opt_binary: BINARY { $$ = TRUE; }
936 | /*EMPTY*/ { $$ = FALSE; }
939 opt_with_copy: WITH OIDS { $$ = TRUE; }
940 | /*EMPTY*/ { $$ = FALSE; }
944 * the default copy delimiter is tab but the user can configure it
946 copy_delimiter: opt_using DELIMITERS Sconst { $$ = $3; }
947 | /*EMPTY*/ { $$ = "\t"; }
950 opt_using: USING { $$ = TRUE; }
951 | /*EMPTY*/ { $$ = TRUE; }
954 copy_null: WITH NULL_P AS Sconst { $$ = $4; }
955 | /*EMPTY*/ { $$ = "\\N"; }
957 /*****************************************************************************
962 *****************************************************************************/
964 CreateStmt: CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
967 CreateStmt *n = makeNode(CreateStmt);
972 n->constraints = NIL;
977 OptTemp: OptTempType { $$ = $1; }
978 | OptTempScope OptTempType { $$ = $2; }
981 OptTempType: TEMP { $$ = TRUE; }
982 | TEMPORARY { $$ = TRUE; }
983 | /*EMPTY*/ { $$ = FALSE; }
988 elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
997 OptTableElementList: OptTableElementList ',' OptTableElement
1000 $$ = lappend($1, $3);
1007 $$ = lcons($1, NIL);
1011 | /*EMPTY*/ { $$ = NULL; }
1014 OptTableElement: columnDef { $$ = $1; }
1015 | TableConstraint { $$ = $1; }
1018 columnDef: ColId Typename ColConstraintList
1020 ColumnDef *n = makeNode(ColumnDef);
1023 n->raw_default = NULL;
1024 n->cooked_default = NULL;
1025 n->is_not_null = FALSE;
1026 n->constraints = $3;
1029 | ColId SERIAL ColPrimaryKey
1031 ColumnDef *n = makeNode(ColumnDef);
1033 n->typename = makeNode(TypeName);
1034 n->typename->name = xlateSqlType("integer");
1035 n->typename->typmod = -1;
1036 n->raw_default = NULL;
1037 n->cooked_default = NULL;
1038 n->is_not_null = TRUE;
1039 n->is_sequence = TRUE;
1040 n->constraints = $3;
1046 ColConstraintList: ColConstraintList ColConstraint
1049 $$ = lappend($1, $2);
1057 ColPrimaryKey: PRIMARY KEY
1059 Constraint *n = makeNode(Constraint);
1060 n->contype = CONSTR_PRIMARY;
1063 n->cooked_expr = NULL;
1065 $$ = lcons((Node *)n, NIL);
1067 | /*EMPTY*/ { $$ = NULL; }
1071 CONSTRAINT name ColConstraintElem
1073 switch (nodeTag($3))
1077 Constraint *n = (Constraint *)$3;
1078 if (n != NULL) n->name = $2;
1081 case T_FkConstraint:
1083 FkConstraint *n = (FkConstraint *)$3;
1084 if (n != NULL) n->constr_name = $2;
1097 * DEFAULT NULL is already the default for Postgres.
1098 * But define it here and carry it forward into the system
1099 * to make it explicit.
1100 * - thomas 1998-09-13
1102 * WITH NULL and NULL are not SQL92-standard syntax elements,
1103 * so leave them out. Use DEFAULT NULL to explicitly indicate
1104 * that a column may have that value. WITH NULL leads to
1105 * shift/reduce conflicts with WITH TIME ZONE anyway.
1106 * - thomas 1999-01-08
1108 * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
1109 * conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
1110 * or be part of a_expr NOT LIKE or similar constructs).
1112 ColConstraintElem: CHECK '(' a_expr ')'
1114 Constraint *n = makeNode(Constraint);
1115 n->contype = CONSTR_CHECK;
1118 n->cooked_expr = NULL;
1124 Constraint *n = makeNode(Constraint);
1125 n->contype = CONSTR_DEFAULT;
1128 n->cooked_expr = NULL;
1134 Constraint *n = makeNode(Constraint);
1135 n->contype = CONSTR_DEFAULT;
1138 n->cooked_expr = NULL;
1144 Constraint *n = makeNode(Constraint);
1145 n->contype = CONSTR_NOTNULL;
1148 n->cooked_expr = NULL;
1154 Constraint *n = makeNode(Constraint);
1155 n->contype = CONSTR_UNIQUE;
1158 n->cooked_expr = NULL;
1164 Constraint *n = makeNode(Constraint);
1165 n->contype = CONSTR_PRIMARY;
1168 n->cooked_expr = NULL;
1172 | REFERENCES ColId opt_column_list key_match key_actions
1175 * Need ConstraintAttributeSpec as $6 -- Jan
1177 FkConstraint *n = makeNode(FkConstraint);
1178 n->constr_name = NULL;
1179 n->pktable_name = $2;
1184 n->deferrable = true;
1185 n->initdeferred = false;
1187 n->deferrable = ($6 & 1) != 0;
1188 n->initdeferred = ($6 & 2) != 0;
1194 /* ConstraintElem specifies constraint syntax which is not embedded into
1195 * a column definition. ColConstraintElem specifies the embedded form.
1196 * - thomas 1997-12-03
1198 TableConstraint: CONSTRAINT name ConstraintElem
1200 switch (nodeTag($3))
1204 Constraint *n = (Constraint *)$3;
1205 if (n != NULL) n->name = $2;
1208 case T_FkConstraint:
1210 FkConstraint *n = (FkConstraint *)$3;
1211 if (n != NULL) n->constr_name = $2;
1223 ConstraintElem: CHECK '(' a_expr ')'
1225 Constraint *n = makeNode(Constraint);
1226 n->contype = CONSTR_CHECK;
1229 n->cooked_expr = NULL;
1232 | UNIQUE '(' columnList ')'
1234 Constraint *n = makeNode(Constraint);
1235 n->contype = CONSTR_UNIQUE;
1238 n->cooked_expr = NULL;
1242 | PRIMARY KEY '(' columnList ')'
1244 Constraint *n = makeNode(Constraint);
1245 n->contype = CONSTR_PRIMARY;
1248 n->cooked_expr = NULL;
1252 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions ConstraintAttributeSpec
1254 FkConstraint *n = makeNode(FkConstraint);
1255 n->constr_name = NULL;
1256 n->pktable_name = $7;
1261 n->deferrable = ($11 & 1) != 0;
1262 n->initdeferred = ($11 & 2) != 0;
1267 key_match: MATCH FULL
1273 elog(ERROR, "FOREIGN KEY match type PARTIAL not implemented yet");
1278 elog(ERROR, "FOREIGN KEY match type UNSPECIFIED not implemented yet");
1283 key_actions: key_action key_action { $$ = $1 | $2; }
1284 | key_action { $$ = $1; }
1285 | /*EMPTY*/ { $$ = 0; }
1288 key_action: ON DELETE key_reference { $$ = $3 << FKCONSTR_ON_DELETE_SHIFT; }
1289 | ON UPDATE key_reference { $$ = $3 << FKCONSTR_ON_UPDATE_SHIFT; }
1292 key_reference: NO ACTION { $$ = FKCONSTR_ON_KEY_NOACTION; }
1293 | RESTRICT { $$ = FKCONSTR_ON_KEY_RESTRICT; }
1294 | CASCADE { $$ = FKCONSTR_ON_KEY_CASCADE; }
1295 | SET NULL_P { $$ = FKCONSTR_ON_KEY_SETNULL; }
1296 | SET DEFAULT { $$ = FKCONSTR_ON_KEY_SETDEFAULT; }
1299 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1300 | /*EMPTY*/ { $$ = NIL; }
1304 * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1308 CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
1310 SelectStmt *n = (SelectStmt *)$7;
1312 mapTargetColumns($5, n->targetList);
1313 if (n->into != NULL)
1314 elog(ERROR,"CREATE TABLE/AS SELECT may not specify INTO");
1321 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1322 | /*EMPTY*/ { $$ = NULL; }
1325 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1326 | CreateAsElement { $$ = lcons($1, NIL); }
1329 CreateAsElement: ColId
1331 ColumnDef *n = makeNode(ColumnDef);
1334 n->raw_default = NULL;
1335 n->cooked_default = NULL;
1336 n->is_not_null = FALSE;
1337 n->constraints = NULL;
1343 /*****************************************************************************
1346 * CREATE SEQUENCE seqname
1348 *****************************************************************************/
1350 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1352 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1359 OptSeqList: OptSeqList OptSeqElem
1360 { $$ = lappend($1, $2); }
1364 OptSeqElem: CACHE IntegerOnly
1366 $$ = makeNode(DefElem);
1367 $$->defname = "cache";
1368 $$->arg = (Node *)$2;
1372 $$ = makeNode(DefElem);
1373 $$->defname = "cycle";
1374 $$->arg = (Node *)NULL;
1376 | INCREMENT IntegerOnly
1378 $$ = makeNode(DefElem);
1379 $$->defname = "increment";
1380 $$->arg = (Node *)$2;
1382 | MAXVALUE IntegerOnly
1384 $$ = makeNode(DefElem);
1385 $$->defname = "maxvalue";
1386 $$->arg = (Node *)$2;
1388 | MINVALUE IntegerOnly
1390 $$ = makeNode(DefElem);
1391 $$->defname = "minvalue";
1392 $$->arg = (Node *)$2;
1396 $$ = makeNode(DefElem);
1397 $$->defname = "start";
1398 $$->arg = (Node *)$2;
1402 NumericOnly: FloatOnly { $$ = $1; }
1403 | IntegerOnly { $$ = $1; }
1412 $$->val.dval = - $$->val.dval;
1418 $$ = makeInteger($1);
1422 $$ = makeInteger($2);
1423 $$->val.ival = - $$->val.ival;
1427 /*****************************************************************************
1430 * CREATE PROCEDURAL LANGUAGE ...
1431 * DROP PROCEDURAL LANGUAGE ...
1433 *****************************************************************************/
1435 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1436 HANDLER def_name LANCOMPILER Sconst
1438 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1447 PLangTrusted: TRUSTED { $$ = TRUE; }
1450 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1452 DropPLangStmt *n = makeNode(DropPLangStmt);
1458 /*****************************************************************************
1461 * CREATE TRIGGER ...
1464 *****************************************************************************/
1466 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1467 relation_name TriggerForSpec EXECUTE PROCEDURE
1468 name '(' TriggerFuncArgs ')'
1470 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1477 memcpy (n->actions, $5, 4);
1478 n->lang = NULL; /* unused */
1479 n->text = NULL; /* unused */
1480 n->attr = NULL; /* unused */
1481 n->when = NULL; /* unused */
1483 n->isconstraint = false;
1484 n->deferrable = false;
1485 n->initdeferred = false;
1486 n->constrrelname = NULL;
1489 | CREATE CONSTRAINT TRIGGER name AFTER TriggerOneEvent ON
1490 relation_name OptConstrFromTable
1491 ConstraintAttributeSpec
1492 FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')'
1494 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1502 n->actions[1] = '\0';
1503 n->lang = NULL; /* unused */
1504 n->text = NULL; /* unused */
1505 n->attr = NULL; /* unused */
1506 n->when = NULL; /* unused */
1508 n->isconstraint = true;
1509 n->deferrable = ($10 & 1) != 0;
1510 n->initdeferred = ($10 & 2) != 0;
1512 n->constrrelname = $9;
1517 TriggerActionTime: BEFORE { $$ = TRUE; }
1518 | AFTER { $$ = FALSE; }
1521 TriggerEvents: TriggerOneEvent
1523 char *e = palloc (4);
1524 e[0] = $1; e[1] = 0; $$ = e;
1526 | TriggerOneEvent OR TriggerOneEvent
1528 char *e = palloc (4);
1529 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1531 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1533 char *e = palloc (4);
1534 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1539 TriggerOneEvent: INSERT { $$ = 'i'; }
1540 | DELETE { $$ = 'd'; }
1541 | UPDATE { $$ = 'u'; }
1544 TriggerForSpec: FOR TriggerForOpt TriggerForType
1550 TriggerForOpt: EACH { $$ = TRUE; }
1551 | /*EMPTY*/ { $$ = FALSE; }
1554 TriggerForType: ROW { $$ = TRUE; }
1555 | STATEMENT { $$ = FALSE; }
1558 TriggerFuncArgs: TriggerFuncArg
1559 { $$ = lcons($1, NIL); }
1560 | TriggerFuncArgs ',' TriggerFuncArg
1561 { $$ = lappend($1, $3); }
1566 TriggerFuncArg: ICONST
1568 char *s = (char *) palloc (256);
1569 sprintf (s, "%d", $1);
1574 char *s = (char *) palloc (256);
1575 sprintf (s, "%g", $1);
1578 | Sconst { $$ = $1; }
1579 | IDENT { $$ = $1; }
1582 OptConstrFromTable: /* Empty */
1586 | FROM relation_name
1592 ConstraintAttributeSpec: /* Empty */
1594 | ConstraintDeferrabilitySpec
1596 | ConstraintDeferrabilitySpec ConstraintTimeSpec
1598 if ($1 == 0 && $2 != 0)
1599 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1602 | ConstraintTimeSpec
1609 | ConstraintTimeSpec ConstraintDeferrabilitySpec
1611 if ($2 == 0 && $1 != 0)
1612 elog(ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
1617 ConstraintDeferrabilitySpec: NOT DEFERRABLE
1623 ConstraintTimeSpec: INITIALLY IMMEDIATE
1625 | INITIALLY DEFERRED
1630 DropTrigStmt: DROP TRIGGER name ON relation_name
1632 DropTrigStmt *n = makeNode(DropTrigStmt);
1640 /*****************************************************************************
1643 * define (type,operator,aggregate)
1645 *****************************************************************************/
1647 DefineStmt: CREATE def_type def_rest
1654 def_rest: def_name definition
1656 $$ = makeNode(DefineStmt);
1658 $$->definition = $2;
1662 def_type: OPERATOR { $$ = OPERATOR; }
1663 | TYPE_P { $$ = TYPE_P; }
1664 | AGGREGATE { $$ = AGGREGATE; }
1667 def_name: PROCEDURE { $$ = "procedure"; }
1668 | JOIN { $$ = "join"; }
1669 | ColId { $$ = $1; }
1670 | all_Op { $$ = $1; }
1673 definition: '(' def_list ')' { $$ = $2; }
1676 def_list: def_elem { $$ = lcons($1, NIL); }
1677 | def_list ',' def_elem { $$ = lappend($1, $3); }
1680 def_elem: def_name '=' def_arg
1682 $$ = makeNode(DefElem);
1684 $$->arg = (Node *)$3;
1688 $$ = makeNode(DefElem);
1690 $$->arg = (Node *)NULL;
1692 | DEFAULT '=' def_arg
1694 $$ = makeNode(DefElem);
1695 $$->defname = "default";
1696 $$->arg = (Node *)$3;
1700 def_arg: ColId { $$ = (Node *)makeString($1); }
1701 | all_Op { $$ = (Node *)makeString($1); }
1702 | NumericOnly { $$ = (Node *)$1; }
1703 | Sconst { $$ = (Node *)makeString($1); }
1706 TypeName *n = makeNode(TypeName);
1709 n->arrayBounds = NULL;
1716 /*****************************************************************************
1719 * drop <relname1> [, <relname2> .. <relnameN> ]
1721 *****************************************************************************/
1723 DropStmt: DROP TABLE relation_name_list
1725 DropStmt *n = makeNode(DropStmt);
1727 n->sequence = FALSE;
1730 | DROP SEQUENCE relation_name_list
1732 DropStmt *n = makeNode(DropStmt);
1739 /*****************************************************************************
1742 * truncate table relname
1744 *****************************************************************************/
1746 TruncateStmt: TRUNCATE TABLE relation_name
1748 TruncateStmt *n = makeNode(TruncateStmt);
1754 /*****************************************************************************
1756 * The COMMENT ON statement can take different forms based upon the type of
1757 * the object associated with the comment. The form of the statement is:
1759 * COMMENT ON [ [ DATABASE | INDEX | RULE | SEQUENCE | TABLE | TYPE | VIEW ]
1760 * <objname> | AGGREGATE <aggname> <aggtype> | FUNCTION
1761 * <funcname> (arg1, arg2, ...) | OPERATOR <op>
1762 * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
1763 * <relname> ] IS 'text'
1765 *****************************************************************************/
1767 CommentStmt: COMMENT ON comment_type name IS comment_text
1769 CommentStmt *n = makeNode(CommentStmt);
1772 n->objproperty = NULL;
1777 | COMMENT ON comment_cl relation_name '.' attr_name IS comment_text
1779 CommentStmt *n = makeNode(CommentStmt);
1782 n->objproperty = $6;
1787 | COMMENT ON comment_ag name aggr_argtype IS comment_text
1789 CommentStmt *n = makeNode(CommentStmt);
1792 n->objproperty = $5;
1797 | COMMENT ON comment_fn func_name func_args IS comment_text
1799 CommentStmt *n = makeNode(CommentStmt);
1802 n->objproperty = NULL;
1807 | COMMENT ON comment_op all_Op '(' oper_argtypes ')' IS comment_text
1809 CommentStmt *n = makeNode(CommentStmt);
1812 n->objproperty = NULL;
1817 | COMMENT ON comment_tg name ON relation_name IS comment_text
1819 CommentStmt *n = makeNode(CommentStmt);
1822 n->objproperty = $6;
1829 comment_type: DATABASE { $$ = DATABASE; }
1830 | INDEX { $$ = INDEX; }
1831 | RULE { $$ = RULE; }
1832 | SEQUENCE { $$ = SEQUENCE; }
1833 | TABLE { $$ = TABLE; }
1834 | TYPE_P { $$ = TYPE_P; }
1835 | VIEW { $$ = VIEW; }
1838 comment_cl: COLUMN { $$ = COLUMN; }
1841 comment_ag: AGGREGATE { $$ = AGGREGATE; }
1844 comment_fn: FUNCTION { $$ = FUNCTION; }
1847 comment_op: OPERATOR { $$ = OPERATOR; }
1850 comment_tg: TRIGGER { $$ = TRIGGER; }
1853 comment_text: Sconst { $$ = $1; }
1854 | NULL_P { $$ = NULL; }
1857 /*****************************************************************************
1860 * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
1861 * fetch [ forward | backward | absolute | relative ]
1862 * [ # | all | next | prior ] [ [ in | from ] <portalname> ]
1864 *****************************************************************************/
1866 FetchStmt: FETCH direction fetch_how_many from_in name
1868 FetchStmt *n = makeNode(FetchStmt);
1872 elog(ERROR,"FETCH/RELATIVE at current position is not supported");
1878 $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
1886 | FETCH fetch_how_many from_in name
1888 FetchStmt *n = makeNode(FetchStmt);
1892 n->direction = BACKWARD;
1896 n->direction = FORWARD;
1903 | FETCH direction from_in name
1905 FetchStmt *n = makeNode(FetchStmt);
1916 | FETCH from_in name
1918 FetchStmt *n = makeNode(FetchStmt);
1919 n->direction = FORWARD;
1927 FetchStmt *n = makeNode(FetchStmt);
1928 n->direction = FORWARD;
1935 | MOVE direction fetch_how_many from_in name
1937 FetchStmt *n = makeNode(FetchStmt);
1941 $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
1949 | MOVE fetch_how_many from_in name
1951 FetchStmt *n = makeNode(FetchStmt);
1955 n->direction = BACKWARD;
1959 n->direction = FORWARD;
1966 | MOVE direction from_in name
1968 FetchStmt *n = makeNode(FetchStmt);
1977 FetchStmt *n = makeNode(FetchStmt);
1978 n->direction = FORWARD;
1986 FetchStmt *n = makeNode(FetchStmt);
1987 n->direction = FORWARD;
1995 direction: FORWARD { $$ = FORWARD; }
1996 | BACKWARD { $$ = BACKWARD; }
1997 | RELATIVE { $$ = RELATIVE; }
2000 elog(NOTICE,"FETCH/ABSOLUTE not supported, using RELATIVE");
2005 fetch_how_many: Iconst { $$ = $1; }
2006 | '-' Iconst { $$ = - $2; }
2007 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
2009 | PRIOR { $$ = -1; }
2017 /*****************************************************************************
2020 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
2022 *****************************************************************************/
2024 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
2026 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
2030 privileges: ALL PRIVILEGES
2032 $$ = aclmakepriv("rwaR",0);
2036 $$ = aclmakepriv("rwaR",0);
2038 | operation_commalist
2044 operation_commalist: operation
2046 $$ = aclmakepriv("",$1);
2048 | operation_commalist ',' operation
2050 $$ = aclmakepriv($1,$3);
2056 $$ = ACL_MODE_RD_CHR;
2060 $$ = ACL_MODE_AP_CHR;
2064 $$ = ACL_MODE_WR_CHR;
2068 $$ = ACL_MODE_WR_CHR;
2072 $$ = ACL_MODE_RU_CHR;
2078 $$ = aclmakeuser("A","");
2082 $$ = aclmakeuser("G",$2);
2086 $$ = aclmakeuser("U",$1);
2090 opt_with_grant: WITH GRANT OPTION
2092 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
2098 /*****************************************************************************
2101 * REVOKE [privileges] ON [relation_name] FROM [user]
2103 *****************************************************************************/
2105 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
2107 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
2112 /*****************************************************************************
2115 * create index <indexname> on <relname>
2116 * using <access> "(" (<col> with <op>)+ ")" [with
2119 * [where <qual>] is not supported anymore
2120 *****************************************************************************/
2122 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
2123 access_method_clause '(' index_params ')' opt_with
2125 /* should check that access_method is valid,
2126 etc ... but doesn't */
2127 IndexStmt *n = makeNode(IndexStmt);
2131 n->accessMethod = $7;
2132 n->indexParams = $9;
2133 n->withClause = $11;
2134 n->whereClause = NULL;
2139 index_opt_unique: UNIQUE { $$ = TRUE; }
2140 | /*EMPTY*/ { $$ = FALSE; }
2143 access_method_clause: USING access_method { $$ = $2; }
2144 | /*EMPTY*/ { $$ = "btree"; }
2147 index_params: index_list { $$ = $1; }
2148 | func_index { $$ = lcons($1,NIL); }
2151 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
2152 | index_elem { $$ = lcons($1, NIL); }
2155 func_index: func_name '(' name_list ')' opt_type opt_class
2157 $$ = makeNode(IndexElem);
2165 index_elem: attr_name opt_type opt_class
2167 $$ = makeNode(IndexElem);
2175 opt_type: ':' Typename { $$ = $2; }
2176 | FOR Typename { $$ = $2; }
2177 | /*EMPTY*/ { $$ = NULL; }
2180 /* opt_class "WITH class" conflicts with preceeding opt_type
2181 * for Typename of "TIMESTAMP WITH TIME ZONE"
2182 * So, remove "WITH class" from the syntax. OK??
2183 * - thomas 1997-10-12
2184 * | WITH class { $$ = $2; }
2186 opt_class: class { $$ = $1; }
2187 | USING class { $$ = $2; }
2188 | /*EMPTY*/ { $$ = NULL; }
2192 /*****************************************************************************
2195 * extend index <indexname> [where <qual>]
2197 *****************************************************************************/
2199 ExtendStmt: EXTEND INDEX index_name where_clause
2201 ExtendStmt *n = makeNode(ExtendStmt);
2203 n->whereClause = $4;
2208 /*****************************************************************************
2211 * execute recipe <recipeName>
2213 *****************************************************************************/
2216 RecipeStmt: EXECUTE RECIPE recipe_name
2219 if (!IsTransactionBlock())
2220 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
2222 n = makeNode(RecipeStmt);
2229 /*****************************************************************************
2232 * define function <fname>
2233 * (language = <lang>, returntype = <typename>
2234 * [, arch_pct = <percentage | pre-defined>]
2235 * [, disk_pct = <percentage | pre-defined>]
2236 * [, byte_pct = <percentage | pre-defined>]
2237 * [, perbyte_cpu = <int | pre-defined>]
2238 * [, percall_cpu = <int | pre-defined>]
2240 * [arg is (<type-1> { , <type-n>})]
2241 * as <filename or code in language as appropriate>
2243 *****************************************************************************/
2245 ProcedureStmt: CREATE FUNCTION func_name func_args
2246 RETURNS func_return opt_with AS func_as LANGUAGE Sconst
2248 ProcedureStmt *n = makeNode(ProcedureStmt);
2258 opt_with: WITH definition { $$ = $2; }
2259 | /*EMPTY*/ { $$ = NIL; }
2262 func_args: '(' func_args_list ')' { $$ = $2; }
2263 | '(' ')' { $$ = NIL; }
2266 func_args_list: TypeId
2267 { $$ = lcons(makeString($1),NIL); }
2268 | func_args_list ',' TypeId
2269 { $$ = lappend($1,makeString($3)); }
2273 { $$ = lcons(makeString($1),NIL); }
2275 { $$ = lappend(lcons(makeString($1),NIL), makeString($3)); }
2278 func_return: set_opt TypeId
2280 TypeName *n = makeNode(TypeName);
2283 n->arrayBounds = NULL;
2289 set_opt: SETOF { $$ = TRUE; }
2290 | /*EMPTY*/ { $$ = FALSE; }
2293 /*****************************************************************************
2297 * remove function <funcname>
2298 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
2299 * remove aggregate <aggname>
2300 * (REMOVE AGGREGATE "aggname" "aggtype")
2301 * remove operator <opname>
2302 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
2303 * remove type <typename>
2304 * (REMOVE TYPE "typename")
2305 * remove rule <rulename>
2306 * (REMOVE RULE "rulename")
2308 *****************************************************************************/
2310 RemoveStmt: DROP remove_type name
2312 RemoveStmt *n = makeNode(RemoveStmt);
2319 remove_type: TYPE_P { $$ = TYPE_P; }
2320 | INDEX { $$ = INDEX; }
2321 | RULE { $$ = RULE; }
2322 | VIEW { $$ = VIEW; }
2326 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
2328 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
2335 aggr_argtype: name { $$ = $1; }
2336 | '*' { $$ = NULL; }
2340 RemoveFuncStmt: DROP FUNCTION func_name func_args
2342 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
2350 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
2352 RemoveOperStmt *n = makeNode(RemoveOperStmt);
2361 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
2364 { $$ = makeList(makeString($1), makeString($3), -1); }
2365 | NONE ',' name /* left unary */
2366 { $$ = makeList(NULL, makeString($3), -1); }
2367 | name ',' NONE /* right unary */
2368 { $$ = makeList(makeString($1), NULL, -1); }
2372 /*****************************************************************************
2375 * rename <attrname1> in <relname> [*] to <attrname2>
2376 * rename <relname1> to <relname2>
2378 *****************************************************************************/
2380 RenameStmt: ALTER TABLE relation_name opt_inh_star
2381 RENAME opt_column opt_name TO name
2383 RenameStmt *n = makeNode(RenameStmt);
2392 opt_name: name { $$ = $1; }
2393 | /*EMPTY*/ { $$ = NULL; }
2396 opt_column: COLUMN { $$ = COLUMN; }
2397 | /*EMPTY*/ { $$ = 0; }
2401 /*****************************************************************************
2403 * QUERY: Define Rewrite Rule , Define Tuple Rule
2404 * Define Rule <old rules >
2406 * only rewrite rule is supported -- ay 9/94
2408 *****************************************************************************/
2410 RuleStmt: CREATE RULE name AS
2411 { QueryIsRule=TRUE; }
2412 ON event TO event_object where_clause
2413 DO opt_instead RuleActionList
2415 RuleStmt *n = makeNode(RuleStmt);
2419 n->whereClause = $10;
2426 RuleActionList: NOTHING { $$ = NIL; }
2427 | SelectStmt { $$ = lcons($1, NIL); }
2428 | RuleActionStmt { $$ = lcons($1, NIL); }
2429 | '[' RuleActionMulti ']' { $$ = $2; }
2430 | '(' RuleActionMulti ')' { $$ = $2; }
2433 /* the thrashing around here is to discard "empty" statements... */
2434 RuleActionMulti: RuleActionMulti ';' RuleActionStmtOrEmpty
2435 { if ($3 != (Node *)NULL)
2436 $$ = lappend($1, $3);
2440 | RuleActionStmtOrEmpty
2441 { if ($1 != (Node *)NULL)
2448 RuleActionStmt: InsertStmt
2454 RuleActionStmtOrEmpty: RuleActionStmt
2456 { $$ = (Node *)NULL; }
2459 event_object: relation_name '.' attr_name
2461 $$ = makeNode(Attr);
2464 $$->attrs = lcons(makeString($3), NIL);
2465 $$->indirection = NIL;
2469 $$ = makeNode(Attr);
2473 $$->indirection = NIL;
2477 /* change me to select, update, etc. some day */
2478 event: SELECT { $$ = CMD_SELECT; }
2479 | UPDATE { $$ = CMD_UPDATE; }
2480 | DELETE { $$ = CMD_DELETE; }
2481 | INSERT { $$ = CMD_INSERT; }
2484 opt_instead: INSTEAD { $$ = TRUE; }
2485 | /*EMPTY*/ { $$ = FALSE; }
2489 /*****************************************************************************
2492 * NOTIFY <relation_name> can appear both in rule bodies and
2493 * as a query-level command
2495 *****************************************************************************/
2497 NotifyStmt: NOTIFY relation_name
2499 NotifyStmt *n = makeNode(NotifyStmt);
2505 ListenStmt: LISTEN relation_name
2507 ListenStmt *n = makeNode(ListenStmt);
2513 UnlistenStmt: UNLISTEN relation_name
2515 UnlistenStmt *n = makeNode(UnlistenStmt);
2521 UnlistenStmt *n = makeNode(UnlistenStmt);
2528 /*****************************************************************************
2539 *****************************************************************************/
2541 TransactionStmt: ABORT_TRANS opt_trans
2543 TransactionStmt *n = makeNode(TransactionStmt);
2544 n->command = ABORT_TRANS;
2547 | BEGIN_TRANS opt_trans
2549 TransactionStmt *n = makeNode(TransactionStmt);
2550 n->command = BEGIN_TRANS;
2555 TransactionStmt *n = makeNode(TransactionStmt);
2556 n->command = END_TRANS;
2559 | END_TRANS opt_trans
2561 TransactionStmt *n = makeNode(TransactionStmt);
2562 n->command = END_TRANS;
2565 | ROLLBACK opt_trans
2567 TransactionStmt *n = makeNode(TransactionStmt);
2568 n->command = ABORT_TRANS;
2573 opt_trans: WORK { $$ = TRUE; }
2574 | TRANSACTION { $$ = TRUE; }
2575 | /*EMPTY*/ { $$ = TRUE; }
2579 /*****************************************************************************
2582 * define view <viewname> '('target-list ')' [where <quals> ]
2584 *****************************************************************************/
2586 ViewStmt: CREATE VIEW name AS SelectStmt
2588 ViewStmt *n = makeNode(ViewStmt);
2590 n->query = (Query *)$5;
2591 if (((SelectStmt *)n->query)->sortClause != NULL)
2592 elog(ERROR,"Order by and Distinct on views is not implemented.");
2593 if (((SelectStmt *)n->query)->unionClause != NULL)
2594 elog(ERROR,"Views on unions not implemented.");
2595 if (((SelectStmt *)n->query)->forUpdate != NULL)
2596 elog(ERROR, "SELECT FOR UPDATE is not allowed in CREATE VIEW");
2602 /*****************************************************************************
2607 *****************************************************************************/
2609 LoadStmt: LOAD file_name
2611 LoadStmt *n = makeNode(LoadStmt);
2618 /*****************************************************************************
2623 *****************************************************************************/
2625 CreatedbStmt: CREATE DATABASE database_name WITH createdb_opt_location createdb_opt_encoding
2629 if ($5 == NULL && $6 == -1)
2630 elog(ERROR, "CREATE DATABASE WITH requires at least one option.");
2632 n = makeNode(CreatedbStmt);
2642 | CREATE DATABASE database_name
2644 CreatedbStmt *n = makeNode(CreatedbStmt);
2648 n->encoding = GetTemplateEncoding();
2656 createdb_opt_location: LOCATION '=' Sconst { $$ = $3; }
2657 | LOCATION '=' DEFAULT { $$ = NULL; }
2658 | /*EMPTY*/ { $$ = NULL; }
2661 createdb_opt_encoding:
2666 i = pg_char_to_encoding($3);
2668 elog(ERROR, "%s is not a valid encoding name.", $3);
2671 elog(ERROR, "WITH ENCODING is not supported.");
2674 | ENCODING '=' Iconst
2677 if (!pg_get_encent_by_encoding($3))
2678 elog(ERROR, "%d is not a valid encoding code.", $3);
2681 elog(ERROR, "WITH ENCODING is not supported.");
2684 | ENCODING '=' DEFAULT
2687 $$ = GetTemplateEncoding();
2695 $$ = GetTemplateEncoding();
2703 /*****************************************************************************
2708 *****************************************************************************/
2710 DropdbStmt: DROP DATABASE database_name
2712 DropdbStmt *n = makeNode(DropdbStmt);
2719 /*****************************************************************************
2722 * cluster <index_name> on <relation_name>
2724 *****************************************************************************/
2726 ClusterStmt: CLUSTER index_name ON relation_name
2728 ClusterStmt *n = makeNode(ClusterStmt);
2735 /*****************************************************************************
2740 *****************************************************************************/
2742 VacuumStmt: VACUUM opt_verbose opt_analyze
2744 VacuumStmt *n = makeNode(VacuumStmt);
2751 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2753 VacuumStmt *n = makeNode(VacuumStmt);
2758 if ( $5 != NIL && !$4 )
2759 elog(ERROR,"parser: syntax error at or near \"(\"");
2764 opt_verbose: VERBOSE { $$ = TRUE; }
2765 | /*EMPTY*/ { $$ = FALSE; }
2768 opt_analyze: ANALYZE { $$ = TRUE; }
2769 | /*EMPTY*/ { $$ = FALSE; }
2772 opt_va_list: '(' va_list ')' { $$ = $2; }
2773 | /*EMPTY*/ { $$ = NIL; }
2777 { $$=lcons($1,NIL); }
2779 { $$=lappend($1,$3); }
2783 /*****************************************************************************
2788 *****************************************************************************/
2790 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2792 ExplainStmt *n = makeNode(ExplainStmt);
2794 n->query = (Query*)$3;
2800 /*****************************************************************************
2802 * Optimizable Stmts: *
2804 * one of the five queries processed by the planner *
2806 * [ultimately] produces query-trees as specified *
2807 * in the query-spec document in ~postgres/ref *
2809 *****************************************************************************/
2811 OptimizableStmt: SelectStmt
2816 | DeleteStmt /* by default all are $$=$1 */
2820 /*****************************************************************************
2825 *****************************************************************************/
2827 /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
2828 * originally. When the second rule of 'insert_rest' was changed to use the
2829 * new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
2830 * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to
2831 * accept the same statements without any shift/reduce conflicts
2833 InsertStmt: INSERT INTO relation_name insert_rest
2840 insert_rest: VALUES '(' target_list ')'
2842 $$ = makeNode(InsertStmt);
2845 $$->targetList = $3;
2846 $$->fromClause = NIL;
2847 $$->whereClause = NULL;
2848 $$->groupClause = NIL;
2849 $$->havingClause = NULL;
2850 $$->unionClause = NIL;
2854 $$ = makeNode(InsertStmt);
2856 $$->targetList = NIL;
2857 $$->fromClause = NIL;
2858 $$->whereClause = NULL;
2859 $$->groupClause = NIL;
2860 $$->havingClause = NULL;
2861 $$->unionClause = NIL;
2862 $$->intersectClause = NIL;
2864 /* We want the full power of SelectStatements including INTERSECT and EXCEPT
2865 * for insertion. However, we can't support sort or limit clauses.
2869 SelectStmt *n = (SelectStmt *) $1;
2871 elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
2872 $$ = makeNode(InsertStmt);
2874 $$->unique = n->unique;
2875 $$->targetList = n->targetList;
2876 $$->fromClause = n->fromClause;
2877 $$->whereClause = n->whereClause;
2878 $$->groupClause = n->groupClause;
2879 $$->havingClause = n->havingClause;
2880 $$->unionClause = n->unionClause;
2881 $$->intersectClause = n->intersectClause;
2882 $$->unionall = n->unionall;
2883 $$->forUpdate = n->forUpdate;
2885 | '(' columnList ')' VALUES '(' target_list ')'
2887 $$ = makeNode(InsertStmt);
2890 $$->targetList = $6;
2891 $$->fromClause = NIL;
2892 $$->whereClause = NULL;
2893 $$->groupClause = NIL;
2894 $$->havingClause = NULL;
2895 $$->unionClause = NIL;
2896 $$->intersectClause = NIL;
2898 | '(' columnList ')' SelectStmt
2900 SelectStmt *n = (SelectStmt *) $4;
2902 elog(ERROR, "INSERT ... SELECT can't have ORDER BY");
2903 $$ = makeNode(InsertStmt);
2905 $$->unique = n->unique;
2906 $$->targetList = n->targetList;
2907 $$->fromClause = n->fromClause;
2908 $$->whereClause = n->whereClause;
2909 $$->groupClause = n->groupClause;
2910 $$->havingClause = n->havingClause;
2911 $$->unionClause = n->unionClause;
2912 $$->intersectClause = n->intersectClause;
2913 $$->unionall = n->unionall;
2914 $$->forUpdate = n->forUpdate;
2918 opt_column_list: '(' columnList ')' { $$ = $2; }
2919 | /*EMPTY*/ { $$ = NIL; }
2923 columnList ',' columnElem
2924 { $$ = lappend($1, $3); }
2926 { $$ = lcons($1, NIL); }
2929 columnElem: ColId opt_indirection
2931 Ident *id = makeNode(Ident);
2933 id->indirection = $2;
2939 /*****************************************************************************
2944 *****************************************************************************/
2946 DeleteStmt: DELETE FROM relation_name
2949 DeleteStmt *n = makeNode(DeleteStmt);
2951 n->whereClause = $4;
2956 LockStmt: LOCK_P opt_table relation_name opt_lock
2958 LockStmt *n = makeNode(LockStmt);
2966 opt_lock: IN lock_type MODE { $$ = $2; }
2967 | /*EMPTY*/ { $$ = AccessExclusiveLock; }
2970 lock_type: SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; }
2971 | ROW opt_lmode { $$ = ($2? RowShareLock: RowExclusiveLock); }
2972 | ACCESS opt_lmode { $$ = ($2? AccessShareLock: AccessExclusiveLock); }
2973 | opt_lmode { $$ = ($1? ShareLock: ExclusiveLock); }
2976 opt_lmode: SHARE { $$ = TRUE; }
2977 | EXCLUSIVE { $$ = FALSE; }
2981 /*****************************************************************************
2984 * UpdateStmt (UPDATE)
2986 *****************************************************************************/
2988 UpdateStmt: UPDATE relation_name
2989 SET update_target_list
2993 UpdateStmt *n = makeNode(UpdateStmt);
2997 n->whereClause = $6;
3003 /*****************************************************************************
3008 *****************************************************************************/
3009 CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
3013 n= (SelectStmt *)$6;
3014 /* from PORTAL name */
3016 * 15 august 1991 -- since 3.0 postgres does locking
3017 * right, we discovered that portals were violating
3018 * locking protocol. portal locks cannot span xacts.
3019 * as a short-term fix, we installed the check here.
3022 if (!IsTransactionBlock())
3023 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
3027 if (n->forUpdate != NULL)
3028 elog(ERROR,"DECLARE/UPDATE not supported;"
3029 " Cursors must be READ ONLY.");
3034 opt_cursor: BINARY { $$ = TRUE; }
3035 | INSENSITIVE { $$ = FALSE; }
3036 | SCROLL { $$ = FALSE; }
3037 | INSENSITIVE SCROLL { $$ = FALSE; }
3038 | /*EMPTY*/ { $$ = FALSE; }
3041 /*****************************************************************************
3046 *****************************************************************************/
3048 /* A complete SELECT statement looks like this. Note sort, for_update,
3049 * and limit clauses can only appear once, not in each subselect.
3051 * The rule returns a SelectStmt Node having the set operations attached to
3052 * unionClause and intersectClause (NIL if no set operations were present)
3055 SelectStmt: select_clause sort_clause for_update_clause opt_select_limit
3057 if IsA($1, SelectStmt)
3059 /* There were no set operations, so just attach the
3062 SelectStmt *n = (SelectStmt *) $1;
3065 n->limitOffset = nth(0, $4);
3066 n->limitCount = nth(1, $4);
3071 /* There were set operations. The root of the operator
3072 * tree is delivered by $1, but we must hand back a
3073 * SelectStmt node not an A_Expr Node.
3074 * So we find the leftmost 'SelectStmt' in the operator
3075 * tree $1 (which is the first Select Statement in the
3076 * query), which will be the returned node.
3077 * Then we attach the whole operator tree to that node's
3078 * 'intersectClause', and a list of all 'SelectStmt' Nodes
3079 * in the tree to its 'unionClause'. (NOTE that this means
3080 * the top node has indirect recursive pointers to itself!
3081 * This would cause trouble if we tried copyObject!!)
3082 * The intersectClause and unionClause subtrees will be
3083 * left untouched by the main parser, and will only be
3084 * processed when control gets to the function
3085 * Except_Intersect_Rewrite() (in rewriteHandler.c).
3087 Node *op = (Node *) $1;
3088 List *select_list = NIL;
3089 SelectStmt *first_select;
3090 bool intersect_present = false,
3091 unionall_present = false;
3093 /* Take the operator tree as an argument and create a
3094 * list of all SelectStmt Nodes found in the tree.
3096 * If one of the SelectStmt Nodes has the 'unionall' flag
3097 * set to true the 'unionall_present' flag is also set to
3100 create_select_list(op, &select_list, &unionall_present);
3102 /* Replace all the A_Expr Nodes in the operator tree by
3105 * If an INTERSECT or an EXCEPT is present, the
3106 * 'intersect_present' flag is set to true
3108 op = A_Expr_to_Expr(op, &intersect_present);
3110 /* If both flags are set to true we have a UNION ALL
3111 * statement mixed up with INTERSECT or EXCEPT
3112 * which can not be handled at the moment.
3114 if (intersect_present && unionall_present)
3115 elog(ERROR, "UNION ALL not allowed in mixed set operations");
3117 /* Get the leftmost SeletStmt Node (which automatically
3118 * represents the first Select Statement of the query!)
3120 first_select = (SelectStmt *) lfirst(select_list);
3122 /* Attach the list of all SeletStmt Nodes to unionClause */
3123 first_select->unionClause = select_list;
3125 /* Attach the whole operator tree to intersectClause */
3126 first_select->intersectClause = (List *) op;
3128 /* finally attach the sort clause &etc */
3129 first_select->sortClause = $2;
3130 first_select->forUpdate = $3;
3131 first_select->limitOffset = nth(0, $4);
3132 first_select->limitCount = nth(1, $4);
3133 $$ = (Node *) first_select;
3135 if (((SelectStmt *)$$)->forUpdate != NULL && QueryIsRule)
3136 elog(ERROR, "SELECT FOR UPDATE is not allowed in RULES");
3140 /* This rule parses Select statements that can appear within set operations,
3141 * including UNION, INTERSECT and EXCEPT. '(' and ')' can be used to specify
3142 * the ordering of the set operations. Without '(' and ')' we want the
3143 * operations to be left associative.
3145 * Note that sort clauses cannot be included at this level --- a sort clause
3146 * can only appear at the end of the complete Select, and it will be handled
3147 * by the topmost SelectStmt rule. Likewise FOR UPDATE and LIMIT.
3149 * The rule builds up an operator tree using A_Expr Nodes. AND Nodes represent
3150 * INTERSECTs, OR Nodes represent UNIONs, and AND NOT nodes represent EXCEPTs.
3151 * The SelectStatements to be connected are the left and right arguments to
3153 * If no set operations appear in the query, the tree consists only of one
3156 select_clause: '(' select_clause ')'
3164 | select_clause EXCEPT select_clause
3166 $$ = (Node *)makeA_Expr(AND,NULL,$1,
3167 makeA_Expr(NOT,NULL,NULL,$3));
3169 | select_clause UNION opt_all select_clause
3171 if (IsA($4, SelectStmt))
3173 SelectStmt *n = (SelectStmt *)$4;
3175 /* NOTE: if UNION ALL appears with a parenthesized set
3176 * operation to its right, the ALL is silently discarded.
3177 * Should we generate an error instead? I think it may
3178 * be OK since ALL with UNION to its right is ignored
3182 $$ = (Node *)makeA_Expr(OR,NULL,$1,$4);
3184 | select_clause INTERSECT select_clause
3186 $$ = (Node *)makeA_Expr(AND,NULL,$1,$3);
3190 SubSelect: SELECT opt_unique target_list
3191 result from_clause where_clause
3192 group_clause having_clause
3194 SelectStmt *n = makeNode(SelectStmt);
3196 n->unionall = FALSE;
3198 /* This is new: Subselects support the INTO clause
3199 * which allows queries that are not part of the
3200 * SQL92 standard and should not be formulated!
3201 * We need it for INTERSECT and EXCEPT and I did not
3202 * want to create a new rule 'SubSelect1' including the
3203 * feature. If it makes troubles we will have to add
3204 * a new rule and change this to prevent INTOs in
3207 n->istemp = (bool) ((Value *) lfirst($4))->val.ival;
3208 n->into = (char *) lnext($4);
3211 n->whereClause = $6;
3212 n->groupClause = $7;
3213 n->havingClause = $8;
3218 /* easy way to return two values. Can someone improve this? bjm */
3219 result: INTO OptTemp opt_table relation_name { $$ = lcons(makeInteger($2), (List *)$4); }
3220 | /*EMPTY*/ { $$ = lcons(makeInteger(false), NIL); }
3223 opt_table: TABLE { $$ = TRUE; }
3224 | /*EMPTY*/ { $$ = FALSE; }
3227 opt_all: ALL { $$ = TRUE; }
3228 | /*EMPTY*/ { $$ = FALSE; }
3231 opt_unique: DISTINCT { $$ = "*"; }
3232 | DISTINCT ON ColId { $$ = $3; }
3233 | ALL { $$ = NULL; }
3234 | /*EMPTY*/ { $$ = NULL; }
3237 sort_clause: ORDER BY sortby_list { $$ = $3; }
3238 | /*EMPTY*/ { $$ = NIL; }
3241 sortby_list: sortby { $$ = lcons($1, NIL); }
3242 | sortby_list ',' sortby { $$ = lappend($1, $3); }
3245 sortby: a_expr OptUseOp
3247 $$ = makeNode(SortGroupBy);
3253 OptUseOp: USING all_Op { $$ = $2; }
3255 | DESC { $$ = ">"; }
3256 | /*EMPTY*/ { $$ = "<"; /*default*/ }
3260 opt_select_limit: LIMIT select_limit_value ',' select_offset_value
3261 { $$ = lappend(lappend(NIL, $4), $2); }
3262 | LIMIT select_limit_value OFFSET select_offset_value
3263 { $$ = lappend(lappend(NIL, $4), $2); }
3264 | LIMIT select_limit_value
3265 { $$ = lappend(lappend(NIL, NULL), $2); }
3266 | OFFSET select_offset_value LIMIT select_limit_value
3267 { $$ = lappend(lappend(NIL, $2), $4); }
3268 | OFFSET select_offset_value
3269 { $$ = lappend(lappend(NIL, $2), NULL); }
3271 { $$ = lappend(lappend(NIL, NULL), NULL); }
3274 select_limit_value: Iconst
3276 Const *n = makeNode(Const);
3279 elog(ERROR, "selection limit must be ALL or a positive integer value > 0");
3281 n->consttype = INT4OID;
3282 n->constlen = sizeof(int4);
3283 n->constvalue = (Datum)$1;
3284 n->constisnull = FALSE;
3285 n->constbyval = TRUE;
3286 n->constisset = FALSE;
3287 n->constiscast = FALSE;
3292 Const *n = makeNode(Const);
3294 n->consttype = INT4OID;
3295 n->constlen = sizeof(int4);
3296 n->constvalue = (Datum)0;
3297 n->constisnull = FALSE;
3298 n->constbyval = TRUE;
3299 n->constisset = FALSE;
3300 n->constiscast = FALSE;
3305 Param *n = makeNode(Param);
3307 n->paramkind = PARAM_NUM;
3309 n->paramtype = INT4OID;
3314 select_offset_value: Iconst
3316 Const *n = makeNode(Const);
3318 n->consttype = INT4OID;
3319 n->constlen = sizeof(int4);
3320 n->constvalue = (Datum)$1;
3321 n->constisnull = FALSE;
3322 n->constbyval = TRUE;
3323 n->constisset = FALSE;
3324 n->constiscast = FALSE;
3329 Param *n = makeNode(Param);
3331 n->paramkind = PARAM_NUM;
3333 n->paramtype = INT4OID;
3338 * jimmy bell-style recursive queries aren't supported in the
3341 * ...however, recursive addattr and rename supported. make special
3344 opt_inh_star: '*' { $$ = TRUE; }
3345 | /*EMPTY*/ { $$ = FALSE; }
3348 relation_name_list: name_list;
3351 { $$ = lcons(makeString($1),NIL); }
3352 | name_list ',' name
3353 { $$ = lappend($1,makeString($3)); }
3356 group_clause: GROUP BY expr_list { $$ = $3; }
3357 | /*EMPTY*/ { $$ = NIL; }
3360 having_clause: HAVING a_expr
3364 | /*EMPTY*/ { $$ = NULL; }
3367 for_update_clause: FOR UPDATE update_list { $$ = $3; }
3368 | FOR READ ONLY { $$ = NULL; }
3369 | /* EMPTY */ { $$ = NULL; }
3372 update_list: OF va_list { $$ = $2; }
3373 | /* EMPTY */ { $$ = lcons(NULL, NULL); }
3376 /*****************************************************************************
3378 * clauses common to all Optimizable Stmts:
3382 *****************************************************************************/
3384 from_clause: FROM from_expr { $$ = $2; }
3385 | /*EMPTY*/ { $$ = NIL; }
3388 from_expr: '(' join_clause_with_union ')'
3396 table_list: table_list ',' table_expr
3397 { $$ = lappend($1, $3); }
3399 { $$ = lcons($1, NIL); }
3402 table_expr: relation_expr AS ColLabel
3404 $$ = makeNode(RangeVar);
3408 | relation_expr ColId
3410 $$ = makeNode(RangeVar);
3416 $$ = makeNode(RangeVar);
3422 /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
3423 * all result rows which would have matched on an INNER JOIN.
3424 * Let's reject this for now. - thomas 1999-01-08
3426 join_clause_with_union: join_clause
3428 | table_expr UNION JOIN table_expr
3429 { elog(ERROR,"UNION JOIN not yet implemented"); }
3432 join_clause: table_expr join_list
3434 Node *n = lfirst($2);
3436 /* JoinExpr came back? then it is a join of some sort...
3438 if (IsA(n, JoinExpr))
3440 JoinExpr *j = (JoinExpr *)n;
3444 /* otherwise, it was a cross join,
3445 * which we just represent as an inner join...
3452 join_list: join_list join_expr
3454 $$ = lappend($1, $2);
3458 $$ = lcons($1, NIL);
3462 /* This is everything but the left side of a join.
3463 * Note that a CROSS JOIN is the same as an unqualified
3464 * inner join, so just pass back the right-side table.
3465 * A NATURAL JOIN implicitly matches column names between
3466 * tables, so we'll collect those during the later transformation.
3468 join_expr: join_type JOIN table_expr join_qual
3470 JoinExpr *n = makeNode(JoinExpr);
3472 n->rarg = (Node *)$3;
3476 | NATURAL join_type JOIN table_expr
3478 JoinExpr *n = makeNode(JoinExpr);
3480 n->rarg = (Node *)$4;
3481 n->quals = NULL; /* figure out which columns later... */
3484 | CROSS JOIN table_expr
3485 { $$ = (Node *)$3; }
3488 /* OUTER is just noise... */
3489 join_type: FULL join_outer
3492 elog(NOTICE,"FULL OUTER JOIN not yet implemented");
3497 elog(NOTICE,"LEFT OUTER JOIN not yet implemented");
3502 elog(NOTICE,"RIGHT OUTER JOIN not yet implemented");
3507 elog(NOTICE,"OUTER JOIN not yet implemented");
3519 join_outer: OUTER_P { $$ = NULL; }
3520 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
3523 /* JOIN qualification clauses
3524 * Possibilities are:
3525 * USING ( column list ) allows only unqualified column names,
3526 * which must match between tables.
3527 * ON expr allows more general qualifications.
3528 * - thomas 1999-01-07
3531 join_qual: USING '(' using_list ')' { $$ = $3; }
3532 | ON a_expr { $$ = lcons($2, NIL); }
3535 using_list: using_list ',' using_expr { $$ = lappend($1, $3); }
3536 | using_expr { $$ = lcons($1, NIL); }
3541 /* could be a column name or a relation_name */
3542 Ident *n = makeNode(Ident);
3544 n->indirection = NULL;
3549 where_clause: WHERE a_expr { $$ = $2; }
3550 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
3553 relation_expr: relation_name
3555 /* normal relations */
3556 $$ = makeNode(RelExpr);
3560 | relation_name '*' %prec '='
3562 /* inheritance query */
3563 $$ = makeNode(RelExpr);
3568 opt_array_bounds: '[' ']' opt_array_bounds
3569 { $$ = lcons(makeInteger(-1), $3); }
3570 | '[' Iconst ']' opt_array_bounds
3571 { $$ = lcons(makeInteger($2), $4); }
3577 /*****************************************************************************
3580 * SQL92 introduces a large amount of type-specific syntax.
3581 * Define individual clauses to handle these cases, and use
3582 * the generic case to handle regular type-extensible Postgres syntax.
3583 * - thomas 1997-10-10
3585 *****************************************************************************/
3587 Typename: SimpleTypename opt_array_bounds
3590 $$->arrayBounds = $2;
3592 /* Is this the name of a complex type? If so, implement
3595 if (!strcmp(saved_relname, $$->name))
3596 /* This attr is the same type as the relation
3597 * being defined. The classic example: create
3598 * emp(name=text,mgr=emp)
3601 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
3602 /* (Eventually add in here that the set can only
3603 * contain one element.)
3609 | SETOF SimpleTypename
3616 SimpleTypename: Generic
3624 $$ = makeNode(TypeName);
3625 $$->name = xlateSqlType($1);
3630 generic: IDENT { $$ = $1; }
3631 | TYPE_P { $$ = "type"; }
3634 /* SQL92 numeric data types
3635 * Check FLOAT() precision limits assuming IEEE floating types.
3636 * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3637 * - thomas 1997-09-18
3639 Numeric: FLOAT opt_float
3641 $$ = makeNode(TypeName);
3642 $$->name = xlateSqlType($2);
3647 $$ = makeNode(TypeName);
3648 $$->name = xlateSqlType("float8");
3651 | DECIMAL opt_decimal
3653 $$ = makeNode(TypeName);
3654 $$->name = xlateSqlType("decimal");
3657 | NUMERIC opt_numeric
3659 $$ = makeNode(TypeName);
3660 $$->name = xlateSqlType("numeric");
3666 { $$ = xlateSqlType("float8"); }
3668 { $$ = xlateSqlType("float8"); }
3670 { $$ = xlateSqlType("decimal"); }
3672 { $$ = xlateSqlType("numeric"); }
3675 opt_float: '(' Iconst ')'
3678 elog(ERROR,"precision for FLOAT must be at least 1");
3680 $$ = xlateSqlType("float4");
3682 $$ = xlateSqlType("float8");
3684 elog(ERROR,"precision for FLOAT must be less than 16");
3688 $$ = xlateSqlType("float8");
3692 opt_numeric: '(' Iconst ',' Iconst ')'
3694 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3695 elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
3696 $2, NUMERIC_MAX_PRECISION);
3697 if ($4 < 0 || $4 > $2)
3698 elog(ERROR,"NUMERIC scale %d must be between 0 and precision %d",
3701 $$ = (($2 << 16) | $4) + VARHDRSZ;
3705 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3706 elog(ERROR,"NUMERIC precision %d must be between 1 and %d",
3707 $2, NUMERIC_MAX_PRECISION);
3709 $$ = ($2 << 16) + VARHDRSZ;
3713 /* Insert "-1" meaning "default"; may be replaced later */
3718 opt_decimal: '(' Iconst ',' Iconst ')'
3720 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3721 elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
3722 $2, NUMERIC_MAX_PRECISION);
3723 if ($4 < 0 || $4 > $2)
3724 elog(ERROR,"DECIMAL scale %d must be between 0 and precision %d",
3727 $$ = (($2 << 16) | $4) + VARHDRSZ;
3731 if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION)
3732 elog(ERROR,"DECIMAL precision %d must be between 1 and %d",
3733 $2, NUMERIC_MAX_PRECISION);
3735 $$ = ($2 << 16) + VARHDRSZ;
3739 /* Insert "-1" meaning "default"; may be replaced later */
3746 * SQL92 character data types
3747 * The following implements CHAR() and VARCHAR().
3749 Character: character '(' Iconst ')'
3751 $$ = makeNode(TypeName);
3752 $$->name = xlateSqlType($1);
3754 elog(ERROR,"length for type '%s' must be at least 1",$1);
3755 else if ($3 > MaxAttrSize)
3756 elog(ERROR,"length for type '%s' cannot exceed %ld",$1,
3759 /* we actually implement these like a varlen, so
3760 * the first 4 bytes is the length. (the difference
3761 * between these and "text" is that we blank-pad and
3762 * truncate where necessary)
3764 $$->typmod = VARHDRSZ + $3;
3768 $$ = makeNode(TypeName);
3769 $$->name = xlateSqlType($1);
3770 /* default length, if needed, will be inserted later */
3775 character: CHARACTER opt_varying opt_charset opt_collate
3778 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
3779 if ($2) type = xlateSqlType("varchar");
3780 else type = xlateSqlType("char");
3783 c = palloc(strlen("var") + strlen($3) + 1);
3786 type = xlateSqlType(c);
3788 type = xlateSqlType($3);
3792 elog(NOTICE,"COLLATE %s not yet implemented; clause ignored",$4);
3795 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
3796 | VARCHAR { $$ = xlateSqlType("varchar"); }
3797 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
3798 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
3801 opt_varying: VARYING { $$ = TRUE; }
3802 | /*EMPTY*/ { $$ = FALSE; }
3805 opt_charset: CHARACTER SET ColId { $$ = $3; }
3806 | /*EMPTY*/ { $$ = NULL; }
3809 opt_collate: COLLATE ColId { $$ = $2; }
3810 | /*EMPTY*/ { $$ = NULL; }
3815 $$ = makeNode(TypeName);
3816 $$->name = xlateSqlType($1);
3819 | TIMESTAMP opt_timezone
3821 $$ = makeNode(TypeName);
3822 $$->name = xlateSqlType("timestamp");
3828 $$ = makeNode(TypeName);
3829 $$->name = xlateSqlType("time");
3832 | INTERVAL opt_interval
3834 $$ = makeNode(TypeName);
3835 $$->name = xlateSqlType("interval");
3840 datetime: YEAR_P { $$ = "year"; }
3841 | MONTH_P { $$ = "month"; }
3842 | DAY_P { $$ = "day"; }
3843 | HOUR_P { $$ = "hour"; }
3844 | MINUTE_P { $$ = "minute"; }
3845 | SECOND_P { $$ = "second"; }
3848 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
3849 | /*EMPTY*/ { $$ = FALSE; }
3852 opt_interval: datetime { $$ = lcons($1, NIL); }
3853 | YEAR_P TO MONTH_P { $$ = NIL; }
3854 | DAY_P TO HOUR_P { $$ = NIL; }
3855 | DAY_P TO MINUTE_P { $$ = NIL; }
3856 | DAY_P TO SECOND_P { $$ = NIL; }
3857 | HOUR_P TO MINUTE_P { $$ = NIL; }
3858 | HOUR_P TO SECOND_P { $$ = NIL; }
3859 | MINUTE_P TO SECOND_P { $$ = NIL; }
3860 | /*EMPTY*/ { $$ = NIL; }
3864 /*****************************************************************************
3866 * expression grammar
3868 *****************************************************************************/
3870 a_expr_or_null: a_expr
3874 A_Const *n = makeNode(A_Const);
3875 n->val.type = T_Null;
3880 /* Expressions using row descriptors
3881 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3882 * with singleton expressions.
3884 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3886 SubLink *n = makeNode(SubLink);
3888 n->oper = lcons("=", NIL);
3890 n->subLinkType = ANY_SUBLINK;
3894 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3896 SubLink *n = makeNode(SubLink);
3898 n->oper = lcons("<>", NIL);
3900 n->subLinkType = ALL_SUBLINK;
3904 | '(' row_descriptor ')' all_Op sub_type '(' SubSelect ')'
3906 SubLink *n = makeNode(SubLink);
3908 n->oper = lcons($4, NIL);
3909 if (strcmp($4,"<>") == 0)
3913 n->subLinkType = $5;
3917 | '(' row_descriptor ')' all_Op '(' SubSelect ')'
3919 SubLink *n = makeNode(SubLink);
3921 n->oper = lcons($4, NIL);
3922 if (strcmp($4,"<>") == 0)
3926 n->subLinkType = MULTIEXPR_SUBLINK;
3930 | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
3932 $$ = makeRowExpr($4, $2, $6);
3936 row_descriptor: row_list ',' a_expr
3938 $$ = lappend($1, $3);
3942 row_list: row_list ',' a_expr
3944 $$ = lappend($1, $3);
3948 $$ = lcons($1, NIL);
3952 sub_type: ANY { $$ = ANY_SUBLINK; }
3953 | ALL { $$ = ALL_SUBLINK; }
3956 all_Op: Op | MathOp;
3958 MathOp: '+' { $$ = "+"; }
3971 * General expressions
3972 * This is the heart of the expression syntax.
3974 * We have two expression types: a_expr is the unrestricted kind, and
3975 * b_expr is a subset that must be used in some places to avoid shift/reduce
3976 * conflicts. For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
3977 * because that use of AND conflicts with AND as a boolean operator. So,
3978 * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
3980 * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
3981 * always be used by surrounding it with parens.
3983 * com_expr is all the productions that are common to a_expr and b_expr;
3984 * it's factored out just to eliminate redundant coding.
3988 | a_expr TYPECAST Typename
3989 { $$ = makeTypeCast($1, $3); }
3991 * Can't collapse this into prior rule by using a_expr_or_null;
3992 * that creates reduce/reduce conflicts. Grumble.
3994 | NULL_P TYPECAST Typename
3996 A_Const *n = makeNode(A_Const);
3997 n->val.type = T_Null;
4002 * These operators must be called out explicitly in order to make use
4003 * of yacc/bison's automatic operator-precedence handling. All other
4004 * operator names are handled by the generic productions using "Op",
4005 * below; and all those operators will have the same precedence.
4007 * If you add more explicitly-known operators, be sure to add them
4008 * also to b_expr and to the MathOp list above.
4010 | '-' a_expr %prec UMINUS
4011 { $$ = doNegate($2); }
4013 { $$ = makeA_Expr(OP, "%", NULL, $2); }
4015 { $$ = makeA_Expr(OP, "^", NULL, $2); }
4017 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4019 { $$ = makeA_Expr(OP, ":", NULL, $2); }
4021 { $$ = makeA_Expr(OP, ";", NULL, $2); }
4023 { $$ = makeA_Expr(OP, "%", $1, NULL); }
4025 { $$ = makeA_Expr(OP, "^", $1, NULL); }
4027 { $$ = makeA_Expr(OP, "|", $1, NULL); }
4029 { $$ = makeA_Expr(OP, "+", $1, $3); }
4031 { $$ = makeA_Expr(OP, "-", $1, $3); }
4033 { $$ = makeA_Expr(OP, "*", $1, $3); }
4035 { $$ = makeA_Expr(OP, "/", $1, $3); }
4037 { $$ = makeA_Expr(OP, "%", $1, $3); }
4039 { $$ = makeA_Expr(OP, "^", $1, $3); }
4041 { $$ = makeA_Expr(OP, "|", $1, $3); }
4043 { $$ = makeA_Expr(OP, "<", $1, $3); }
4045 { $$ = makeA_Expr(OP, ">", $1, $3); }
4048 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
4049 /* We allow this for standards-broken SQL products, like MS stuff */
4051 { $$ = makeA_Expr(ISNULL, NULL, $3, NULL); }
4054 { $$ = makeA_Expr(OP, "=", $1, $3); }
4057 { $$ = makeA_Expr(OP, $2, $1, $3); }
4059 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4061 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4064 { $$ = makeA_Expr(AND, NULL, $1, $3); }
4066 { $$ = makeA_Expr(OR, NULL, $1, $3); }
4068 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
4070 | a_expr LIKE a_expr
4071 { $$ = makeA_Expr(OP, "~~", $1, $3); }
4072 | a_expr NOT LIKE a_expr
4073 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
4076 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
4078 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
4080 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
4081 | a_expr IS NOT NULL_P
4082 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
4083 /* IS TRUE, IS FALSE, etc used to be function calls
4084 * but let's make them expressions to allow the optimizer
4085 * a chance to eliminate them if a_expr is a constant string.
4086 * - thomas 1997-12-22
4090 A_Const *n = makeNode(A_Const);
4091 n->val.type = T_String;
4092 n->val.val.str = "t";
4093 n->typename = makeNode(TypeName);
4094 n->typename->name = xlateSqlType("bool");
4095 n->typename->typmod = -1;
4096 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4098 | a_expr IS NOT FALSE_P
4100 A_Const *n = makeNode(A_Const);
4101 n->val.type = T_String;
4102 n->val.val.str = "t";
4103 n->typename = makeNode(TypeName);
4104 n->typename->name = xlateSqlType("bool");
4105 n->typename->typmod = -1;
4106 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4110 A_Const *n = makeNode(A_Const);
4111 n->val.type = T_String;
4112 n->val.val.str = "f";
4113 n->typename = makeNode(TypeName);
4114 n->typename->name = xlateSqlType("bool");
4115 n->typename->typmod = -1;
4116 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4118 | a_expr IS NOT TRUE_P
4120 A_Const *n = makeNode(A_Const);
4121 n->val.type = T_String;
4122 n->val.val.str = "f";
4123 n->typename = makeNode(TypeName);
4124 n->typename->name = xlateSqlType("bool");
4125 n->typename->typmod = -1;
4126 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
4128 | a_expr BETWEEN b_expr AND b_expr
4130 $$ = makeA_Expr(AND, NULL,
4131 makeA_Expr(OP, ">=", $1, $3),
4132 makeA_Expr(OP, "<=", $1, $5));
4134 | a_expr NOT BETWEEN b_expr AND b_expr
4136 $$ = makeA_Expr(OR, NULL,
4137 makeA_Expr(OP, "<", $1, $4),
4138 makeA_Expr(OP, ">", $1, $6));
4140 | a_expr IN '(' in_expr ')'
4142 /* in_expr returns a SubLink or a list of a_exprs */
4143 if (IsA($4, SubLink))
4145 SubLink *n = (SubLink *)$4;
4146 n->lefthand = lcons($1, NIL);
4147 n->oper = lcons("=", NIL);
4149 n->subLinkType = ANY_SUBLINK;
4156 foreach(l, (List *) $4)
4158 Node *cmp = makeA_Expr(OP, "=", $1, lfirst(l));
4162 n = makeA_Expr(OR, NULL, n, cmp);
4167 | a_expr NOT IN '(' in_expr ')'
4169 /* in_expr returns a SubLink or a list of a_exprs */
4170 if (IsA($5, SubLink))
4172 SubLink *n = (SubLink *)$5;
4173 n->lefthand = lcons($1, NIL);
4174 n->oper = lcons("<>", NIL);
4176 n->subLinkType = ALL_SUBLINK;
4183 foreach(l, (List *) $5)
4185 Node *cmp = makeA_Expr(OP, "<>", $1, lfirst(l));
4189 n = makeA_Expr(AND, NULL, n, cmp);
4194 | a_expr all_Op sub_type '(' SubSelect ')'
4196 SubLink *n = makeNode(SubLink);
4197 n->lefthand = lcons($1, NIL);
4198 n->oper = lcons($2, NIL);
4199 n->useor = false; /* doesn't matter since only one col */
4200 n->subLinkType = $3;
4209 * Restricted expressions
4211 * b_expr is a subset of the complete expression syntax defined by a_expr.
4213 * Presently, AND, NOT, IS, IN, and NULL are the a_expr keywords that would
4214 * cause trouble in the places where b_expr is used. For simplicity, we
4215 * just eliminate all the boolean-keyword-operator productions from b_expr.
4219 | b_expr TYPECAST Typename
4220 { $$ = makeTypeCast($1, $3); }
4221 | NULL_P TYPECAST Typename
4223 A_Const *n = makeNode(A_Const);
4224 n->val.type = T_Null;
4228 | '-' b_expr %prec UMINUS
4229 { $$ = doNegate($2); }
4231 { $$ = makeA_Expr(OP, "%", NULL, $2); }
4233 { $$ = makeA_Expr(OP, "^", NULL, $2); }
4235 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4237 { $$ = makeA_Expr(OP, ":", NULL, $2); }
4239 { $$ = makeA_Expr(OP, ";", NULL, $2); }
4241 { $$ = makeA_Expr(OP, "%", $1, NULL); }
4243 { $$ = makeA_Expr(OP, "^", $1, NULL); }
4245 { $$ = makeA_Expr(OP, "|", $1, NULL); }
4247 { $$ = makeA_Expr(OP, "+", $1, $3); }
4249 { $$ = makeA_Expr(OP, "-", $1, $3); }
4251 { $$ = makeA_Expr(OP, "*", $1, $3); }
4253 { $$ = makeA_Expr(OP, "/", $1, $3); }
4255 { $$ = makeA_Expr(OP, "%", $1, $3); }
4257 { $$ = makeA_Expr(OP, "^", $1, $3); }
4259 { $$ = makeA_Expr(OP, "|", $1, $3); }
4261 { $$ = makeA_Expr(OP, "<", $1, $3); }
4263 { $$ = makeA_Expr(OP, ">", $1, $3); }
4265 { $$ = makeA_Expr(OP, "=", $1, $3); }
4268 { $$ = makeA_Expr(OP, $2, $1, $3); }
4270 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4272 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4276 * Productions that can be used in both a_expr and b_expr.
4278 * Note: productions that refer recursively to a_expr or b_expr mostly
4279 * cannot appear here. However, it's OK to refer to a_exprs that occur
4280 * inside parentheses, such as function arguments; that cannot introduce
4281 * ambiguity to the b_expr syntax.
4284 { $$ = (Node *) $1; }
4285 | ColId opt_indirection
4287 /* could be a column name or a relation_name */
4288 Ident *n = makeNode(Ident);
4290 n->indirection = $2;
4295 | '(' a_expr_or_null ')'
4297 | CAST '(' a_expr_or_null AS Typename ')'
4298 { $$ = makeTypeCast($3, $5); }
4303 FuncCall *n = makeNode(FuncCall);
4306 n->agg_star = false;
4307 n->agg_distinct = false;
4310 | func_name '(' expr_list ')'
4312 FuncCall *n = makeNode(FuncCall);
4315 n->agg_star = false;
4316 n->agg_distinct = false;
4319 | func_name '(' DISTINCT expr_list ')'
4321 FuncCall *n = makeNode(FuncCall);
4324 n->agg_star = false;
4325 n->agg_distinct = true;
4328 | func_name '(' '*' ')'
4331 * For now, we transform AGGREGATE(*) into AGGREGATE(1).
4333 * This does the right thing for COUNT(*) (in fact,
4334 * any certainly-non-null expression would do for COUNT),
4335 * and there are no other aggregates in SQL92 that accept
4338 * The FuncCall node is also marked agg_star = true,
4339 * so that later processing can detect what the argument
4342 FuncCall *n = makeNode(FuncCall);
4343 A_Const *star = makeNode(A_Const);
4345 star->val.type = T_Integer;
4346 star->val.val.ival = 1;
4348 n->args = lcons(star, NIL);
4350 n->agg_distinct = false;
4356 * Translate as "date('now'::text)".
4358 * We cannot use "'now'::date" because coerce_type() will
4359 * immediately reduce that to a constant representing
4360 * today's date. We need to delay the conversion until
4361 * runtime, else the wrong things will happen when
4362 * CURRENT_DATE is used in a column default value or rule.
4364 * This could be simplified if we had a way to generate
4365 * an expression tree representing runtime application
4366 * of type-input conversion functions...
4368 A_Const *s = makeNode(A_Const);
4369 TypeName *t = makeNode(TypeName);
4370 FuncCall *n = makeNode(FuncCall);
4372 s->val.type = T_String;
4373 s->val.val.str = "now";
4376 t->name = xlateSqlType("text");
4380 n->funcname = xlateSqlType("date");
4381 n->args = lcons(s, NIL);
4382 n->agg_star = false;
4383 n->agg_distinct = false;
4390 * Translate as "time('now'::text)".
4391 * See comments for CURRENT_DATE.
4393 A_Const *s = makeNode(A_Const);
4394 TypeName *t = makeNode(TypeName);
4395 FuncCall *n = makeNode(FuncCall);
4397 s->val.type = T_String;
4398 s->val.val.str = "now";
4401 t->name = xlateSqlType("text");
4405 n->funcname = xlateSqlType("time");
4406 n->args = lcons(s, NIL);
4407 n->agg_star = false;
4408 n->agg_distinct = false;
4412 | CURRENT_TIME '(' Iconst ')'
4415 * Translate as "time('now'::text)".
4416 * See comments for CURRENT_DATE.
4418 A_Const *s = makeNode(A_Const);
4419 TypeName *t = makeNode(TypeName);
4420 FuncCall *n = makeNode(FuncCall);
4422 s->val.type = T_String;
4423 s->val.val.str = "now";
4426 t->name = xlateSqlType("text");
4430 n->funcname = xlateSqlType("time");
4431 n->args = lcons(s, NIL);
4432 n->agg_star = false;
4433 n->agg_distinct = false;
4436 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4443 * Translate as "timestamp('now'::text)".
4444 * See comments for CURRENT_DATE.
4446 A_Const *s = makeNode(A_Const);
4447 TypeName *t = makeNode(TypeName);
4448 FuncCall *n = makeNode(FuncCall);
4450 s->val.type = T_String;
4451 s->val.val.str = "now";
4454 t->name = xlateSqlType("text");
4458 n->funcname = xlateSqlType("timestamp");
4459 n->args = lcons(s, NIL);
4460 n->agg_star = false;
4461 n->agg_distinct = false;
4465 | CURRENT_TIMESTAMP '(' Iconst ')'
4468 * Translate as "timestamp('now'::text)".
4469 * See comments for CURRENT_DATE.
4471 A_Const *s = makeNode(A_Const);
4472 TypeName *t = makeNode(TypeName);
4473 FuncCall *n = makeNode(FuncCall);
4475 s->val.type = T_String;
4476 s->val.val.str = "now";
4479 t->name = xlateSqlType("text");
4483 n->funcname = xlateSqlType("timestamp");
4484 n->args = lcons(s, NIL);
4485 n->agg_star = false;
4486 n->agg_distinct = false;
4489 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4495 FuncCall *n = makeNode(FuncCall);
4496 n->funcname = "getpgusername";
4498 n->agg_star = false;
4499 n->agg_distinct = false;
4504 FuncCall *n = makeNode(FuncCall);
4505 n->funcname = "getpgusername";
4507 n->agg_star = false;
4508 n->agg_distinct = false;
4511 | EXTRACT '(' extract_list ')'
4513 FuncCall *n = makeNode(FuncCall);
4514 n->funcname = "date_part";
4516 n->agg_star = false;
4517 n->agg_distinct = false;
4520 | POSITION '(' position_list ')'
4522 FuncCall *n = makeNode(FuncCall);
4523 n->funcname = "strpos";
4525 n->agg_star = false;
4526 n->agg_distinct = false;
4529 | SUBSTRING '(' substr_list ')'
4531 FuncCall *n = makeNode(FuncCall);
4532 n->funcname = "substr";
4534 n->agg_star = false;
4535 n->agg_distinct = false;
4538 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4539 | TRIM '(' BOTH trim_list ')'
4541 FuncCall *n = makeNode(FuncCall);
4542 n->funcname = "btrim";
4544 n->agg_star = false;
4545 n->agg_distinct = false;
4548 | TRIM '(' LEADING trim_list ')'
4550 FuncCall *n = makeNode(FuncCall);
4551 n->funcname = "ltrim";
4553 n->agg_star = false;
4554 n->agg_distinct = false;
4557 | TRIM '(' TRAILING trim_list ')'
4559 FuncCall *n = makeNode(FuncCall);
4560 n->funcname = "rtrim";
4562 n->agg_star = false;
4563 n->agg_distinct = false;
4566 | TRIM '(' trim_list ')'
4568 FuncCall *n = makeNode(FuncCall);
4569 n->funcname = "btrim";
4571 n->agg_star = false;
4572 n->agg_distinct = false;
4577 SubLink *n = makeNode(SubLink);
4581 n->subLinkType = EXPR_SUBLINK;
4585 | EXISTS '(' SubSelect ')'
4587 SubLink *n = makeNode(SubLink);
4591 n->subLinkType = EXISTS_SUBLINK;
4598 * Supporting nonterminals for expressions.
4601 opt_indirection: '[' a_expr ']' opt_indirection
4603 A_Indices *ai = makeNode(A_Indices);
4608 | '[' a_expr ':' a_expr ']' opt_indirection
4610 A_Indices *ai = makeNode(A_Indices);
4619 expr_list: a_expr_or_null
4620 { $$ = lcons($1, NIL); }
4621 | expr_list ',' a_expr_or_null
4622 { $$ = lappend($1, $3); }
4623 | expr_list USING a_expr
4624 { $$ = lappend($1, $3); }
4627 extract_list: extract_arg FROM a_expr
4629 A_Const *n = makeNode(A_Const);
4630 n->val.type = T_String;
4631 n->val.val.str = $1;
4632 $$ = lappend(lcons((Node *)n,NIL), $3);
4638 extract_arg: datetime { $$ = $1; }
4639 | TIMEZONE_HOUR { $$ = "tz_hour"; }
4640 | TIMEZONE_MINUTE { $$ = "tz_minute"; }
4643 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
4645 position_list: b_expr IN b_expr
4646 { $$ = makeList($3, $1, -1); }
4651 substr_list: expr_list substr_from substr_for
4653 $$ = nconc(nconc($1,$2),$3);
4659 substr_from: FROM expr_list
4663 A_Const *n = makeNode(A_Const);
4664 n->val.type = T_Integer;
4665 n->val.val.ival = 1;
4666 $$ = lcons((Node *)n,NIL);
4670 substr_for: FOR expr_list
4676 trim_list: a_expr FROM expr_list
4677 { $$ = lappend($3, $1); }
4686 SubLink *n = makeNode(SubLink);
4691 { $$ = (Node *)$1; }
4694 in_expr_nodes: a_expr
4695 { $$ = lcons($1, NIL); }
4696 | in_expr_nodes ',' a_expr
4697 { $$ = lappend($1, $3); }
4701 * Define SQL92-style case clause.
4702 * Allow all four forms described in the standard:
4703 * - Full specification
4704 * CASE WHEN a = b THEN c ... ELSE d END
4705 * - Implicit argument
4706 * CASE a WHEN b THEN c ... ELSE d END
4707 * - Conditional NULL
4709 * same as CASE WHEN x = y THEN NULL ELSE x END
4710 * - Conditional substitution from list, use first non-null argument
4712 * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
4713 * - thomas 1998-11-09
4715 case_expr: CASE case_arg when_clause_list case_default END_TRANS
4717 CaseExpr *c = makeNode(CaseExpr);
4723 | NULLIF '(' a_expr ',' a_expr ')'
4725 CaseExpr *c = makeNode(CaseExpr);
4726 CaseWhen *w = makeNode(CaseWhen);
4728 A_Const *n = makeNode(A_Const);
4729 n->val.type = T_Null;
4730 w->result = (Node *)n;
4732 w->expr = makeA_Expr(OP, "=", $3, $5);
4733 c->args = lcons(w, NIL);
4737 | COALESCE '(' expr_list ')'
4739 CaseExpr *c = makeNode(CaseExpr);
4744 w = makeNode(CaseWhen);
4745 w->expr = makeA_Expr(NOTNULL, NULL, lfirst(l), NULL);
4746 w->result = lfirst(l);
4747 c->args = lappend(c->args, w);
4753 when_clause_list: when_clause_list when_clause
4754 { $$ = lappend($1, $2); }
4756 { $$ = lcons($1, NIL); }
4759 when_clause: WHEN a_expr THEN a_expr_or_null
4761 CaseWhen *w = makeNode(CaseWhen);
4768 case_default: ELSE a_expr_or_null { $$ = $2; }
4769 | /*EMPTY*/ { $$ = NULL; }
4778 attr: relation_name '.' attrs opt_indirection
4780 $$ = makeNode(Attr);
4784 $$->indirection = $4;
4786 | ParamNo '.' attrs opt_indirection
4788 $$ = makeNode(Attr);
4792 $$->indirection = $4;
4797 { $$ = lcons(makeString($1), NIL); }
4798 | attrs '.' attr_name
4799 { $$ = lappend($1, makeString($3)); }
4801 { $$ = lappend($1, makeString("*")); }
4805 /*****************************************************************************
4809 *****************************************************************************/
4811 /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
4813 target_list: target_list ',' target_el
4814 { $$ = lappend($1, $3); }
4816 { $$ = lcons($1, NIL); }
4819 /* AS is not optional because shift/red conflict with unary ops */
4820 target_el: a_expr_or_null AS ColLabel
4822 $$ = makeNode(ResTarget);
4824 $$->indirection = NULL;
4825 $$->val = (Node *)$1;
4829 $$ = makeNode(ResTarget);
4831 $$->indirection = NULL;
4832 $$->val = (Node *)$1;
4834 | relation_name '.' '*'
4836 Attr *att = makeNode(Attr);
4838 att->paramNo = NULL;
4839 att->attrs = lcons(makeString("*"), NIL);
4840 att->indirection = NIL;
4841 $$ = makeNode(ResTarget);
4843 $$->indirection = NULL;
4844 $$->val = (Node *)att;
4848 Attr *att = makeNode(Attr);
4850 att->paramNo = NULL;
4852 att->indirection = NIL;
4853 $$ = makeNode(ResTarget);
4855 $$->indirection = NULL;
4856 $$->val = (Node *)att;
4860 /* Target list as found in UPDATE table SET ... */
4862 update_target_list: update_target_list ',' update_target_el
4863 { $$ = lappend($1,$3); }
4865 { $$ = lcons($1, NIL); }
4868 update_target_el: ColId opt_indirection '=' a_expr_or_null
4870 $$ = makeNode(ResTarget);
4872 $$->indirection = $2;
4873 $$->val = (Node *)$4;
4877 /*****************************************************************************
4879 * Names and constants
4881 *****************************************************************************/
4883 relation_name: SpecialRuleRelation
4886 StrNCpy(saved_relname, $1, NAMEDATALEN);
4890 /* disallow refs to variable system tables */
4891 if (strcmp(LogRelationName, $1) == 0
4892 || strcmp(VariableRelationName, $1) == 0)
4893 elog(ERROR,"%s cannot be accessed by users",$1);
4896 StrNCpy(saved_relname, $1, NAMEDATALEN);
4900 database_name: ColId { $$ = $1; };
4901 access_method: IDENT { $$ = $1; };
4902 attr_name: ColId { $$ = $1; };
4903 class: IDENT { $$ = $1; };
4904 index_name: ColId { $$ = $1; };
4907 * Include date/time keywords as SQL92 extension.
4908 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4910 name: ColId { $$ = $1; };
4911 func_name: ColId { $$ = xlateSqlFunc($1); };
4913 file_name: Sconst { $$ = $1; };
4914 /* NOT USED recipe_name: IDENT { $$ = $1; };*/
4917 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4921 A_Const *n = makeNode(A_Const);
4922 n->val.type = T_Integer;
4923 n->val.val.ival = $1;
4928 A_Const *n = makeNode(A_Const);
4929 n->val.type = T_Float;
4930 n->val.val.dval = $1;
4935 A_Const *n = makeNode(A_Const);
4936 n->val.type = T_String;
4937 n->val.val.str = $1;
4940 /* this rule formerly used Typename, but that causes reduce conflicts
4941 * with subscripted column names ...
4943 | SimpleTypename Sconst
4945 A_Const *n = makeNode(A_Const);
4947 n->val.type = T_String;
4948 n->val.val.str = $2;
4952 { $$ = (Node *)$1; }
4955 A_Const *n = makeNode(A_Const);
4956 n->val.type = T_String;
4957 n->val.val.str = "t";
4958 n->typename = makeNode(TypeName);
4959 n->typename->name = xlateSqlType("bool");
4960 n->typename->typmod = -1;
4965 A_Const *n = makeNode(A_Const);
4966 n->val.type = T_String;
4967 n->val.val.str = "f";
4968 n->typename = makeNode(TypeName);
4969 n->typename->name = xlateSqlType("bool");
4970 n->typename->typmod = -1;
4975 ParamNo: PARAM opt_indirection
4977 $$ = makeNode(ParamNo);
4979 $$->indirection = $2;
4983 Iconst: ICONST { $$ = $1; };
4984 Sconst: SCONST { $$ = $1; };
4985 UserId: IDENT { $$ = $1; };
4987 /* Column and type identifier
4988 * Does not include explicit datetime types
4989 * since these must be decoupled in Typename syntax.
4990 * Use ColId for most identifiers. - thomas 1997-10-21
4993 { $$ = xlateSqlType($1); }
4995 { $$ = xlateSqlType($1); }
4997 { $$ = xlateSqlType($1); }
4999 /* Column identifier
5000 * Include date/time keywords as SQL92 extension.
5001 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
5002 * Add other keywords. Note that as the syntax expands,
5003 * some of these keywords will have to be removed from this
5004 * list due to shift/reduce conflicts in yacc. If so, move
5005 * down to the ColLabel entity. - thomas 1997-11-06
5007 ColId: IDENT { $$ = $1; }
5008 | datetime { $$ = $1; }
5009 | ABSOLUTE { $$ = "absolute"; }
5010 | ACCESS { $$ = "access"; }
5011 | ACTION { $$ = "action"; }
5012 | AFTER { $$ = "after"; }
5013 | AGGREGATE { $$ = "aggregate"; }
5014 | BACKWARD { $$ = "backward"; }
5015 | BEFORE { $$ = "before"; }
5016 | CACHE { $$ = "cache"; }
5017 | COMMENT { $$ = "comment"; }
5018 | COMMITTED { $$ = "committed"; }
5019 | CONSTRAINTS { $$ = "constraints"; }
5020 | CREATEDB { $$ = "createdb"; }
5021 | CREATEUSER { $$ = "createuser"; }
5022 | CYCLE { $$ = "cycle"; }
5023 | DATABASE { $$ = "database"; }
5024 | DEFERRABLE { $$ = "deferrable"; }
5025 | DEFERRED { $$ = "deferred"; }
5026 | DELIMITERS { $$ = "delimiters"; }
5027 | DOUBLE { $$ = "double"; }
5028 | EACH { $$ = "each"; }
5029 | ENCODING { $$ = "encoding"; }
5030 | EXCLUSIVE { $$ = "exclusive"; }
5031 | FORWARD { $$ = "forward"; }
5032 | FUNCTION { $$ = "function"; }
5033 | HANDLER { $$ = "handler"; }
5034 | IMMEDIATE { $$ = "immediate"; }
5035 | INCREMENT { $$ = "increment"; }
5036 | INDEX { $$ = "index"; }
5037 | INHERITS { $$ = "inherits"; }
5038 | INITIALLY { $$ = "initially"; }
5039 | INSENSITIVE { $$ = "insensitive"; }
5040 | INSTEAD { $$ = "instead"; }
5041 | ISNULL { $$ = "isnull"; }
5042 | ISOLATION { $$ = "isolation"; }
5043 | KEY { $$ = "key"; }
5044 | LANGUAGE { $$ = "language"; }
5045 | LANCOMPILER { $$ = "lancompiler"; }
5046 | LEVEL { $$ = "level"; }
5047 | LOCATION { $$ = "location"; }
5048 | MATCH { $$ = "match"; }
5049 | MAXVALUE { $$ = "maxvalue"; }
5050 | MINVALUE { $$ = "minvalue"; }
5051 | MODE { $$ = "mode"; }
5052 | NEXT { $$ = "next"; }
5053 | NOCREATEDB { $$ = "nocreatedb"; }
5054 | NOCREATEUSER { $$ = "nocreateuser"; }
5055 | NOTHING { $$ = "nothing"; }
5056 | NOTNULL { $$ = "notnull"; }
5058 | OIDS { $$ = "oids"; }
5059 | ONLY { $$ = "only"; }
5060 | OPERATOR { $$ = "operator"; }
5061 | OPTION { $$ = "option"; }
5062 | PASSWORD { $$ = "password"; }
5063 | PENDANT { $$ = "pendant"; }
5064 | PRIOR { $$ = "prior"; }
5065 | PRIVILEGES { $$ = "privileges"; }
5066 | PROCEDURAL { $$ = "procedural"; }
5067 | READ { $$ = "read"; }
5068 | RELATIVE { $$ = "relative"; }
5069 | RENAME { $$ = "rename"; }
5070 | RESTRICT { $$ = "restrict"; }
5071 | RETURNS { $$ = "returns"; }
5072 | ROW { $$ = "row"; }
5073 | RULE { $$ = "rule"; }
5074 | SCROLL { $$ = "scroll"; }
5075 | SEQUENCE { $$ = "sequence"; }
5076 | SERIAL { $$ = "serial"; }
5077 | SERIALIZABLE { $$ = "serializable"; }
5078 | SHARE { $$ = "share"; }
5079 | START { $$ = "start"; }
5080 | STATEMENT { $$ = "statement"; }
5081 | STDIN { $$ = "stdin"; }
5082 | STDOUT { $$ = "stdout"; }
5083 | SYSID { $$ = "sysid"; }
5084 | TIME { $$ = "time"; }
5085 | TIMESTAMP { $$ = "timestamp"; }
5086 | TIMEZONE_HOUR { $$ = "timezone_hour"; }
5087 | TIMEZONE_MINUTE { $$ = "timezone_minute"; }
5088 | TRIGGER { $$ = "trigger"; }
5089 | TRUNCATE { $$ = "truncate"; }
5090 | TRUSTED { $$ = "trusted"; }
5091 | TYPE_P { $$ = "type"; }
5092 | VALID { $$ = "valid"; }
5093 | VERSION { $$ = "version"; }
5094 | ZONE { $$ = "zone"; }
5098 * Allowed labels in "AS" clauses.
5099 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
5100 * compatibility. Cannot allow this for column names since the
5101 * syntax would not distinguish between the constant value and
5102 * a column name. - thomas 1997-10-24
5103 * Add other keywords to this list. Note that they appear here
5104 * rather than in ColId if there was a shift/reduce conflict
5105 * when used as a full identifier. - thomas 1997-11-06
5107 ColLabel: ColId { $$ = $1; }
5108 | ABORT_TRANS { $$ = "abort"; }
5109 | ANALYZE { $$ = "analyze"; }
5110 | BINARY { $$ = "binary"; }
5111 | CASE { $$ = "case"; }
5112 | CLUSTER { $$ = "cluster"; }
5113 | COALESCE { $$ = "coalesce"; }
5114 | CONSTRAINT { $$ = "constraint"; }
5115 | COPY { $$ = "copy"; }
5116 | CURRENT { $$ = "current"; }
5117 | DECIMAL { $$ = "decimal"; }
5119 | ELSE { $$ = "else"; }
5120 | END_TRANS { $$ = "end"; }
5121 | EXPLAIN { $$ = "explain"; }
5122 | EXTEND { $$ = "extend"; }
5123 | FALSE_P { $$ = "false"; }
5124 | FLOAT { $$ = "float"; }
5125 | FOREIGN { $$ = "foreign"; }
5126 | GLOBAL { $$ = "global"; }
5127 | GROUP { $$ = "group"; }
5128 | LISTEN { $$ = "listen"; }
5129 | LOAD { $$ = "load"; }
5130 | LOCAL { $$ = "local"; }
5131 | LOCK_P { $$ = "lock"; }
5132 | MOVE { $$ = "move"; }
5133 | NEW { $$ = "new"; }
5134 | NONE { $$ = "none"; }
5135 | NULLIF { $$ = "nullif"; }
5136 | NUMERIC { $$ = "numeric"; }
5137 | ORDER { $$ = "order"; }
5138 | POSITION { $$ = "position"; }
5139 | PRECISION { $$ = "precision"; }
5140 | RESET { $$ = "reset"; }
5141 | SETOF { $$ = "setof"; }
5142 | SHOW { $$ = "show"; }
5143 | TABLE { $$ = "table"; }
5144 | THEN { $$ = "then"; }
5145 | TRANSACTION { $$ = "transaction"; }
5146 | TRUE_P { $$ = "true"; }
5147 | VACUUM { $$ = "vacuum"; }
5148 | VERBOSE { $$ = "verbose"; }
5149 | WHEN { $$ = "when"; }
5152 SpecialRuleRelation: CURRENT
5157 elog(ERROR,"CURRENT used in non-rule query");
5164 elog(ERROR,"NEW used in non-rule query");
5171 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
5173 A_Expr *a = makeNode(A_Expr);
5182 makeTypeCast(Node *arg, TypeName *typename)
5185 * If arg is an A_Const or ParamNo, just stick the typename into the
5186 * field reserved for it --- unless there's something there already!
5187 * (We don't want to collapse x::type1::type2 into just x::type2.)
5188 * Otherwise, generate a TypeCast node.
5190 if (IsA(arg, A_Const) &&
5191 ((A_Const *) arg)->typename == NULL)
5193 ((A_Const *) arg)->typename = typename;
5196 else if (IsA(arg, ParamNo) &&
5197 ((ParamNo *) arg)->typename == NULL)
5199 ((ParamNo *) arg)->typename = typename;
5204 TypeCast *n = makeNode(TypeCast);
5206 n->typename = typename;
5212 * Generate separate operator nodes for a single row descriptor expression.
5213 * Perhaps this should go deeper in the parser someday...
5214 * - thomas 1997-12-22
5217 makeRowExpr(char *opr, List *largs, List *rargs)
5222 if (length(largs) != length(rargs))
5223 elog(ERROR,"Unequal number of entries in row expression");
5225 if (lnext(largs) != NIL)
5226 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
5228 larg = lfirst(largs);
5229 rarg = lfirst(rargs);
5231 if ((strcmp(opr, "=") == 0)
5232 || (strcmp(opr, "<") == 0)
5233 || (strcmp(opr, "<=") == 0)
5234 || (strcmp(opr, ">") == 0)
5235 || (strcmp(opr, ">=") == 0))
5238 expr = makeA_Expr(OP, opr, larg, rarg);
5240 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
5242 else if (strcmp(opr, "<>") == 0)
5245 expr = makeA_Expr(OP, opr, larg, rarg);
5247 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
5251 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
5258 mapTargetColumns(List *src, List *dst)
5263 if (length(src) != length(dst))
5264 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
5266 while ((src != NIL) && (dst != NIL))
5268 s = (ColumnDef *)lfirst(src);
5269 d = (ResTarget *)lfirst(dst);
5271 d->name = s->colname;
5276 } /* mapTargetColumns() */
5280 * Convert alternate type names to internal Postgres types.
5281 * Do not convert "float", since that is handled elsewhere
5282 * for FLOAT(p) syntax.
5285 xlateSqlFunc(char *name)
5287 if (!strcasecmp(name,"character_length")
5288 || !strcasecmp(name,"char_length"))
5292 } /* xlateSqlFunc() */
5295 * Convert alternate type names to internal Postgres types.
5298 xlateSqlType(char *name)
5300 if (!strcasecmp(name,"int")
5301 || !strcasecmp(name,"integer"))
5303 else if (!strcasecmp(name, "smallint"))
5305 else if (!strcasecmp(name, "real")
5306 || !strcasecmp(name, "float"))
5308 else if (!strcasecmp(name, "decimal"))
5310 else if (!strcasecmp(name, "char"))
5312 else if (!strcasecmp(name, "interval"))
5314 else if (!strcasecmp(name, "boolean"))
5318 } /* xlateSqlType() */
5321 void parser_init(Oid *typev, int nargs)
5323 QueryIsRule = FALSE;
5324 saved_relname[0]= '\0';
5326 param_type_init(typev, nargs);
5333 * keep enough information around fill out the type of param nodes
5334 * used in postquel functions
5337 param_type_init(Oid *typev, int nargs)
5339 pfunc_num_args = nargs;
5340 param_type_info = typev;
5343 Oid param_type(int t)
5345 if ((t > pfunc_num_args) || (t == 0))
5347 return param_type_info[t - 1];
5351 * The optimizer doesn't like '-' 4 for index use. It only checks for
5352 * Var '=' Const. It wants an integer of -4, so we try to merge the
5353 * minus into the constant.
5355 * This code is no longer essential as of 10/1999, since the optimizer
5356 * now has a constant-subexpression simplifier. However, we can save
5357 * a few cycles throughout the parse and rewrite stages if we collapse
5358 * the minus into the constant sooner rather than later...
5360 static Node *doNegate(Node *n)
5362 if (IsA(n, A_Const))
5364 A_Const *con = (A_Const *)n;
5366 if (con->val.type == T_Integer)
5368 con->val.val.ival = -con->val.val.ival;
5371 if (con->val.type == T_Float)
5373 con->val.val.dval = -con->val.val.dval;
5378 return makeA_Expr(OP, "-", NULL, n);