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.8 1998/03/30 16:36:35 momjian Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlFunc(char *);
65 static char *xlateSqlType(char *);
66 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
67 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
68 void mapTargetColumns(List *source, List *target);
69 static List *makeConstantList( A_Const *node);
70 static char *FlattenStringList(List *list);
71 static char *fmtId(char *rawid);
72 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
73 static void param_type_init(Oid *typev, int nargs);
75 Oid param_type(int t); /* used in parse_expr.c */
77 /* old versions of flex define this as a macro */
91 bool* pboolean; /* for pg_shadow privileges */
101 SortGroupBy *sortgroupby;
116 AddAttrStmt, ClosePortalStmt,
117 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
118 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
119 CreatePLangStmt, DropPLangStmt,
120 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
121 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
122 RemoveFuncStmt, RemoveStmt,
123 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
124 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
125 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
126 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
127 CreateUserStmt, AlterUserStmt, DropUserStmt
129 %type <str> opt_database, location
131 %type <pboolean> user_createdb_clause, user_createuser_clause
132 %type <str> user_passwd_clause
133 %type <str> user_valid_clause
134 %type <list> user_group_list, user_group_clause
136 %type <str> join_expr, join_outer, join_spec
137 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
139 %type <str> TriggerEvents, TriggerFuncArg
141 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
142 database_name, access_method_clause, access_method, attr_name,
143 class, index_name, name, func_name, file_name, recipe_name, aggr_argtype
145 %type <str> opt_id, opt_portal_name,
146 all_Op, MathOp, opt_name, opt_unique,
147 result, OptUseOp, opt_class, SpecialRuleRelation
149 %type <str> privileges, operation_commalist, grantee
150 %type <chr> operation, TriggerOneEvent
152 %type <list> stmtblock, stmtmulti,
153 relation_name_list, OptTableElementList,
154 OptInherit, definition,
155 opt_with, func_args, func_args_list,
156 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
157 opt_column_list, columnList, opt_va_list, va_list,
158 sort_clause, sortby_list, index_params, index_list, name_list,
159 from_clause, from_list, opt_array_bounds, nest_array_bounds,
160 expr_list, attrs, res_target_list, res_target_list2,
161 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
163 %type <node> func_return
164 %type <boolean> set_opt
166 %type <boolean> TriggerForOpt, TriggerForType
168 %type <list> union_clause, select_list
169 %type <list> join_list
172 %type <boolean> opt_union
173 %type <boolean> opt_table
175 %type <node> position_expr
176 %type <list> extract_list, position_list
177 %type <list> substr_list, substr_from, substr_for, trim_list
178 %type <list> opt_interval
180 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
181 index_opt_unique, opt_verbose, opt_analyze
183 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
186 %type <ival> fetch_how_many
188 %type <list> OptSeqList
189 %type <defelt> OptSeqElem
191 %type <dstmt> def_rest
192 %type <astmt> insert_rest
194 %type <node> OptTableElement, ConstraintElem
195 %type <node> columnDef, alter_clause
196 %type <defelt> def_elem
197 %type <node> def_arg, columnElem, where_clause,
198 a_expr, a_expr_or_null, b_expr, AexprConst,
199 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
201 %type <list> row_descriptor, row_list
202 %type <node> row_expr
203 %type <list> OptCreateAs, CreateAsList
204 %type <node> CreateAsElement
205 %type <value> NumConst
206 %type <value> IntegerOnly
207 %type <attr> event_object, attr
208 %type <sortgroupby> groupby
209 %type <sortgroupby> sortby
210 %type <ielem> index_elem, func_index
211 %type <range> from_val
212 %type <relexp> relation_expr
213 %type <target> res_target_el, res_target_el2
214 %type <paramno> ParamNo
216 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
217 %type <str> generic, numeric, character, datetime
218 %type <str> opt_charset, opt_collate
219 %type <str> opt_float, opt_numeric, opt_decimal
220 %type <boolean> opt_varying, opt_timezone
224 %type <str> UserId, var_value, zone_value
225 %type <str> ColId, ColLabel
228 %type <node> TableConstraint
229 %type <list> constraint_list, constraint_expr
230 %type <list> default_list, default_expr
231 %type <list> ColQualList, ColQualifier
232 %type <node> ColConstraint, ColConstraintElem
233 %type <list> key_actions, key_action
234 %type <str> key_match, key_reference
237 * If you make any token changes, remember to:
238 * - use "yacc -d" and update parse.h
239 * - update the keyword table in parser/keywords.c
242 /* Reserved word tokens
243 * SQL92 syntax has many type-specific constructs.
244 * So, go ahead and make these types reserved words,
245 * and call-out the syntax explicitly.
246 * This gets annoying when trying to also retain Postgres' nice
247 * type-extensible features, but we don't really have a choice.
248 * - thomas 1997-10-11
251 /* Keywords (in SQL92 reserved words) */
252 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
253 BEGIN_TRANS, BETWEEN, BOTH, BY,
254 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
255 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
256 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
257 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
258 END_TRANS, EXECUTE, EXISTS, EXTRACT,
259 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
260 GRANT, GROUP, HAVING, HOUR_P,
261 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
262 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
263 MATCH, MINUTE_P, MONTH_P,
264 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
265 ON, OPTION, OR, ORDER, OUTER_P,
266 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
267 REFERENCES, REVOKE, RIGHT, ROLLBACK,
268 SECOND_P, SELECT, SET, SUBSTRING,
269 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
270 UNION, UNIQUE, UPDATE, USING,
271 VALUES, VARCHAR, VARYING, VIEW,
272 WHERE, WITH, WORK, YEAR_P, ZONE
274 /* Keywords (in SQL3 reserved words) */
275 %token FALSE_P, TRIGGER, TRUE_P
277 /* Keywords (in SQL92 non-reserved words) */
280 /* Keywords for Postgres support (not in SQL92 reserved words) */
281 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
282 BACKWARD, BEFORE, BINARY, CACHE, CLUSTER, COPY, CYCLE,
283 DATABASE, DELIMITERS, DO, EACH, EXPLAIN, EXTEND,
284 FORWARD, FUNCTION, HANDLER,
285 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
286 LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MAXVALUE, MINVALUE, MOVE,
287 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
288 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
289 SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
290 VACUUM, VERBOSE, VERSION
292 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
296 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
297 * when some sort of pg_privileges relation is introduced.
301 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
303 /* Special keywords, not in the query language - see the "lex" file */
304 %token <str> IDENT, SCONST, Op
305 %token <ival> ICONST, PARAM
308 /* these are not real. they are here so that they get generated as #define's*/
320 %nonassoc Op /* multi-character ops and user-defined operators */
326 %left '|' /* this is the relation union op, not logical or */
327 /* Unary Operators */
329 %left ';' /* end of statement or natural log */
341 { parsetree = lcons($1,NIL); }
344 stmtmulti: stmtmulti stmt ';'
345 { $$ = lappend($1, $2); }
347 { $$ = lappend($1, $2); }
349 { $$ = lcons($1,NIL); }
396 /*****************************************************************************
398 * Create a new Postgres DBMS user
401 *****************************************************************************/
403 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
404 user_createuser_clause user_group_clause user_valid_clause
406 CreateUserStmt *n = makeNode(CreateUserStmt);
417 /*****************************************************************************
419 * Alter a postresql DBMS user
422 *****************************************************************************/
424 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
425 user_createuser_clause user_group_clause user_valid_clause
427 AlterUserStmt *n = makeNode(AlterUserStmt);
438 /*****************************************************************************
440 * Drop a postresql DBMS user
443 *****************************************************************************/
445 DropUserStmt: DROP USER UserId
447 DropUserStmt *n = makeNode(DropUserStmt);
453 user_passwd_clause: WITH PASSWORD UserId { $$ = $3; }
454 | /*EMPTY*/ { $$ = NULL; }
457 user_createdb_clause: CREATEDB
460 $$ = (b = (bool*)palloc(sizeof(bool)));
466 $$ = (b = (bool*)palloc(sizeof(bool)));
469 | /*EMPTY*/ { $$ = NULL; }
472 user_createuser_clause: CREATEUSER
475 $$ = (b = (bool*)palloc(sizeof(bool)));
481 $$ = (b = (bool*)palloc(sizeof(bool)));
484 | /*EMPTY*/ { $$ = NULL; }
487 user_group_list: user_group_list ',' UserId
489 $$ = lcons((void*)makeString($3), $1);
493 $$ = lcons((void*)makeString($1), NIL);
497 user_group_clause: IN GROUP user_group_list { $$ = $3; }
498 | /*EMPTY*/ { $$ = NULL; }
501 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
502 | /*EMPTY*/ { $$ = NULL; }
505 /*****************************************************************************
507 * Set PG internal variable
508 * SET name TO 'var_value'
509 * Include SQL92 syntax (thomas 1997-10-22):
510 * SET TIME ZONE 'var_value'
512 *****************************************************************************/
514 VariableSetStmt: SET ColId TO var_value
516 VariableSetStmt *n = makeNode(VariableSetStmt);
521 | SET ColId '=' var_value
523 VariableSetStmt *n = makeNode(VariableSetStmt);
528 | SET TIME ZONE zone_value
530 VariableSetStmt *n = makeNode(VariableSetStmt);
531 n->name = "timezone";
537 var_value: Sconst { $$ = $1; }
538 | DEFAULT { $$ = NULL; }
541 zone_value: Sconst { $$ = $1; }
542 | DEFAULT { $$ = NULL; }
543 | LOCAL { $$ = "default"; }
546 VariableShowStmt: SHOW ColId
548 VariableShowStmt *n = makeNode(VariableShowStmt);
554 VariableShowStmt *n = makeNode(VariableShowStmt);
555 n->name = "timezone";
560 VariableResetStmt: RESET ColId
562 VariableResetStmt *n = makeNode(VariableResetStmt);
568 VariableResetStmt *n = makeNode(VariableResetStmt);
569 n->name = "timezone";
575 /*****************************************************************************
578 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
580 *****************************************************************************/
582 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
584 AddAttrStmt *n = makeNode(AddAttrStmt);
592 alter_clause: ADD opt_column columnDef
596 | ADD '(' OptTableElementList ')'
598 Node *lp = lfirst($3);
601 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
604 | DROP opt_column ColId
605 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
606 | ALTER opt_column ColId SET DEFAULT default_expr
607 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
608 | ALTER opt_column ColId DROP DEFAULT
609 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
611 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
615 /*****************************************************************************
620 *****************************************************************************/
622 ClosePortalStmt: CLOSE opt_id
624 ClosePortalStmt *n = makeNode(ClosePortalStmt);
631 /*****************************************************************************
634 * COPY [BINARY] <relname> FROM/TO
635 * [USING DELIMITERS <delimiter>]
637 *****************************************************************************/
639 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
641 CopyStmt *n = makeNode(CopyStmt);
659 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
660 * used depends on the direction. (It really doesn't make sense to copy from
661 * stdout. We silently correct the "typo". - AY 9/94
663 copy_file_name: Sconst { $$ = $1; }
664 | STDIN { $$ = NULL; }
665 | STDOUT { $$ = NULL; }
668 opt_binary: BINARY { $$ = TRUE; }
669 | /*EMPTY*/ { $$ = FALSE; }
672 opt_with_copy: WITH OIDS { $$ = TRUE; }
673 | /*EMPTY*/ { $$ = FALSE; }
677 * the default copy delimiter is tab but the user can configure it
679 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
680 | /*EMPTY*/ { $$ = "\t"; }
684 /*****************************************************************************
689 *****************************************************************************/
691 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
692 OptInherit OptArchiveType
694 CreateStmt *n = makeNode(CreateStmt);
698 n->constraints = NIL;
703 OptTableElementList: OptTableElementList ',' OptTableElement
704 { $$ = lappend($1, $3); }
705 | OptTableElement { $$ = lcons($1, NIL); }
706 | /*EMPTY*/ { $$ = NULL; }
709 OptTableElement: columnDef { $$ = $1; }
710 | TableConstraint { $$ = $1; }
713 columnDef: ColId Typename ColQualifier
715 ColumnDef *n = makeNode(ColumnDef);
719 n->is_not_null = FALSE;
725 ColQualifier: ColQualList { $$ = $1; }
726 | /*EMPTY*/ { $$ = NULL; }
729 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
730 | ColConstraint { $$ = lcons($1, NIL); }
734 CONSTRAINT name ColConstraintElem
736 Constraint *n = (Constraint *)$3;
744 ColConstraintElem: CHECK '(' constraint_expr ')'
746 Constraint *n = makeNode(Constraint);
747 n->contype = CONSTR_CHECK;
749 n->def = FlattenStringList($3);
753 | DEFAULT default_expr
755 Constraint *n = makeNode(Constraint);
756 n->contype = CONSTR_DEFAULT;
758 n->def = FlattenStringList($2);
764 Constraint *n = makeNode(Constraint);
765 n->contype = CONSTR_NOTNULL;
773 Constraint *n = makeNode(Constraint);
774 n->contype = CONSTR_UNIQUE;
782 Constraint *n = makeNode(Constraint);
783 n->contype = CONSTR_PRIMARY;
789 | REFERENCES ColId opt_column_list key_match key_actions
791 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
796 default_list: default_list ',' default_expr
798 $$ = lappend($1,makeString(","));
807 default_expr: AexprConst
808 { $$ = makeConstantList((A_Const *) $1); }
810 { $$ = lcons( makeString("NULL"), NIL); }
811 | '-' default_expr %prec UMINUS
812 { $$ = lcons( makeString( "-"), $2); }
813 | default_expr '+' default_expr
814 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
815 | default_expr '-' default_expr
816 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
817 | default_expr '/' default_expr
818 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
819 | default_expr '*' default_expr
820 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
821 | default_expr '=' default_expr
822 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
823 | default_expr '<' default_expr
824 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
825 | default_expr '>' default_expr
826 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
828 { $$ = lcons( makeString( ":"), $2); }
830 { $$ = lcons( makeString( ";"), $2); }
832 { $$ = lcons( makeString( "|"), $2); }
833 | default_expr TYPECAST Typename
835 $3->name = fmtId($3->name);
836 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
838 | CAST '(' default_expr AS Typename ')'
840 $5->name = fmtId($5->name);
841 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
843 | '(' default_expr ')'
844 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
847 $$ = makeList( makeString($1), makeString("("), -1);
848 $$ = lappend( $$, makeString(")"));
850 | func_name '(' default_list ')'
852 $$ = makeList( makeString($1), makeString("("), -1);
854 $$ = lappend( $$, makeString(")"));
856 | default_expr Op default_expr
858 if (!strcmp("<=", $2) || !strcmp(">=", $2))
859 elog(ERROR,"boolean expressions not supported in DEFAULT");
860 $$ = nconc( $1, lcons( makeString( $2), $3));
863 { $$ = lcons( makeString( $1), $2); }
865 { $$ = lappend( $1, makeString( $2)); }
866 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
868 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
870 { $$ = lcons( makeString( "'now'::time"), NIL); }
871 | CURRENT_TIME '(' Iconst ')'
874 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
875 $$ = lcons( makeString( "'now'::time"), NIL);
878 { $$ = lcons( makeString( "now()"), NIL); }
879 | CURRENT_TIMESTAMP '(' Iconst ')'
882 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
883 $$ = lcons( makeString( "now()"), NIL);
886 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
889 /* ConstraintElem specifies constraint syntax which is not embedded into
890 * a column definition. ColConstraintElem specifies the embedded form.
891 * - thomas 1997-12-03
893 TableConstraint: CONSTRAINT name ConstraintElem
895 Constraint *n = (Constraint *)$3;
903 ConstraintElem: CHECK '(' constraint_expr ')'
905 Constraint *n = makeNode(Constraint);
906 n->contype = CONSTR_CHECK;
908 n->def = FlattenStringList($3);
911 | UNIQUE '(' columnList ')'
913 Constraint *n = makeNode(Constraint);
914 n->contype = CONSTR_UNIQUE;
920 | PRIMARY KEY '(' columnList ')'
922 Constraint *n = makeNode(Constraint);
923 n->contype = CONSTR_PRIMARY;
929 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
930 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented"); }
933 constraint_list: constraint_list ',' constraint_expr
935 $$ = lappend($1,makeString(","));
944 constraint_expr: AexprConst
945 { $$ = makeConstantList((A_Const *) $1); }
947 { $$ = lcons( makeString("NULL"), NIL); }
950 $$ = lcons( makeString(fmtId($1)), NIL);
952 | '-' constraint_expr %prec UMINUS
953 { $$ = lcons( makeString( "-"), $2); }
954 | constraint_expr '+' constraint_expr
955 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
956 | constraint_expr '-' constraint_expr
957 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
958 | constraint_expr '/' constraint_expr
959 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
960 | constraint_expr '*' constraint_expr
961 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
962 | constraint_expr '=' constraint_expr
963 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
964 | constraint_expr '<' constraint_expr
965 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
966 | constraint_expr '>' constraint_expr
967 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
968 | ':' constraint_expr
969 { $$ = lcons( makeString( ":"), $2); }
970 | ';' constraint_expr
971 { $$ = lcons( makeString( ";"), $2); }
972 | '|' constraint_expr
973 { $$ = lcons( makeString( "|"), $2); }
974 | constraint_expr TYPECAST Typename
976 $3->name = fmtId($3->name);
977 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
979 | CAST '(' constraint_expr AS Typename ')'
981 $5->name = fmtId($5->name);
982 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
984 | '(' constraint_expr ')'
985 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
988 $$ = makeList( makeString($1), makeString("("), -1);
989 $$ = lappend( $$, makeString(")"));
991 | func_name '(' constraint_list ')'
993 $$ = makeList( makeString($1), makeString("("), -1);
995 $$ = lappend( $$, makeString(")"));
997 | constraint_expr Op constraint_expr
998 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
999 | constraint_expr LIKE constraint_expr
1000 { $$ = nconc( $1, lcons( makeString( "like"), $3)); }
1001 | constraint_expr AND constraint_expr
1002 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
1003 | constraint_expr OR constraint_expr
1004 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
1005 | NOT constraint_expr
1006 { $$ = lcons( makeString( "NOT"), $2); }
1007 | Op constraint_expr
1008 { $$ = lcons( makeString( $1), $2); }
1009 | constraint_expr Op
1010 { $$ = lappend( $1, makeString( $2)); }
1011 | constraint_expr ISNULL
1012 { $$ = lappend( $1, makeString( "IS NULL")); }
1013 | constraint_expr IS NULL_P
1014 { $$ = lappend( $1, makeString( "IS NULL")); }
1015 | constraint_expr NOTNULL
1016 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1017 | constraint_expr IS NOT NULL_P
1018 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1019 | constraint_expr IS TRUE_P
1020 { $$ = lappend( $1, makeString( "IS TRUE")); }
1021 | constraint_expr IS FALSE_P
1022 { $$ = lappend( $1, makeString( "IS FALSE")); }
1023 | constraint_expr IS NOT TRUE_P
1024 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1025 | constraint_expr IS NOT FALSE_P
1026 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1029 key_match: MATCH FULL { $$ = NULL; }
1030 | MATCH PARTIAL { $$ = NULL; }
1031 | /*EMPTY*/ { $$ = NULL; }
1034 key_actions: key_action key_action { $$ = NIL; }
1035 | key_action { $$ = NIL; }
1036 | /*EMPTY*/ { $$ = NIL; }
1039 key_action: ON DELETE key_reference { $$ = NIL; }
1040 | ON UPDATE key_reference { $$ = NIL; }
1043 key_reference: NO ACTION { $$ = NULL; }
1044 | CASCADE { $$ = NULL; }
1045 | SET DEFAULT { $$ = NULL; }
1046 | SET NULL_P { $$ = NULL; }
1049 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1050 | /*EMPTY*/ { $$ = NIL; }
1054 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1055 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1057 OptArchiveType: ARCHIVE '=' NONE { }
1061 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1063 SelectStmt *n = (SelectStmt *)$6;
1065 mapTargetColumns($4, n->targetList);
1071 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1072 | /*EMPTY*/ { $$ = NULL; }
1075 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1076 | CreateAsElement { $$ = lcons($1, NIL); }
1079 CreateAsElement: ColId
1081 ColumnDef *n = makeNode(ColumnDef);
1085 n->is_not_null = FALSE;
1086 n->constraints = NULL;
1092 /*****************************************************************************
1095 * CREATE SEQUENCE seqname
1097 *****************************************************************************/
1099 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1101 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1108 OptSeqList: OptSeqList OptSeqElem
1109 { $$ = lappend($1, $2); }
1113 OptSeqElem: CACHE IntegerOnly
1115 $$ = makeNode(DefElem);
1116 $$->defname = "cache";
1117 $$->arg = (Node *)$2;
1121 $$ = makeNode(DefElem);
1122 $$->defname = "cycle";
1123 $$->arg = (Node *)NULL;
1125 | INCREMENT IntegerOnly
1127 $$ = makeNode(DefElem);
1128 $$->defname = "increment";
1129 $$->arg = (Node *)$2;
1131 | MAXVALUE IntegerOnly
1133 $$ = makeNode(DefElem);
1134 $$->defname = "maxvalue";
1135 $$->arg = (Node *)$2;
1137 | MINVALUE IntegerOnly
1139 $$ = makeNode(DefElem);
1140 $$->defname = "minvalue";
1141 $$->arg = (Node *)$2;
1145 $$ = makeNode(DefElem);
1146 $$->defname = "start";
1147 $$->arg = (Node *)$2;
1153 $$ = makeInteger($1);
1157 $$ = makeInteger($2);
1158 $$->val.ival = - $$->val.ival;
1162 /*****************************************************************************
1165 * CREATE PROCEDURAL LANGUAGE ...
1166 * DROP PROCEDURAL LANGUAGE ...
1168 *****************************************************************************/
1170 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1171 HANDLER def_name LANCOMPILER Sconst
1173 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1182 PLangTrusted: TRUSTED { $$ = TRUE; }
1185 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1187 DropPLangStmt *n = makeNode(DropPLangStmt);
1193 /*****************************************************************************
1196 * CREATE TRIGGER ...
1199 *****************************************************************************/
1201 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1202 relation_name TriggerForSpec EXECUTE PROCEDURE
1203 name '(' TriggerFuncArgs ')'
1205 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1212 memcpy (n->actions, $5, 4);
1217 TriggerActionTime: BEFORE { $$ = TRUE; }
1218 | AFTER { $$ = FALSE; }
1221 TriggerEvents: TriggerOneEvent
1223 char *e = palloc (4);
1224 e[0] = $1; e[1] = 0; $$ = e;
1226 | TriggerOneEvent OR TriggerOneEvent
1228 char *e = palloc (4);
1229 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1231 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1233 char *e = palloc (4);
1234 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1239 TriggerOneEvent: INSERT { $$ = 'i'; }
1240 | DELETE { $$ = 'd'; }
1241 | UPDATE { $$ = 'u'; }
1244 TriggerForSpec: FOR TriggerForOpt TriggerForType
1250 TriggerForOpt: EACH { $$ = TRUE; }
1251 | /*EMPTY*/ { $$ = FALSE; }
1254 TriggerForType: ROW { $$ = TRUE; }
1255 | STATEMENT { $$ = FALSE; }
1258 TriggerFuncArgs: TriggerFuncArg
1259 { $$ = lcons($1, NIL); }
1260 | TriggerFuncArgs ',' TriggerFuncArg
1261 { $$ = lappend($1, $3); }
1266 TriggerFuncArg: ICONST
1268 char *s = (char *) palloc (256);
1269 sprintf (s, "%d", $1);
1274 char *s = (char *) palloc (256);
1275 sprintf (s, "%g", $1);
1278 | Sconst { $$ = $1; }
1279 | IDENT { $$ = $1; }
1282 DropTrigStmt: DROP TRIGGER name ON relation_name
1284 DropTrigStmt *n = makeNode(DropTrigStmt);
1292 /*****************************************************************************
1295 * define (type,operator,aggregate)
1297 *****************************************************************************/
1299 DefineStmt: CREATE def_type def_rest
1306 def_rest: def_name definition
1308 $$ = makeNode(DefineStmt);
1310 $$->definition = $2;
1314 def_type: OPERATOR { $$ = OPERATOR; }
1315 | TYPE_P { $$ = TYPE_P; }
1316 | AGGREGATE { $$ = AGGREGATE; }
1319 def_name: PROCEDURE { $$ = "procedure"; }
1320 | JOIN { $$ = "join"; }
1321 | ColId { $$ = $1; }
1322 | MathOp { $$ = $1; }
1326 definition: '(' def_list ')' { $$ = $2; }
1329 def_list: def_elem { $$ = lcons($1, NIL); }
1330 | def_list ',' def_elem { $$ = lappend($1, $3); }
1333 def_elem: def_name '=' def_arg
1335 $$ = makeNode(DefElem);
1337 $$->arg = (Node *)$3;
1341 $$ = makeNode(DefElem);
1343 $$->arg = (Node *)NULL;
1345 | DEFAULT '=' def_arg
1347 $$ = makeNode(DefElem);
1348 $$->defname = "default";
1349 $$->arg = (Node *)$3;
1353 def_arg: ColId { $$ = (Node *)makeString($1); }
1354 | all_Op { $$ = (Node *)makeString($1); }
1355 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1356 | Sconst { $$ = (Node *)makeString($1); }
1359 TypeName *n = makeNode(TypeName);
1362 n->arrayBounds = NULL;
1369 /*****************************************************************************
1372 * destroy <relname1> [, <relname2> .. <relnameN> ]
1374 *****************************************************************************/
1376 DestroyStmt: DROP TABLE relation_name_list
1378 DestroyStmt *n = makeNode(DestroyStmt);
1380 n->sequence = FALSE;
1383 | DROP SEQUENCE relation_name_list
1385 DestroyStmt *n = makeNode(DestroyStmt);
1393 /*****************************************************************************
1396 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1398 *****************************************************************************/
1400 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1402 FetchStmt *n = makeNode(FetchStmt);
1409 | MOVE opt_direction fetch_how_many opt_portal_name
1411 FetchStmt *n = makeNode(FetchStmt);
1420 opt_direction: FORWARD { $$ = FORWARD; }
1421 | BACKWARD { $$ = BACKWARD; }
1422 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1425 fetch_how_many: Iconst
1427 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1428 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1429 | /*EMPTY*/ { $$ = 1; /*default*/ }
1432 opt_portal_name: IN name { $$ = $2; }
1433 | /*EMPTY*/ { $$ = NULL; }
1437 /*****************************************************************************
1440 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1442 *****************************************************************************/
1444 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1446 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1450 privileges: ALL PRIVILEGES
1452 $$ = aclmakepriv("rwaR",0);
1456 $$ = aclmakepriv("rwaR",0);
1458 | operation_commalist
1464 operation_commalist: operation
1466 $$ = aclmakepriv("",$1);
1468 | operation_commalist ',' operation
1470 $$ = aclmakepriv($1,$3);
1476 $$ = ACL_MODE_RD_CHR;
1480 $$ = ACL_MODE_AP_CHR;
1484 $$ = ACL_MODE_WR_CHR;
1488 $$ = ACL_MODE_WR_CHR;
1492 $$ = ACL_MODE_RU_CHR;
1498 $$ = aclmakeuser("A","");
1502 $$ = aclmakeuser("G",$2);
1506 $$ = aclmakeuser("U",$1);
1510 opt_with_grant: WITH GRANT OPTION
1512 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1518 /*****************************************************************************
1521 * REVOKE [privileges] ON [relation_name] FROM [user]
1523 *****************************************************************************/
1525 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1527 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1532 /*****************************************************************************
1535 * create index <indexname> on <relname>
1536 * using <access> "(" (<col> with <op>)+ ")" [with
1539 * [where <qual>] is not supported anymore
1540 *****************************************************************************/
1542 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1543 access_method_clause '(' index_params ')' opt_with
1545 /* should check that access_method is valid,
1546 etc ... but doesn't */
1547 IndexStmt *n = makeNode(IndexStmt);
1551 n->accessMethod = $7;
1552 n->indexParams = $9;
1553 n->withClause = $11;
1554 n->whereClause = NULL;
1559 index_opt_unique: UNIQUE { $$ = TRUE; }
1560 | /*EMPTY*/ { $$ = FALSE; }
1563 access_method_clause: USING access_method { $$ = $2; }
1564 | /*EMPTY*/ { $$ = "btree"; }
1567 index_params: index_list { $$ = $1; }
1568 | func_index { $$ = lcons($1,NIL); }
1571 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1572 | index_elem { $$ = lcons($1, NIL); }
1575 func_index: func_name '(' name_list ')' opt_type opt_class
1577 $$ = makeNode(IndexElem);
1585 index_elem: attr_name opt_type opt_class
1587 $$ = makeNode(IndexElem);
1595 opt_type: ':' Typename { $$ = $2; }
1596 | FOR Typename { $$ = $2; }
1597 | /*EMPTY*/ { $$ = NULL; }
1600 /* opt_class "WITH class" conflicts with preceeding opt_type
1601 * for Typename of "TIMESTAMP WITH TIME ZONE"
1602 * So, remove "WITH class" from the syntax. OK??
1603 * - thomas 1997-10-12
1604 * | WITH class { $$ = $2; }
1606 opt_class: class { $$ = $1; }
1607 | USING class { $$ = $2; }
1608 | /*EMPTY*/ { $$ = NULL; }
1612 /*****************************************************************************
1615 * extend index <indexname> [where <qual>]
1617 *****************************************************************************/
1619 ExtendStmt: EXTEND INDEX index_name where_clause
1621 ExtendStmt *n = makeNode(ExtendStmt);
1623 n->whereClause = $4;
1629 /*****************************************************************************
1632 * execute recipe <recipeName>
1634 *****************************************************************************/
1636 RecipeStmt: EXECUTE RECIPE recipe_name
1639 if (!IsTransactionBlock())
1640 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1642 n = makeNode(RecipeStmt);
1649 /*****************************************************************************
1652 * define function <fname>
1653 * (language = <lang>, returntype = <typename>
1654 * [, arch_pct = <percentage | pre-defined>]
1655 * [, disk_pct = <percentage | pre-defined>]
1656 * [, byte_pct = <percentage | pre-defined>]
1657 * [, perbyte_cpu = <int | pre-defined>]
1658 * [, percall_cpu = <int | pre-defined>]
1660 * [arg is (<type-1> { , <type-n>})]
1661 * as <filename or code in language as appropriate>
1663 *****************************************************************************/
1665 ProcedureStmt: CREATE FUNCTION func_name func_args
1666 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
1668 ProcedureStmt *n = makeNode(ProcedureStmt);
1678 opt_with: WITH definition { $$ = $2; }
1679 | /*EMPTY*/ { $$ = NIL; }
1682 func_args: '(' func_args_list ')' { $$ = $2; }
1683 | '(' ')' { $$ = NIL; }
1686 func_args_list: TypeId
1687 { $$ = lcons(makeString($1),NIL); }
1688 | func_args_list ',' TypeId
1689 { $$ = lappend($1,makeString($3)); }
1692 func_return: set_opt TypeId
1694 TypeName *n = makeNode(TypeName);
1697 n->arrayBounds = NULL;
1702 set_opt: SETOF { $$ = TRUE; }
1703 | /*EMPTY*/ { $$ = FALSE; }
1706 /*****************************************************************************
1710 * remove function <funcname>
1711 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1712 * remove aggregate <aggname>
1713 * (REMOVE AGGREGATE "aggname" "aggtype")
1714 * remove operator <opname>
1715 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1716 * remove type <typename>
1717 * (REMOVE TYPE "typename")
1718 * remove rule <rulename>
1719 * (REMOVE RULE "rulename")
1721 *****************************************************************************/
1723 RemoveStmt: DROP remove_type name
1725 RemoveStmt *n = makeNode(RemoveStmt);
1732 remove_type: TYPE_P { $$ = TYPE_P; }
1733 | INDEX { $$ = INDEX; }
1734 | RULE { $$ = RULE; }
1735 | VIEW { $$ = VIEW; }
1739 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1741 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1748 aggr_argtype: name { $$ = $1; }
1749 | '*' { $$ = NULL; }
1753 RemoveFuncStmt: DROP FUNCTION func_name func_args
1755 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1763 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1765 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1772 all_Op: Op | MathOp;
1774 MathOp: '+' { $$ = "+"; }
1785 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1788 { $$ = makeList(makeString($1), makeString($3), -1); }
1789 | NONE ',' name /* left unary */
1790 { $$ = makeList(NULL, makeString($3), -1); }
1791 | name ',' NONE /* right unary */
1792 { $$ = makeList(makeString($1), NULL, -1); }
1796 /*****************************************************************************
1799 * rename <attrname1> in <relname> [*] to <attrname2>
1800 * rename <relname1> to <relname2>
1802 *****************************************************************************/
1804 RenameStmt: ALTER TABLE relation_name opt_inh_star
1805 RENAME opt_column opt_name TO name
1807 RenameStmt *n = makeNode(RenameStmt);
1816 opt_name: name { $$ = $1; }
1817 | /*EMPTY*/ { $$ = NULL; }
1820 opt_column: COLUMN { $$ = COLUMN; }
1821 | /*EMPTY*/ { $$ = 0; }
1825 /*****************************************************************************
1827 * QUERY: Define Rewrite Rule , Define Tuple Rule
1828 * Define Rule <old rules >
1830 * only rewrite rule is supported -- ay 9/94
1832 *****************************************************************************/
1834 RuleStmt: CREATE RULE name AS
1835 { QueryIsRule=TRUE; }
1836 ON event TO event_object where_clause
1837 DO opt_instead OptStmtList
1839 RuleStmt *n = makeNode(RuleStmt);
1843 n->whereClause = $10;
1850 OptStmtList: NOTHING { $$ = NIL; }
1851 | OptimizableStmt { $$ = lcons($1, NIL); }
1852 | '[' OptStmtBlock ']' { $$ = $2; }
1855 OptStmtBlock: OptStmtMulti
1858 { $$ = lcons($1, NIL); }
1861 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1862 { $$ = lappend($1, $2); }
1863 | OptStmtMulti OptimizableStmt
1864 { $$ = lappend($1, $2); }
1865 | OptimizableStmt ';'
1866 { $$ = lcons($1, NIL); }
1869 event_object: relation_name '.' attr_name
1871 $$ = makeNode(Attr);
1874 $$->attrs = lcons(makeString($3), NIL);
1875 $$->indirection = NIL;
1879 $$ = makeNode(Attr);
1883 $$->indirection = NIL;
1887 /* change me to select, update, etc. some day */
1888 event: SELECT { $$ = CMD_SELECT; }
1889 | UPDATE { $$ = CMD_UPDATE; }
1890 | DELETE { $$ = CMD_DELETE; }
1891 | INSERT { $$ = CMD_INSERT; }
1894 opt_instead: INSTEAD { $$ = TRUE; }
1895 | /*EMPTY*/ { $$ = FALSE; }
1899 /*****************************************************************************
1902 * NOTIFY <relation_name> can appear both in rule bodies and
1903 * as a query-level command
1905 *****************************************************************************/
1907 NotifyStmt: NOTIFY relation_name
1909 NotifyStmt *n = makeNode(NotifyStmt);
1915 ListenStmt: LISTEN relation_name
1917 ListenStmt *n = makeNode(ListenStmt);
1924 /*****************************************************************************
1935 *****************************************************************************/
1937 TransactionStmt: ABORT_TRANS TRANSACTION
1939 TransactionStmt *n = makeNode(TransactionStmt);
1940 n->command = ABORT_TRANS;
1943 | BEGIN_TRANS TRANSACTION
1945 TransactionStmt *n = makeNode(TransactionStmt);
1946 n->command = BEGIN_TRANS;
1951 TransactionStmt *n = makeNode(TransactionStmt);
1952 n->command = BEGIN_TRANS;
1957 TransactionStmt *n = makeNode(TransactionStmt);
1958 n->command = END_TRANS;
1961 | END_TRANS TRANSACTION
1963 TransactionStmt *n = makeNode(TransactionStmt);
1964 n->command = END_TRANS;
1969 TransactionStmt *n = makeNode(TransactionStmt);
1970 n->command = ABORT_TRANS;
1976 TransactionStmt *n = makeNode(TransactionStmt);
1977 n->command = ABORT_TRANS;
1982 TransactionStmt *n = makeNode(TransactionStmt);
1983 n->command = BEGIN_TRANS;
1988 TransactionStmt *n = makeNode(TransactionStmt);
1989 n->command = END_TRANS;
1995 TransactionStmt *n = makeNode(TransactionStmt);
1996 n->command = END_TRANS;
2001 TransactionStmt *n = makeNode(TransactionStmt);
2002 n->command = ABORT_TRANS;
2008 /*****************************************************************************
2011 * define view <viewname> '('target-list ')' [where <quals> ]
2013 *****************************************************************************/
2015 ViewStmt: CREATE VIEW name AS SelectStmt
2017 ViewStmt *n = makeNode(ViewStmt);
2019 n->query = (Query *)$5;
2020 if (((SelectStmt *)n->query)->sortClause != NULL)
2021 elog(ERROR,"Order by and Distinct on views is not implemented.");
2022 if (((SelectStmt *)n->query)->unionClause != NULL)
2023 elog(ERROR,"Views on unions not implemented.");
2029 /*****************************************************************************
2034 *****************************************************************************/
2036 LoadStmt: LOAD file_name
2038 LoadStmt *n = makeNode(LoadStmt);
2045 /*****************************************************************************
2050 *****************************************************************************/
2052 CreatedbStmt: CREATE DATABASE database_name opt_database
2054 CreatedbStmt *n = makeNode(CreatedbStmt);
2061 opt_database: WITH LOCATION '=' location { $$ = $4; }
2062 | /*EMPTY*/ { $$ = NULL; }
2065 location: Sconst { $$ = $1; }
2066 | DEFAULT { $$ = NULL; }
2067 | /*EMPTY*/ { $$ = NULL; }
2070 /*****************************************************************************
2075 *****************************************************************************/
2077 DestroydbStmt: DROP DATABASE database_name
2079 DestroydbStmt *n = makeNode(DestroydbStmt);
2086 /*****************************************************************************
2089 * cluster <index_name> on <relation_name>
2091 *****************************************************************************/
2093 ClusterStmt: CLUSTER index_name ON relation_name
2095 ClusterStmt *n = makeNode(ClusterStmt);
2103 /*****************************************************************************
2108 *****************************************************************************/
2110 VacuumStmt: VACUUM opt_verbose opt_analyze
2112 VacuumStmt *n = makeNode(VacuumStmt);
2119 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2121 VacuumStmt *n = makeNode(VacuumStmt);
2126 if ( $5 != NIL && !$4 )
2127 elog(ERROR,"parser: syntax error at or near \"(\"");
2132 opt_verbose: VERBOSE { $$ = TRUE; }
2133 | /*EMPTY*/ { $$ = FALSE; }
2136 opt_analyze: ANALYZE { $$ = TRUE; }
2137 | /*EMPTY*/ { $$ = FALSE; }
2140 opt_va_list: '(' va_list ')' { $$ = $2; }
2141 | /*EMPTY*/ { $$ = NIL; }
2145 { $$=lcons($1,NIL); }
2147 { $$=lappend($1,$3); }
2151 /*****************************************************************************
2156 *****************************************************************************/
2158 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2160 ExplainStmt *n = makeNode(ExplainStmt);
2162 n->query = (Query*)$3;
2168 /*****************************************************************************
2170 * Optimizable Stmts: *
2172 * one of the five queries processed by the planner *
2174 * [ultimately] produces query-trees as specified *
2175 * in the query-spec document in ~postgres/ref *
2177 *****************************************************************************/
2179 OptimizableStmt: SelectStmt
2184 | DeleteStmt /* by default all are $$=$1 */
2188 /*****************************************************************************
2193 *****************************************************************************/
2195 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2203 insert_rest: VALUES '(' res_target_list2 ')'
2205 $$ = makeNode(InsertStmt);
2207 $$->targetList = $3;
2208 $$->fromClause = NIL;
2209 $$->whereClause = NULL;
2210 $$->groupClause = NIL;
2211 $$->havingClause = NULL;
2212 $$->unionClause = NIL;
2214 | SELECT opt_unique res_target_list2
2215 from_clause where_clause
2216 group_clause having_clause
2219 $$ = makeNode(InsertStmt);
2221 $$->targetList = $3;
2222 $$->fromClause = $4;
2223 $$->whereClause = $5;
2224 $$->groupClause = $6;
2225 $$->havingClause = $7;
2226 $$->unionClause = $8;
2230 opt_column_list: '(' columnList ')' { $$ = $2; }
2231 | /*EMPTY*/ { $$ = NIL; }
2235 columnList ',' columnElem
2236 { $$ = lappend($1, $3); }
2238 { $$ = lcons($1, NIL); }
2241 columnElem: ColId opt_indirection
2243 Ident *id = makeNode(Ident);
2245 id->indirection = $2;
2251 /*****************************************************************************
2256 *****************************************************************************/
2258 DeleteStmt: DELETE FROM relation_name
2261 DeleteStmt *n = makeNode(DeleteStmt);
2263 n->whereClause = $4;
2269 * Total hack to just lock a table inside a transaction.
2270 * Is it worth making this a separate command, with
2271 * its own node type and file. I don't think so. bjm 1998/1/22
2273 LockStmt: LOCK_P opt_table relation_name
2275 DeleteStmt *n = makeNode(DeleteStmt);
2276 A_Const *c = makeNode(A_Const);
2278 c->val.type = T_String;
2279 c->val.val.str = "f";
2280 c->typename = makeNode(TypeName);
2281 c->typename->name = xlateSqlType("bool");
2282 c->typename->typmod = -1;
2285 n->whereClause = (Node *)c;
2291 /*****************************************************************************
2294 * UpdateStmt (UPDATE)
2296 *****************************************************************************/
2298 UpdateStmt: UPDATE relation_name
2303 UpdateStmt *n = makeNode(UpdateStmt);
2307 n->whereClause = $6;
2313 /*****************************************************************************
2318 *****************************************************************************/
2319 CursorStmt: DECLARE name opt_binary CURSOR FOR
2320 SELECT opt_unique res_target_list2
2321 from_clause where_clause
2322 group_clause having_clause
2323 union_clause sort_clause
2325 SelectStmt *n = makeNode(SelectStmt);
2327 /* from PORTAL name */
2329 * 15 august 1991 -- since 3.0 postgres does locking
2330 * right, we discovered that portals were violating
2331 * locking protocol. portal locks cannot span xacts.
2332 * as a short-term fix, we installed the check here.
2335 if (!IsTransactionBlock())
2336 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2343 n->whereClause = $10;
2344 n->groupClause = $11;
2345 n->havingClause = $12;
2346 n->unionClause = $13;
2347 n->sortClause = $14;
2353 /*****************************************************************************
2358 *****************************************************************************/
2360 SelectStmt: SELECT opt_unique res_target_list2
2361 result from_clause where_clause
2362 group_clause having_clause
2363 union_clause sort_clause
2365 SelectStmt *n = makeNode(SelectStmt);
2370 n->whereClause = $6;
2371 n->groupClause = $7;
2372 n->havingClause = $8;
2373 n->unionClause = $9;
2374 n->sortClause = $10;
2379 union_clause: UNION opt_union select_list
2381 SelectStmt *n = (SelectStmt *)lfirst($3);
2389 select_list: select_list UNION opt_union SubSelect
2391 SelectStmt *n = (SelectStmt *)$4;
2393 $$ = lappend($1, $4);
2396 { $$ = lcons($1, NIL); }
2399 SubSelect: SELECT opt_unique res_target_list2
2400 from_clause where_clause
2401 group_clause having_clause
2403 SelectStmt *n = makeNode(SelectStmt);
2405 n->unionall = FALSE;
2408 n->whereClause = $5;
2409 n->groupClause = $6;
2410 n->havingClause = $7;
2415 result: INTO opt_table relation_name { $$= $3; }
2416 | /*EMPTY*/ { $$ = NULL; }
2419 opt_table: TABLE { $$ = TRUE; }
2420 | /*EMPTY*/ { $$ = FALSE; }
2423 opt_union: ALL { $$ = TRUE; }
2424 | /*EMPTY*/ { $$ = FALSE; }
2427 opt_unique: DISTINCT { $$ = "*"; }
2428 | DISTINCT ON ColId { $$ = $3; }
2429 | ALL { $$ = NULL; }
2430 | /*EMPTY*/ { $$ = NULL; }
2433 sort_clause: ORDER BY sortby_list { $$ = $3; }
2434 | /*EMPTY*/ { $$ = NIL; }
2437 sortby_list: sortby { $$ = lcons($1, NIL); }
2438 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2441 sortby: ColId OptUseOp
2443 $$ = makeNode(SortGroupBy);
2449 | ColId '.' ColId OptUseOp
2451 $$ = makeNode(SortGroupBy);
2459 $$ = makeNode(SortGroupBy);
2467 OptUseOp: USING Op { $$ = $2; }
2468 | USING '<' { $$ = "<"; }
2469 | USING '>' { $$ = ">"; }
2471 | DESC { $$ = ">"; }
2472 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2476 * jimmy bell-style recursive queries aren't supported in the
2479 * ...however, recursive addattr and rename supported. make special
2482 opt_inh_star: '*' { $$ = TRUE; }
2483 | /*EMPTY*/ { $$ = FALSE; }
2486 relation_name_list: name_list;
2489 { $$ = lcons(makeString($1),NIL); }
2490 | name_list ',' name
2491 { $$ = lappend($1,makeString($3)); }
2494 group_clause: GROUP BY groupby_list { $$ = $3; }
2495 | /*EMPTY*/ { $$ = NIL; }
2498 groupby_list: groupby { $$ = lcons($1, NIL); }
2499 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2504 $$ = makeNode(SortGroupBy);
2512 $$ = makeNode(SortGroupBy);
2520 $$ = makeNode(SortGroupBy);
2528 having_clause: HAVING a_expr
2530 /***S*H***/ /* elog(NOTICE, "HAVING not yet supported; ignore clause");*/
2533 | /*EMPTY*/ { $$ = NULL; }
2537 /*****************************************************************************
2539 * clauses common to all Optimizable Stmts:
2543 *****************************************************************************/
2545 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2548 elog(ERROR,"JOIN not yet implemented");
2550 | FROM from_list { $$ = $2; }
2551 | /*EMPTY*/ { $$ = NIL; }
2554 from_list: from_list ',' from_val
2555 { $$ = lappend($1, $3); }
2556 | from_val CROSS JOIN from_val
2557 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2559 { $$ = lcons($1, NIL); }
2562 from_val: relation_expr AS ColLabel
2564 $$ = makeNode(RangeVar);
2568 | relation_expr ColId
2570 $$ = makeNode(RangeVar);
2576 $$ = makeNode(RangeVar);
2582 join_expr: NATURAL join_expr { $$ = NULL; }
2584 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2586 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2588 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2590 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2592 { elog(ERROR,"INNER JOIN not yet implemented"); }
2594 { elog(ERROR,"UNION JOIN not yet implemented"); }
2596 { elog(ERROR,"INNER JOIN not yet implemented"); }
2599 join_outer: OUTER_P { $$ = NULL; }
2600 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2603 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2604 | USING '(' join_list ')' { $$ = NULL; }
2605 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2608 join_list: join_using { $$ = lcons($1, NIL); }
2609 | join_list ',' join_using { $$ = lappend($1, $3); }
2614 $$ = makeNode(SortGroupBy);
2622 $$ = makeNode(SortGroupBy);
2630 $$ = makeNode(SortGroupBy);
2638 where_clause: WHERE a_expr { $$ = $2; }
2639 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2642 relation_expr: relation_name
2644 /* normal relations */
2645 $$ = makeNode(RelExpr);
2649 | relation_name '*' %prec '='
2651 /* inheritance query */
2652 $$ = makeNode(RelExpr);
2657 opt_array_bounds: '[' ']' nest_array_bounds
2658 { $$ = lcons(makeInteger(-1), $3); }
2659 | '[' Iconst ']' nest_array_bounds
2660 { $$ = lcons(makeInteger($2), $4); }
2665 nest_array_bounds: '[' ']' nest_array_bounds
2666 { $$ = lcons(makeInteger(-1), $3); }
2667 | '[' Iconst ']' nest_array_bounds
2668 { $$ = lcons(makeInteger($2), $4); }
2674 /*****************************************************************************
2677 * SQL92 introduces a large amount of type-specific syntax.
2678 * Define individual clauses to handle these cases, and use
2679 * the generic case to handle regular type-extensible Postgres syntax.
2680 * - thomas 1997-10-10
2682 *****************************************************************************/
2684 Typename: Array opt_array_bounds
2687 $$->arrayBounds = $2;
2689 /* Is this the name of a complex type? If so, implement
2692 if (!strcmp(saved_relname, $$->name))
2693 /* This attr is the same type as the relation
2694 * being defined. The classic example: create
2695 * emp(name=text,mgr=emp)
2698 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2699 /* (Eventually add in here that the set can only
2700 * contain one element.)
2721 $$ = makeNode(TypeName);
2722 $$->name = xlateSqlType($1);
2727 generic: IDENT { $$ = $1; }
2728 | TYPE_P { $$ = xlateSqlType("type"); }
2731 /* SQL92 numeric data types
2732 * Check FLOAT() precision limits assuming IEEE floating types.
2733 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2734 * by checking parameters and making sure they match what is possible with INTEGER.
2735 * - thomas 1997-09-18
2737 Numeric: FLOAT opt_float
2739 $$ = makeNode(TypeName);
2740 $$->name = xlateSqlType($2);
2745 $$ = makeNode(TypeName);
2746 $$->name = xlateSqlType("float");
2748 | DECIMAL opt_decimal
2750 $$ = makeNode(TypeName);
2751 $$->name = xlateSqlType("integer");
2754 | NUMERIC opt_numeric
2756 $$ = makeNode(TypeName);
2757 $$->name = xlateSqlType("integer");
2763 { $$ = xlateSqlType("float8"); }
2765 { $$ = xlateSqlType("float8"); }
2767 { $$ = xlateSqlType("decimal"); }
2769 { $$ = xlateSqlType("numeric"); }
2772 opt_float: '(' Iconst ')'
2775 elog(ERROR,"precision for FLOAT must be at least 1");
2777 $$ = xlateSqlType("float4");
2779 $$ = xlateSqlType("float8");
2781 elog(ERROR,"precision for FLOAT must be less than 16");
2785 $$ = xlateSqlType("float8");
2789 opt_numeric: '(' Iconst ',' Iconst ')'
2792 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2794 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2799 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2807 opt_decimal: '(' Iconst ',' Iconst ')'
2810 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2812 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2818 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2827 /* SQL92 character data types
2828 * The following implements CHAR() and VARCHAR().
2829 * We do it here instead of the 'Generic' production
2830 * because we don't want to allow arrays of VARCHAR().
2831 * I haven't thought about whether that will work or not.
2834 Character: character '(' Iconst ')'
2836 $$ = makeNode(TypeName);
2837 if (!strcasecmp($1, "char"))
2838 $$->name = xlateSqlType("bpchar");
2839 else if (!strcasecmp($1, "varchar"))
2840 $$->name = xlateSqlType("varchar");
2842 yyerror("parse error");
2844 elog(ERROR,"length for '%s' type must be at least 1",$1);
2846 /* we can store a char() of length up to the size
2847 * of a page (8KB) - page headers and friends but
2848 * just to be safe here... - ay 6/95
2849 * XXX note this hardcoded limit - thomas 1997-07-13
2851 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2853 /* we actually implement this sort of like a varlen, so
2854 * the first 4 bytes is the length. (the difference
2855 * between this and "text" is that we blank-pad and
2856 * truncate where necessary
2858 $$->typmod = VARHDRSZ + $3;
2862 $$ = makeNode(TypeName);
2863 $$->name = xlateSqlType($1);
2868 character: CHARACTER opt_varying opt_charset opt_collate
2871 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2872 if ($2) type = xlateSqlType("varchar");
2873 else type = xlateSqlType("char");
2876 c = palloc(strlen("var") + strlen($3) + 1);
2879 type = xlateSqlType(c);
2881 type = xlateSqlType($3);
2885 elog(ERROR,"COLLATE %s not yet implemented",$4);
2888 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2889 | VARCHAR { $$ = xlateSqlType("varchar"); }
2890 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2891 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2894 opt_varying: VARYING { $$ = TRUE; }
2895 | /*EMPTY*/ { $$ = FALSE; }
2898 opt_charset: CHARACTER SET ColId { $$ = $3; }
2899 | /*EMPTY*/ { $$ = NULL; }
2902 opt_collate: COLLATE ColId { $$ = $2; }
2903 | /*EMPTY*/ { $$ = NULL; }
2908 $$ = makeNode(TypeName);
2909 $$->name = xlateSqlType($1);
2912 | TIMESTAMP opt_timezone
2914 $$ = makeNode(TypeName);
2915 $$->name = xlateSqlType("timestamp");
2921 $$ = makeNode(TypeName);
2922 $$->name = xlateSqlType("time");
2925 | INTERVAL opt_interval
2927 $$ = makeNode(TypeName);
2928 $$->name = xlateSqlType("interval");
2933 datetime: YEAR_P { $$ = "year"; }
2934 | MONTH_P { $$ = "month"; }
2935 | DAY_P { $$ = "day"; }
2936 | HOUR_P { $$ = "hour"; }
2937 | MINUTE_P { $$ = "minute"; }
2938 | SECOND_P { $$ = "second"; }
2941 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2942 | /*EMPTY*/ { $$ = FALSE; }
2945 opt_interval: datetime { $$ = lcons($1, NIL); }
2946 | YEAR_P TO MONTH_P { $$ = NIL; }
2947 | DAY_P TO HOUR_P { $$ = NIL; }
2948 | DAY_P TO MINUTE_P { $$ = NIL; }
2949 | DAY_P TO SECOND_P { $$ = NIL; }
2950 | HOUR_P TO MINUTE_P { $$ = NIL; }
2951 | HOUR_P TO SECOND_P { $$ = NIL; }
2952 | /*EMPTY*/ { $$ = NIL; }
2956 /*****************************************************************************
2958 * expression grammar, still needs some cleanup
2960 *****************************************************************************/
2962 a_expr_or_null: a_expr
2966 A_Const *n = makeNode(A_Const);
2967 n->val.type = T_Null;
2972 /* Expressions using row descriptors
2973 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2974 * with singleton expressions.
2976 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2978 SubLink *n = makeNode(SubLink);
2980 n->oper = lcons("=",NIL);
2982 n->subLinkType = ANY_SUBLINK;
2986 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
2988 SubLink *n = makeNode(SubLink);
2990 n->oper = lcons("<>",NIL);
2992 n->subLinkType = ALL_SUBLINK;
2996 | '(' row_descriptor ')' Op '(' SubSelect ')'
2998 SubLink *n = makeNode(SubLink);
3000 n->oper = lcons($4, NIL);
3001 if (strcmp($4,"<>") == 0)
3005 n->subLinkType = EXPR_SUBLINK;
3009 | '(' row_descriptor ')' '+' '(' SubSelect ')'
3011 SubLink *n = makeNode(SubLink);
3013 n->oper = lcons("+", NIL);
3015 n->subLinkType = EXPR_SUBLINK;
3019 | '(' row_descriptor ')' '-' '(' SubSelect ')'
3021 SubLink *n = makeNode(SubLink);
3023 n->oper = lcons("-", NIL);
3025 n->subLinkType = EXPR_SUBLINK;
3029 | '(' row_descriptor ')' '/' '(' SubSelect ')'
3031 SubLink *n = makeNode(SubLink);
3033 n->oper = lcons("/", NIL);
3035 n->subLinkType = EXPR_SUBLINK;
3039 | '(' row_descriptor ')' '*' '(' SubSelect ')'
3041 SubLink *n = makeNode(SubLink);
3043 n->oper = lcons("*", NIL);
3045 n->subLinkType = EXPR_SUBLINK;
3049 | '(' row_descriptor ')' '<' '(' SubSelect ')'
3051 SubLink *n = makeNode(SubLink);
3053 n->oper = lcons("<", NIL);
3055 n->subLinkType = EXPR_SUBLINK;
3059 | '(' row_descriptor ')' '>' '(' SubSelect ')'
3061 SubLink *n = makeNode(SubLink);
3063 n->oper = lcons(">", NIL);
3065 n->subLinkType = EXPR_SUBLINK;
3069 | '(' row_descriptor ')' '=' '(' SubSelect ')'
3071 SubLink *n = makeNode(SubLink);
3073 n->oper = lcons("=", NIL);
3075 n->subLinkType = EXPR_SUBLINK;
3079 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
3081 SubLink *n = makeNode(SubLink);
3083 n->oper = lcons($4,NIL);
3084 if (strcmp($4,"<>") == 0)
3088 n->subLinkType = ANY_SUBLINK;
3092 | '(' row_descriptor ')' '+' ANY '(' SubSelect ')'
3094 SubLink *n = makeNode(SubLink);
3096 n->oper = lcons("+",NIL);
3098 n->subLinkType = ANY_SUBLINK;
3102 | '(' row_descriptor ')' '-' ANY '(' SubSelect ')'
3104 SubLink *n = makeNode(SubLink);
3106 n->oper = lcons("-",NIL);
3108 n->subLinkType = ANY_SUBLINK;
3112 | '(' row_descriptor ')' '/' ANY '(' SubSelect ')'
3114 SubLink *n = makeNode(SubLink);
3116 n->oper = lcons("/",NIL);
3118 n->subLinkType = ANY_SUBLINK;
3122 | '(' row_descriptor ')' '*' ANY '(' SubSelect ')'
3124 SubLink *n = makeNode(SubLink);
3126 n->oper = lcons("*",NIL);
3128 n->subLinkType = ANY_SUBLINK;
3132 | '(' row_descriptor ')' '<' ANY '(' SubSelect ')'
3134 SubLink *n = makeNode(SubLink);
3136 n->oper = lcons("<",NIL);
3138 n->subLinkType = ANY_SUBLINK;
3142 | '(' row_descriptor ')' '>' ANY '(' SubSelect ')'
3144 SubLink *n = makeNode(SubLink);
3146 n->oper = lcons(">",NIL);
3148 n->subLinkType = ANY_SUBLINK;
3152 | '(' row_descriptor ')' '=' ANY '(' SubSelect ')'
3154 SubLink *n = makeNode(SubLink);
3156 n->oper = lcons("=",NIL);
3158 n->subLinkType = ANY_SUBLINK;
3162 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
3164 SubLink *n = makeNode(SubLink);
3166 n->oper = lcons($4,NIL);
3167 if (strcmp($4,"<>") == 0)
3171 n->subLinkType = ALL_SUBLINK;
3175 | '(' row_descriptor ')' '+' ALL '(' SubSelect ')'
3177 SubLink *n = makeNode(SubLink);
3179 n->oper = lcons("+",NIL);
3181 n->subLinkType = ALL_SUBLINK;
3185 | '(' row_descriptor ')' '-' ALL '(' SubSelect ')'
3187 SubLink *n = makeNode(SubLink);
3189 n->oper = lcons("-",NIL);
3191 n->subLinkType = ALL_SUBLINK;
3195 | '(' row_descriptor ')' '/' ALL '(' SubSelect ')'
3197 SubLink *n = makeNode(SubLink);
3199 n->oper = lcons("/",NIL);
3201 n->subLinkType = ALL_SUBLINK;
3205 | '(' row_descriptor ')' '*' ALL '(' SubSelect ')'
3207 SubLink *n = makeNode(SubLink);
3209 n->oper = lcons("*",NIL);
3211 n->subLinkType = ALL_SUBLINK;
3215 | '(' row_descriptor ')' '<' ALL '(' SubSelect ')'
3217 SubLink *n = makeNode(SubLink);
3219 n->oper = lcons("<",NIL);
3221 n->subLinkType = ALL_SUBLINK;
3225 | '(' row_descriptor ')' '>' ALL '(' SubSelect ')'
3227 SubLink *n = makeNode(SubLink);
3229 n->oper = lcons(">",NIL);
3231 n->subLinkType = ALL_SUBLINK;
3235 | '(' row_descriptor ')' '=' ALL '(' SubSelect ')'
3237 SubLink *n = makeNode(SubLink);
3239 n->oper = lcons("=",NIL);
3241 n->subLinkType = ALL_SUBLINK;
3245 | '(' row_descriptor ')' Op '(' row_descriptor ')'
3247 $$ = makeRowExpr($4, $2, $6);
3249 | '(' row_descriptor ')' '+' '(' row_descriptor ')'
3251 $$ = makeRowExpr("+", $2, $6);
3253 | '(' row_descriptor ')' '-' '(' row_descriptor ')'
3255 $$ = makeRowExpr("-", $2, $6);
3257 | '(' row_descriptor ')' '/' '(' row_descriptor ')'
3259 $$ = makeRowExpr("/", $2, $6);
3261 | '(' row_descriptor ')' '*' '(' row_descriptor ')'
3263 $$ = makeRowExpr("*", $2, $6);
3265 | '(' row_descriptor ')' '<' '(' row_descriptor ')'
3267 $$ = makeRowExpr("<", $2, $6);
3269 | '(' row_descriptor ')' '>' '(' row_descriptor ')'
3271 $$ = makeRowExpr(">", $2, $6);
3273 | '(' row_descriptor ')' '=' '(' row_descriptor ')'
3275 $$ = makeRowExpr("=", $2, $6);
3279 row_descriptor: row_list ',' a_expr
3281 $$ = lappend($1, $3);
3285 row_list: row_list ',' a_expr
3287 $$ = lappend($1, $3);
3291 $$ = lcons($1, NIL);
3296 * This is the heart of the expression syntax.
3297 * Note that the BETWEEN clause looks similar to a boolean expression
3298 * and so we must define b_expr which is almost the same as a_expr
3299 * but without the boolean expressions.
3300 * All operations are allowed in a BETWEEN clause if surrounded by parens.
3303 a_expr: attr opt_indirection
3305 $1->indirection = $2;
3314 /* could be a column name or a relation_name */
3315 Ident *n = makeNode(Ident);
3317 n->indirection = NULL;
3320 | '-' a_expr %prec UMINUS
3321 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3323 { $$ = makeA_Expr(OP, "+", $1, $3); }
3325 { $$ = makeA_Expr(OP, "-", $1, $3); }
3327 { $$ = makeA_Expr(OP, "/", $1, $3); }
3329 { $$ = makeA_Expr(OP, "*", $1, $3); }
3331 { $$ = makeA_Expr(OP, "<", $1, $3); }
3333 { $$ = makeA_Expr(OP, ">", $1, $3); }
3335 { $$ = makeA_Expr(OP, "=", $1, $3); }
3337 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3339 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3341 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3342 | a_expr TYPECAST Typename
3345 /* AexprConst can be either A_Const or ParamNo */
3346 if (nodeTag($1) == T_A_Const) {
3347 ((A_Const *)$1)->typename = $3;
3348 } else if (nodeTag($1) == T_Param) {
3349 ((ParamNo *)$1)->typename = $3;
3350 /* otherwise, try to transform to a function call */
3352 FuncCall *n = makeNode(FuncCall);
3353 n->funcname = $3->name;
3354 n->args = lcons($1,NIL);
3358 | CAST '(' a_expr AS Typename ')'
3361 /* AexprConst can be either A_Const or ParamNo */
3362 if (nodeTag($3) == T_A_Const) {
3363 ((A_Const *)$3)->typename = $5;
3364 } else if (nodeTag($5) == T_Param) {
3365 ((ParamNo *)$3)->typename = $5;
3366 /* otherwise, try to transform to a function call */
3368 FuncCall *n = makeNode(FuncCall);
3369 n->funcname = $5->name;
3370 n->args = lcons($3,NIL);
3374 | '(' a_expr_or_null ')'
3377 { $$ = makeIndexable($2,$1,$3); }
3378 | a_expr LIKE a_expr
3379 { $$ = makeIndexable("~~", $1, $3); }
3380 | a_expr NOT LIKE a_expr
3381 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3383 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3385 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3386 | func_name '(' '*' ')'
3388 /* cheap hack for aggregate (eg. count) */
3389 FuncCall *n = makeNode(FuncCall);
3390 A_Const *star = makeNode(A_Const);
3392 star->val.type = T_String;
3393 star->val.val.str = "";
3395 n->args = lcons(star, NIL);
3400 FuncCall *n = makeNode(FuncCall);
3405 | func_name '(' expr_list ')'
3407 FuncCall *n = makeNode(FuncCall);
3414 A_Const *n = makeNode(A_Const);
3415 TypeName *t = makeNode(TypeName);
3417 n->val.type = T_String;
3418 n->val.val.str = "now";
3421 t->name = xlateSqlType("date");
3429 A_Const *n = makeNode(A_Const);
3430 TypeName *t = makeNode(TypeName);
3432 n->val.type = T_String;
3433 n->val.val.str = "now";
3436 t->name = xlateSqlType("time");
3442 | CURRENT_TIME '(' Iconst ')'
3444 FuncCall *n = makeNode(FuncCall);
3445 A_Const *s = makeNode(A_Const);
3446 TypeName *t = makeNode(TypeName);
3448 n->funcname = xlateSqlType("time");
3449 n->args = lcons(s, NIL);
3451 s->val.type = T_String;
3452 s->val.val.str = "now";
3455 t->name = xlateSqlType("time");
3460 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3466 A_Const *n = makeNode(A_Const);
3467 TypeName *t = makeNode(TypeName);
3469 n->val.type = T_String;
3470 n->val.val.str = "now";
3473 t->name = xlateSqlType("timestamp");
3479 | CURRENT_TIMESTAMP '(' Iconst ')'
3481 FuncCall *n = makeNode(FuncCall);
3482 A_Const *s = makeNode(A_Const);
3483 TypeName *t = makeNode(TypeName);
3485 n->funcname = xlateSqlType("timestamp");
3486 n->args = lcons(s, NIL);
3488 s->val.type = T_String;
3489 s->val.val.str = "now";
3492 t->name = xlateSqlType("timestamp");
3497 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3503 FuncCall *n = makeNode(FuncCall);
3504 n->funcname = "getpgusername";
3508 | EXISTS '(' SubSelect ')'
3510 SubLink *n = makeNode(SubLink);
3514 n->subLinkType = EXISTS_SUBLINK;
3518 | EXTRACT '(' extract_list ')'
3520 FuncCall *n = makeNode(FuncCall);
3521 n->funcname = "date_part";
3525 | POSITION '(' position_list ')'
3527 FuncCall *n = makeNode(FuncCall);
3528 n->funcname = "strpos";
3532 | SUBSTRING '(' substr_list ')'
3534 FuncCall *n = makeNode(FuncCall);
3535 n->funcname = "substr";
3539 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3540 | TRIM '(' BOTH trim_list ')'
3542 FuncCall *n = makeNode(FuncCall);
3543 n->funcname = "btrim";
3547 | TRIM '(' LEADING trim_list ')'
3549 FuncCall *n = makeNode(FuncCall);
3550 n->funcname = "ltrim";
3554 | TRIM '(' TRAILING trim_list ')'
3556 FuncCall *n = makeNode(FuncCall);
3557 n->funcname = "rtrim";
3561 | TRIM '(' trim_list ')'
3563 FuncCall *n = makeNode(FuncCall);
3564 n->funcname = "btrim";
3569 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3571 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3573 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3574 | a_expr IS NOT NULL_P
3575 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3576 /* IS TRUE, IS FALSE, etc used to be function calls
3577 * but let's make them expressions to allow the optimizer
3578 * a chance to eliminate them if a_expr is a constant string.
3579 * - thomas 1997-12-22
3583 A_Const *n = makeNode(A_Const);
3584 n->val.type = T_String;
3585 n->val.val.str = "t";
3586 n->typename = makeNode(TypeName);
3587 n->typename->name = xlateSqlType("bool");
3588 n->typename->typmod = -1;
3589 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3591 | a_expr IS NOT FALSE_P
3593 A_Const *n = makeNode(A_Const);
3594 n->val.type = T_String;
3595 n->val.val.str = "t";
3596 n->typename = makeNode(TypeName);
3597 n->typename->name = xlateSqlType("bool");
3598 n->typename->typmod = -1;
3599 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3603 A_Const *n = makeNode(A_Const);
3604 n->val.type = T_String;
3605 n->val.val.str = "f";
3606 n->typename = makeNode(TypeName);
3607 n->typename->name = xlateSqlType("bool");
3608 n->typename->typmod = -1;
3609 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3611 | a_expr IS NOT TRUE_P
3613 A_Const *n = makeNode(A_Const);
3614 n->val.type = T_String;
3615 n->val.val.str = "f";
3616 n->typename = makeNode(TypeName);
3617 n->typename->name = xlateSqlType("bool");
3618 n->typename->typmod = -1;
3619 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3621 | a_expr BETWEEN b_expr AND b_expr
3623 $$ = makeA_Expr(AND, NULL,
3624 makeA_Expr(OP, ">=", $1, $3),
3625 makeA_Expr(OP, "<=", $1, $5));
3627 | a_expr NOT BETWEEN b_expr AND b_expr
3629 $$ = makeA_Expr(OR, NULL,
3630 makeA_Expr(OP, "<", $1, $4),
3631 makeA_Expr(OP, ">", $1, $6));
3633 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3635 saved_In_Expr = lnext(saved_In_Expr);
3636 if (nodeTag($5) == T_SubLink)
3638 SubLink *n = (SubLink *)$5;
3639 n->lefthand = lcons($1, NIL);
3640 n->oper = lcons("=",NIL);
3642 n->subLinkType = ANY_SUBLINK;
3647 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
3649 saved_In_Expr = lnext(saved_In_Expr);
3650 if (nodeTag($6) == T_SubLink)
3652 SubLink *n = (SubLink *)$6;
3653 n->lefthand = lcons($1, NIL);
3654 n->oper = lcons("<>",NIL);
3656 n->subLinkType = ALL_SUBLINK;
3661 | a_expr Op '(' SubSelect ')'
3663 SubLink *n = makeNode(SubLink);
3664 n->lefthand = lcons($1, NULL);
3665 n->oper = lcons($2,NIL);
3667 n->subLinkType = EXPR_SUBLINK;
3671 | a_expr '+' '(' SubSelect ')'
3673 SubLink *n = makeNode(SubLink);
3674 n->lefthand = lcons($1, NULL);
3675 n->oper = lcons("+",NIL);
3677 n->subLinkType = EXPR_SUBLINK;
3681 | a_expr '-' '(' SubSelect ')'
3683 SubLink *n = makeNode(SubLink);
3684 n->lefthand = lcons($1, NULL);
3685 n->oper = lcons("-",NIL);
3687 n->subLinkType = EXPR_SUBLINK;
3691 | a_expr '/' '(' SubSelect ')'
3693 SubLink *n = makeNode(SubLink);
3694 n->lefthand = lcons($1, NULL);
3695 n->oper = lcons("/",NIL);
3697 n->subLinkType = EXPR_SUBLINK;
3701 | a_expr '*' '(' SubSelect ')'
3703 SubLink *n = makeNode(SubLink);
3704 n->lefthand = lcons($1, NULL);
3705 n->oper = lcons("*",NIL);
3707 n->subLinkType = EXPR_SUBLINK;
3711 | a_expr '<' '(' SubSelect ')'
3713 SubLink *n = makeNode(SubLink);
3714 n->lefthand = lcons($1, NULL);
3715 n->oper = lcons("<",NIL);
3717 n->subLinkType = EXPR_SUBLINK;
3721 | a_expr '>' '(' SubSelect ')'
3723 SubLink *n = makeNode(SubLink);
3724 n->lefthand = lcons($1, NULL);
3725 n->oper = lcons(">",NIL);
3727 n->subLinkType = EXPR_SUBLINK;
3731 | a_expr '=' '(' SubSelect ')'
3733 SubLink *n = makeNode(SubLink);
3734 n->lefthand = lcons($1, NULL);
3735 n->oper = lcons("=",NIL);
3737 n->subLinkType = EXPR_SUBLINK;
3741 | a_expr Op ANY '(' SubSelect ')'
3743 SubLink *n = makeNode(SubLink);
3744 n->lefthand = lcons($1,NIL);
3745 n->oper = lcons($2,NIL);
3747 n->subLinkType = ANY_SUBLINK;
3751 | a_expr '+' ANY '(' SubSelect ')'
3753 SubLink *n = makeNode(SubLink);
3754 n->lefthand = lcons($1,NIL);
3755 n->oper = lcons("+",NIL);
3757 n->subLinkType = ANY_SUBLINK;
3761 | a_expr '-' ANY '(' SubSelect ')'
3763 SubLink *n = makeNode(SubLink);
3764 n->lefthand = lcons($1,NIL);
3765 n->oper = lcons("-",NIL);
3767 n->subLinkType = ANY_SUBLINK;
3771 | a_expr '/' ANY '(' SubSelect ')'
3773 SubLink *n = makeNode(SubLink);
3774 n->lefthand = lcons($1,NIL);
3775 n->oper = lcons("/",NIL);
3777 n->subLinkType = ANY_SUBLINK;
3781 | a_expr '*' ANY '(' SubSelect ')'
3783 SubLink *n = makeNode(SubLink);
3784 n->lefthand = lcons($1,NIL);
3785 n->oper = lcons("*",NIL);
3787 n->subLinkType = ANY_SUBLINK;
3791 | a_expr '<' ANY '(' SubSelect ')'
3793 SubLink *n = makeNode(SubLink);
3794 n->lefthand = lcons($1,NIL);
3795 n->oper = lcons("<",NIL);
3797 n->subLinkType = ANY_SUBLINK;
3801 | a_expr '>' ANY '(' SubSelect ')'
3803 SubLink *n = makeNode(SubLink);
3804 n->lefthand = lcons($1,NIL);
3805 n->oper = lcons(">",NIL);
3807 n->subLinkType = ANY_SUBLINK;
3811 | a_expr '=' ANY '(' SubSelect ')'
3813 SubLink *n = makeNode(SubLink);
3814 n->lefthand = lcons($1,NIL);
3815 n->oper = lcons("=",NIL);
3817 n->subLinkType = ANY_SUBLINK;
3821 | a_expr Op ALL '(' SubSelect ')'
3823 SubLink *n = makeNode(SubLink);
3824 n->lefthand = lcons($1, NULL);
3825 n->oper = lcons($2,NIL);
3827 n->subLinkType = ALL_SUBLINK;
3831 | a_expr '+' ALL '(' SubSelect ')'
3833 SubLink *n = makeNode(SubLink);
3834 n->lefthand = lcons($1, NULL);
3835 n->oper = lcons("+",NIL);
3837 n->subLinkType = ALL_SUBLINK;
3841 | a_expr '-' ALL '(' SubSelect ')'
3843 SubLink *n = makeNode(SubLink);
3844 n->lefthand = lcons($1, NULL);
3845 n->oper = lcons("-",NIL);
3847 n->subLinkType = ALL_SUBLINK;
3851 | a_expr '/' ALL '(' SubSelect ')'
3853 SubLink *n = makeNode(SubLink);
3854 n->lefthand = lcons($1, NULL);
3855 n->oper = lcons("/",NIL);
3857 n->subLinkType = ALL_SUBLINK;
3861 | a_expr '*' ALL '(' SubSelect ')'
3863 SubLink *n = makeNode(SubLink);
3864 n->lefthand = lcons($1, NULL);
3865 n->oper = lcons("*",NIL);
3867 n->subLinkType = ALL_SUBLINK;
3871 | a_expr '<' ALL '(' SubSelect ')'
3873 SubLink *n = makeNode(SubLink);
3874 n->lefthand = lcons($1, NULL);
3875 n->oper = lcons("<",NIL);
3877 n->subLinkType = ALL_SUBLINK;
3881 | a_expr '>' ALL '(' SubSelect ')'
3883 SubLink *n = makeNode(SubLink);
3884 n->lefthand = lcons($1, NULL);
3885 n->oper = lcons(">",NIL);
3887 n->subLinkType = ALL_SUBLINK;
3891 | a_expr '=' ALL '(' SubSelect ')'
3893 SubLink *n = makeNode(SubLink);
3894 n->lefthand = lcons($1, NULL);
3895 n->oper = lcons("=",NIL);
3897 n->subLinkType = ALL_SUBLINK;
3902 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3904 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3906 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3910 * b_expr is a subset of the complete expression syntax
3911 * defined by a_expr. b_expr is used in BETWEEN clauses
3912 * to eliminate parser ambiguities stemming from the AND keyword.
3915 b_expr: attr opt_indirection
3917 $1->indirection = $2;
3924 /* could be a column name or a relation_name */
3925 Ident *n = makeNode(Ident);
3927 n->indirection = NULL;
3930 | '-' b_expr %prec UMINUS
3931 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3933 { $$ = makeA_Expr(OP, "+", $1, $3); }
3935 { $$ = makeA_Expr(OP, "-", $1, $3); }
3937 { $$ = makeA_Expr(OP, "/", $1, $3); }
3939 { $$ = makeA_Expr(OP, "*", $1, $3); }
3941 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3943 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3945 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3946 | b_expr TYPECAST Typename
3949 /* AexprConst can be either A_Const or ParamNo */
3950 if (nodeTag($1) == T_A_Const) {
3951 ((A_Const *)$1)->typename = $3;
3952 } else if (nodeTag($1) == T_Param) {
3953 ((ParamNo *)$1)->typename = $3;
3954 /* otherwise, try to transform to a function call */
3956 FuncCall *n = makeNode(FuncCall);
3957 n->funcname = $3->name;
3958 n->args = lcons($1,NIL);
3962 | CAST '(' b_expr AS Typename ')'
3965 /* AexprConst can be either A_Const or ParamNo */
3966 if (nodeTag($3) == T_A_Const) {
3967 ((A_Const *)$3)->typename = $5;
3968 } else if (nodeTag($3) == T_Param) {
3969 ((ParamNo *)$3)->typename = $5;
3970 /* otherwise, try to transform to a function call */
3972 FuncCall *n = makeNode(FuncCall);
3973 n->funcname = $5->name;
3974 n->args = lcons($3,NIL);
3981 { $$ = makeIndexable($2,$1,$3); }
3983 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3985 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3988 FuncCall *n = makeNode(FuncCall);
3993 | func_name '(' expr_list ')'
3995 FuncCall *n = makeNode(FuncCall);
4002 A_Const *n = makeNode(A_Const);
4003 TypeName *t = makeNode(TypeName);
4005 n->val.type = T_String;
4006 n->val.val.str = "now";
4009 t->name = xlateSqlType("date");
4017 A_Const *n = makeNode(A_Const);
4018 TypeName *t = makeNode(TypeName);
4020 n->val.type = T_String;
4021 n->val.val.str = "now";
4024 t->name = xlateSqlType("time");
4030 | CURRENT_TIME '(' Iconst ')'
4032 FuncCall *n = makeNode(FuncCall);
4033 A_Const *s = makeNode(A_Const);
4034 TypeName *t = makeNode(TypeName);
4036 n->funcname = xlateSqlType("time");
4037 n->args = lcons(s, NIL);
4039 s->val.type = T_String;
4040 s->val.val.str = "now";
4043 t->name = xlateSqlType("time");
4048 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4054 A_Const *n = makeNode(A_Const);
4055 TypeName *t = makeNode(TypeName);
4057 n->val.type = T_String;
4058 n->val.val.str = "now";
4061 t->name = xlateSqlType("timestamp");
4067 | CURRENT_TIMESTAMP '(' Iconst ')'
4069 FuncCall *n = makeNode(FuncCall);
4070 A_Const *s = makeNode(A_Const);
4071 TypeName *t = makeNode(TypeName);
4073 n->funcname = xlateSqlType("timestamp");
4074 n->args = lcons(s, NIL);
4076 s->val.type = T_String;
4077 s->val.val.str = "now";
4080 t->name = xlateSqlType("timestamp");
4085 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4091 FuncCall *n = makeNode(FuncCall);
4092 n->funcname = "getpgusername";
4096 | POSITION '(' position_list ')'
4098 FuncCall *n = makeNode(FuncCall);
4099 n->funcname = "strpos";
4103 | SUBSTRING '(' substr_list ')'
4105 FuncCall *n = makeNode(FuncCall);
4106 n->funcname = "substr";
4110 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4111 | TRIM '(' BOTH trim_list ')'
4113 FuncCall *n = makeNode(FuncCall);
4114 n->funcname = "btrim";
4118 | TRIM '(' LEADING trim_list ')'
4120 FuncCall *n = makeNode(FuncCall);
4121 n->funcname = "ltrim";
4125 | TRIM '(' TRAILING trim_list ')'
4127 FuncCall *n = makeNode(FuncCall);
4128 n->funcname = "rtrim";
4132 | TRIM '(' trim_list ')'
4134 FuncCall *n = makeNode(FuncCall);
4135 n->funcname = "btrim";
4141 opt_indirection: '[' a_expr ']' opt_indirection
4143 A_Indices *ai = makeNode(A_Indices);
4148 | '[' a_expr ':' a_expr ']' opt_indirection
4150 A_Indices *ai = makeNode(A_Indices);
4159 expr_list: a_expr_or_null
4160 { $$ = lcons($1, NIL); }
4161 | expr_list ',' a_expr_or_null
4162 { $$ = lappend($1, $3); }
4163 | expr_list USING a_expr
4164 { $$ = lappend($1, $3); }
4167 extract_list: datetime FROM a_expr
4169 A_Const *n = makeNode(A_Const);
4170 n->val.type = T_String;
4171 n->val.val.str = $1;
4172 $$ = lappend(lcons((Node *)n,NIL), $3);
4178 position_list: position_expr IN position_expr
4179 { $$ = makeList($3, $1, -1); }
4184 position_expr: attr opt_indirection
4186 $1->indirection = $2;
4191 | '-' position_expr %prec UMINUS
4192 { $$ = makeA_Expr(OP, "-", NULL, $2); }
4193 | position_expr '+' position_expr
4194 { $$ = makeA_Expr(OP, "+", $1, $3); }
4195 | position_expr '-' position_expr
4196 { $$ = makeA_Expr(OP, "-", $1, $3); }
4197 | position_expr '/' position_expr
4198 { $$ = makeA_Expr(OP, "/", $1, $3); }
4199 | position_expr '*' position_expr
4200 { $$ = makeA_Expr(OP, "*", $1, $3); }
4202 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4203 | position_expr TYPECAST Typename
4206 /* AexprConst can be either A_Const or ParamNo */
4207 if (nodeTag($1) == T_A_Const) {
4208 ((A_Const *)$1)->typename = $3;
4209 } else if (nodeTag($1) == T_Param) {
4210 ((ParamNo *)$1)->typename = $3;
4211 /* otherwise, try to transform to a function call */
4213 FuncCall *n = makeNode(FuncCall);
4214 n->funcname = $3->name;
4215 n->args = lcons($1,NIL);
4219 | CAST '(' position_expr AS Typename ')'
4222 /* AexprConst can be either A_Const or ParamNo */
4223 if (nodeTag($3) == T_A_Const) {
4224 ((A_Const *)$3)->typename = $5;
4225 } else if (nodeTag($3) == T_Param) {
4226 ((ParamNo *)$3)->typename = $5;
4227 /* otherwise, try to transform to a function call */
4229 FuncCall *n = makeNode(FuncCall);
4230 n->funcname = $5->name;
4231 n->args = lcons($3,NIL);
4235 | '(' position_expr ')'
4237 | position_expr Op position_expr
4238 { $$ = makeA_Expr(OP, $2, $1, $3); }
4240 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4242 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4245 /* could be a column name or a relation_name */
4246 Ident *n = makeNode(Ident);
4248 n->indirection = NULL;
4253 FuncCall *n = makeNode(FuncCall);
4258 | func_name '(' expr_list ')'
4260 FuncCall *n = makeNode(FuncCall);
4265 | POSITION '(' position_list ')'
4267 FuncCall *n = makeNode(FuncCall);
4268 n->funcname = "strpos";
4272 | SUBSTRING '(' substr_list ')'
4274 FuncCall *n = makeNode(FuncCall);
4275 n->funcname = "substr";
4279 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4280 | TRIM '(' BOTH trim_list ')'
4282 FuncCall *n = makeNode(FuncCall);
4283 n->funcname = "btrim";
4287 | TRIM '(' LEADING trim_list ')'
4289 FuncCall *n = makeNode(FuncCall);
4290 n->funcname = "ltrim";
4294 | TRIM '(' TRAILING trim_list ')'
4296 FuncCall *n = makeNode(FuncCall);
4297 n->funcname = "rtrim";
4301 | TRIM '(' trim_list ')'
4303 FuncCall *n = makeNode(FuncCall);
4304 n->funcname = "btrim";
4310 substr_list: expr_list substr_from substr_for
4312 $$ = nconc(nconc($1,$2),$3);
4318 substr_from: FROM expr_list
4322 A_Const *n = makeNode(A_Const);
4323 n->val.type = T_Integer;
4324 n->val.val.ival = 1;
4325 $$ = lcons((Node *)n,NIL);
4329 substr_for: FOR expr_list
4335 trim_list: a_expr FROM expr_list
4336 { $$ = lappend($3, $1); }
4345 SubLink *n = makeNode(SubLink);
4353 in_expr_nodes: AexprConst
4354 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4355 | in_expr_nodes ',' AexprConst
4356 { $$ = makeA_Expr(OR, NULL, $1,
4357 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4361 not_in_expr: SubSelect
4363 SubLink *n = makeNode(SubLink);
4371 not_in_expr_nodes: AexprConst
4372 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4373 | not_in_expr_nodes ',' AexprConst
4374 { $$ = makeA_Expr(AND, NULL, $1,
4375 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4379 attr: relation_name '.' attrs
4381 $$ = makeNode(Attr);
4385 $$->indirection = NULL;
4389 $$ = makeNode(Attr);
4393 $$->indirection = NULL;
4398 { $$ = lcons(makeString($1), NIL); }
4399 | attrs '.' attr_name
4400 { $$ = lappend($1, makeString($3)); }
4402 { $$ = lappend($1, makeString("*")); }
4406 /*****************************************************************************
4410 *****************************************************************************/
4412 res_target_list: res_target_list ',' res_target_el
4413 { $$ = lappend($1,$3); }
4415 { $$ = lcons($1, NIL); }
4418 ResTarget *rt = makeNode(ResTarget);
4419 Attr *att = makeNode(Attr);
4421 att->paramNo = NULL;
4423 att->indirection = NIL;
4425 rt->indirection = NULL;
4426 rt->val = (Node *)att;
4427 $$ = lcons(rt, NIL);
4431 res_target_el: ColId opt_indirection '=' a_expr_or_null
4433 $$ = makeNode(ResTarget);
4435 $$->indirection = $2;
4436 $$->val = (Node *)$4;
4438 | attr opt_indirection
4440 $$ = makeNode(ResTarget);
4442 $$->indirection = $2;
4443 $$->val = (Node *)$1;
4445 | relation_name '.' '*'
4447 Attr *att = makeNode(Attr);
4449 att->paramNo = NULL;
4450 att->attrs = lcons(makeString("*"), NIL);
4451 att->indirection = NIL;
4452 $$ = makeNode(ResTarget);
4454 $$->indirection = NULL;
4455 $$->val = (Node *)att;
4460 ** target list for select.
4461 ** should get rid of the other but is still needed by the defunct select into
4462 ** and update (uses a subset)
4464 res_target_list2: res_target_list2 ',' res_target_el2
4465 { $$ = lappend($1, $3); }
4467 { $$ = lcons($1, NIL); }
4470 /* AS is not optional because shift/red conflict with unary ops */
4471 res_target_el2: a_expr_or_null AS ColLabel
4473 $$ = makeNode(ResTarget);
4475 $$->indirection = NULL;
4476 $$->val = (Node *)$1;
4480 $$ = makeNode(ResTarget);
4482 $$->indirection = NULL;
4483 $$->val = (Node *)$1;
4485 | relation_name '.' '*'
4487 Attr *att = makeNode(Attr);
4489 att->paramNo = NULL;
4490 att->attrs = lcons(makeString("*"), NIL);
4491 att->indirection = NIL;
4492 $$ = makeNode(ResTarget);
4494 $$->indirection = NULL;
4495 $$->val = (Node *)att;
4499 Attr *att = makeNode(Attr);
4501 att->paramNo = NULL;
4503 att->indirection = NIL;
4504 $$ = makeNode(ResTarget);
4506 $$->indirection = NULL;
4507 $$->val = (Node *)att;
4511 opt_id: ColId { $$ = $1; }
4512 | /* EMPTY */ { $$ = NULL; }
4515 relation_name: SpecialRuleRelation
4518 StrNCpy(saved_relname, $1, NAMEDATALEN);
4522 /* disallow refs to variable system tables */
4523 if (strcmp(LogRelationName, $1) == 0
4524 || strcmp(VariableRelationName, $1) == 0)
4525 elog(ERROR,"%s cannot be accessed by users",$1);
4528 StrNCpy(saved_relname, $1, NAMEDATALEN);
4532 database_name: ColId { $$ = $1; };
4533 access_method: IDENT { $$ = $1; };
4534 attr_name: ColId { $$ = $1; };
4535 class: IDENT { $$ = $1; };
4536 index_name: ColId { $$ = $1; };
4539 * Include date/time keywords as SQL92 extension.
4540 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4542 name: ColId { $$ = $1; };
4543 func_name: ColId { $$ = xlateSqlFunc($1); };
4545 file_name: Sconst { $$ = $1; };
4546 recipe_name: IDENT { $$ = $1; };
4549 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4553 A_Const *n = makeNode(A_Const);
4554 n->val.type = T_Integer;
4555 n->val.val.ival = $1;
4560 A_Const *n = makeNode(A_Const);
4561 n->val.type = T_Float;
4562 n->val.val.dval = $1;
4567 A_Const *n = makeNode(A_Const);
4568 n->val.type = T_String;
4569 n->val.val.str = $1;
4574 A_Const *n = makeNode(A_Const);
4576 n->val.type = T_String;
4577 n->val.val.str = $2;
4581 { $$ = (Node *)$1; }
4584 A_Const *n = makeNode(A_Const);
4585 n->val.type = T_String;
4586 n->val.val.str = "t";
4587 n->typename = makeNode(TypeName);
4588 n->typename->name = xlateSqlType("bool");
4589 n->typename->typmod = -1;
4594 A_Const *n = makeNode(A_Const);
4595 n->val.type = T_String;
4596 n->val.val.str = "f";
4597 n->typename = makeNode(TypeName);
4598 n->typename->name = xlateSqlType("bool");
4599 n->typename->typmod = -1;
4606 $$ = makeNode(ParamNo);
4611 NumConst: Iconst { $$ = makeInteger($1); }
4612 | FCONST { $$ = makeFloat($1); }
4615 Iconst: ICONST { $$ = $1; };
4616 Sconst: SCONST { $$ = $1; };
4617 UserId: IDENT { $$ = $1; };
4619 /* Column and type identifier
4620 * Does not include explicit datetime types
4621 * since these must be decoupled in Typename syntax.
4622 * Use ColId for most identifiers. - thomas 1997-10-21
4625 { $$ = xlateSqlType($1); }
4627 { $$ = xlateSqlType($1); }
4629 { $$ = xlateSqlType($1); }
4631 /* Column identifier
4632 * Include date/time keywords as SQL92 extension.
4633 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4634 * Add other keywords. Note that as the syntax expands,
4635 * some of these keywords will have to be removed from this
4636 * list due to shift/reduce conflicts in yacc. If so, move
4637 * down to the ColLabel entity. - thomas 1997-11-06
4639 ColId: IDENT { $$ = $1; }
4640 | datetime { $$ = $1; }
4641 | ACTION { $$ = "action"; }
4642 | CACHE { $$ = "cache"; }
4643 | CYCLE { $$ = "cycle"; }
4644 | DATABASE { $$ = "database"; }
4645 | DELIMITERS { $$ = "delimiters"; }
4646 | DOUBLE { $$ = "double"; }
4647 | EACH { $$ = "each"; }
4648 | FUNCTION { $$ = "function"; }
4649 | INCREMENT { $$ = "increment"; }
4650 | INDEX { $$ = "index"; }
4651 | KEY { $$ = "key"; }
4652 | LANGUAGE { $$ = "language"; }
4653 | LOCATION { $$ = "location"; }
4654 | MATCH { $$ = "match"; }
4655 | MAXVALUE { $$ = "maxvalue"; }
4656 | MINVALUE { $$ = "minvalue"; }
4657 | OPERATOR { $$ = "operator"; }
4658 | OPTION { $$ = "option"; }
4659 | PASSWORD { $$ = "password"; }
4660 | PRIVILEGES { $$ = "privileges"; }
4661 | RECIPE { $$ = "recipe"; }
4662 | ROW { $$ = "row"; }
4663 | STATEMENT { $$ = "statement"; }
4664 | TIME { $$ = "time"; }
4665 | TRIGGER { $$ = "trigger"; }
4666 | TYPE_P { $$ = "type"; }
4667 | USER { $$ = "user"; }
4668 | VALID { $$ = "valid"; }
4669 | VERSION { $$ = "version"; }
4670 | ZONE { $$ = "zone"; }
4674 * Allowed labels in "AS" clauses.
4675 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4676 * compatibility. Cannot allow this for column names since the
4677 * syntax would not distinguish between the constant value and
4678 * a column name. - thomas 1997-10-24
4679 * Add other keywords to this list. Note that they appear here
4680 * rather than in ColId if there was a shift/reduce conflict
4681 * when used as a full identifier. - thomas 1997-11-06
4683 ColLabel: ColId { $$ = $1; }
4684 | ARCHIVE { $$ = "archive"; }
4685 | CLUSTER { $$ = "cluster"; }
4686 | CONSTRAINT { $$ = "constraint"; }
4687 | CROSS { $$ = "cross"; }
4688 | FOREIGN { $$ = "foreign"; }
4689 | GROUP { $$ = "group"; }
4690 | LOAD { $$ = "load"; }
4691 | ORDER { $$ = "order"; }
4692 | POSITION { $$ = "position"; }
4693 | PRECISION { $$ = "precision"; }
4694 | TABLE { $$ = "table"; }
4695 | TRANSACTION { $$ = "transaction"; }
4696 | TRUE_P { $$ = "true"; }
4697 | FALSE_P { $$ = "false"; }
4700 SpecialRuleRelation: CURRENT
4705 elog(ERROR,"CURRENT used in non-rule query");
4712 elog(ERROR,"NEW used in non-rule query");
4719 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
4721 A_Expr *a = makeNode(A_Expr);
4730 * Generate separate operator nodes for a single row descriptor expression.
4731 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
4734 makeRowExpr(char *opr, List *largs, List *rargs)
4739 if (length(largs) != length(rargs))
4740 elog(ERROR,"Unequal number of entries in row expression");
4742 if (lnext(largs) != NIL)
4743 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
4745 larg = lfirst(largs);
4746 rarg = lfirst(rargs);
4748 if ((strcmp(opr, "=") == 0)
4749 || (strcmp(opr, "<") == 0)
4750 || (strcmp(opr, "<=") == 0)
4751 || (strcmp(opr, ">") == 0)
4752 || (strcmp(opr, ">=") == 0))
4755 expr = makeA_Expr(OP, opr, larg, rarg);
4757 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4759 else if (strcmp(opr, "<>") == 0)
4762 expr = makeA_Expr(OP, opr, larg, rarg);
4764 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4768 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
4772 while ((largs != NIL) && (rargs != NIL))
4774 larg = lfirst(largs);
4775 rarg = lfirst(rargs);
4778 expr = makeA_Expr(OP, opr, larg, rarg);
4780 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4782 largs = lnext(largs);
4783 rargs = lnext(rargs);
4792 mapTargetColumns(List *src, List *dst)
4797 if (length(src) != length(dst))
4798 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
4800 while ((src != NIL) && (dst != NIL))
4802 s = (ColumnDef *)lfirst(src);
4803 d = (ResTarget *)lfirst(dst);
4805 d->name = s->colname;
4812 } /* mapTargetColumns() */
4814 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
4816 Node *result = NULL;
4818 /* we do this so indexes can be used */
4819 if (strcmp(opname,"~") == 0 ||
4820 strcmp(opname,"~*") == 0)
4822 if (nodeTag(rexpr) == T_A_Const &&
4823 ((A_Const *)rexpr)->val.type == T_String &&
4824 ((A_Const *)rexpr)->val.val.str[0] == '^')
4826 A_Const *n = (A_Const *)rexpr;
4827 char *match_least = palloc(strlen(n->val.val.str)+2);
4828 char *match_most = palloc(strlen(n->val.val.str)+2);
4829 int pos, match_pos=0;
4831 /* skip leading ^ */
4832 for (pos = 1; n->val.val.str[pos]; pos++)
4834 if (n->val.val.str[pos] == '.' ||
4835 n->val.val.str[pos] == '?' ||
4836 n->val.val.str[pos] == '*' ||
4837 n->val.val.str[pos] == '[' ||
4838 n->val.val.str[pos] == '$' ||
4839 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4841 if (n->val.val.str[pos] == '\\')
4843 match_least[match_pos] = n->val.val.str[pos];
4844 match_most[match_pos++] = n->val.val.str[pos];
4849 A_Const *least = makeNode(A_Const);
4850 A_Const *most = makeNode(A_Const);
4852 /* make strings to be used in index use */
4853 match_least[match_pos] = '\0';
4854 match_most[match_pos] = '\377';
4855 match_most[match_pos+1] = '\0';
4856 least->val.type = T_String;
4857 least->val.val.str = match_least;
4858 most->val.type = T_String;
4859 most->val.val.str = match_most;
4860 result = makeA_Expr(AND, NULL,
4861 makeA_Expr(OP, "~", lexpr, rexpr),
4862 makeA_Expr(AND, NULL,
4863 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4864 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4868 else if (strcmp(opname,"~~") == 0)
4870 if (nodeTag(rexpr) == T_A_Const &&
4871 ((A_Const *)rexpr)->val.type == T_String)
4873 A_Const *n = (A_Const *)rexpr;
4874 char *match_least = palloc(strlen(n->val.val.str)+2);
4875 char *match_most = palloc(strlen(n->val.val.str)+2);
4876 int pos, match_pos=0;
4878 for (pos = 0; n->val.val.str[pos]; pos++)
4880 if (n->val.val.str[pos] == '%' &&
4881 n->val.val.str[pos+1] != '%')
4883 if(n->val.val.str[pos] == '_')
4885 if (n->val.val.str[pos] == '\\' ||
4886 n->val.val.str[pos] == '%')
4888 if (n->val.val.str[pos] == '\0')
4890 match_least[match_pos] = n->val.val.str[pos];
4891 match_most[match_pos++] = n->val.val.str[pos];
4896 A_Const *least = makeNode(A_Const);
4897 A_Const *most = makeNode(A_Const);
4899 /* make strings to be used in index use */
4900 match_least[match_pos] = '\0';
4901 match_most[match_pos] = '\377';
4902 match_most[match_pos+1] = '\0';
4903 least->val.type = T_String;
4904 least->val.val.str = match_least;
4905 most->val.type = T_String;
4906 most->val.val.str = match_most;
4907 result = makeA_Expr(AND, NULL,
4908 makeA_Expr(OP, "~~", lexpr, rexpr),
4909 makeA_Expr(AND, NULL,
4910 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4911 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4917 result = makeA_Expr(OP, opname, lexpr, rexpr);
4919 } /* makeIndexable() */
4923 * Convert alternate type names to internal Postgres types.
4924 * Do not convert "float", since that is handled elsewhere
4925 * for FLOAT(p) syntax.
4928 xlateSqlFunc(char *name)
4930 if (!strcasecmp(name,"character_length")
4931 || !strcasecmp(name,"char_length"))
4935 } /* xlateSqlFunc() */
4938 * Convert alternate type names to internal Postgres types.
4941 xlateSqlType(char *name)
4943 if (!strcasecmp(name,"int")
4944 || !strcasecmp(name,"integer"))
4946 else if (!strcasecmp(name, "smallint"))
4948 else if (!strcasecmp(name, "real")
4949 || !strcasecmp(name, "float"))
4951 else if (!strcasecmp(name, "interval"))
4953 else if (!strcasecmp(name, "boolean"))
4957 } /* xlateSqlType() */
4960 void parser_init(Oid *typev, int nargs)
4962 QueryIsRule = FALSE;
4963 saved_relname[0]= '\0';
4964 saved_In_Expr = NULL;
4966 param_type_init(typev, nargs);
4970 /* FlattenStringList()
4971 * Traverse list of string nodes and convert to a single string.
4972 * Used for reconstructing string form of complex expressions.
4974 * Allocate at least one byte for terminator.
4977 FlattenStringList(List *list)
4985 nlist = length(list);
4988 v = (Value *)lfirst(l);
4995 s = (char*) palloc(len+1);
5000 v = (Value *)lfirst(l);
5004 if (l != NIL) strcat(s," ");
5009 printf( "flattened string is \"%s\"\n", s);
5013 } /* FlattenStringList() */
5016 /* makeConstantList()
5017 * Convert constant value node into string node.
5020 makeConstantList( A_Const *n)
5022 char *defval = NULL;
5023 if (nodeTag(n) != T_A_Const) {
5024 elog(ERROR,"Cannot handle non-constant parameter");
5026 } else if (n->val.type == T_Float) {
5027 defval = (char*) palloc(20+1);
5028 sprintf( defval, "%g", n->val.val.dval);
5030 } else if (n->val.type == T_Integer) {
5031 defval = (char*) palloc(20+1);
5032 sprintf( defval, "%ld", n->val.val.ival);
5034 } else if (n->val.type == T_String) {
5035 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
5036 strcpy( defval, "'");
5037 strcat( defval, ((A_Const *) n)->val.val.str);
5038 strcat( defval, "'");
5041 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
5045 printf( "AexprConst argument is \"%s\"\n", defval);
5048 return( lcons( makeString(defval), NIL));
5049 } /* makeConstantList() */
5053 * Check input string for non-lowercase/non-numeric characters.
5054 * Returns either input string or input surrounded by double quotes.
5061 for (cp = rawid; *cp != '\0'; cp++)
5062 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
5065 cp = palloc(strlen(rawid)+1);
5074 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
5083 * keep enough information around fill out the type of param nodes
5084 * used in postquel functions
5087 param_type_init(Oid *typev, int nargs)
5089 pfunc_num_args = nargs;
5090 param_type_info = typev;
5093 Oid param_type(int t)
5095 if ((t > pfunc_num_args) || (t == 0))
5097 return param_type_info[t - 1];