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.13 1998/07/08 14:04:09 thomas Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlFunc(char *);
65 static char *xlateSqlType(char *);
66 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
67 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
68 void mapTargetColumns(List *source, List *target);
69 static List *makeConstantList( A_Const *node);
70 static char *FlattenStringList(List *list);
71 static char *fmtId(char *rawid);
72 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
73 static void param_type_init(Oid *typev, int nargs);
75 Oid param_type(int t); /* used in parse_expr.c */
77 /* old versions of flex define this as a macro */
91 bool* pboolean; /* for pg_shadow privileges */
101 SortGroupBy *sortgroupby;
116 AddAttrStmt, ClosePortalStmt,
117 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
118 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
119 CreatePLangStmt, DropPLangStmt,
120 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
121 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
122 RemoveFuncStmt, RemoveStmt,
123 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
124 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
125 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
126 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
127 CreateUserStmt, AlterUserStmt, DropUserStmt
129 %type <str> opt_database, location
131 %type <pboolean> user_createdb_clause, user_createuser_clause
132 %type <str> user_passwd_clause
133 %type <str> user_valid_clause
134 %type <list> user_group_list, user_group_clause
136 %type <str> join_expr, join_outer, join_spec
137 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
139 %type <str> TriggerEvents, TriggerFuncArg
141 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
142 database_name, access_method_clause, access_method, attr_name,
143 class, index_name, name, func_name, file_name, recipe_name, aggr_argtype
145 %type <str> opt_id, opt_portal_name,
146 all_Op, MathOp, opt_name, opt_unique,
147 result, OptUseOp, opt_class, SpecialRuleRelation
149 %type <str> privileges, operation_commalist, grantee
150 %type <chr> operation, TriggerOneEvent
152 %type <list> stmtblock, stmtmulti,
153 relation_name_list, OptTableElementList,
154 OptInherit, definition,
155 opt_with, func_args, func_args_list,
156 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
157 opt_column_list, columnList, opt_va_list, va_list,
158 sort_clause, sortby_list, index_params, index_list, name_list,
159 from_clause, from_list, opt_array_bounds, nest_array_bounds,
160 expr_list, attrs, res_target_list, res_target_list2,
161 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
163 %type <node> func_return
164 %type <boolean> set_opt
166 %type <boolean> TriggerForOpt, TriggerForType
168 %type <list> union_clause, select_list
169 %type <list> join_list
172 %type <boolean> opt_union
173 %type <boolean> opt_table
175 %type <node> position_expr
176 %type <list> extract_list, position_list
177 %type <list> substr_list, substr_from, substr_for, trim_list
178 %type <list> opt_interval
180 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
181 index_opt_unique, opt_verbose, opt_analyze
183 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
186 %type <ival> fetch_how_many
188 %type <list> OptSeqList
189 %type <defelt> OptSeqElem
191 %type <dstmt> def_rest
192 %type <astmt> insert_rest
194 %type <node> OptTableElement, ConstraintElem
195 %type <node> columnDef, alter_clause
196 %type <defelt> def_elem
197 %type <node> def_arg, columnElem, where_clause,
198 a_expr, a_expr_or_null, b_expr, AexprConst,
199 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
201 %type <list> row_descriptor, row_list
202 %type <node> row_expr
204 %type <ival> sub_type
205 %type <list> OptCreateAs, CreateAsList
206 %type <node> CreateAsElement
207 %type <value> NumericOnly, FloatOnly, IntegerOnly
208 %type <attr> event_object, attr
209 %type <sortgroupby> groupby
210 %type <sortgroupby> sortby
211 %type <ielem> index_elem, func_index
212 %type <range> from_val
213 %type <relexp> relation_expr
214 %type <target> res_target_el, res_target_el2
215 %type <paramno> ParamNo
217 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
218 %type <str> generic, numeric, character, datetime
219 %type <str> extract_arg
220 %type <str> opt_charset, opt_collate
221 %type <str> opt_float, opt_numeric, opt_decimal
222 %type <boolean> opt_varying, opt_timezone
226 %type <str> UserId, var_value, zone_value
227 %type <str> ColId, ColLabel
230 %type <node> TableConstraint
231 %type <list> constraint_list, constraint_expr
232 %type <list> default_list, default_expr
233 %type <list> ColQualList, ColQualifier
234 %type <node> ColConstraint, ColConstraintElem
235 %type <list> key_actions, key_action
236 %type <str> key_match, key_reference
239 * If you make any token changes, remember to:
240 * - use "yacc -d" and update parse.h
241 * - update the keyword table in parser/keywords.c
244 /* Reserved word tokens
245 * SQL92 syntax has many type-specific constructs.
246 * So, go ahead and make these types reserved words,
247 * and call-out the syntax explicitly.
248 * This gets annoying when trying to also retain Postgres' nice
249 * type-extensible features, but we don't really have a choice.
250 * - thomas 1997-10-11
253 /* Keywords (in SQL92 reserved words) */
254 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
255 BEGIN_TRANS, BETWEEN, BOTH, BY,
256 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
257 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
258 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
259 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
260 END_TRANS, EXECUTE, EXISTS, EXTRACT,
261 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
262 GRANT, GROUP, HAVING, HOUR_P,
263 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
264 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
265 MATCH, MINUTE_P, MONTH_P,
266 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
267 ON, OPTION, OR, ORDER, OUTER_P,
268 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
269 REFERENCES, REVOKE, RIGHT, ROLLBACK,
270 SECOND_P, SELECT, SET, SUBSTRING,
271 TABLE, TIME, TIMESTAMP, TIMEZONE_HOUR, TIMEZONE_MINUTE,
272 TO, TRAILING, TRANSACTION, TRIM,
273 UNION, UNIQUE, UPDATE, USER, USING,
274 VALUES, VARCHAR, VARYING, VIEW,
275 WHERE, WITH, WORK, YEAR_P, ZONE
277 /* Keywords (in SQL3 reserved words) */
278 %token FALSE_P, TRIGGER, TRUE_P
280 /* Keywords (in SQL92 non-reserved words) */
283 /* Keywords for Postgres support (not in SQL92 reserved words) */
284 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
285 BACKWARD, BEFORE, BINARY, CACHE, CLUSTER, COPY, CYCLE,
286 DATABASE, DELIMITERS, DO, EACH, EXPLAIN, EXTEND,
287 FORWARD, FUNCTION, HANDLER,
288 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
289 LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MAXVALUE, MINVALUE, MOVE,
290 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
291 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
292 SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
293 VACUUM, VERBOSE, VERSION
295 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
299 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
300 * when some sort of pg_privileges relation is introduced.
304 %token PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
306 /* Special keywords, not in the query language - see the "lex" file */
307 %token <str> IDENT, SCONST, Op
308 %token <ival> ICONST, PARAM
311 /* these are not real. they are here so that they get generated as #define's*/
323 %nonassoc Op /* multi-character ops and user-defined operators */
329 %left '|' /* this is the relation union op, not logical or */
330 /* Unary Operators */
332 %left ';' /* end of statement or natural log */
344 { parsetree = lcons($1,NIL); }
347 stmtmulti: stmtmulti stmt ';'
348 { $$ = lappend($1, $2); }
350 { $$ = lappend($1, $2); }
352 { $$ = lcons($1,NIL); }
399 /*****************************************************************************
401 * Create a new Postgres DBMS user
404 *****************************************************************************/
406 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
407 user_createuser_clause user_group_clause user_valid_clause
409 CreateUserStmt *n = makeNode(CreateUserStmt);
420 /*****************************************************************************
422 * Alter a postresql DBMS user
425 *****************************************************************************/
427 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
428 user_createuser_clause user_group_clause user_valid_clause
430 AlterUserStmt *n = makeNode(AlterUserStmt);
441 /*****************************************************************************
443 * Drop a postresql DBMS user
446 *****************************************************************************/
448 DropUserStmt: DROP USER UserId
450 DropUserStmt *n = makeNode(DropUserStmt);
456 user_passwd_clause: WITH PASSWORD UserId { $$ = $3; }
457 | /*EMPTY*/ { $$ = NULL; }
460 user_createdb_clause: CREATEDB
463 $$ = (b = (bool*)palloc(sizeof(bool)));
469 $$ = (b = (bool*)palloc(sizeof(bool)));
472 | /*EMPTY*/ { $$ = NULL; }
475 user_createuser_clause: CREATEUSER
478 $$ = (b = (bool*)palloc(sizeof(bool)));
484 $$ = (b = (bool*)palloc(sizeof(bool)));
487 | /*EMPTY*/ { $$ = NULL; }
490 user_group_list: user_group_list ',' UserId
492 $$ = lcons((void*)makeString($3), $1);
496 $$ = lcons((void*)makeString($1), NIL);
500 user_group_clause: IN GROUP user_group_list { $$ = $3; }
501 | /*EMPTY*/ { $$ = NULL; }
504 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
505 | /*EMPTY*/ { $$ = NULL; }
508 /*****************************************************************************
510 * Set PG internal variable
511 * SET name TO 'var_value'
512 * Include SQL92 syntax (thomas 1997-10-22):
513 * SET TIME ZONE 'var_value'
515 *****************************************************************************/
517 VariableSetStmt: SET ColId TO var_value
519 VariableSetStmt *n = makeNode(VariableSetStmt);
524 | SET ColId '=' var_value
526 VariableSetStmt *n = makeNode(VariableSetStmt);
531 | SET TIME ZONE zone_value
533 VariableSetStmt *n = makeNode(VariableSetStmt);
534 n->name = "timezone";
540 var_value: Sconst { $$ = $1; }
541 | DEFAULT { $$ = NULL; }
544 zone_value: Sconst { $$ = $1; }
545 | DEFAULT { $$ = NULL; }
546 | LOCAL { $$ = NULL; }
549 VariableShowStmt: SHOW ColId
551 VariableShowStmt *n = makeNode(VariableShowStmt);
557 VariableShowStmt *n = makeNode(VariableShowStmt);
558 n->name = "timezone";
563 VariableResetStmt: RESET ColId
565 VariableResetStmt *n = makeNode(VariableResetStmt);
571 VariableResetStmt *n = makeNode(VariableResetStmt);
572 n->name = "timezone";
578 /*****************************************************************************
581 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
583 *****************************************************************************/
585 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
587 AddAttrStmt *n = makeNode(AddAttrStmt);
595 alter_clause: ADD opt_column columnDef
599 | ADD '(' OptTableElementList ')'
601 Node *lp = lfirst($3);
604 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
607 | DROP opt_column ColId
608 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
609 | ALTER opt_column ColId SET DEFAULT default_expr
610 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
611 | ALTER opt_column ColId DROP DEFAULT
612 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
614 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
618 /*****************************************************************************
623 *****************************************************************************/
625 ClosePortalStmt: CLOSE opt_id
627 ClosePortalStmt *n = makeNode(ClosePortalStmt);
634 /*****************************************************************************
637 * COPY [BINARY] <relname> FROM/TO
638 * [USING DELIMITERS <delimiter>]
640 *****************************************************************************/
642 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
644 CopyStmt *n = makeNode(CopyStmt);
662 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
663 * used depends on the direction. (It really doesn't make sense to copy from
664 * stdout. We silently correct the "typo". - AY 9/94
666 copy_file_name: Sconst { $$ = $1; }
667 | STDIN { $$ = NULL; }
668 | STDOUT { $$ = NULL; }
671 opt_binary: BINARY { $$ = TRUE; }
672 | /*EMPTY*/ { $$ = FALSE; }
675 opt_with_copy: WITH OIDS { $$ = TRUE; }
676 | /*EMPTY*/ { $$ = FALSE; }
680 * the default copy delimiter is tab but the user can configure it
682 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
683 | /*EMPTY*/ { $$ = "\t"; }
687 /*****************************************************************************
692 *****************************************************************************/
694 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
695 OptInherit OptArchiveType
697 CreateStmt *n = makeNode(CreateStmt);
701 n->constraints = NIL;
706 OptTableElementList: OptTableElementList ',' OptTableElement
709 $$ = lappend($1, $3);
720 | /*EMPTY*/ { $$ = NULL; }
723 OptTableElement: columnDef { $$ = $1; }
724 | TableConstraint { $$ = $1; }
727 columnDef: ColId Typename ColQualifier
729 ColumnDef *n = makeNode(ColumnDef);
733 n->is_not_null = FALSE;
739 ColQualifier: ColQualList { $$ = $1; }
740 | /*EMPTY*/ { $$ = NULL; }
743 ColQualList: ColQualList ColConstraint
746 $$ = lappend($1, $2);
760 CONSTRAINT name ColConstraintElem
762 Constraint *n = (Constraint *)$3;
763 if (n != NULL) n->name = fmtId($2);
770 ColConstraintElem: CHECK '(' constraint_expr ')'
772 Constraint *n = makeNode(Constraint);
773 n->contype = CONSTR_CHECK;
775 n->def = FlattenStringList($3);
779 | DEFAULT default_expr
781 Constraint *n = makeNode(Constraint);
782 n->contype = CONSTR_DEFAULT;
784 n->def = FlattenStringList($2);
790 Constraint *n = makeNode(Constraint);
791 n->contype = CONSTR_NOTNULL;
799 Constraint *n = makeNode(Constraint);
800 n->contype = CONSTR_UNIQUE;
808 Constraint *n = makeNode(Constraint);
809 n->contype = CONSTR_PRIMARY;
815 | REFERENCES ColId opt_column_list key_match key_actions
817 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
822 default_list: default_list ',' default_expr
824 $$ = lappend($1,makeString(","));
833 default_expr: AexprConst
834 { $$ = makeConstantList((A_Const *) $1); }
836 { $$ = lcons( makeString("NULL"), NIL); }
837 | '-' default_expr %prec UMINUS
838 { $$ = lcons( makeString( "-"), $2); }
839 | default_expr '+' default_expr
840 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
841 | default_expr '-' default_expr
842 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
843 | default_expr '/' default_expr
844 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
845 | default_expr '*' default_expr
846 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
847 | default_expr '=' default_expr
848 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
849 | default_expr '<' default_expr
850 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
851 | default_expr '>' default_expr
852 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
854 { $$ = lcons( makeString( ":"), $2); }
856 { $$ = lcons( makeString( ";"), $2); }
858 { $$ = lcons( makeString( "|"), $2); }
859 | default_expr TYPECAST Typename
861 $3->name = fmtId($3->name);
862 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
864 | CAST '(' default_expr AS Typename ')'
866 $5->name = fmtId($5->name);
867 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
869 | '(' default_expr ')'
870 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
873 $$ = makeList( makeString($1), makeString("("), -1);
874 $$ = lappend( $$, makeString(")"));
876 | func_name '(' default_list ')'
878 $$ = makeList( makeString($1), makeString("("), -1);
880 $$ = lappend( $$, makeString(")"));
882 | default_expr Op default_expr
884 if (!strcmp("<=", $2) || !strcmp(">=", $2))
885 elog(ERROR,"boolean expressions not supported in DEFAULT");
886 $$ = nconc( $1, lcons( makeString( $2), $3));
889 { $$ = lcons( makeString( $1), $2); }
891 { $$ = lappend( $1, makeString( $2)); }
892 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
894 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
896 { $$ = lcons( makeString( "'now'::time"), NIL); }
897 | CURRENT_TIME '(' Iconst ')'
900 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
901 $$ = lcons( makeString( "'now'::time"), NIL);
904 { $$ = lcons( makeString( "now()"), NIL); }
905 | CURRENT_TIMESTAMP '(' Iconst ')'
908 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
909 $$ = lcons( makeString( "now()"), NIL);
912 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
914 { $$ = lcons( makeString( "USER"), NIL); }
917 /* ConstraintElem specifies constraint syntax which is not embedded into
918 * a column definition. ColConstraintElem specifies the embedded form.
919 * - thomas 1997-12-03
921 TableConstraint: CONSTRAINT name ConstraintElem
923 Constraint *n = (Constraint *)$3;
924 if (n != NULL) n->name = fmtId($2);
931 ConstraintElem: CHECK '(' constraint_expr ')'
933 Constraint *n = makeNode(Constraint);
934 n->contype = CONSTR_CHECK;
936 n->def = FlattenStringList($3);
939 | UNIQUE '(' columnList ')'
941 Constraint *n = makeNode(Constraint);
942 n->contype = CONSTR_UNIQUE;
948 | PRIMARY KEY '(' columnList ')'
950 Constraint *n = makeNode(Constraint);
951 n->contype = CONSTR_PRIMARY;
957 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
959 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
964 constraint_list: constraint_list ',' constraint_expr
966 $$ = lappend($1,makeString(","));
975 constraint_expr: AexprConst
976 { $$ = makeConstantList((A_Const *) $1); }
978 { $$ = lcons( makeString("NULL"), NIL); }
981 $$ = lcons( makeString(fmtId($1)), NIL);
983 | '-' constraint_expr %prec UMINUS
984 { $$ = lcons( makeString( "-"), $2); }
985 | constraint_expr '+' constraint_expr
986 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
987 | constraint_expr '-' constraint_expr
988 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
989 | constraint_expr '/' constraint_expr
990 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
991 | constraint_expr '*' constraint_expr
992 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
993 | constraint_expr '=' constraint_expr
994 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
995 | constraint_expr '<' constraint_expr
996 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
997 | constraint_expr '>' constraint_expr
998 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
999 | ':' constraint_expr
1000 { $$ = lcons( makeString( ":"), $2); }
1001 | ';' constraint_expr
1002 { $$ = lcons( makeString( ";"), $2); }
1003 | '|' constraint_expr
1004 { $$ = lcons( makeString( "|"), $2); }
1005 | constraint_expr TYPECAST Typename
1007 $3->name = fmtId($3->name);
1008 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
1010 | CAST '(' constraint_expr AS Typename ')'
1012 $5->name = fmtId($5->name);
1013 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
1015 | '(' constraint_expr ')'
1016 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
1019 $$ = makeList( makeString($1), makeString("("), -1);
1020 $$ = lappend( $$, makeString(")"));
1022 | func_name '(' constraint_list ')'
1024 $$ = makeList( makeString($1), makeString("("), -1);
1025 $$ = nconc( $$, $3);
1026 $$ = lappend( $$, makeString(")"));
1028 | constraint_expr Op constraint_expr
1029 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
1030 | constraint_expr LIKE constraint_expr
1031 { $$ = nconc( $1, lcons( makeString( "like"), $3)); }
1032 | constraint_expr AND constraint_expr
1033 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
1034 | constraint_expr OR constraint_expr
1035 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
1036 | NOT constraint_expr
1037 { $$ = lcons( makeString( "NOT"), $2); }
1038 | Op constraint_expr
1039 { $$ = lcons( makeString( $1), $2); }
1040 | constraint_expr Op
1041 { $$ = lappend( $1, makeString( $2)); }
1042 | constraint_expr ISNULL
1043 { $$ = lappend( $1, makeString( "IS NULL")); }
1044 | constraint_expr IS NULL_P
1045 { $$ = lappend( $1, makeString( "IS NULL")); }
1046 | constraint_expr NOTNULL
1047 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1048 | constraint_expr IS NOT NULL_P
1049 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1050 | constraint_expr IS TRUE_P
1051 { $$ = lappend( $1, makeString( "IS TRUE")); }
1052 | constraint_expr IS FALSE_P
1053 { $$ = lappend( $1, makeString( "IS FALSE")); }
1054 | constraint_expr IS NOT TRUE_P
1055 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1056 | constraint_expr IS NOT FALSE_P
1057 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1060 key_match: MATCH FULL { $$ = NULL; }
1061 | MATCH PARTIAL { $$ = NULL; }
1062 | /*EMPTY*/ { $$ = NULL; }
1065 key_actions: key_action key_action { $$ = NIL; }
1066 | key_action { $$ = NIL; }
1067 | /*EMPTY*/ { $$ = NIL; }
1070 key_action: ON DELETE key_reference { $$ = NIL; }
1071 | ON UPDATE key_reference { $$ = NIL; }
1074 key_reference: NO ACTION { $$ = NULL; }
1075 | CASCADE { $$ = NULL; }
1076 | SET DEFAULT { $$ = NULL; }
1077 | SET NULL_P { $$ = NULL; }
1080 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1081 | /*EMPTY*/ { $$ = NIL; }
1085 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1086 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1088 OptArchiveType: ARCHIVE '=' NONE { }
1092 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1094 SelectStmt *n = (SelectStmt *)$6;
1096 mapTargetColumns($4, n->targetList);
1102 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1103 | /*EMPTY*/ { $$ = NULL; }
1106 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1107 | CreateAsElement { $$ = lcons($1, NIL); }
1110 CreateAsElement: ColId
1112 ColumnDef *n = makeNode(ColumnDef);
1116 n->is_not_null = FALSE;
1117 n->constraints = NULL;
1123 /*****************************************************************************
1126 * CREATE SEQUENCE seqname
1128 *****************************************************************************/
1130 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1132 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1139 OptSeqList: OptSeqList OptSeqElem
1140 { $$ = lappend($1, $2); }
1144 OptSeqElem: CACHE IntegerOnly
1146 $$ = makeNode(DefElem);
1147 $$->defname = "cache";
1148 $$->arg = (Node *)$2;
1152 $$ = makeNode(DefElem);
1153 $$->defname = "cycle";
1154 $$->arg = (Node *)NULL;
1156 | INCREMENT IntegerOnly
1158 $$ = makeNode(DefElem);
1159 $$->defname = "increment";
1160 $$->arg = (Node *)$2;
1162 | MAXVALUE IntegerOnly
1164 $$ = makeNode(DefElem);
1165 $$->defname = "maxvalue";
1166 $$->arg = (Node *)$2;
1168 | MINVALUE IntegerOnly
1170 $$ = makeNode(DefElem);
1171 $$->defname = "minvalue";
1172 $$->arg = (Node *)$2;
1176 $$ = makeNode(DefElem);
1177 $$->defname = "start";
1178 $$->arg = (Node *)$2;
1182 NumericOnly: FloatOnly { $$ = $1; }
1183 | IntegerOnly { $$ = $1; }
1192 $$->val.dval = - $$->val.dval;
1198 $$ = makeInteger($1);
1202 $$ = makeInteger($2);
1203 $$->val.ival = - $$->val.ival;
1207 /*****************************************************************************
1210 * CREATE PROCEDURAL LANGUAGE ...
1211 * DROP PROCEDURAL LANGUAGE ...
1213 *****************************************************************************/
1215 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1216 HANDLER def_name LANCOMPILER Sconst
1218 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1227 PLangTrusted: TRUSTED { $$ = TRUE; }
1230 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1232 DropPLangStmt *n = makeNode(DropPLangStmt);
1238 /*****************************************************************************
1241 * CREATE TRIGGER ...
1244 *****************************************************************************/
1246 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1247 relation_name TriggerForSpec EXECUTE PROCEDURE
1248 name '(' TriggerFuncArgs ')'
1250 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1257 memcpy (n->actions, $5, 4);
1262 TriggerActionTime: BEFORE { $$ = TRUE; }
1263 | AFTER { $$ = FALSE; }
1266 TriggerEvents: TriggerOneEvent
1268 char *e = palloc (4);
1269 e[0] = $1; e[1] = 0; $$ = e;
1271 | TriggerOneEvent OR TriggerOneEvent
1273 char *e = palloc (4);
1274 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1276 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1278 char *e = palloc (4);
1279 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1284 TriggerOneEvent: INSERT { $$ = 'i'; }
1285 | DELETE { $$ = 'd'; }
1286 | UPDATE { $$ = 'u'; }
1289 TriggerForSpec: FOR TriggerForOpt TriggerForType
1295 TriggerForOpt: EACH { $$ = TRUE; }
1296 | /*EMPTY*/ { $$ = FALSE; }
1299 TriggerForType: ROW { $$ = TRUE; }
1300 | STATEMENT { $$ = FALSE; }
1303 TriggerFuncArgs: TriggerFuncArg
1304 { $$ = lcons($1, NIL); }
1305 | TriggerFuncArgs ',' TriggerFuncArg
1306 { $$ = lappend($1, $3); }
1311 TriggerFuncArg: ICONST
1313 char *s = (char *) palloc (256);
1314 sprintf (s, "%d", $1);
1319 char *s = (char *) palloc (256);
1320 sprintf (s, "%g", $1);
1323 | Sconst { $$ = $1; }
1324 | IDENT { $$ = $1; }
1327 DropTrigStmt: DROP TRIGGER name ON relation_name
1329 DropTrigStmt *n = makeNode(DropTrigStmt);
1337 /*****************************************************************************
1340 * define (type,operator,aggregate)
1342 *****************************************************************************/
1344 DefineStmt: CREATE def_type def_rest
1351 def_rest: def_name definition
1353 $$ = makeNode(DefineStmt);
1355 $$->definition = $2;
1359 def_type: OPERATOR { $$ = OPERATOR; }
1360 | TYPE_P { $$ = TYPE_P; }
1361 | AGGREGATE { $$ = AGGREGATE; }
1364 def_name: PROCEDURE { $$ = "procedure"; }
1365 | JOIN { $$ = "join"; }
1366 | ColId { $$ = $1; }
1367 | MathOp { $$ = $1; }
1371 definition: '(' def_list ')' { $$ = $2; }
1374 def_list: def_elem { $$ = lcons($1, NIL); }
1375 | def_list ',' def_elem { $$ = lappend($1, $3); }
1378 def_elem: def_name '=' def_arg
1380 $$ = makeNode(DefElem);
1382 $$->arg = (Node *)$3;
1386 $$ = makeNode(DefElem);
1388 $$->arg = (Node *)NULL;
1390 | DEFAULT '=' def_arg
1392 $$ = makeNode(DefElem);
1393 $$->defname = "default";
1394 $$->arg = (Node *)$3;
1398 def_arg: ColId { $$ = (Node *)makeString($1); }
1399 | all_Op { $$ = (Node *)makeString($1); }
1400 | NumericOnly { $$ = (Node *)$1; }
1401 | Sconst { $$ = (Node *)makeString($1); }
1404 TypeName *n = makeNode(TypeName);
1407 n->arrayBounds = NULL;
1414 /*****************************************************************************
1417 * destroy <relname1> [, <relname2> .. <relnameN> ]
1419 *****************************************************************************/
1421 DestroyStmt: DROP TABLE relation_name_list
1423 DestroyStmt *n = makeNode(DestroyStmt);
1425 n->sequence = FALSE;
1428 | DROP SEQUENCE relation_name_list
1430 DestroyStmt *n = makeNode(DestroyStmt);
1438 /*****************************************************************************
1441 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1443 *****************************************************************************/
1445 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1447 FetchStmt *n = makeNode(FetchStmt);
1454 | MOVE opt_direction fetch_how_many opt_portal_name
1456 FetchStmt *n = makeNode(FetchStmt);
1465 opt_direction: FORWARD { $$ = FORWARD; }
1466 | BACKWARD { $$ = BACKWARD; }
1467 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1470 fetch_how_many: Iconst
1472 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1473 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1474 | /*EMPTY*/ { $$ = 1; /*default*/ }
1477 opt_portal_name: IN name { $$ = $2; }
1478 | /*EMPTY*/ { $$ = NULL; }
1482 /*****************************************************************************
1485 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1487 *****************************************************************************/
1489 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1491 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1495 privileges: ALL PRIVILEGES
1497 $$ = aclmakepriv("rwaR",0);
1501 $$ = aclmakepriv("rwaR",0);
1503 | operation_commalist
1509 operation_commalist: operation
1511 $$ = aclmakepriv("",$1);
1513 | operation_commalist ',' operation
1515 $$ = aclmakepriv($1,$3);
1521 $$ = ACL_MODE_RD_CHR;
1525 $$ = ACL_MODE_AP_CHR;
1529 $$ = ACL_MODE_WR_CHR;
1533 $$ = ACL_MODE_WR_CHR;
1537 $$ = ACL_MODE_RU_CHR;
1543 $$ = aclmakeuser("A","");
1547 $$ = aclmakeuser("G",$2);
1551 $$ = aclmakeuser("U",$1);
1555 opt_with_grant: WITH GRANT OPTION
1557 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1563 /*****************************************************************************
1566 * REVOKE [privileges] ON [relation_name] FROM [user]
1568 *****************************************************************************/
1570 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1572 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1577 /*****************************************************************************
1580 * create index <indexname> on <relname>
1581 * using <access> "(" (<col> with <op>)+ ")" [with
1584 * [where <qual>] is not supported anymore
1585 *****************************************************************************/
1587 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1588 access_method_clause '(' index_params ')' opt_with
1590 /* should check that access_method is valid,
1591 etc ... but doesn't */
1592 IndexStmt *n = makeNode(IndexStmt);
1596 n->accessMethod = $7;
1597 n->indexParams = $9;
1598 n->withClause = $11;
1599 n->whereClause = NULL;
1604 index_opt_unique: UNIQUE { $$ = TRUE; }
1605 | /*EMPTY*/ { $$ = FALSE; }
1608 access_method_clause: USING access_method { $$ = $2; }
1609 | /*EMPTY*/ { $$ = "btree"; }
1612 index_params: index_list { $$ = $1; }
1613 | func_index { $$ = lcons($1,NIL); }
1616 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1617 | index_elem { $$ = lcons($1, NIL); }
1620 func_index: func_name '(' name_list ')' opt_type opt_class
1622 $$ = makeNode(IndexElem);
1630 index_elem: attr_name opt_type opt_class
1632 $$ = makeNode(IndexElem);
1640 opt_type: ':' Typename { $$ = $2; }
1641 | FOR Typename { $$ = $2; }
1642 | /*EMPTY*/ { $$ = NULL; }
1645 /* opt_class "WITH class" conflicts with preceeding opt_type
1646 * for Typename of "TIMESTAMP WITH TIME ZONE"
1647 * So, remove "WITH class" from the syntax. OK??
1648 * - thomas 1997-10-12
1649 * | WITH class { $$ = $2; }
1651 opt_class: class { $$ = $1; }
1652 | USING class { $$ = $2; }
1653 | /*EMPTY*/ { $$ = NULL; }
1657 /*****************************************************************************
1660 * extend index <indexname> [where <qual>]
1662 *****************************************************************************/
1664 ExtendStmt: EXTEND INDEX index_name where_clause
1666 ExtendStmt *n = makeNode(ExtendStmt);
1668 n->whereClause = $4;
1674 /*****************************************************************************
1677 * execute recipe <recipeName>
1679 *****************************************************************************/
1681 RecipeStmt: EXECUTE RECIPE recipe_name
1684 if (!IsTransactionBlock())
1685 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1687 n = makeNode(RecipeStmt);
1694 /*****************************************************************************
1697 * define function <fname>
1698 * (language = <lang>, returntype = <typename>
1699 * [, arch_pct = <percentage | pre-defined>]
1700 * [, disk_pct = <percentage | pre-defined>]
1701 * [, byte_pct = <percentage | pre-defined>]
1702 * [, perbyte_cpu = <int | pre-defined>]
1703 * [, percall_cpu = <int | pre-defined>]
1705 * [arg is (<type-1> { , <type-n>})]
1706 * as <filename or code in language as appropriate>
1708 *****************************************************************************/
1710 ProcedureStmt: CREATE FUNCTION func_name func_args
1711 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
1713 ProcedureStmt *n = makeNode(ProcedureStmt);
1723 opt_with: WITH definition { $$ = $2; }
1724 | /*EMPTY*/ { $$ = NIL; }
1727 func_args: '(' func_args_list ')' { $$ = $2; }
1728 | '(' ')' { $$ = NIL; }
1731 func_args_list: TypeId
1732 { $$ = lcons(makeString($1),NIL); }
1733 | func_args_list ',' TypeId
1734 { $$ = lappend($1,makeString($3)); }
1737 func_return: set_opt TypeId
1739 TypeName *n = makeNode(TypeName);
1742 n->arrayBounds = NULL;
1747 set_opt: SETOF { $$ = TRUE; }
1748 | /*EMPTY*/ { $$ = FALSE; }
1751 /*****************************************************************************
1755 * remove function <funcname>
1756 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1757 * remove aggregate <aggname>
1758 * (REMOVE AGGREGATE "aggname" "aggtype")
1759 * remove operator <opname>
1760 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1761 * remove type <typename>
1762 * (REMOVE TYPE "typename")
1763 * remove rule <rulename>
1764 * (REMOVE RULE "rulename")
1766 *****************************************************************************/
1768 RemoveStmt: DROP remove_type name
1770 RemoveStmt *n = makeNode(RemoveStmt);
1777 remove_type: TYPE_P { $$ = TYPE_P; }
1778 | INDEX { $$ = INDEX; }
1779 | RULE { $$ = RULE; }
1780 | VIEW { $$ = VIEW; }
1784 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1786 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1793 aggr_argtype: name { $$ = $1; }
1794 | '*' { $$ = NULL; }
1798 RemoveFuncStmt: DROP FUNCTION func_name func_args
1800 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1808 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1810 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1817 all_Op: Op | MathOp;
1819 MathOp: '+' { $$ = "+"; }
1830 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1833 { $$ = makeList(makeString($1), makeString($3), -1); }
1834 | NONE ',' name /* left unary */
1835 { $$ = makeList(NULL, makeString($3), -1); }
1836 | name ',' NONE /* right unary */
1837 { $$ = makeList(makeString($1), NULL, -1); }
1841 /*****************************************************************************
1844 * rename <attrname1> in <relname> [*] to <attrname2>
1845 * rename <relname1> to <relname2>
1847 *****************************************************************************/
1849 RenameStmt: ALTER TABLE relation_name opt_inh_star
1850 RENAME opt_column opt_name TO name
1852 RenameStmt *n = makeNode(RenameStmt);
1861 opt_name: name { $$ = $1; }
1862 | /*EMPTY*/ { $$ = NULL; }
1865 opt_column: COLUMN { $$ = COLUMN; }
1866 | /*EMPTY*/ { $$ = 0; }
1870 /*****************************************************************************
1872 * QUERY: Define Rewrite Rule , Define Tuple Rule
1873 * Define Rule <old rules >
1875 * only rewrite rule is supported -- ay 9/94
1877 *****************************************************************************/
1879 RuleStmt: CREATE RULE name AS
1880 { QueryIsRule=TRUE; }
1881 ON event TO event_object where_clause
1882 DO opt_instead OptStmtList
1884 RuleStmt *n = makeNode(RuleStmt);
1888 n->whereClause = $10;
1895 OptStmtList: NOTHING { $$ = NIL; }
1896 | OptimizableStmt { $$ = lcons($1, NIL); }
1897 | '[' OptStmtBlock ']' { $$ = $2; }
1900 OptStmtBlock: OptStmtMulti
1903 { $$ = lcons($1, NIL); }
1906 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1907 { $$ = lappend($1, $2); }
1908 | OptStmtMulti OptimizableStmt
1909 { $$ = lappend($1, $2); }
1910 | OptimizableStmt ';'
1911 { $$ = lcons($1, NIL); }
1914 event_object: relation_name '.' attr_name
1916 $$ = makeNode(Attr);
1919 $$->attrs = lcons(makeString($3), NIL);
1920 $$->indirection = NIL;
1924 $$ = makeNode(Attr);
1928 $$->indirection = NIL;
1932 /* change me to select, update, etc. some day */
1933 event: SELECT { $$ = CMD_SELECT; }
1934 | UPDATE { $$ = CMD_UPDATE; }
1935 | DELETE { $$ = CMD_DELETE; }
1936 | INSERT { $$ = CMD_INSERT; }
1939 opt_instead: INSTEAD { $$ = TRUE; }
1940 | /*EMPTY*/ { $$ = FALSE; }
1944 /*****************************************************************************
1947 * NOTIFY <relation_name> can appear both in rule bodies and
1948 * as a query-level command
1950 *****************************************************************************/
1952 NotifyStmt: NOTIFY relation_name
1954 NotifyStmt *n = makeNode(NotifyStmt);
1960 ListenStmt: LISTEN relation_name
1962 ListenStmt *n = makeNode(ListenStmt);
1969 /*****************************************************************************
1980 *****************************************************************************/
1982 TransactionStmt: ABORT_TRANS TRANSACTION
1984 TransactionStmt *n = makeNode(TransactionStmt);
1985 n->command = ABORT_TRANS;
1988 | BEGIN_TRANS TRANSACTION
1990 TransactionStmt *n = makeNode(TransactionStmt);
1991 n->command = BEGIN_TRANS;
1996 TransactionStmt *n = makeNode(TransactionStmt);
1997 n->command = BEGIN_TRANS;
2002 TransactionStmt *n = makeNode(TransactionStmt);
2003 n->command = END_TRANS;
2006 | END_TRANS TRANSACTION
2008 TransactionStmt *n = makeNode(TransactionStmt);
2009 n->command = END_TRANS;
2014 TransactionStmt *n = makeNode(TransactionStmt);
2015 n->command = ABORT_TRANS;
2021 TransactionStmt *n = makeNode(TransactionStmt);
2022 n->command = ABORT_TRANS;
2027 TransactionStmt *n = makeNode(TransactionStmt);
2028 n->command = BEGIN_TRANS;
2033 TransactionStmt *n = makeNode(TransactionStmt);
2034 n->command = END_TRANS;
2040 TransactionStmt *n = makeNode(TransactionStmt);
2041 n->command = END_TRANS;
2046 TransactionStmt *n = makeNode(TransactionStmt);
2047 n->command = ABORT_TRANS;
2053 /*****************************************************************************
2056 * define view <viewname> '('target-list ')' [where <quals> ]
2058 *****************************************************************************/
2060 ViewStmt: CREATE VIEW name AS SelectStmt
2062 ViewStmt *n = makeNode(ViewStmt);
2064 n->query = (Query *)$5;
2065 if (((SelectStmt *)n->query)->sortClause != NULL)
2066 elog(ERROR,"Order by and Distinct on views is not implemented.");
2067 if (((SelectStmt *)n->query)->unionClause != NULL)
2068 elog(ERROR,"Views on unions not implemented.");
2074 /*****************************************************************************
2079 *****************************************************************************/
2081 LoadStmt: LOAD file_name
2083 LoadStmt *n = makeNode(LoadStmt);
2090 /*****************************************************************************
2095 *****************************************************************************/
2097 CreatedbStmt: CREATE DATABASE database_name opt_database
2099 CreatedbStmt *n = makeNode(CreatedbStmt);
2106 opt_database: WITH LOCATION '=' location { $$ = $4; }
2107 | /*EMPTY*/ { $$ = NULL; }
2110 location: Sconst { $$ = $1; }
2111 | DEFAULT { $$ = NULL; }
2112 | /*EMPTY*/ { $$ = NULL; }
2115 /*****************************************************************************
2120 *****************************************************************************/
2122 DestroydbStmt: DROP DATABASE database_name
2124 DestroydbStmt *n = makeNode(DestroydbStmt);
2131 /*****************************************************************************
2134 * cluster <index_name> on <relation_name>
2136 *****************************************************************************/
2138 ClusterStmt: CLUSTER index_name ON relation_name
2140 ClusterStmt *n = makeNode(ClusterStmt);
2148 /*****************************************************************************
2153 *****************************************************************************/
2155 VacuumStmt: VACUUM opt_verbose opt_analyze
2157 VacuumStmt *n = makeNode(VacuumStmt);
2164 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2166 VacuumStmt *n = makeNode(VacuumStmt);
2171 if ( $5 != NIL && !$4 )
2172 elog(ERROR,"parser: syntax error at or near \"(\"");
2177 opt_verbose: VERBOSE { $$ = TRUE; }
2178 | /*EMPTY*/ { $$ = FALSE; }
2181 opt_analyze: ANALYZE { $$ = TRUE; }
2182 | /*EMPTY*/ { $$ = FALSE; }
2185 opt_va_list: '(' va_list ')' { $$ = $2; }
2186 | /*EMPTY*/ { $$ = NIL; }
2190 { $$=lcons($1,NIL); }
2192 { $$=lappend($1,$3); }
2196 /*****************************************************************************
2201 *****************************************************************************/
2203 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2205 ExplainStmt *n = makeNode(ExplainStmt);
2207 n->query = (Query*)$3;
2213 /*****************************************************************************
2215 * Optimizable Stmts: *
2217 * one of the five queries processed by the planner *
2219 * [ultimately] produces query-trees as specified *
2220 * in the query-spec document in ~postgres/ref *
2222 *****************************************************************************/
2224 OptimizableStmt: SelectStmt
2229 | DeleteStmt /* by default all are $$=$1 */
2233 /*****************************************************************************
2238 *****************************************************************************/
2240 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2248 insert_rest: VALUES '(' res_target_list2 ')'
2250 $$ = makeNode(InsertStmt);
2252 $$->targetList = $3;
2253 $$->fromClause = NIL;
2254 $$->whereClause = NULL;
2255 $$->groupClause = NIL;
2256 $$->havingClause = NULL;
2257 $$->unionClause = NIL;
2259 | SELECT opt_unique res_target_list2
2260 from_clause where_clause
2261 group_clause having_clause
2264 $$ = makeNode(InsertStmt);
2266 $$->targetList = $3;
2267 $$->fromClause = $4;
2268 $$->whereClause = $5;
2269 $$->groupClause = $6;
2270 $$->havingClause = $7;
2271 $$->unionClause = $8;
2275 opt_column_list: '(' columnList ')' { $$ = $2; }
2276 | /*EMPTY*/ { $$ = NIL; }
2280 columnList ',' columnElem
2281 { $$ = lappend($1, $3); }
2283 { $$ = lcons($1, NIL); }
2286 columnElem: ColId opt_indirection
2288 Ident *id = makeNode(Ident);
2290 id->indirection = $2;
2296 /*****************************************************************************
2301 *****************************************************************************/
2303 DeleteStmt: DELETE FROM relation_name
2306 DeleteStmt *n = makeNode(DeleteStmt);
2308 n->whereClause = $4;
2314 * Total hack to just lock a table inside a transaction.
2315 * Is it worth making this a separate command, with
2316 * its own node type and file. I don't think so. bjm 1998/1/22
2318 LockStmt: LOCK_P opt_table relation_name
2320 DeleteStmt *n = makeNode(DeleteStmt);
2321 A_Const *c = makeNode(A_Const);
2323 c->val.type = T_String;
2324 c->val.val.str = "f";
2325 c->typename = makeNode(TypeName);
2326 c->typename->name = xlateSqlType("bool");
2327 c->typename->typmod = -1;
2330 n->whereClause = (Node *)c;
2336 /*****************************************************************************
2339 * UpdateStmt (UPDATE)
2341 *****************************************************************************/
2343 UpdateStmt: UPDATE relation_name
2348 UpdateStmt *n = makeNode(UpdateStmt);
2352 n->whereClause = $6;
2358 /*****************************************************************************
2363 *****************************************************************************/
2364 CursorStmt: DECLARE name opt_binary CURSOR FOR
2365 SELECT opt_unique res_target_list2
2366 from_clause where_clause
2367 group_clause having_clause
2368 union_clause sort_clause
2370 SelectStmt *n = makeNode(SelectStmt);
2372 /* from PORTAL name */
2374 * 15 august 1991 -- since 3.0 postgres does locking
2375 * right, we discovered that portals were violating
2376 * locking protocol. portal locks cannot span xacts.
2377 * as a short-term fix, we installed the check here.
2380 if (!IsTransactionBlock())
2381 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2388 n->whereClause = $10;
2389 n->groupClause = $11;
2390 n->havingClause = $12;
2391 n->unionClause = $13;
2392 n->sortClause = $14;
2398 /*****************************************************************************
2403 *****************************************************************************/
2405 SelectStmt: SELECT opt_unique res_target_list2
2406 result from_clause where_clause
2407 group_clause having_clause
2408 union_clause sort_clause
2410 SelectStmt *n = makeNode(SelectStmt);
2415 n->whereClause = $6;
2416 n->groupClause = $7;
2417 n->havingClause = $8;
2418 n->unionClause = $9;
2419 n->sortClause = $10;
2424 union_clause: UNION opt_union select_list
2426 SelectStmt *n = (SelectStmt *)lfirst($3);
2434 select_list: select_list UNION opt_union SubSelect
2436 SelectStmt *n = (SelectStmt *)$4;
2438 $$ = lappend($1, $4);
2441 { $$ = lcons($1, NIL); }
2444 SubSelect: SELECT opt_unique res_target_list2
2445 from_clause where_clause
2446 group_clause having_clause
2448 SelectStmt *n = makeNode(SelectStmt);
2450 n->unionall = FALSE;
2453 n->whereClause = $5;
2454 n->groupClause = $6;
2455 n->havingClause = $7;
2460 result: INTO opt_table relation_name { $$= $3; }
2461 | /*EMPTY*/ { $$ = NULL; }
2464 opt_table: TABLE { $$ = TRUE; }
2465 | /*EMPTY*/ { $$ = FALSE; }
2468 opt_union: ALL { $$ = TRUE; }
2469 | /*EMPTY*/ { $$ = FALSE; }
2472 opt_unique: DISTINCT { $$ = "*"; }
2473 | DISTINCT ON ColId { $$ = $3; }
2474 | ALL { $$ = NULL; }
2475 | /*EMPTY*/ { $$ = NULL; }
2478 sort_clause: ORDER BY sortby_list { $$ = $3; }
2479 | /*EMPTY*/ { $$ = NIL; }
2482 sortby_list: sortby { $$ = lcons($1, NIL); }
2483 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2486 sortby: ColId OptUseOp
2488 $$ = makeNode(SortGroupBy);
2494 | ColId '.' ColId OptUseOp
2496 $$ = makeNode(SortGroupBy);
2504 $$ = makeNode(SortGroupBy);
2512 OptUseOp: USING Op { $$ = $2; }
2513 | USING '<' { $$ = "<"; }
2514 | USING '>' { $$ = ">"; }
2516 | DESC { $$ = ">"; }
2517 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2521 * jimmy bell-style recursive queries aren't supported in the
2524 * ...however, recursive addattr and rename supported. make special
2527 opt_inh_star: '*' { $$ = TRUE; }
2528 | /*EMPTY*/ { $$ = FALSE; }
2531 relation_name_list: name_list;
2534 { $$ = lcons(makeString($1),NIL); }
2535 | name_list ',' name
2536 { $$ = lappend($1,makeString($3)); }
2539 group_clause: GROUP BY groupby_list { $$ = $3; }
2540 | /*EMPTY*/ { $$ = NIL; }
2543 groupby_list: groupby { $$ = lcons($1, NIL); }
2544 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2549 $$ = makeNode(SortGroupBy);
2557 $$ = makeNode(SortGroupBy);
2565 $$ = makeNode(SortGroupBy);
2573 having_clause: HAVING a_expr
2576 elog(ERROR,"HAVING clause not yet implemented");
2580 | /*EMPTY*/ { $$ = NULL; }
2584 /*****************************************************************************
2586 * clauses common to all Optimizable Stmts:
2590 *****************************************************************************/
2592 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2595 elog(ERROR,"JOIN not yet implemented");
2597 | FROM from_list { $$ = $2; }
2598 | /*EMPTY*/ { $$ = NIL; }
2601 from_list: from_list ',' from_val
2602 { $$ = lappend($1, $3); }
2603 | from_val CROSS JOIN from_val
2604 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2606 { $$ = lcons($1, NIL); }
2609 from_val: relation_expr AS ColLabel
2611 $$ = makeNode(RangeVar);
2615 | relation_expr ColId
2617 $$ = makeNode(RangeVar);
2623 $$ = makeNode(RangeVar);
2629 join_expr: NATURAL join_expr { $$ = NULL; }
2631 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2633 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2635 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2637 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2639 { elog(ERROR,"INNER JOIN not yet implemented"); }
2641 { elog(ERROR,"UNION JOIN not yet implemented"); }
2643 { elog(ERROR,"INNER JOIN not yet implemented"); }
2646 join_outer: OUTER_P { $$ = NULL; }
2647 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2650 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2651 | USING '(' join_list ')' { $$ = NULL; }
2652 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2655 join_list: join_using { $$ = lcons($1, NIL); }
2656 | join_list ',' join_using { $$ = lappend($1, $3); }
2661 $$ = makeNode(SortGroupBy);
2669 $$ = makeNode(SortGroupBy);
2677 $$ = makeNode(SortGroupBy);
2685 where_clause: WHERE a_expr { $$ = $2; }
2686 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2689 relation_expr: relation_name
2691 /* normal relations */
2692 $$ = makeNode(RelExpr);
2696 | relation_name '*' %prec '='
2698 /* inheritance query */
2699 $$ = makeNode(RelExpr);
2704 opt_array_bounds: '[' ']' nest_array_bounds
2705 { $$ = lcons(makeInteger(-1), $3); }
2706 | '[' Iconst ']' nest_array_bounds
2707 { $$ = lcons(makeInteger($2), $4); }
2712 nest_array_bounds: '[' ']' nest_array_bounds
2713 { $$ = lcons(makeInteger(-1), $3); }
2714 | '[' Iconst ']' nest_array_bounds
2715 { $$ = lcons(makeInteger($2), $4); }
2721 /*****************************************************************************
2724 * SQL92 introduces a large amount of type-specific syntax.
2725 * Define individual clauses to handle these cases, and use
2726 * the generic case to handle regular type-extensible Postgres syntax.
2727 * - thomas 1997-10-10
2729 *****************************************************************************/
2731 Typename: Array opt_array_bounds
2734 $$->arrayBounds = $2;
2736 /* Is this the name of a complex type? If so, implement
2739 if (!strcmp(saved_relname, $$->name))
2740 /* This attr is the same type as the relation
2741 * being defined. The classic example: create
2742 * emp(name=text,mgr=emp)
2745 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2746 /* (Eventually add in here that the set can only
2747 * contain one element.)
2768 $$ = makeNode(TypeName);
2769 $$->name = xlateSqlType($1);
2774 generic: IDENT { $$ = $1; }
2775 | TYPE_P { $$ = xlateSqlType("type"); }
2778 /* SQL92 numeric data types
2779 * Check FLOAT() precision limits assuming IEEE floating types.
2780 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2781 * by checking parameters and making sure they match what is possible with INTEGER.
2782 * - thomas 1997-09-18
2784 Numeric: FLOAT opt_float
2786 $$ = makeNode(TypeName);
2787 $$->name = xlateSqlType($2);
2792 $$ = makeNode(TypeName);
2793 $$->name = xlateSqlType("float");
2795 | DECIMAL opt_decimal
2797 $$ = makeNode(TypeName);
2798 $$->name = xlateSqlType("integer");
2801 | NUMERIC opt_numeric
2803 $$ = makeNode(TypeName);
2804 $$->name = xlateSqlType("integer");
2810 { $$ = xlateSqlType("float8"); }
2812 { $$ = xlateSqlType("float8"); }
2814 { $$ = xlateSqlType("decimal"); }
2816 { $$ = xlateSqlType("numeric"); }
2819 opt_float: '(' Iconst ')'
2822 elog(ERROR,"precision for FLOAT must be at least 1");
2824 $$ = xlateSqlType("float4");
2826 $$ = xlateSqlType("float8");
2828 elog(ERROR,"precision for FLOAT must be less than 16");
2832 $$ = xlateSqlType("float8");
2836 opt_numeric: '(' Iconst ',' Iconst ')'
2839 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2841 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2846 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2854 opt_decimal: '(' Iconst ',' Iconst ')'
2857 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2859 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2865 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2874 /* SQL92 character data types
2875 * The following implements CHAR() and VARCHAR().
2876 * We do it here instead of the 'Generic' production
2877 * because we don't want to allow arrays of VARCHAR().
2878 * I haven't thought about whether that will work or not.
2881 Character: character '(' Iconst ')'
2883 $$ = makeNode(TypeName);
2884 if (strcasecmp($1, "char") == 0)
2885 $$->name = xlateSqlType("bpchar");
2886 else if (strcasecmp($1, "varchar") == 0)
2887 $$->name = xlateSqlType("varchar");
2889 yyerror("internal parsing error; unrecognized character type");
2892 elog(ERROR,"length for '%s' type must be at least 1",$1);
2894 /* we can store a char() of length up to the size
2895 * of a page (8KB) - page headers and friends but
2896 * just to be safe here... - ay 6/95
2897 * XXX note this hardcoded limit - thomas 1997-07-13
2899 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2901 /* we actually implement this sort of like a varlen, so
2902 * the first 4 bytes is the length. (the difference
2903 * between this and "text" is that we blank-pad and
2904 * truncate where necessary
2906 $$->typmod = VARHDRSZ + $3;
2910 $$ = makeNode(TypeName);
2911 /* Let's try to make all single-character types into bpchar(1)
2912 * - thomas 1998-05-07
2914 if (strcasecmp($1, "char") == 0)
2916 $$->name = xlateSqlType("bpchar");
2917 $$->typmod = VARHDRSZ + 1;
2921 $$->name = xlateSqlType($1);
2927 character: CHARACTER opt_varying opt_charset opt_collate
2930 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2931 if ($2) type = xlateSqlType("varchar");
2932 else type = xlateSqlType("char");
2935 c = palloc(strlen("var") + strlen($3) + 1);
2938 type = xlateSqlType(c);
2940 type = xlateSqlType($3);
2944 elog(NOTICE,"COLLATE %s not yet implemented; clause ignored",$4);
2947 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2948 | VARCHAR { $$ = xlateSqlType("varchar"); }
2949 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2950 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2953 opt_varying: VARYING { $$ = TRUE; }
2954 | /*EMPTY*/ { $$ = FALSE; }
2957 opt_charset: CHARACTER SET ColId { $$ = $3; }
2958 | /*EMPTY*/ { $$ = NULL; }
2961 opt_collate: COLLATE ColId { $$ = $2; }
2962 | /*EMPTY*/ { $$ = NULL; }
2967 $$ = makeNode(TypeName);
2968 $$->name = xlateSqlType($1);
2971 | TIMESTAMP opt_timezone
2973 $$ = makeNode(TypeName);
2974 $$->name = xlateSqlType("timestamp");
2980 $$ = makeNode(TypeName);
2981 $$->name = xlateSqlType("time");
2984 | INTERVAL opt_interval
2986 $$ = makeNode(TypeName);
2987 $$->name = xlateSqlType("interval");
2992 datetime: YEAR_P { $$ = "year"; }
2993 | MONTH_P { $$ = "month"; }
2994 | DAY_P { $$ = "day"; }
2995 | HOUR_P { $$ = "hour"; }
2996 | MINUTE_P { $$ = "minute"; }
2997 | SECOND_P { $$ = "second"; }
3000 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
3001 | /*EMPTY*/ { $$ = FALSE; }
3004 opt_interval: datetime { $$ = lcons($1, NIL); }
3005 | YEAR_P TO MONTH_P { $$ = NIL; }
3006 | DAY_P TO HOUR_P { $$ = NIL; }
3007 | DAY_P TO MINUTE_P { $$ = NIL; }
3008 | DAY_P TO SECOND_P { $$ = NIL; }
3009 | HOUR_P TO MINUTE_P { $$ = NIL; }
3010 | HOUR_P TO SECOND_P { $$ = NIL; }
3011 | MINUTE_P TO SECOND_P { $$ = NIL; }
3012 | /*EMPTY*/ { $$ = NIL; }
3016 /*****************************************************************************
3018 * expression grammar, still needs some cleanup
3020 *****************************************************************************/
3022 a_expr_or_null: a_expr
3026 A_Const *n = makeNode(A_Const);
3027 n->val.type = T_Null;
3032 /* Expressions using row descriptors
3033 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
3034 * with singleton expressions.
3035 * Eliminated lots of code by defining row_op and sub_type clauses.
3036 * However, can not consolidate EXPR_LINK case with others subselects
3037 * due to shift/reduce conflict with the non-subselect clause (the parser
3038 * would have to look ahead more than one token to resolve the conflict).
3039 * - thomas 1998-05-09
3041 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
3043 SubLink *n = makeNode(SubLink);
3045 n->oper = lcons("=",NIL);
3047 n->subLinkType = ANY_SUBLINK;
3051 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3053 SubLink *n = makeNode(SubLink);
3055 n->oper = lcons("<>",NIL);
3057 n->subLinkType = ALL_SUBLINK;
3061 | '(' row_descriptor ')' row_op sub_type '(' SubSelect ')'
3063 SubLink *n = makeNode(SubLink);
3065 n->oper = lcons($4, NIL);
3066 if (strcmp($4,"<>") == 0)
3070 n->subLinkType = $5;
3074 | '(' row_descriptor ')' row_op '(' SubSelect ')'
3076 SubLink *n = makeNode(SubLink);
3078 n->oper = lcons($4, NIL);
3079 if (strcmp($4,"<>") == 0)
3083 n->subLinkType = EXPR_SUBLINK;
3087 | '(' row_descriptor ')' row_op '(' row_descriptor ')'
3089 $$ = makeRowExpr($4, $2, $6);
3093 row_descriptor: row_list ',' a_expr
3095 $$ = lappend($1, $3);
3099 row_list: row_list ',' a_expr
3101 $$ = lappend($1, $3);
3105 $$ = lcons($1, NIL);
3109 row_op: Op { $$ = $1; }
3119 sub_type: ANY { $$ = ANY_SUBLINK; }
3120 | ALL { $$ = ALL_SUBLINK; }
3124 * This is the heart of the expression syntax.
3125 * Note that the BETWEEN clause looks similar to a boolean expression
3126 * and so we must define b_expr which is almost the same as a_expr
3127 * but without the boolean expressions.
3128 * All operations are allowed in a BETWEEN clause if surrounded by parens.
3131 a_expr: attr opt_indirection
3133 $1->indirection = $2;
3142 /* could be a column name or a relation_name */
3143 Ident *n = makeNode(Ident);
3145 n->indirection = NULL;
3148 | '-' a_expr %prec UMINUS
3149 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3151 { $$ = makeA_Expr(OP, "+", $1, $3); }
3153 { $$ = makeA_Expr(OP, "-", $1, $3); }
3155 { $$ = makeA_Expr(OP, "/", $1, $3); }
3157 { $$ = makeA_Expr(OP, "*", $1, $3); }
3159 { $$ = makeA_Expr(OP, "<", $1, $3); }
3161 { $$ = makeA_Expr(OP, ">", $1, $3); }
3163 { $$ = makeA_Expr(OP, "=", $1, $3); }
3165 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3167 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3169 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3170 | a_expr TYPECAST Typename
3173 /* AexprConst can be either A_Const or ParamNo */
3174 if (nodeTag($1) == T_A_Const) {
3175 ((A_Const *)$1)->typename = $3;
3176 } else if (nodeTag($1) == T_Param) {
3177 ((ParamNo *)$1)->typename = $3;
3178 /* otherwise, try to transform to a function call */
3180 FuncCall *n = makeNode(FuncCall);
3181 n->funcname = $3->name;
3182 n->args = lcons($1,NIL);
3186 | CAST '(' a_expr AS Typename ')'
3189 /* AexprConst can be either A_Const or ParamNo */
3190 if (nodeTag($3) == T_A_Const) {
3191 ((A_Const *)$3)->typename = $5;
3192 } else if (nodeTag($5) == T_Param) {
3193 ((ParamNo *)$3)->typename = $5;
3194 /* otherwise, try to transform to a function call */
3196 FuncCall *n = makeNode(FuncCall);
3197 n->funcname = $5->name;
3198 n->args = lcons($3,NIL);
3202 | '(' a_expr_or_null ')'
3205 { $$ = makeIndexable($2,$1,$3); }
3206 | a_expr LIKE a_expr
3207 { $$ = makeIndexable("~~", $1, $3); }
3208 | a_expr NOT LIKE a_expr
3209 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3211 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3213 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3214 | func_name '(' '*' ')'
3216 /* cheap hack for aggregate (eg. count) */
3217 FuncCall *n = makeNode(FuncCall);
3218 A_Const *star = makeNode(A_Const);
3220 star->val.type = T_String;
3221 star->val.val.str = "";
3223 n->args = lcons(star, NIL);
3228 FuncCall *n = makeNode(FuncCall);
3233 | func_name '(' expr_list ')'
3235 FuncCall *n = makeNode(FuncCall);
3242 A_Const *n = makeNode(A_Const);
3243 TypeName *t = makeNode(TypeName);
3245 n->val.type = T_String;
3246 n->val.val.str = "now";
3249 t->name = xlateSqlType("date");
3257 A_Const *n = makeNode(A_Const);
3258 TypeName *t = makeNode(TypeName);
3260 n->val.type = T_String;
3261 n->val.val.str = "now";
3264 t->name = xlateSqlType("time");
3270 | CURRENT_TIME '(' Iconst ')'
3272 FuncCall *n = makeNode(FuncCall);
3273 A_Const *s = makeNode(A_Const);
3274 TypeName *t = makeNode(TypeName);
3276 n->funcname = xlateSqlType("time");
3277 n->args = lcons(s, NIL);
3279 s->val.type = T_String;
3280 s->val.val.str = "now";
3283 t->name = xlateSqlType("time");
3288 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3294 A_Const *n = makeNode(A_Const);
3295 TypeName *t = makeNode(TypeName);
3297 n->val.type = T_String;
3298 n->val.val.str = "now";
3301 t->name = xlateSqlType("timestamp");
3307 | CURRENT_TIMESTAMP '(' Iconst ')'
3309 FuncCall *n = makeNode(FuncCall);
3310 A_Const *s = makeNode(A_Const);
3311 TypeName *t = makeNode(TypeName);
3313 n->funcname = xlateSqlType("timestamp");
3314 n->args = lcons(s, NIL);
3316 s->val.type = T_String;
3317 s->val.val.str = "now";
3320 t->name = xlateSqlType("timestamp");
3325 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3331 FuncCall *n = makeNode(FuncCall);
3332 n->funcname = "getpgusername";
3338 FuncCall *n = makeNode(FuncCall);
3339 n->funcname = "getpgusername";
3343 | EXISTS '(' SubSelect ')'
3345 SubLink *n = makeNode(SubLink);
3349 n->subLinkType = EXISTS_SUBLINK;
3353 | EXTRACT '(' extract_list ')'
3355 FuncCall *n = makeNode(FuncCall);
3356 n->funcname = "date_part";
3360 | POSITION '(' position_list ')'
3362 FuncCall *n = makeNode(FuncCall);
3363 n->funcname = "strpos";
3367 | SUBSTRING '(' substr_list ')'
3369 FuncCall *n = makeNode(FuncCall);
3370 n->funcname = "substr";
3374 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3375 | TRIM '(' BOTH trim_list ')'
3377 FuncCall *n = makeNode(FuncCall);
3378 n->funcname = "btrim";
3382 | TRIM '(' LEADING trim_list ')'
3384 FuncCall *n = makeNode(FuncCall);
3385 n->funcname = "ltrim";
3389 | TRIM '(' TRAILING trim_list ')'
3391 FuncCall *n = makeNode(FuncCall);
3392 n->funcname = "rtrim";
3396 | TRIM '(' trim_list ')'
3398 FuncCall *n = makeNode(FuncCall);
3399 n->funcname = "btrim";
3404 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3406 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3408 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3409 | a_expr IS NOT NULL_P
3410 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3411 /* IS TRUE, IS FALSE, etc used to be function calls
3412 * but let's make them expressions to allow the optimizer
3413 * a chance to eliminate them if a_expr is a constant string.
3414 * - thomas 1997-12-22
3418 A_Const *n = makeNode(A_Const);
3419 n->val.type = T_String;
3420 n->val.val.str = "t";
3421 n->typename = makeNode(TypeName);
3422 n->typename->name = xlateSqlType("bool");
3423 n->typename->typmod = -1;
3424 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3426 | a_expr IS NOT FALSE_P
3428 A_Const *n = makeNode(A_Const);
3429 n->val.type = T_String;
3430 n->val.val.str = "t";
3431 n->typename = makeNode(TypeName);
3432 n->typename->name = xlateSqlType("bool");
3433 n->typename->typmod = -1;
3434 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3438 A_Const *n = makeNode(A_Const);
3439 n->val.type = T_String;
3440 n->val.val.str = "f";
3441 n->typename = makeNode(TypeName);
3442 n->typename->name = xlateSqlType("bool");
3443 n->typename->typmod = -1;
3444 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3446 | a_expr IS NOT TRUE_P
3448 A_Const *n = makeNode(A_Const);
3449 n->val.type = T_String;
3450 n->val.val.str = "f";
3451 n->typename = makeNode(TypeName);
3452 n->typename->name = xlateSqlType("bool");
3453 n->typename->typmod = -1;
3454 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3456 | a_expr BETWEEN b_expr AND b_expr
3458 $$ = makeA_Expr(AND, NULL,
3459 makeA_Expr(OP, ">=", $1, $3),
3460 makeA_Expr(OP, "<=", $1, $5));
3462 | a_expr NOT BETWEEN b_expr AND b_expr
3464 $$ = makeA_Expr(OR, NULL,
3465 makeA_Expr(OP, "<", $1, $4),
3466 makeA_Expr(OP, ">", $1, $6));
3468 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3470 saved_In_Expr = lnext(saved_In_Expr);
3471 if (nodeTag($5) == T_SubLink)
3473 SubLink *n = (SubLink *)$5;
3474 n->lefthand = lcons($1, NIL);
3475 n->oper = lcons("=",NIL);
3477 n->subLinkType = ANY_SUBLINK;
3482 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
3484 saved_In_Expr = lnext(saved_In_Expr);
3485 if (nodeTag($6) == T_SubLink)
3487 SubLink *n = (SubLink *)$6;
3488 n->lefthand = lcons($1, NIL);
3489 n->oper = lcons("<>",NIL);
3491 n->subLinkType = ALL_SUBLINK;
3496 | a_expr Op '(' SubSelect ')'
3498 SubLink *n = makeNode(SubLink);
3499 n->lefthand = lcons($1, NULL);
3500 n->oper = lcons($2,NIL);
3502 n->subLinkType = EXPR_SUBLINK;
3506 | a_expr '+' '(' SubSelect ')'
3508 SubLink *n = makeNode(SubLink);
3509 n->lefthand = lcons($1, NULL);
3510 n->oper = lcons("+",NIL);
3512 n->subLinkType = EXPR_SUBLINK;
3516 | a_expr '-' '(' SubSelect ')'
3518 SubLink *n = makeNode(SubLink);
3519 n->lefthand = lcons($1, NULL);
3520 n->oper = lcons("-",NIL);
3522 n->subLinkType = EXPR_SUBLINK;
3526 | a_expr '/' '(' SubSelect ')'
3528 SubLink *n = makeNode(SubLink);
3529 n->lefthand = lcons($1, NULL);
3530 n->oper = lcons("/",NIL);
3532 n->subLinkType = EXPR_SUBLINK;
3536 | a_expr '*' '(' SubSelect ')'
3538 SubLink *n = makeNode(SubLink);
3539 n->lefthand = lcons($1, NULL);
3540 n->oper = lcons("*",NIL);
3542 n->subLinkType = EXPR_SUBLINK;
3546 | a_expr '<' '(' SubSelect ')'
3548 SubLink *n = makeNode(SubLink);
3549 n->lefthand = lcons($1, NULL);
3550 n->oper = lcons("<",NIL);
3552 n->subLinkType = EXPR_SUBLINK;
3556 | a_expr '>' '(' SubSelect ')'
3558 SubLink *n = makeNode(SubLink);
3559 n->lefthand = lcons($1, NULL);
3560 n->oper = lcons(">",NIL);
3562 n->subLinkType = EXPR_SUBLINK;
3566 | a_expr '=' '(' SubSelect ')'
3568 SubLink *n = makeNode(SubLink);
3569 n->lefthand = lcons($1, NULL);
3570 n->oper = lcons("=",NIL);
3572 n->subLinkType = EXPR_SUBLINK;
3576 | a_expr Op ANY '(' SubSelect ')'
3578 SubLink *n = makeNode(SubLink);
3579 n->lefthand = lcons($1,NIL);
3580 n->oper = lcons($2,NIL);
3582 n->subLinkType = ANY_SUBLINK;
3586 | a_expr '+' ANY '(' SubSelect ')'
3588 SubLink *n = makeNode(SubLink);
3589 n->lefthand = lcons($1,NIL);
3590 n->oper = lcons("+",NIL);
3592 n->subLinkType = ANY_SUBLINK;
3596 | a_expr '-' ANY '(' SubSelect ')'
3598 SubLink *n = makeNode(SubLink);
3599 n->lefthand = lcons($1,NIL);
3600 n->oper = lcons("-",NIL);
3602 n->subLinkType = ANY_SUBLINK;
3606 | a_expr '/' ANY '(' SubSelect ')'
3608 SubLink *n = makeNode(SubLink);
3609 n->lefthand = lcons($1,NIL);
3610 n->oper = lcons("/",NIL);
3612 n->subLinkType = ANY_SUBLINK;
3616 | a_expr '*' ANY '(' SubSelect ')'
3618 SubLink *n = makeNode(SubLink);
3619 n->lefthand = lcons($1,NIL);
3620 n->oper = lcons("*",NIL);
3622 n->subLinkType = ANY_SUBLINK;
3626 | a_expr '<' ANY '(' SubSelect ')'
3628 SubLink *n = makeNode(SubLink);
3629 n->lefthand = lcons($1,NIL);
3630 n->oper = lcons("<",NIL);
3632 n->subLinkType = ANY_SUBLINK;
3636 | a_expr '>' ANY '(' SubSelect ')'
3638 SubLink *n = makeNode(SubLink);
3639 n->lefthand = lcons($1,NIL);
3640 n->oper = lcons(">",NIL);
3642 n->subLinkType = ANY_SUBLINK;
3646 | a_expr '=' ANY '(' SubSelect ')'
3648 SubLink *n = makeNode(SubLink);
3649 n->lefthand = lcons($1,NIL);
3650 n->oper = lcons("=",NIL);
3652 n->subLinkType = ANY_SUBLINK;
3656 | a_expr Op ALL '(' SubSelect ')'
3658 SubLink *n = makeNode(SubLink);
3659 n->lefthand = lcons($1, NULL);
3660 n->oper = lcons($2,NIL);
3662 n->subLinkType = ALL_SUBLINK;
3666 | a_expr '+' ALL '(' SubSelect ')'
3668 SubLink *n = makeNode(SubLink);
3669 n->lefthand = lcons($1, NULL);
3670 n->oper = lcons("+",NIL);
3672 n->subLinkType = ALL_SUBLINK;
3676 | a_expr '-' ALL '(' SubSelect ')'
3678 SubLink *n = makeNode(SubLink);
3679 n->lefthand = lcons($1, NULL);
3680 n->oper = lcons("-",NIL);
3682 n->subLinkType = ALL_SUBLINK;
3686 | a_expr '/' ALL '(' SubSelect ')'
3688 SubLink *n = makeNode(SubLink);
3689 n->lefthand = lcons($1, NULL);
3690 n->oper = lcons("/",NIL);
3692 n->subLinkType = ALL_SUBLINK;
3696 | a_expr '*' ALL '(' SubSelect ')'
3698 SubLink *n = makeNode(SubLink);
3699 n->lefthand = lcons($1, NULL);
3700 n->oper = lcons("*",NIL);
3702 n->subLinkType = ALL_SUBLINK;
3706 | a_expr '<' ALL '(' SubSelect ')'
3708 SubLink *n = makeNode(SubLink);
3709 n->lefthand = lcons($1, NULL);
3710 n->oper = lcons("<",NIL);
3712 n->subLinkType = ALL_SUBLINK;
3716 | a_expr '>' ALL '(' SubSelect ')'
3718 SubLink *n = makeNode(SubLink);
3719 n->lefthand = lcons($1, NULL);
3720 n->oper = lcons(">",NIL);
3722 n->subLinkType = ALL_SUBLINK;
3726 | a_expr '=' ALL '(' SubSelect ')'
3728 SubLink *n = makeNode(SubLink);
3729 n->lefthand = lcons($1, NULL);
3730 n->oper = lcons("=",NIL);
3732 n->subLinkType = ALL_SUBLINK;
3737 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3739 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3741 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3745 * b_expr is a subset of the complete expression syntax
3746 * defined by a_expr. b_expr is used in BETWEEN clauses
3747 * to eliminate parser ambiguities stemming from the AND keyword.
3750 b_expr: attr opt_indirection
3752 $1->indirection = $2;
3759 /* could be a column name or a relation_name */
3760 Ident *n = makeNode(Ident);
3762 n->indirection = NULL;
3765 | '-' b_expr %prec UMINUS
3766 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3768 { $$ = makeA_Expr(OP, "+", $1, $3); }
3770 { $$ = makeA_Expr(OP, "-", $1, $3); }
3772 { $$ = makeA_Expr(OP, "/", $1, $3); }
3774 { $$ = makeA_Expr(OP, "*", $1, $3); }
3776 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3778 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3780 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3781 | b_expr TYPECAST Typename
3784 /* AexprConst can be either A_Const or ParamNo */
3785 if (nodeTag($1) == T_A_Const) {
3786 ((A_Const *)$1)->typename = $3;
3787 } else if (nodeTag($1) == T_Param) {
3788 ((ParamNo *)$1)->typename = $3;
3789 /* otherwise, try to transform to a function call */
3791 FuncCall *n = makeNode(FuncCall);
3792 n->funcname = $3->name;
3793 n->args = lcons($1,NIL);
3797 | CAST '(' b_expr AS Typename ')'
3800 /* AexprConst can be either A_Const or ParamNo */
3801 if (nodeTag($3) == T_A_Const) {
3802 ((A_Const *)$3)->typename = $5;
3803 } else if (nodeTag($3) == T_Param) {
3804 ((ParamNo *)$3)->typename = $5;
3805 /* otherwise, try to transform to a function call */
3807 FuncCall *n = makeNode(FuncCall);
3808 n->funcname = $5->name;
3809 n->args = lcons($3,NIL);
3816 { $$ = makeIndexable($2,$1,$3); }
3818 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3820 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3823 FuncCall *n = makeNode(FuncCall);
3828 | func_name '(' expr_list ')'
3830 FuncCall *n = makeNode(FuncCall);
3837 A_Const *n = makeNode(A_Const);
3838 TypeName *t = makeNode(TypeName);
3840 n->val.type = T_String;
3841 n->val.val.str = "now";
3844 t->name = xlateSqlType("date");
3852 A_Const *n = makeNode(A_Const);
3853 TypeName *t = makeNode(TypeName);
3855 n->val.type = T_String;
3856 n->val.val.str = "now";
3859 t->name = xlateSqlType("time");
3865 | CURRENT_TIME '(' Iconst ')'
3867 FuncCall *n = makeNode(FuncCall);
3868 A_Const *s = makeNode(A_Const);
3869 TypeName *t = makeNode(TypeName);
3871 n->funcname = xlateSqlType("time");
3872 n->args = lcons(s, NIL);
3874 s->val.type = T_String;
3875 s->val.val.str = "now";
3878 t->name = xlateSqlType("time");
3883 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3889 A_Const *n = makeNode(A_Const);
3890 TypeName *t = makeNode(TypeName);
3892 n->val.type = T_String;
3893 n->val.val.str = "now";
3896 t->name = xlateSqlType("timestamp");
3902 | CURRENT_TIMESTAMP '(' Iconst ')'
3904 FuncCall *n = makeNode(FuncCall);
3905 A_Const *s = makeNode(A_Const);
3906 TypeName *t = makeNode(TypeName);
3908 n->funcname = xlateSqlType("timestamp");
3909 n->args = lcons(s, NIL);
3911 s->val.type = T_String;
3912 s->val.val.str = "now";
3915 t->name = xlateSqlType("timestamp");
3920 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3926 FuncCall *n = makeNode(FuncCall);
3927 n->funcname = "getpgusername";
3933 FuncCall *n = makeNode(FuncCall);
3934 n->funcname = "getpgusername";
3938 | POSITION '(' position_list ')'
3940 FuncCall *n = makeNode(FuncCall);
3941 n->funcname = "strpos";
3945 | SUBSTRING '(' substr_list ')'
3947 FuncCall *n = makeNode(FuncCall);
3948 n->funcname = "substr";
3952 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3953 | TRIM '(' BOTH trim_list ')'
3955 FuncCall *n = makeNode(FuncCall);
3956 n->funcname = "btrim";
3960 | TRIM '(' LEADING trim_list ')'
3962 FuncCall *n = makeNode(FuncCall);
3963 n->funcname = "ltrim";
3967 | TRIM '(' TRAILING trim_list ')'
3969 FuncCall *n = makeNode(FuncCall);
3970 n->funcname = "rtrim";
3974 | TRIM '(' trim_list ')'
3976 FuncCall *n = makeNode(FuncCall);
3977 n->funcname = "btrim";
3983 opt_indirection: '[' a_expr ']' opt_indirection
3985 A_Indices *ai = makeNode(A_Indices);
3990 | '[' a_expr ':' a_expr ']' opt_indirection
3992 A_Indices *ai = makeNode(A_Indices);
4001 expr_list: a_expr_or_null
4002 { $$ = lcons($1, NIL); }
4003 | expr_list ',' a_expr_or_null
4004 { $$ = lappend($1, $3); }
4005 | expr_list USING a_expr
4006 { $$ = lappend($1, $3); }
4009 extract_list: extract_arg FROM a_expr
4011 A_Const *n = makeNode(A_Const);
4012 n->val.type = T_String;
4013 n->val.val.str = $1;
4014 $$ = lappend(lcons((Node *)n,NIL), $3);
4020 extract_arg: datetime { $$ = $1; }
4021 | TIMEZONE_HOUR { $$ = "tz_hour"; }
4022 | TIMEZONE_MINUTE { $$ = "tz_minute"; }
4025 position_list: position_expr IN position_expr
4026 { $$ = makeList($3, $1, -1); }
4031 position_expr: attr opt_indirection
4033 $1->indirection = $2;
4038 | '-' position_expr %prec UMINUS
4039 { $$ = makeA_Expr(OP, "-", NULL, $2); }
4040 | position_expr '+' position_expr
4041 { $$ = makeA_Expr(OP, "+", $1, $3); }
4042 | position_expr '-' position_expr
4043 { $$ = makeA_Expr(OP, "-", $1, $3); }
4044 | position_expr '/' position_expr
4045 { $$ = makeA_Expr(OP, "/", $1, $3); }
4046 | position_expr '*' position_expr
4047 { $$ = makeA_Expr(OP, "*", $1, $3); }
4049 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4050 | position_expr TYPECAST Typename
4053 /* AexprConst can be either A_Const or ParamNo */
4054 if (nodeTag($1) == T_A_Const) {
4055 ((A_Const *)$1)->typename = $3;
4056 } else if (nodeTag($1) == T_Param) {
4057 ((ParamNo *)$1)->typename = $3;
4058 /* otherwise, try to transform to a function call */
4060 FuncCall *n = makeNode(FuncCall);
4061 n->funcname = $3->name;
4062 n->args = lcons($1,NIL);
4066 | CAST '(' position_expr AS Typename ')'
4069 /* AexprConst can be either A_Const or ParamNo */
4070 if (nodeTag($3) == T_A_Const) {
4071 ((A_Const *)$3)->typename = $5;
4072 } else if (nodeTag($3) == T_Param) {
4073 ((ParamNo *)$3)->typename = $5;
4074 /* otherwise, try to transform to a function call */
4076 FuncCall *n = makeNode(FuncCall);
4077 n->funcname = $5->name;
4078 n->args = lcons($3,NIL);
4082 | '(' position_expr ')'
4084 | position_expr Op position_expr
4085 { $$ = makeA_Expr(OP, $2, $1, $3); }
4087 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4089 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4092 /* could be a column name or a relation_name */
4093 Ident *n = makeNode(Ident);
4095 n->indirection = NULL;
4100 FuncCall *n = makeNode(FuncCall);
4105 | func_name '(' expr_list ')'
4107 FuncCall *n = makeNode(FuncCall);
4112 | POSITION '(' position_list ')'
4114 FuncCall *n = makeNode(FuncCall);
4115 n->funcname = "strpos";
4119 | SUBSTRING '(' substr_list ')'
4121 FuncCall *n = makeNode(FuncCall);
4122 n->funcname = "substr";
4126 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4127 | TRIM '(' BOTH trim_list ')'
4129 FuncCall *n = makeNode(FuncCall);
4130 n->funcname = "btrim";
4134 | TRIM '(' LEADING trim_list ')'
4136 FuncCall *n = makeNode(FuncCall);
4137 n->funcname = "ltrim";
4141 | TRIM '(' TRAILING trim_list ')'
4143 FuncCall *n = makeNode(FuncCall);
4144 n->funcname = "rtrim";
4148 | TRIM '(' trim_list ')'
4150 FuncCall *n = makeNode(FuncCall);
4151 n->funcname = "btrim";
4157 substr_list: expr_list substr_from substr_for
4159 $$ = nconc(nconc($1,$2),$3);
4165 substr_from: FROM expr_list
4169 A_Const *n = makeNode(A_Const);
4170 n->val.type = T_Integer;
4171 n->val.val.ival = 1;
4172 $$ = lcons((Node *)n,NIL);
4176 substr_for: FOR expr_list
4182 trim_list: a_expr FROM expr_list
4183 { $$ = lappend($3, $1); }
4192 SubLink *n = makeNode(SubLink);
4200 in_expr_nodes: AexprConst
4201 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4202 | in_expr_nodes ',' AexprConst
4203 { $$ = makeA_Expr(OR, NULL, $1,
4204 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4208 not_in_expr: SubSelect
4210 SubLink *n = makeNode(SubLink);
4218 not_in_expr_nodes: AexprConst
4219 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4220 | not_in_expr_nodes ',' AexprConst
4221 { $$ = makeA_Expr(AND, NULL, $1,
4222 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4226 attr: relation_name '.' attrs
4228 $$ = makeNode(Attr);
4232 $$->indirection = NULL;
4236 $$ = makeNode(Attr);
4240 $$->indirection = NULL;
4245 { $$ = lcons(makeString($1), NIL); }
4246 | attrs '.' attr_name
4247 { $$ = lappend($1, makeString($3)); }
4249 { $$ = lappend($1, makeString("*")); }
4253 /*****************************************************************************
4257 *****************************************************************************/
4259 res_target_list: res_target_list ',' res_target_el
4260 { $$ = lappend($1,$3); }
4262 { $$ = lcons($1, NIL); }
4265 ResTarget *rt = makeNode(ResTarget);
4266 Attr *att = makeNode(Attr);
4268 att->paramNo = NULL;
4270 att->indirection = NIL;
4272 rt->indirection = NULL;
4273 rt->val = (Node *)att;
4274 $$ = lcons(rt, NIL);
4278 res_target_el: ColId opt_indirection '=' a_expr_or_null
4280 $$ = makeNode(ResTarget);
4282 $$->indirection = $2;
4283 $$->val = (Node *)$4;
4285 | attr opt_indirection
4287 $$ = makeNode(ResTarget);
4289 $$->indirection = $2;
4290 $$->val = (Node *)$1;
4292 | relation_name '.' '*'
4294 Attr *att = makeNode(Attr);
4296 att->paramNo = NULL;
4297 att->attrs = lcons(makeString("*"), NIL);
4298 att->indirection = NIL;
4299 $$ = makeNode(ResTarget);
4301 $$->indirection = NULL;
4302 $$->val = (Node *)att;
4307 ** target list for select.
4308 ** should get rid of the other but is still needed by the defunct select into
4309 ** and update (uses a subset)
4311 res_target_list2: res_target_list2 ',' res_target_el2
4312 { $$ = lappend($1, $3); }
4314 { $$ = lcons($1, NIL); }
4317 /* AS is not optional because shift/red conflict with unary ops */
4318 res_target_el2: a_expr_or_null AS ColLabel
4320 $$ = makeNode(ResTarget);
4322 $$->indirection = NULL;
4323 $$->val = (Node *)$1;
4327 $$ = makeNode(ResTarget);
4329 $$->indirection = NULL;
4330 $$->val = (Node *)$1;
4332 | relation_name '.' '*'
4334 Attr *att = makeNode(Attr);
4336 att->paramNo = NULL;
4337 att->attrs = lcons(makeString("*"), NIL);
4338 att->indirection = NIL;
4339 $$ = makeNode(ResTarget);
4341 $$->indirection = NULL;
4342 $$->val = (Node *)att;
4346 Attr *att = makeNode(Attr);
4348 att->paramNo = NULL;
4350 att->indirection = NIL;
4351 $$ = makeNode(ResTarget);
4353 $$->indirection = NULL;
4354 $$->val = (Node *)att;
4358 opt_id: ColId { $$ = $1; }
4359 | /* EMPTY */ { $$ = NULL; }
4362 relation_name: SpecialRuleRelation
4365 StrNCpy(saved_relname, $1, NAMEDATALEN);
4369 /* disallow refs to variable system tables */
4370 if (strcmp(LogRelationName, $1) == 0
4371 || strcmp(VariableRelationName, $1) == 0)
4372 elog(ERROR,"%s cannot be accessed by users",$1);
4375 StrNCpy(saved_relname, $1, NAMEDATALEN);
4379 database_name: ColId { $$ = $1; };
4380 access_method: IDENT { $$ = $1; };
4381 attr_name: ColId { $$ = $1; };
4382 class: IDENT { $$ = $1; };
4383 index_name: ColId { $$ = $1; };
4386 * Include date/time keywords as SQL92 extension.
4387 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4389 name: ColId { $$ = $1; };
4390 func_name: ColId { $$ = xlateSqlFunc($1); };
4392 file_name: Sconst { $$ = $1; };
4393 recipe_name: IDENT { $$ = $1; };
4396 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4400 A_Const *n = makeNode(A_Const);
4401 n->val.type = T_Integer;
4402 n->val.val.ival = $1;
4407 A_Const *n = makeNode(A_Const);
4408 n->val.type = T_Float;
4409 n->val.val.dval = $1;
4414 A_Const *n = makeNode(A_Const);
4415 n->val.type = T_String;
4416 n->val.val.str = $1;
4421 A_Const *n = makeNode(A_Const);
4423 n->val.type = T_String;
4424 n->val.val.str = $2;
4428 { $$ = (Node *)$1; }
4431 A_Const *n = makeNode(A_Const);
4432 n->val.type = T_String;
4433 n->val.val.str = "t";
4434 n->typename = makeNode(TypeName);
4435 n->typename->name = xlateSqlType("bool");
4436 n->typename->typmod = -1;
4441 A_Const *n = makeNode(A_Const);
4442 n->val.type = T_String;
4443 n->val.val.str = "f";
4444 n->typename = makeNode(TypeName);
4445 n->typename->name = xlateSqlType("bool");
4446 n->typename->typmod = -1;
4453 $$ = makeNode(ParamNo);
4458 Iconst: ICONST { $$ = $1; };
4459 Sconst: SCONST { $$ = $1; };
4460 UserId: IDENT { $$ = $1; };
4462 /* Column and type identifier
4463 * Does not include explicit datetime types
4464 * since these must be decoupled in Typename syntax.
4465 * Use ColId for most identifiers. - thomas 1997-10-21
4468 { $$ = xlateSqlType($1); }
4470 { $$ = xlateSqlType($1); }
4472 { $$ = xlateSqlType($1); }
4474 /* Column identifier
4475 * Include date/time keywords as SQL92 extension.
4476 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4477 * Add other keywords. Note that as the syntax expands,
4478 * some of these keywords will have to be removed from this
4479 * list due to shift/reduce conflicts in yacc. If so, move
4480 * down to the ColLabel entity. - thomas 1997-11-06
4482 ColId: IDENT { $$ = $1; }
4483 | datetime { $$ = $1; }
4484 | ACTION { $$ = "action"; }
4485 | CACHE { $$ = "cache"; }
4486 | CYCLE { $$ = "cycle"; }
4487 | DATABASE { $$ = "database"; }
4488 | DELIMITERS { $$ = "delimiters"; }
4489 | DOUBLE { $$ = "double"; }
4490 | EACH { $$ = "each"; }
4491 | FUNCTION { $$ = "function"; }
4492 | INCREMENT { $$ = "increment"; }
4493 | INDEX { $$ = "index"; }
4494 | KEY { $$ = "key"; }
4495 | LANGUAGE { $$ = "language"; }
4496 | LOCATION { $$ = "location"; }
4497 | MATCH { $$ = "match"; }
4498 | MAXVALUE { $$ = "maxvalue"; }
4499 | MINVALUE { $$ = "minvalue"; }
4500 | OPERATOR { $$ = "operator"; }
4501 | OPTION { $$ = "option"; }
4502 | PASSWORD { $$ = "password"; }
4503 | PRIVILEGES { $$ = "privileges"; }
4504 | RECIPE { $$ = "recipe"; }
4505 | ROW { $$ = "row"; }
4506 | START { $$ = "start"; }
4507 | STATEMENT { $$ = "statement"; }
4508 | TIME { $$ = "time"; }
4509 | TIMEZONE_HOUR { $$ = "timezone_hour"; }
4510 | TIMEZONE_MINUTE { $$ = "timezone_minute"; }
4511 | TRIGGER { $$ = "trigger"; }
4512 | TYPE_P { $$ = "type"; }
4513 | VALID { $$ = "valid"; }
4514 | VERSION { $$ = "version"; }
4515 | ZONE { $$ = "zone"; }
4519 * Allowed labels in "AS" clauses.
4520 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4521 * compatibility. Cannot allow this for column names since the
4522 * syntax would not distinguish between the constant value and
4523 * a column name. - thomas 1997-10-24
4524 * Add other keywords to this list. Note that they appear here
4525 * rather than in ColId if there was a shift/reduce conflict
4526 * when used as a full identifier. - thomas 1997-11-06
4528 ColLabel: ColId { $$ = $1; }
4529 | ARCHIVE { $$ = "archive"; }
4530 | CLUSTER { $$ = "cluster"; }
4531 | CONSTRAINT { $$ = "constraint"; }
4532 | CROSS { $$ = "cross"; }
4533 | FOREIGN { $$ = "foreign"; }
4534 | GROUP { $$ = "group"; }
4535 | LOAD { $$ = "load"; }
4536 | ORDER { $$ = "order"; }
4537 | POSITION { $$ = "position"; }
4538 | PRECISION { $$ = "precision"; }
4539 | TABLE { $$ = "table"; }
4540 | TRANSACTION { $$ = "transaction"; }
4541 | TRUE_P { $$ = "true"; }
4542 | FALSE_P { $$ = "false"; }
4545 SpecialRuleRelation: CURRENT
4550 elog(ERROR,"CURRENT used in non-rule query");
4557 elog(ERROR,"NEW used in non-rule query");
4564 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
4566 A_Expr *a = makeNode(A_Expr);
4575 * Generate separate operator nodes for a single row descriptor expression.
4576 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
4579 makeRowExpr(char *opr, List *largs, List *rargs)
4584 if (length(largs) != length(rargs))
4585 elog(ERROR,"Unequal number of entries in row expression");
4587 if (lnext(largs) != NIL)
4588 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
4590 larg = lfirst(largs);
4591 rarg = lfirst(rargs);
4593 if ((strcmp(opr, "=") == 0)
4594 || (strcmp(opr, "<") == 0)
4595 || (strcmp(opr, "<=") == 0)
4596 || (strcmp(opr, ">") == 0)
4597 || (strcmp(opr, ">=") == 0))
4600 expr = makeA_Expr(OP, opr, larg, rarg);
4602 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4604 else if (strcmp(opr, "<>") == 0)
4607 expr = makeA_Expr(OP, opr, larg, rarg);
4609 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4613 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
4617 while ((largs != NIL) && (rargs != NIL))
4619 larg = lfirst(largs);
4620 rarg = lfirst(rargs);
4623 expr = makeA_Expr(OP, opr, larg, rarg);
4625 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4627 largs = lnext(largs);
4628 rargs = lnext(rargs);
4637 mapTargetColumns(List *src, List *dst)
4642 if (length(src) != length(dst))
4643 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
4645 while ((src != NIL) && (dst != NIL))
4647 s = (ColumnDef *)lfirst(src);
4648 d = (ResTarget *)lfirst(dst);
4650 d->name = s->colname;
4657 } /* mapTargetColumns() */
4659 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
4661 Node *result = NULL;
4663 /* we do this so indexes can be used */
4664 if (strcmp(opname,"~") == 0 ||
4665 strcmp(opname,"~*") == 0)
4667 if (nodeTag(rexpr) == T_A_Const &&
4668 ((A_Const *)rexpr)->val.type == T_String &&
4669 ((A_Const *)rexpr)->val.val.str[0] == '^')
4671 A_Const *n = (A_Const *)rexpr;
4672 char *match_least = palloc(strlen(n->val.val.str)+2);
4673 char *match_most = palloc(strlen(n->val.val.str)+2);
4674 int pos, match_pos=0;
4676 /* skip leading ^ */
4677 for (pos = 1; n->val.val.str[pos]; pos++)
4679 if (n->val.val.str[pos] == '.' ||
4680 n->val.val.str[pos] == '?' ||
4681 n->val.val.str[pos] == '*' ||
4682 n->val.val.str[pos] == '[' ||
4683 n->val.val.str[pos] == '$' ||
4684 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4686 if (n->val.val.str[pos] == '\\')
4688 match_least[match_pos] = n->val.val.str[pos];
4689 match_most[match_pos++] = n->val.val.str[pos];
4694 A_Const *least = makeNode(A_Const);
4695 A_Const *most = makeNode(A_Const);
4697 /* make strings to be used in index use */
4698 match_least[match_pos] = '\0';
4699 match_most[match_pos] = '\377';
4700 match_most[match_pos+1] = '\0';
4701 least->val.type = T_String;
4702 least->val.val.str = match_least;
4703 most->val.type = T_String;
4704 most->val.val.str = match_most;
4705 result = makeA_Expr(AND, NULL,
4706 makeA_Expr(OP, "~", lexpr, rexpr),
4707 makeA_Expr(AND, NULL,
4708 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4709 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4713 else if (strcmp(opname,"~~") == 0)
4715 if (nodeTag(rexpr) == T_A_Const &&
4716 ((A_Const *)rexpr)->val.type == T_String)
4718 A_Const *n = (A_Const *)rexpr;
4719 char *match_least = palloc(strlen(n->val.val.str)+2);
4720 char *match_most = palloc(strlen(n->val.val.str)+2);
4721 int pos, match_pos=0;
4723 for (pos = 0; n->val.val.str[pos]; pos++)
4725 if (n->val.val.str[pos] == '%' &&
4726 n->val.val.str[pos+1] != '%')
4728 if(n->val.val.str[pos] == '_')
4730 if (n->val.val.str[pos] == '\\' ||
4731 n->val.val.str[pos] == '%')
4733 if (n->val.val.str[pos] == '\0')
4735 match_least[match_pos] = n->val.val.str[pos];
4736 match_most[match_pos++] = n->val.val.str[pos];
4741 A_Const *least = makeNode(A_Const);
4742 A_Const *most = makeNode(A_Const);
4744 /* make strings to be used in index use */
4745 match_least[match_pos] = '\0';
4746 match_most[match_pos] = '\377';
4747 match_most[match_pos+1] = '\0';
4748 least->val.type = T_String;
4749 least->val.val.str = match_least;
4750 most->val.type = T_String;
4751 most->val.val.str = match_most;
4752 result = makeA_Expr(AND, NULL,
4753 makeA_Expr(OP, "~~", lexpr, rexpr),
4754 makeA_Expr(AND, NULL,
4755 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4756 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4762 result = makeA_Expr(OP, opname, lexpr, rexpr);
4764 } /* makeIndexable() */
4768 * Convert alternate type names to internal Postgres types.
4769 * Do not convert "float", since that is handled elsewhere
4770 * for FLOAT(p) syntax.
4773 xlateSqlFunc(char *name)
4775 if (!strcasecmp(name,"character_length")
4776 || !strcasecmp(name,"char_length"))
4780 } /* xlateSqlFunc() */
4783 * Convert alternate type names to internal Postgres types.
4786 xlateSqlType(char *name)
4788 if (!strcasecmp(name,"int")
4789 || !strcasecmp(name,"integer"))
4791 else if (!strcasecmp(name, "smallint"))
4793 else if (!strcasecmp(name, "real")
4794 || !strcasecmp(name, "float"))
4796 else if (!strcasecmp(name, "interval"))
4798 else if (!strcasecmp(name, "boolean"))
4802 } /* xlateSqlType() */
4805 void parser_init(Oid *typev, int nargs)
4807 QueryIsRule = FALSE;
4808 saved_relname[0]= '\0';
4809 saved_In_Expr = NULL;
4811 param_type_init(typev, nargs);
4815 /* FlattenStringList()
4816 * Traverse list of string nodes and convert to a single string.
4817 * Used for reconstructing string form of complex expressions.
4819 * Allocate at least one byte for terminator.
4822 FlattenStringList(List *list)
4830 nlist = length(list);
4833 v = (Value *)lfirst(l);
4840 s = (char*) palloc(len+1);
4845 v = (Value *)lfirst(l);
4849 if (l != NIL) strcat(s," ");
4854 elog(DEBUG, "flattened string is \"%s\"\n", s);
4858 } /* FlattenStringList() */
4861 /* makeConstantList()
4862 * Convert constant value node into string node.
4865 makeConstantList( A_Const *n)
4868 char *typval = NULL;
4869 char *defval = NULL;
4871 if (nodeTag(n) != T_A_Const) {
4872 elog(ERROR,"Cannot handle non-constant parameter");
4874 } else if (n->val.type == T_Float) {
4875 defval = (char*) palloc(20+1);
4876 sprintf( defval, "%g", n->val.val.dval);
4877 result = lcons( makeString(defval), NIL);
4879 } else if (n->val.type == T_Integer) {
4880 defval = (char*) palloc(20+1);
4881 sprintf( defval, "%ld", n->val.val.ival);
4882 result = lcons( makeString(defval), NIL);
4884 } else if (n->val.type == T_String) {
4885 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
4886 strcpy( defval, "'");
4887 strcat( defval, ((A_Const *) n)->val.val.str);
4888 strcat( defval, "'");
4889 if (n->typename != NULL)
4891 typval = (char*) palloc(strlen( n->typename->name) + 1);
4892 strcpy(typval, n->typename->name);
4893 result = lappend( lcons( makeString(typval), NIL), makeString(defval));
4897 result = lcons( makeString(defval), NIL);
4901 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
4905 elog(DEBUG, "AexprConst argument is \"%s\"\n", defval);
4909 } /* makeConstantList() */
4913 * Check input string for non-lowercase/non-numeric characters.
4914 * Returns either input string or input surrounded by double quotes.
4921 for (cp = rawid; *cp != '\0'; cp++)
4922 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
4925 cp = palloc(strlen(rawid)+1);
4934 elog(DEBUG, "fmtId- %sconvert %s to %s\n",
4935 ((cp == rawid)? "do not ": ""), rawid, cp);
4944 * keep enough information around fill out the type of param nodes
4945 * used in postquel functions
4948 param_type_init(Oid *typev, int nargs)
4950 pfunc_num_args = nargs;
4951 param_type_info = typev;
4954 Oid param_type(int t)
4956 if ((t > pfunc_num_args) || (t == 0))
4958 return param_type_info[t - 1];