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.9 1998/04/08 06:38:57 thomas Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlFunc(char *);
65 static char *xlateSqlType(char *);
66 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
67 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
68 void mapTargetColumns(List *source, List *target);
69 static List *makeConstantList( A_Const *node);
70 static char *FlattenStringList(List *list);
71 static char *fmtId(char *rawid);
72 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
73 static void param_type_init(Oid *typev, int nargs);
75 Oid param_type(int t); /* used in parse_expr.c */
77 /* old versions of flex define this as a macro */
91 bool* pboolean; /* for pg_shadow privileges */
101 SortGroupBy *sortgroupby;
116 AddAttrStmt, ClosePortalStmt,
117 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
118 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
119 CreatePLangStmt, DropPLangStmt,
120 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
121 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
122 RemoveFuncStmt, RemoveStmt,
123 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
124 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
125 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
126 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
127 CreateUserStmt, AlterUserStmt, DropUserStmt
129 %type <str> opt_database, location
131 %type <pboolean> user_createdb_clause, user_createuser_clause
132 %type <str> user_passwd_clause
133 %type <str> user_valid_clause
134 %type <list> user_group_list, user_group_clause
136 %type <str> join_expr, join_outer, join_spec
137 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
139 %type <str> TriggerEvents, TriggerFuncArg
141 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
142 database_name, access_method_clause, access_method, attr_name,
143 class, index_name, name, func_name, file_name, recipe_name, aggr_argtype
145 %type <str> opt_id, opt_portal_name,
146 all_Op, MathOp, opt_name, opt_unique,
147 result, OptUseOp, opt_class, SpecialRuleRelation
149 %type <str> privileges, operation_commalist, grantee
150 %type <chr> operation, TriggerOneEvent
152 %type <list> stmtblock, stmtmulti,
153 relation_name_list, OptTableElementList,
154 OptInherit, definition,
155 opt_with, func_args, func_args_list,
156 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
157 opt_column_list, columnList, opt_va_list, va_list,
158 sort_clause, sortby_list, index_params, index_list, name_list,
159 from_clause, from_list, opt_array_bounds, nest_array_bounds,
160 expr_list, attrs, res_target_list, res_target_list2,
161 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
163 %type <node> func_return
164 %type <boolean> set_opt
166 %type <boolean> TriggerForOpt, TriggerForType
168 %type <list> union_clause, select_list
169 %type <list> join_list
172 %type <boolean> opt_union
173 %type <boolean> opt_table
175 %type <node> position_expr
176 %type <list> extract_list, position_list
177 %type <list> substr_list, substr_from, substr_for, trim_list
178 %type <list> opt_interval
180 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
181 index_opt_unique, opt_verbose, opt_analyze
183 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
186 %type <ival> fetch_how_many
188 %type <list> OptSeqList
189 %type <defelt> OptSeqElem
191 %type <dstmt> def_rest
192 %type <astmt> insert_rest
194 %type <node> OptTableElement, ConstraintElem
195 %type <node> columnDef, alter_clause
196 %type <defelt> def_elem
197 %type <node> def_arg, columnElem, where_clause,
198 a_expr, a_expr_or_null, b_expr, AexprConst,
199 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
201 %type <list> row_descriptor, row_list
202 %type <node> row_expr
203 %type <list> OptCreateAs, CreateAsList
204 %type <node> CreateAsElement
205 %type <value> NumConst
206 %type <value> IntegerOnly
207 %type <attr> event_object, attr
208 %type <sortgroupby> groupby
209 %type <sortgroupby> sortby
210 %type <ielem> index_elem, func_index
211 %type <range> from_val
212 %type <relexp> relation_expr
213 %type <target> res_target_el, res_target_el2
214 %type <paramno> ParamNo
216 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
217 %type <str> generic, numeric, character, datetime
218 %type <str> extract_arg
219 %type <str> opt_charset, opt_collate
220 %type <str> opt_float, opt_numeric, opt_decimal
221 %type <boolean> opt_varying, opt_timezone
225 %type <str> UserId, var_value, zone_value
226 %type <str> ColId, ColLabel
229 %type <node> TableConstraint
230 %type <list> constraint_list, constraint_expr
231 %type <list> default_list, default_expr
232 %type <list> ColQualList, ColQualifier
233 %type <node> ColConstraint, ColConstraintElem
234 %type <list> key_actions, key_action
235 %type <str> key_match, key_reference
238 * If you make any token changes, remember to:
239 * - use "yacc -d" and update parse.h
240 * - update the keyword table in parser/keywords.c
243 /* Reserved word tokens
244 * SQL92 syntax has many type-specific constructs.
245 * So, go ahead and make these types reserved words,
246 * and call-out the syntax explicitly.
247 * This gets annoying when trying to also retain Postgres' nice
248 * type-extensible features, but we don't really have a choice.
249 * - thomas 1997-10-11
252 /* Keywords (in SQL92 reserved words) */
253 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
254 BEGIN_TRANS, BETWEEN, BOTH, BY,
255 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
256 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
257 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
258 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
259 END_TRANS, EXECUTE, EXISTS, EXTRACT,
260 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
261 GRANT, GROUP, HAVING, HOUR_P,
262 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
263 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
264 MATCH, MINUTE_P, MONTH_P,
265 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
266 ON, OPTION, OR, ORDER, OUTER_P,
267 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
268 REFERENCES, REVOKE, RIGHT, ROLLBACK,
269 SECOND_P, SELECT, SET, SUBSTRING,
270 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
271 UNION, UNIQUE, UPDATE, USING,
272 VALUES, VARCHAR, VARYING, VIEW,
273 WHERE, WITH, WORK, YEAR_P, ZONE
275 /* Keywords (in SQL3 reserved words) */
276 %token FALSE_P, TRIGGER, TRUE_P
278 /* Keywords (in SQL92 non-reserved words) */
281 /* Keywords for Postgres support (not in SQL92 reserved words) */
282 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
283 BACKWARD, BEFORE, BINARY, CACHE, CLUSTER, COPY, CYCLE,
284 DATABASE, DELIMITERS, DO, EACH, EXPLAIN, EXTEND,
285 FORWARD, FUNCTION, HANDLER,
286 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
287 LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MAXVALUE, MINVALUE, MOVE,
288 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
289 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
290 SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
291 VACUUM, VERBOSE, VERSION
293 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
297 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
298 * when some sort of pg_privileges relation is introduced.
302 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
304 /* Special keywords, not in the query language - see the "lex" file */
305 %token <str> IDENT, SCONST, Op
306 %token <ival> ICONST, PARAM
309 /* these are not real. they are here so that they get generated as #define's*/
321 %nonassoc Op /* multi-character ops and user-defined operators */
327 %left '|' /* this is the relation union op, not logical or */
328 /* Unary Operators */
330 %left ';' /* end of statement or natural log */
342 { parsetree = lcons($1,NIL); }
345 stmtmulti: stmtmulti stmt ';'
346 { $$ = lappend($1, $2); }
348 { $$ = lappend($1, $2); }
350 { $$ = lcons($1,NIL); }
397 /*****************************************************************************
399 * Create a new Postgres DBMS user
402 *****************************************************************************/
404 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
405 user_createuser_clause user_group_clause user_valid_clause
407 CreateUserStmt *n = makeNode(CreateUserStmt);
418 /*****************************************************************************
420 * Alter a postresql DBMS user
423 *****************************************************************************/
425 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
426 user_createuser_clause user_group_clause user_valid_clause
428 AlterUserStmt *n = makeNode(AlterUserStmt);
439 /*****************************************************************************
441 * Drop a postresql DBMS user
444 *****************************************************************************/
446 DropUserStmt: DROP USER UserId
448 DropUserStmt *n = makeNode(DropUserStmt);
454 user_passwd_clause: WITH PASSWORD UserId { $$ = $3; }
455 | /*EMPTY*/ { $$ = NULL; }
458 user_createdb_clause: CREATEDB
461 $$ = (b = (bool*)palloc(sizeof(bool)));
467 $$ = (b = (bool*)palloc(sizeof(bool)));
470 | /*EMPTY*/ { $$ = NULL; }
473 user_createuser_clause: CREATEUSER
476 $$ = (b = (bool*)palloc(sizeof(bool)));
482 $$ = (b = (bool*)palloc(sizeof(bool)));
485 | /*EMPTY*/ { $$ = NULL; }
488 user_group_list: user_group_list ',' UserId
490 $$ = lcons((void*)makeString($3), $1);
494 $$ = lcons((void*)makeString($1), NIL);
498 user_group_clause: IN GROUP user_group_list { $$ = $3; }
499 | /*EMPTY*/ { $$ = NULL; }
502 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
503 | /*EMPTY*/ { $$ = NULL; }
506 /*****************************************************************************
508 * Set PG internal variable
509 * SET name TO 'var_value'
510 * Include SQL92 syntax (thomas 1997-10-22):
511 * SET TIME ZONE 'var_value'
513 *****************************************************************************/
515 VariableSetStmt: SET ColId TO var_value
517 VariableSetStmt *n = makeNode(VariableSetStmt);
522 | SET ColId '=' var_value
524 VariableSetStmt *n = makeNode(VariableSetStmt);
529 | SET TIME ZONE zone_value
531 VariableSetStmt *n = makeNode(VariableSetStmt);
532 n->name = "timezone";
538 var_value: Sconst { $$ = $1; }
539 | DEFAULT { $$ = NULL; }
542 zone_value: Sconst { $$ = $1; }
543 | DEFAULT { $$ = NULL; }
544 | LOCAL { $$ = NULL; }
547 VariableShowStmt: SHOW ColId
549 VariableShowStmt *n = makeNode(VariableShowStmt);
555 VariableShowStmt *n = makeNode(VariableShowStmt);
556 n->name = "timezone";
561 VariableResetStmt: RESET ColId
563 VariableResetStmt *n = makeNode(VariableResetStmt);
569 VariableResetStmt *n = makeNode(VariableResetStmt);
570 n->name = "timezone";
576 /*****************************************************************************
579 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
581 *****************************************************************************/
583 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
585 AddAttrStmt *n = makeNode(AddAttrStmt);
593 alter_clause: ADD opt_column columnDef
597 | ADD '(' OptTableElementList ')'
599 Node *lp = lfirst($3);
602 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
605 | DROP opt_column ColId
606 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
607 | ALTER opt_column ColId SET DEFAULT default_expr
608 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
609 | ALTER opt_column ColId DROP DEFAULT
610 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
612 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
616 /*****************************************************************************
621 *****************************************************************************/
623 ClosePortalStmt: CLOSE opt_id
625 ClosePortalStmt *n = makeNode(ClosePortalStmt);
632 /*****************************************************************************
635 * COPY [BINARY] <relname> FROM/TO
636 * [USING DELIMITERS <delimiter>]
638 *****************************************************************************/
640 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
642 CopyStmt *n = makeNode(CopyStmt);
660 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
661 * used depends on the direction. (It really doesn't make sense to copy from
662 * stdout. We silently correct the "typo". - AY 9/94
664 copy_file_name: Sconst { $$ = $1; }
665 | STDIN { $$ = NULL; }
666 | STDOUT { $$ = NULL; }
669 opt_binary: BINARY { $$ = TRUE; }
670 | /*EMPTY*/ { $$ = FALSE; }
673 opt_with_copy: WITH OIDS { $$ = TRUE; }
674 | /*EMPTY*/ { $$ = FALSE; }
678 * the default copy delimiter is tab but the user can configure it
680 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
681 | /*EMPTY*/ { $$ = "\t"; }
685 /*****************************************************************************
690 *****************************************************************************/
692 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
693 OptInherit OptArchiveType
695 CreateStmt *n = makeNode(CreateStmt);
699 n->constraints = NIL;
704 OptTableElementList: OptTableElementList ',' OptTableElement
707 $$ = lappend($1, $3);
718 | /*EMPTY*/ { $$ = NULL; }
721 OptTableElement: columnDef { $$ = $1; }
722 | TableConstraint { $$ = $1; }
725 columnDef: ColId Typename ColQualifier
727 ColumnDef *n = makeNode(ColumnDef);
731 n->is_not_null = FALSE;
737 ColQualifier: ColQualList { $$ = $1; }
738 | /*EMPTY*/ { $$ = NULL; }
741 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
742 | ColConstraint { $$ = lcons($1, NIL); }
746 CONSTRAINT name ColConstraintElem
748 Constraint *n = (Constraint *)$3;
749 if (n != NULL) n->name = fmtId($2);
756 ColConstraintElem: CHECK '(' constraint_expr ')'
758 Constraint *n = makeNode(Constraint);
759 n->contype = CONSTR_CHECK;
761 n->def = FlattenStringList($3);
765 | DEFAULT default_expr
767 Constraint *n = makeNode(Constraint);
768 n->contype = CONSTR_DEFAULT;
770 n->def = FlattenStringList($2);
776 Constraint *n = makeNode(Constraint);
777 n->contype = CONSTR_NOTNULL;
785 Constraint *n = makeNode(Constraint);
786 n->contype = CONSTR_UNIQUE;
794 Constraint *n = makeNode(Constraint);
795 n->contype = CONSTR_PRIMARY;
801 | REFERENCES ColId opt_column_list key_match key_actions
803 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
808 default_list: default_list ',' default_expr
810 $$ = lappend($1,makeString(","));
819 default_expr: AexprConst
820 { $$ = makeConstantList((A_Const *) $1); }
822 { $$ = lcons( makeString("NULL"), NIL); }
823 | '-' default_expr %prec UMINUS
824 { $$ = lcons( makeString( "-"), $2); }
825 | default_expr '+' default_expr
826 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
827 | default_expr '-' default_expr
828 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
829 | default_expr '/' default_expr
830 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
831 | default_expr '*' default_expr
832 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
833 | default_expr '=' default_expr
834 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
835 | default_expr '<' default_expr
836 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
837 | default_expr '>' default_expr
838 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
840 { $$ = lcons( makeString( ":"), $2); }
842 { $$ = lcons( makeString( ";"), $2); }
844 { $$ = lcons( makeString( "|"), $2); }
845 | default_expr TYPECAST Typename
847 $3->name = fmtId($3->name);
848 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
850 | CAST '(' default_expr AS Typename ')'
852 $5->name = fmtId($5->name);
853 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
855 | '(' default_expr ')'
856 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
859 $$ = makeList( makeString($1), makeString("("), -1);
860 $$ = lappend( $$, makeString(")"));
862 | func_name '(' default_list ')'
864 $$ = makeList( makeString($1), makeString("("), -1);
866 $$ = lappend( $$, makeString(")"));
868 | default_expr Op default_expr
870 if (!strcmp("<=", $2) || !strcmp(">=", $2))
871 elog(ERROR,"boolean expressions not supported in DEFAULT");
872 $$ = nconc( $1, lcons( makeString( $2), $3));
875 { $$ = lcons( makeString( $1), $2); }
877 { $$ = lappend( $1, makeString( $2)); }
878 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
880 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
882 { $$ = lcons( makeString( "'now'::time"), NIL); }
883 | CURRENT_TIME '(' Iconst ')'
886 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
887 $$ = lcons( makeString( "'now'::time"), NIL);
890 { $$ = lcons( makeString( "now()"), NIL); }
891 | CURRENT_TIMESTAMP '(' Iconst ')'
894 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
895 $$ = lcons( makeString( "now()"), NIL);
898 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
901 /* ConstraintElem specifies constraint syntax which is not embedded into
902 * a column definition. ColConstraintElem specifies the embedded form.
903 * - thomas 1997-12-03
905 TableConstraint: CONSTRAINT name ConstraintElem
907 Constraint *n = (Constraint *)$3;
908 if (n != NULL) n->name = fmtId($2);
915 ConstraintElem: CHECK '(' constraint_expr ')'
917 Constraint *n = makeNode(Constraint);
918 n->contype = CONSTR_CHECK;
920 n->def = FlattenStringList($3);
923 | UNIQUE '(' columnList ')'
925 Constraint *n = makeNode(Constraint);
926 n->contype = CONSTR_UNIQUE;
932 | PRIMARY KEY '(' columnList ')'
934 Constraint *n = makeNode(Constraint);
935 n->contype = CONSTR_PRIMARY;
941 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
943 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
948 constraint_list: constraint_list ',' constraint_expr
950 $$ = lappend($1,makeString(","));
959 constraint_expr: AexprConst
960 { $$ = makeConstantList((A_Const *) $1); }
962 { $$ = lcons( makeString("NULL"), NIL); }
965 $$ = lcons( makeString(fmtId($1)), NIL);
967 | '-' constraint_expr %prec UMINUS
968 { $$ = lcons( makeString( "-"), $2); }
969 | constraint_expr '+' constraint_expr
970 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
971 | constraint_expr '-' constraint_expr
972 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
973 | constraint_expr '/' constraint_expr
974 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
975 | constraint_expr '*' constraint_expr
976 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
977 | constraint_expr '=' constraint_expr
978 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
979 | constraint_expr '<' constraint_expr
980 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
981 | constraint_expr '>' constraint_expr
982 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
983 | ':' constraint_expr
984 { $$ = lcons( makeString( ":"), $2); }
985 | ';' constraint_expr
986 { $$ = lcons( makeString( ";"), $2); }
987 | '|' constraint_expr
988 { $$ = lcons( makeString( "|"), $2); }
989 | constraint_expr TYPECAST Typename
991 $3->name = fmtId($3->name);
992 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
994 | CAST '(' constraint_expr AS Typename ')'
996 $5->name = fmtId($5->name);
997 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
999 | '(' constraint_expr ')'
1000 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
1003 $$ = makeList( makeString($1), makeString("("), -1);
1004 $$ = lappend( $$, makeString(")"));
1006 | func_name '(' constraint_list ')'
1008 $$ = makeList( makeString($1), makeString("("), -1);
1009 $$ = nconc( $$, $3);
1010 $$ = lappend( $$, makeString(")"));
1012 | constraint_expr Op constraint_expr
1013 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
1014 | constraint_expr LIKE constraint_expr
1015 { $$ = nconc( $1, lcons( makeString( "like"), $3)); }
1016 | constraint_expr AND constraint_expr
1017 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
1018 | constraint_expr OR constraint_expr
1019 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
1020 | NOT constraint_expr
1021 { $$ = lcons( makeString( "NOT"), $2); }
1022 | Op constraint_expr
1023 { $$ = lcons( makeString( $1), $2); }
1024 | constraint_expr Op
1025 { $$ = lappend( $1, makeString( $2)); }
1026 | constraint_expr ISNULL
1027 { $$ = lappend( $1, makeString( "IS NULL")); }
1028 | constraint_expr IS NULL_P
1029 { $$ = lappend( $1, makeString( "IS NULL")); }
1030 | constraint_expr NOTNULL
1031 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1032 | constraint_expr IS NOT NULL_P
1033 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1034 | constraint_expr IS TRUE_P
1035 { $$ = lappend( $1, makeString( "IS TRUE")); }
1036 | constraint_expr IS FALSE_P
1037 { $$ = lappend( $1, makeString( "IS FALSE")); }
1038 | constraint_expr IS NOT TRUE_P
1039 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1040 | constraint_expr IS NOT FALSE_P
1041 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1044 key_match: MATCH FULL { $$ = NULL; }
1045 | MATCH PARTIAL { $$ = NULL; }
1046 | /*EMPTY*/ { $$ = NULL; }
1049 key_actions: key_action key_action { $$ = NIL; }
1050 | key_action { $$ = NIL; }
1051 | /*EMPTY*/ { $$ = NIL; }
1054 key_action: ON DELETE key_reference { $$ = NIL; }
1055 | ON UPDATE key_reference { $$ = NIL; }
1058 key_reference: NO ACTION { $$ = NULL; }
1059 | CASCADE { $$ = NULL; }
1060 | SET DEFAULT { $$ = NULL; }
1061 | SET NULL_P { $$ = NULL; }
1064 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1065 | /*EMPTY*/ { $$ = NIL; }
1069 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1070 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1072 OptArchiveType: ARCHIVE '=' NONE { }
1076 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1078 SelectStmt *n = (SelectStmt *)$6;
1080 mapTargetColumns($4, n->targetList);
1086 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1087 | /*EMPTY*/ { $$ = NULL; }
1090 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1091 | CreateAsElement { $$ = lcons($1, NIL); }
1094 CreateAsElement: ColId
1096 ColumnDef *n = makeNode(ColumnDef);
1100 n->is_not_null = FALSE;
1101 n->constraints = NULL;
1107 /*****************************************************************************
1110 * CREATE SEQUENCE seqname
1112 *****************************************************************************/
1114 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1116 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1123 OptSeqList: OptSeqList OptSeqElem
1124 { $$ = lappend($1, $2); }
1128 OptSeqElem: CACHE IntegerOnly
1130 $$ = makeNode(DefElem);
1131 $$->defname = "cache";
1132 $$->arg = (Node *)$2;
1136 $$ = makeNode(DefElem);
1137 $$->defname = "cycle";
1138 $$->arg = (Node *)NULL;
1140 | INCREMENT IntegerOnly
1142 $$ = makeNode(DefElem);
1143 $$->defname = "increment";
1144 $$->arg = (Node *)$2;
1146 | MAXVALUE IntegerOnly
1148 $$ = makeNode(DefElem);
1149 $$->defname = "maxvalue";
1150 $$->arg = (Node *)$2;
1152 | MINVALUE IntegerOnly
1154 $$ = makeNode(DefElem);
1155 $$->defname = "minvalue";
1156 $$->arg = (Node *)$2;
1160 $$ = makeNode(DefElem);
1161 $$->defname = "start";
1162 $$->arg = (Node *)$2;
1168 $$ = makeInteger($1);
1172 $$ = makeInteger($2);
1173 $$->val.ival = - $$->val.ival;
1177 /*****************************************************************************
1180 * CREATE PROCEDURAL LANGUAGE ...
1181 * DROP PROCEDURAL LANGUAGE ...
1183 *****************************************************************************/
1185 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1186 HANDLER def_name LANCOMPILER Sconst
1188 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1197 PLangTrusted: TRUSTED { $$ = TRUE; }
1200 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1202 DropPLangStmt *n = makeNode(DropPLangStmt);
1208 /*****************************************************************************
1211 * CREATE TRIGGER ...
1214 *****************************************************************************/
1216 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1217 relation_name TriggerForSpec EXECUTE PROCEDURE
1218 name '(' TriggerFuncArgs ')'
1220 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1227 memcpy (n->actions, $5, 4);
1232 TriggerActionTime: BEFORE { $$ = TRUE; }
1233 | AFTER { $$ = FALSE; }
1236 TriggerEvents: TriggerOneEvent
1238 char *e = palloc (4);
1239 e[0] = $1; e[1] = 0; $$ = e;
1241 | TriggerOneEvent OR TriggerOneEvent
1243 char *e = palloc (4);
1244 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1246 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1248 char *e = palloc (4);
1249 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1254 TriggerOneEvent: INSERT { $$ = 'i'; }
1255 | DELETE { $$ = 'd'; }
1256 | UPDATE { $$ = 'u'; }
1259 TriggerForSpec: FOR TriggerForOpt TriggerForType
1265 TriggerForOpt: EACH { $$ = TRUE; }
1266 | /*EMPTY*/ { $$ = FALSE; }
1269 TriggerForType: ROW { $$ = TRUE; }
1270 | STATEMENT { $$ = FALSE; }
1273 TriggerFuncArgs: TriggerFuncArg
1274 { $$ = lcons($1, NIL); }
1275 | TriggerFuncArgs ',' TriggerFuncArg
1276 { $$ = lappend($1, $3); }
1281 TriggerFuncArg: ICONST
1283 char *s = (char *) palloc (256);
1284 sprintf (s, "%d", $1);
1289 char *s = (char *) palloc (256);
1290 sprintf (s, "%g", $1);
1293 | Sconst { $$ = $1; }
1294 | IDENT { $$ = $1; }
1297 DropTrigStmt: DROP TRIGGER name ON relation_name
1299 DropTrigStmt *n = makeNode(DropTrigStmt);
1307 /*****************************************************************************
1310 * define (type,operator,aggregate)
1312 *****************************************************************************/
1314 DefineStmt: CREATE def_type def_rest
1321 def_rest: def_name definition
1323 $$ = makeNode(DefineStmt);
1325 $$->definition = $2;
1329 def_type: OPERATOR { $$ = OPERATOR; }
1330 | TYPE_P { $$ = TYPE_P; }
1331 | AGGREGATE { $$ = AGGREGATE; }
1334 def_name: PROCEDURE { $$ = "procedure"; }
1335 | JOIN { $$ = "join"; }
1336 | ColId { $$ = $1; }
1337 | MathOp { $$ = $1; }
1341 definition: '(' def_list ')' { $$ = $2; }
1344 def_list: def_elem { $$ = lcons($1, NIL); }
1345 | def_list ',' def_elem { $$ = lappend($1, $3); }
1348 def_elem: def_name '=' def_arg
1350 $$ = makeNode(DefElem);
1352 $$->arg = (Node *)$3;
1356 $$ = makeNode(DefElem);
1358 $$->arg = (Node *)NULL;
1360 | DEFAULT '=' def_arg
1362 $$ = makeNode(DefElem);
1363 $$->defname = "default";
1364 $$->arg = (Node *)$3;
1368 def_arg: ColId { $$ = (Node *)makeString($1); }
1369 | all_Op { $$ = (Node *)makeString($1); }
1370 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1371 | Sconst { $$ = (Node *)makeString($1); }
1374 TypeName *n = makeNode(TypeName);
1377 n->arrayBounds = NULL;
1384 /*****************************************************************************
1387 * destroy <relname1> [, <relname2> .. <relnameN> ]
1389 *****************************************************************************/
1391 DestroyStmt: DROP TABLE relation_name_list
1393 DestroyStmt *n = makeNode(DestroyStmt);
1395 n->sequence = FALSE;
1398 | DROP SEQUENCE relation_name_list
1400 DestroyStmt *n = makeNode(DestroyStmt);
1408 /*****************************************************************************
1411 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1413 *****************************************************************************/
1415 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1417 FetchStmt *n = makeNode(FetchStmt);
1424 | MOVE opt_direction fetch_how_many opt_portal_name
1426 FetchStmt *n = makeNode(FetchStmt);
1435 opt_direction: FORWARD { $$ = FORWARD; }
1436 | BACKWARD { $$ = BACKWARD; }
1437 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1440 fetch_how_many: Iconst
1442 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1443 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1444 | /*EMPTY*/ { $$ = 1; /*default*/ }
1447 opt_portal_name: IN name { $$ = $2; }
1448 | /*EMPTY*/ { $$ = NULL; }
1452 /*****************************************************************************
1455 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1457 *****************************************************************************/
1459 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1461 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1465 privileges: ALL PRIVILEGES
1467 $$ = aclmakepriv("rwaR",0);
1471 $$ = aclmakepriv("rwaR",0);
1473 | operation_commalist
1479 operation_commalist: operation
1481 $$ = aclmakepriv("",$1);
1483 | operation_commalist ',' operation
1485 $$ = aclmakepriv($1,$3);
1491 $$ = ACL_MODE_RD_CHR;
1495 $$ = ACL_MODE_AP_CHR;
1499 $$ = ACL_MODE_WR_CHR;
1503 $$ = ACL_MODE_WR_CHR;
1507 $$ = ACL_MODE_RU_CHR;
1513 $$ = aclmakeuser("A","");
1517 $$ = aclmakeuser("G",$2);
1521 $$ = aclmakeuser("U",$1);
1525 opt_with_grant: WITH GRANT OPTION
1527 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1533 /*****************************************************************************
1536 * REVOKE [privileges] ON [relation_name] FROM [user]
1538 *****************************************************************************/
1540 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1542 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1547 /*****************************************************************************
1550 * create index <indexname> on <relname>
1551 * using <access> "(" (<col> with <op>)+ ")" [with
1554 * [where <qual>] is not supported anymore
1555 *****************************************************************************/
1557 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1558 access_method_clause '(' index_params ')' opt_with
1560 /* should check that access_method is valid,
1561 etc ... but doesn't */
1562 IndexStmt *n = makeNode(IndexStmt);
1566 n->accessMethod = $7;
1567 n->indexParams = $9;
1568 n->withClause = $11;
1569 n->whereClause = NULL;
1574 index_opt_unique: UNIQUE { $$ = TRUE; }
1575 | /*EMPTY*/ { $$ = FALSE; }
1578 access_method_clause: USING access_method { $$ = $2; }
1579 | /*EMPTY*/ { $$ = "btree"; }
1582 index_params: index_list { $$ = $1; }
1583 | func_index { $$ = lcons($1,NIL); }
1586 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1587 | index_elem { $$ = lcons($1, NIL); }
1590 func_index: func_name '(' name_list ')' opt_type opt_class
1592 $$ = makeNode(IndexElem);
1600 index_elem: attr_name opt_type opt_class
1602 $$ = makeNode(IndexElem);
1610 opt_type: ':' Typename { $$ = $2; }
1611 | FOR Typename { $$ = $2; }
1612 | /*EMPTY*/ { $$ = NULL; }
1615 /* opt_class "WITH class" conflicts with preceeding opt_type
1616 * for Typename of "TIMESTAMP WITH TIME ZONE"
1617 * So, remove "WITH class" from the syntax. OK??
1618 * - thomas 1997-10-12
1619 * | WITH class { $$ = $2; }
1621 opt_class: class { $$ = $1; }
1622 | USING class { $$ = $2; }
1623 | /*EMPTY*/ { $$ = NULL; }
1627 /*****************************************************************************
1630 * extend index <indexname> [where <qual>]
1632 *****************************************************************************/
1634 ExtendStmt: EXTEND INDEX index_name where_clause
1636 ExtendStmt *n = makeNode(ExtendStmt);
1638 n->whereClause = $4;
1644 /*****************************************************************************
1647 * execute recipe <recipeName>
1649 *****************************************************************************/
1651 RecipeStmt: EXECUTE RECIPE recipe_name
1654 if (!IsTransactionBlock())
1655 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1657 n = makeNode(RecipeStmt);
1664 /*****************************************************************************
1667 * define function <fname>
1668 * (language = <lang>, returntype = <typename>
1669 * [, arch_pct = <percentage | pre-defined>]
1670 * [, disk_pct = <percentage | pre-defined>]
1671 * [, byte_pct = <percentage | pre-defined>]
1672 * [, perbyte_cpu = <int | pre-defined>]
1673 * [, percall_cpu = <int | pre-defined>]
1675 * [arg is (<type-1> { , <type-n>})]
1676 * as <filename or code in language as appropriate>
1678 *****************************************************************************/
1680 ProcedureStmt: CREATE FUNCTION func_name func_args
1681 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
1683 ProcedureStmt *n = makeNode(ProcedureStmt);
1693 opt_with: WITH definition { $$ = $2; }
1694 | /*EMPTY*/ { $$ = NIL; }
1697 func_args: '(' func_args_list ')' { $$ = $2; }
1698 | '(' ')' { $$ = NIL; }
1701 func_args_list: TypeId
1702 { $$ = lcons(makeString($1),NIL); }
1703 | func_args_list ',' TypeId
1704 { $$ = lappend($1,makeString($3)); }
1707 func_return: set_opt TypeId
1709 TypeName *n = makeNode(TypeName);
1712 n->arrayBounds = NULL;
1717 set_opt: SETOF { $$ = TRUE; }
1718 | /*EMPTY*/ { $$ = FALSE; }
1721 /*****************************************************************************
1725 * remove function <funcname>
1726 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1727 * remove aggregate <aggname>
1728 * (REMOVE AGGREGATE "aggname" "aggtype")
1729 * remove operator <opname>
1730 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1731 * remove type <typename>
1732 * (REMOVE TYPE "typename")
1733 * remove rule <rulename>
1734 * (REMOVE RULE "rulename")
1736 *****************************************************************************/
1738 RemoveStmt: DROP remove_type name
1740 RemoveStmt *n = makeNode(RemoveStmt);
1747 remove_type: TYPE_P { $$ = TYPE_P; }
1748 | INDEX { $$ = INDEX; }
1749 | RULE { $$ = RULE; }
1750 | VIEW { $$ = VIEW; }
1754 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1756 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1763 aggr_argtype: name { $$ = $1; }
1764 | '*' { $$ = NULL; }
1768 RemoveFuncStmt: DROP FUNCTION func_name func_args
1770 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1778 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1780 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1787 all_Op: Op | MathOp;
1789 MathOp: '+' { $$ = "+"; }
1800 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1803 { $$ = makeList(makeString($1), makeString($3), -1); }
1804 | NONE ',' name /* left unary */
1805 { $$ = makeList(NULL, makeString($3), -1); }
1806 | name ',' NONE /* right unary */
1807 { $$ = makeList(makeString($1), NULL, -1); }
1811 /*****************************************************************************
1814 * rename <attrname1> in <relname> [*] to <attrname2>
1815 * rename <relname1> to <relname2>
1817 *****************************************************************************/
1819 RenameStmt: ALTER TABLE relation_name opt_inh_star
1820 RENAME opt_column opt_name TO name
1822 RenameStmt *n = makeNode(RenameStmt);
1831 opt_name: name { $$ = $1; }
1832 | /*EMPTY*/ { $$ = NULL; }
1835 opt_column: COLUMN { $$ = COLUMN; }
1836 | /*EMPTY*/ { $$ = 0; }
1840 /*****************************************************************************
1842 * QUERY: Define Rewrite Rule , Define Tuple Rule
1843 * Define Rule <old rules >
1845 * only rewrite rule is supported -- ay 9/94
1847 *****************************************************************************/
1849 RuleStmt: CREATE RULE name AS
1850 { QueryIsRule=TRUE; }
1851 ON event TO event_object where_clause
1852 DO opt_instead OptStmtList
1854 RuleStmt *n = makeNode(RuleStmt);
1858 n->whereClause = $10;
1865 OptStmtList: NOTHING { $$ = NIL; }
1866 | OptimizableStmt { $$ = lcons($1, NIL); }
1867 | '[' OptStmtBlock ']' { $$ = $2; }
1870 OptStmtBlock: OptStmtMulti
1873 { $$ = lcons($1, NIL); }
1876 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1877 { $$ = lappend($1, $2); }
1878 | OptStmtMulti OptimizableStmt
1879 { $$ = lappend($1, $2); }
1880 | OptimizableStmt ';'
1881 { $$ = lcons($1, NIL); }
1884 event_object: relation_name '.' attr_name
1886 $$ = makeNode(Attr);
1889 $$->attrs = lcons(makeString($3), NIL);
1890 $$->indirection = NIL;
1894 $$ = makeNode(Attr);
1898 $$->indirection = NIL;
1902 /* change me to select, update, etc. some day */
1903 event: SELECT { $$ = CMD_SELECT; }
1904 | UPDATE { $$ = CMD_UPDATE; }
1905 | DELETE { $$ = CMD_DELETE; }
1906 | INSERT { $$ = CMD_INSERT; }
1909 opt_instead: INSTEAD { $$ = TRUE; }
1910 | /*EMPTY*/ { $$ = FALSE; }
1914 /*****************************************************************************
1917 * NOTIFY <relation_name> can appear both in rule bodies and
1918 * as a query-level command
1920 *****************************************************************************/
1922 NotifyStmt: NOTIFY relation_name
1924 NotifyStmt *n = makeNode(NotifyStmt);
1930 ListenStmt: LISTEN relation_name
1932 ListenStmt *n = makeNode(ListenStmt);
1939 /*****************************************************************************
1950 *****************************************************************************/
1952 TransactionStmt: ABORT_TRANS TRANSACTION
1954 TransactionStmt *n = makeNode(TransactionStmt);
1955 n->command = ABORT_TRANS;
1958 | BEGIN_TRANS TRANSACTION
1960 TransactionStmt *n = makeNode(TransactionStmt);
1961 n->command = BEGIN_TRANS;
1966 TransactionStmt *n = makeNode(TransactionStmt);
1967 n->command = BEGIN_TRANS;
1972 TransactionStmt *n = makeNode(TransactionStmt);
1973 n->command = END_TRANS;
1976 | END_TRANS TRANSACTION
1978 TransactionStmt *n = makeNode(TransactionStmt);
1979 n->command = END_TRANS;
1984 TransactionStmt *n = makeNode(TransactionStmt);
1985 n->command = ABORT_TRANS;
1991 TransactionStmt *n = makeNode(TransactionStmt);
1992 n->command = ABORT_TRANS;
1997 TransactionStmt *n = makeNode(TransactionStmt);
1998 n->command = BEGIN_TRANS;
2003 TransactionStmt *n = makeNode(TransactionStmt);
2004 n->command = END_TRANS;
2010 TransactionStmt *n = makeNode(TransactionStmt);
2011 n->command = END_TRANS;
2016 TransactionStmt *n = makeNode(TransactionStmt);
2017 n->command = ABORT_TRANS;
2023 /*****************************************************************************
2026 * define view <viewname> '('target-list ')' [where <quals> ]
2028 *****************************************************************************/
2030 ViewStmt: CREATE VIEW name AS SelectStmt
2032 ViewStmt *n = makeNode(ViewStmt);
2034 n->query = (Query *)$5;
2035 if (((SelectStmt *)n->query)->sortClause != NULL)
2036 elog(ERROR,"Order by and Distinct on views is not implemented.");
2037 if (((SelectStmt *)n->query)->unionClause != NULL)
2038 elog(ERROR,"Views on unions not implemented.");
2044 /*****************************************************************************
2049 *****************************************************************************/
2051 LoadStmt: LOAD file_name
2053 LoadStmt *n = makeNode(LoadStmt);
2060 /*****************************************************************************
2065 *****************************************************************************/
2067 CreatedbStmt: CREATE DATABASE database_name opt_database
2069 CreatedbStmt *n = makeNode(CreatedbStmt);
2076 opt_database: WITH LOCATION '=' location { $$ = $4; }
2077 | /*EMPTY*/ { $$ = NULL; }
2080 location: Sconst { $$ = $1; }
2081 | DEFAULT { $$ = NULL; }
2082 | /*EMPTY*/ { $$ = NULL; }
2085 /*****************************************************************************
2090 *****************************************************************************/
2092 DestroydbStmt: DROP DATABASE database_name
2094 DestroydbStmt *n = makeNode(DestroydbStmt);
2101 /*****************************************************************************
2104 * cluster <index_name> on <relation_name>
2106 *****************************************************************************/
2108 ClusterStmt: CLUSTER index_name ON relation_name
2110 ClusterStmt *n = makeNode(ClusterStmt);
2118 /*****************************************************************************
2123 *****************************************************************************/
2125 VacuumStmt: VACUUM opt_verbose opt_analyze
2127 VacuumStmt *n = makeNode(VacuumStmt);
2134 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2136 VacuumStmt *n = makeNode(VacuumStmt);
2141 if ( $5 != NIL && !$4 )
2142 elog(ERROR,"parser: syntax error at or near \"(\"");
2147 opt_verbose: VERBOSE { $$ = TRUE; }
2148 | /*EMPTY*/ { $$ = FALSE; }
2151 opt_analyze: ANALYZE { $$ = TRUE; }
2152 | /*EMPTY*/ { $$ = FALSE; }
2155 opt_va_list: '(' va_list ')' { $$ = $2; }
2156 | /*EMPTY*/ { $$ = NIL; }
2160 { $$=lcons($1,NIL); }
2162 { $$=lappend($1,$3); }
2166 /*****************************************************************************
2171 *****************************************************************************/
2173 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2175 ExplainStmt *n = makeNode(ExplainStmt);
2177 n->query = (Query*)$3;
2183 /*****************************************************************************
2185 * Optimizable Stmts: *
2187 * one of the five queries processed by the planner *
2189 * [ultimately] produces query-trees as specified *
2190 * in the query-spec document in ~postgres/ref *
2192 *****************************************************************************/
2194 OptimizableStmt: SelectStmt
2199 | DeleteStmt /* by default all are $$=$1 */
2203 /*****************************************************************************
2208 *****************************************************************************/
2210 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2218 insert_rest: VALUES '(' res_target_list2 ')'
2220 $$ = makeNode(InsertStmt);
2222 $$->targetList = $3;
2223 $$->fromClause = NIL;
2224 $$->whereClause = NULL;
2225 $$->groupClause = NIL;
2226 $$->havingClause = NULL;
2227 $$->unionClause = NIL;
2229 | SELECT opt_unique res_target_list2
2230 from_clause where_clause
2231 group_clause having_clause
2234 $$ = makeNode(InsertStmt);
2236 $$->targetList = $3;
2237 $$->fromClause = $4;
2238 $$->whereClause = $5;
2239 $$->groupClause = $6;
2240 $$->havingClause = $7;
2241 $$->unionClause = $8;
2245 opt_column_list: '(' columnList ')' { $$ = $2; }
2246 | /*EMPTY*/ { $$ = NIL; }
2250 columnList ',' columnElem
2251 { $$ = lappend($1, $3); }
2253 { $$ = lcons($1, NIL); }
2256 columnElem: ColId opt_indirection
2258 Ident *id = makeNode(Ident);
2260 id->indirection = $2;
2266 /*****************************************************************************
2271 *****************************************************************************/
2273 DeleteStmt: DELETE FROM relation_name
2276 DeleteStmt *n = makeNode(DeleteStmt);
2278 n->whereClause = $4;
2284 * Total hack to just lock a table inside a transaction.
2285 * Is it worth making this a separate command, with
2286 * its own node type and file. I don't think so. bjm 1998/1/22
2288 LockStmt: LOCK_P opt_table relation_name
2290 DeleteStmt *n = makeNode(DeleteStmt);
2291 A_Const *c = makeNode(A_Const);
2293 c->val.type = T_String;
2294 c->val.val.str = "f";
2295 c->typename = makeNode(TypeName);
2296 c->typename->name = xlateSqlType("bool");
2297 c->typename->typmod = -1;
2300 n->whereClause = (Node *)c;
2306 /*****************************************************************************
2309 * UpdateStmt (UPDATE)
2311 *****************************************************************************/
2313 UpdateStmt: UPDATE relation_name
2318 UpdateStmt *n = makeNode(UpdateStmt);
2322 n->whereClause = $6;
2328 /*****************************************************************************
2333 *****************************************************************************/
2334 CursorStmt: DECLARE name opt_binary CURSOR FOR
2335 SELECT opt_unique res_target_list2
2336 from_clause where_clause
2337 group_clause having_clause
2338 union_clause sort_clause
2340 SelectStmt *n = makeNode(SelectStmt);
2342 /* from PORTAL name */
2344 * 15 august 1991 -- since 3.0 postgres does locking
2345 * right, we discovered that portals were violating
2346 * locking protocol. portal locks cannot span xacts.
2347 * as a short-term fix, we installed the check here.
2350 if (!IsTransactionBlock())
2351 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2358 n->whereClause = $10;
2359 n->groupClause = $11;
2360 n->havingClause = $12;
2361 n->unionClause = $13;
2362 n->sortClause = $14;
2368 /*****************************************************************************
2373 *****************************************************************************/
2375 SelectStmt: SELECT opt_unique res_target_list2
2376 result from_clause where_clause
2377 group_clause having_clause
2378 union_clause sort_clause
2380 SelectStmt *n = makeNode(SelectStmt);
2385 n->whereClause = $6;
2386 n->groupClause = $7;
2387 n->havingClause = $8;
2388 n->unionClause = $9;
2389 n->sortClause = $10;
2394 union_clause: UNION opt_union select_list
2396 SelectStmt *n = (SelectStmt *)lfirst($3);
2404 select_list: select_list UNION opt_union SubSelect
2406 SelectStmt *n = (SelectStmt *)$4;
2408 $$ = lappend($1, $4);
2411 { $$ = lcons($1, NIL); }
2414 SubSelect: SELECT opt_unique res_target_list2
2415 from_clause where_clause
2416 group_clause having_clause
2418 SelectStmt *n = makeNode(SelectStmt);
2420 n->unionall = FALSE;
2423 n->whereClause = $5;
2424 n->groupClause = $6;
2425 n->havingClause = $7;
2430 result: INTO opt_table relation_name { $$= $3; }
2431 | /*EMPTY*/ { $$ = NULL; }
2434 opt_table: TABLE { $$ = TRUE; }
2435 | /*EMPTY*/ { $$ = FALSE; }
2438 opt_union: ALL { $$ = TRUE; }
2439 | /*EMPTY*/ { $$ = FALSE; }
2442 opt_unique: DISTINCT { $$ = "*"; }
2443 | DISTINCT ON ColId { $$ = $3; }
2444 | ALL { $$ = NULL; }
2445 | /*EMPTY*/ { $$ = NULL; }
2448 sort_clause: ORDER BY sortby_list { $$ = $3; }
2449 | /*EMPTY*/ { $$ = NIL; }
2452 sortby_list: sortby { $$ = lcons($1, NIL); }
2453 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2456 sortby: ColId OptUseOp
2458 $$ = makeNode(SortGroupBy);
2464 | ColId '.' ColId OptUseOp
2466 $$ = makeNode(SortGroupBy);
2474 $$ = makeNode(SortGroupBy);
2482 OptUseOp: USING Op { $$ = $2; }
2483 | USING '<' { $$ = "<"; }
2484 | USING '>' { $$ = ">"; }
2486 | DESC { $$ = ">"; }
2487 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2491 * jimmy bell-style recursive queries aren't supported in the
2494 * ...however, recursive addattr and rename supported. make special
2497 opt_inh_star: '*' { $$ = TRUE; }
2498 | /*EMPTY*/ { $$ = FALSE; }
2501 relation_name_list: name_list;
2504 { $$ = lcons(makeString($1),NIL); }
2505 | name_list ',' name
2506 { $$ = lappend($1,makeString($3)); }
2509 group_clause: GROUP BY groupby_list { $$ = $3; }
2510 | /*EMPTY*/ { $$ = NIL; }
2513 groupby_list: groupby { $$ = lcons($1, NIL); }
2514 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2519 $$ = makeNode(SortGroupBy);
2527 $$ = makeNode(SortGroupBy);
2535 $$ = makeNode(SortGroupBy);
2543 having_clause: HAVING a_expr
2545 /***S*H***/ /* elog(NOTICE, "HAVING not yet supported; ignore clause");*/
2548 | /*EMPTY*/ { $$ = NULL; }
2552 /*****************************************************************************
2554 * clauses common to all Optimizable Stmts:
2558 *****************************************************************************/
2560 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2563 elog(ERROR,"JOIN not yet implemented");
2565 | FROM from_list { $$ = $2; }
2566 | /*EMPTY*/ { $$ = NIL; }
2569 from_list: from_list ',' from_val
2570 { $$ = lappend($1, $3); }
2571 | from_val CROSS JOIN from_val
2572 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2574 { $$ = lcons($1, NIL); }
2577 from_val: relation_expr AS ColLabel
2579 $$ = makeNode(RangeVar);
2583 | relation_expr ColId
2585 $$ = makeNode(RangeVar);
2591 $$ = makeNode(RangeVar);
2597 join_expr: NATURAL join_expr { $$ = NULL; }
2599 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2601 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2603 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2605 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2607 { elog(ERROR,"INNER JOIN not yet implemented"); }
2609 { elog(ERROR,"UNION JOIN not yet implemented"); }
2611 { elog(ERROR,"INNER JOIN not yet implemented"); }
2614 join_outer: OUTER_P { $$ = NULL; }
2615 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2618 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2619 | USING '(' join_list ')' { $$ = NULL; }
2620 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2623 join_list: join_using { $$ = lcons($1, NIL); }
2624 | join_list ',' join_using { $$ = lappend($1, $3); }
2629 $$ = makeNode(SortGroupBy);
2637 $$ = makeNode(SortGroupBy);
2645 $$ = makeNode(SortGroupBy);
2653 where_clause: WHERE a_expr { $$ = $2; }
2654 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2657 relation_expr: relation_name
2659 /* normal relations */
2660 $$ = makeNode(RelExpr);
2664 | relation_name '*' %prec '='
2666 /* inheritance query */
2667 $$ = makeNode(RelExpr);
2672 opt_array_bounds: '[' ']' nest_array_bounds
2673 { $$ = lcons(makeInteger(-1), $3); }
2674 | '[' Iconst ']' nest_array_bounds
2675 { $$ = lcons(makeInteger($2), $4); }
2680 nest_array_bounds: '[' ']' nest_array_bounds
2681 { $$ = lcons(makeInteger(-1), $3); }
2682 | '[' Iconst ']' nest_array_bounds
2683 { $$ = lcons(makeInteger($2), $4); }
2689 /*****************************************************************************
2692 * SQL92 introduces a large amount of type-specific syntax.
2693 * Define individual clauses to handle these cases, and use
2694 * the generic case to handle regular type-extensible Postgres syntax.
2695 * - thomas 1997-10-10
2697 *****************************************************************************/
2699 Typename: Array opt_array_bounds
2702 $$->arrayBounds = $2;
2704 /* Is this the name of a complex type? If so, implement
2707 if (!strcmp(saved_relname, $$->name))
2708 /* This attr is the same type as the relation
2709 * being defined. The classic example: create
2710 * emp(name=text,mgr=emp)
2713 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2714 /* (Eventually add in here that the set can only
2715 * contain one element.)
2736 $$ = makeNode(TypeName);
2737 $$->name = xlateSqlType($1);
2742 generic: IDENT { $$ = $1; }
2743 | TYPE_P { $$ = xlateSqlType("type"); }
2746 /* SQL92 numeric data types
2747 * Check FLOAT() precision limits assuming IEEE floating types.
2748 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2749 * by checking parameters and making sure they match what is possible with INTEGER.
2750 * - thomas 1997-09-18
2752 Numeric: FLOAT opt_float
2754 $$ = makeNode(TypeName);
2755 $$->name = xlateSqlType($2);
2760 $$ = makeNode(TypeName);
2761 $$->name = xlateSqlType("float");
2763 | DECIMAL opt_decimal
2765 $$ = makeNode(TypeName);
2766 $$->name = xlateSqlType("integer");
2769 | NUMERIC opt_numeric
2771 $$ = makeNode(TypeName);
2772 $$->name = xlateSqlType("integer");
2778 { $$ = xlateSqlType("float8"); }
2780 { $$ = xlateSqlType("float8"); }
2782 { $$ = xlateSqlType("decimal"); }
2784 { $$ = xlateSqlType("numeric"); }
2787 opt_float: '(' Iconst ')'
2790 elog(ERROR,"precision for FLOAT must be at least 1");
2792 $$ = xlateSqlType("float4");
2794 $$ = xlateSqlType("float8");
2796 elog(ERROR,"precision for FLOAT must be less than 16");
2800 $$ = xlateSqlType("float8");
2804 opt_numeric: '(' Iconst ',' Iconst ')'
2807 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2809 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2814 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2822 opt_decimal: '(' Iconst ',' Iconst ')'
2825 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2827 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2833 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2842 /* SQL92 character data types
2843 * The following implements CHAR() and VARCHAR().
2844 * We do it here instead of the 'Generic' production
2845 * because we don't want to allow arrays of VARCHAR().
2846 * I haven't thought about whether that will work or not.
2849 Character: character '(' Iconst ')'
2851 $$ = makeNode(TypeName);
2852 if (!strcasecmp($1, "char"))
2853 $$->name = xlateSqlType("bpchar");
2854 else if (!strcasecmp($1, "varchar"))
2855 $$->name = xlateSqlType("varchar");
2857 yyerror("parse error");
2859 elog(ERROR,"length for '%s' type must be at least 1",$1);
2861 /* we can store a char() of length up to the size
2862 * of a page (8KB) - page headers and friends but
2863 * just to be safe here... - ay 6/95
2864 * XXX note this hardcoded limit - thomas 1997-07-13
2866 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2868 /* we actually implement this sort of like a varlen, so
2869 * the first 4 bytes is the length. (the difference
2870 * between this and "text" is that we blank-pad and
2871 * truncate where necessary
2873 $$->typmod = VARHDRSZ + $3;
2877 $$ = makeNode(TypeName);
2878 $$->name = xlateSqlType($1);
2883 character: CHARACTER opt_varying opt_charset opt_collate
2886 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2887 if ($2) type = xlateSqlType("varchar");
2888 else type = xlateSqlType("char");
2891 c = palloc(strlen("var") + strlen($3) + 1);
2894 type = xlateSqlType(c);
2896 type = xlateSqlType($3);
2900 elog(ERROR,"COLLATE %s not yet implemented",$4);
2903 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2904 | VARCHAR { $$ = xlateSqlType("varchar"); }
2905 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2906 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2909 opt_varying: VARYING { $$ = TRUE; }
2910 | /*EMPTY*/ { $$ = FALSE; }
2913 opt_charset: CHARACTER SET ColId { $$ = $3; }
2914 | /*EMPTY*/ { $$ = NULL; }
2917 opt_collate: COLLATE ColId { $$ = $2; }
2918 | /*EMPTY*/ { $$ = NULL; }
2923 $$ = makeNode(TypeName);
2924 $$->name = xlateSqlType($1);
2927 | TIMESTAMP opt_timezone
2929 $$ = makeNode(TypeName);
2930 $$->name = xlateSqlType("timestamp");
2936 $$ = makeNode(TypeName);
2937 $$->name = xlateSqlType("time");
2940 | INTERVAL opt_interval
2942 $$ = makeNode(TypeName);
2943 $$->name = xlateSqlType("interval");
2948 datetime: YEAR_P { $$ = "year"; }
2949 | MONTH_P { $$ = "month"; }
2950 | DAY_P { $$ = "day"; }
2951 | HOUR_P { $$ = "hour"; }
2952 | MINUTE_P { $$ = "minute"; }
2953 | SECOND_P { $$ = "second"; }
2956 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2957 | /*EMPTY*/ { $$ = FALSE; }
2960 opt_interval: datetime { $$ = lcons($1, NIL); }
2961 | YEAR_P TO MONTH_P { $$ = NIL; }
2962 | DAY_P TO HOUR_P { $$ = NIL; }
2963 | DAY_P TO MINUTE_P { $$ = NIL; }
2964 | DAY_P TO SECOND_P { $$ = NIL; }
2965 | HOUR_P TO MINUTE_P { $$ = NIL; }
2966 | HOUR_P TO SECOND_P { $$ = NIL; }
2967 | /*EMPTY*/ { $$ = NIL; }
2971 /*****************************************************************************
2973 * expression grammar, still needs some cleanup
2975 *****************************************************************************/
2977 a_expr_or_null: a_expr
2981 A_Const *n = makeNode(A_Const);
2982 n->val.type = T_Null;
2987 /* Expressions using row descriptors
2988 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2989 * with singleton expressions.
2991 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2993 SubLink *n = makeNode(SubLink);
2995 n->oper = lcons("=",NIL);
2997 n->subLinkType = ANY_SUBLINK;
3001 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
3003 SubLink *n = makeNode(SubLink);
3005 n->oper = lcons("<>",NIL);
3007 n->subLinkType = ALL_SUBLINK;
3011 | '(' row_descriptor ')' Op '(' SubSelect ')'
3013 SubLink *n = makeNode(SubLink);
3015 n->oper = lcons($4, NIL);
3016 if (strcmp($4,"<>") == 0)
3020 n->subLinkType = EXPR_SUBLINK;
3024 | '(' row_descriptor ')' '+' '(' SubSelect ')'
3026 SubLink *n = makeNode(SubLink);
3028 n->oper = lcons("+", NIL);
3030 n->subLinkType = EXPR_SUBLINK;
3034 | '(' row_descriptor ')' '-' '(' SubSelect ')'
3036 SubLink *n = makeNode(SubLink);
3038 n->oper = lcons("-", NIL);
3040 n->subLinkType = EXPR_SUBLINK;
3044 | '(' row_descriptor ')' '/' '(' SubSelect ')'
3046 SubLink *n = makeNode(SubLink);
3048 n->oper = lcons("/", NIL);
3050 n->subLinkType = EXPR_SUBLINK;
3054 | '(' row_descriptor ')' '*' '(' SubSelect ')'
3056 SubLink *n = makeNode(SubLink);
3058 n->oper = lcons("*", NIL);
3060 n->subLinkType = EXPR_SUBLINK;
3064 | '(' row_descriptor ')' '<' '(' SubSelect ')'
3066 SubLink *n = makeNode(SubLink);
3068 n->oper = lcons("<", NIL);
3070 n->subLinkType = EXPR_SUBLINK;
3074 | '(' row_descriptor ')' '>' '(' SubSelect ')'
3076 SubLink *n = makeNode(SubLink);
3078 n->oper = lcons(">", NIL);
3080 n->subLinkType = EXPR_SUBLINK;
3084 | '(' row_descriptor ')' '=' '(' SubSelect ')'
3086 SubLink *n = makeNode(SubLink);
3088 n->oper = lcons("=", NIL);
3090 n->subLinkType = EXPR_SUBLINK;
3094 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
3096 SubLink *n = makeNode(SubLink);
3098 n->oper = lcons($4,NIL);
3099 if (strcmp($4,"<>") == 0)
3103 n->subLinkType = ANY_SUBLINK;
3107 | '(' row_descriptor ')' '+' ANY '(' SubSelect ')'
3109 SubLink *n = makeNode(SubLink);
3111 n->oper = lcons("+",NIL);
3113 n->subLinkType = ANY_SUBLINK;
3117 | '(' row_descriptor ')' '-' ANY '(' SubSelect ')'
3119 SubLink *n = makeNode(SubLink);
3121 n->oper = lcons("-",NIL);
3123 n->subLinkType = ANY_SUBLINK;
3127 | '(' row_descriptor ')' '/' ANY '(' SubSelect ')'
3129 SubLink *n = makeNode(SubLink);
3131 n->oper = lcons("/",NIL);
3133 n->subLinkType = ANY_SUBLINK;
3137 | '(' row_descriptor ')' '*' ANY '(' SubSelect ')'
3139 SubLink *n = makeNode(SubLink);
3141 n->oper = lcons("*",NIL);
3143 n->subLinkType = ANY_SUBLINK;
3147 | '(' row_descriptor ')' '<' ANY '(' SubSelect ')'
3149 SubLink *n = makeNode(SubLink);
3151 n->oper = lcons("<",NIL);
3153 n->subLinkType = ANY_SUBLINK;
3157 | '(' row_descriptor ')' '>' ANY '(' SubSelect ')'
3159 SubLink *n = makeNode(SubLink);
3161 n->oper = lcons(">",NIL);
3163 n->subLinkType = ANY_SUBLINK;
3167 | '(' row_descriptor ')' '=' ANY '(' SubSelect ')'
3169 SubLink *n = makeNode(SubLink);
3171 n->oper = lcons("=",NIL);
3173 n->subLinkType = ANY_SUBLINK;
3177 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
3179 SubLink *n = makeNode(SubLink);
3181 n->oper = lcons($4,NIL);
3182 if (strcmp($4,"<>") == 0)
3186 n->subLinkType = ALL_SUBLINK;
3190 | '(' row_descriptor ')' '+' ALL '(' SubSelect ')'
3192 SubLink *n = makeNode(SubLink);
3194 n->oper = lcons("+",NIL);
3196 n->subLinkType = ALL_SUBLINK;
3200 | '(' row_descriptor ')' '-' ALL '(' SubSelect ')'
3202 SubLink *n = makeNode(SubLink);
3204 n->oper = lcons("-",NIL);
3206 n->subLinkType = ALL_SUBLINK;
3210 | '(' row_descriptor ')' '/' ALL '(' SubSelect ')'
3212 SubLink *n = makeNode(SubLink);
3214 n->oper = lcons("/",NIL);
3216 n->subLinkType = ALL_SUBLINK;
3220 | '(' row_descriptor ')' '*' ALL '(' SubSelect ')'
3222 SubLink *n = makeNode(SubLink);
3224 n->oper = lcons("*",NIL);
3226 n->subLinkType = ALL_SUBLINK;
3230 | '(' row_descriptor ')' '<' ALL '(' SubSelect ')'
3232 SubLink *n = makeNode(SubLink);
3234 n->oper = lcons("<",NIL);
3236 n->subLinkType = ALL_SUBLINK;
3240 | '(' row_descriptor ')' '>' ALL '(' SubSelect ')'
3242 SubLink *n = makeNode(SubLink);
3244 n->oper = lcons(">",NIL);
3246 n->subLinkType = ALL_SUBLINK;
3250 | '(' row_descriptor ')' '=' ALL '(' SubSelect ')'
3252 SubLink *n = makeNode(SubLink);
3254 n->oper = lcons("=",NIL);
3256 n->subLinkType = ALL_SUBLINK;
3260 | '(' row_descriptor ')' Op '(' row_descriptor ')'
3262 $$ = makeRowExpr($4, $2, $6);
3264 | '(' row_descriptor ')' '+' '(' row_descriptor ')'
3266 $$ = makeRowExpr("+", $2, $6);
3268 | '(' row_descriptor ')' '-' '(' row_descriptor ')'
3270 $$ = makeRowExpr("-", $2, $6);
3272 | '(' row_descriptor ')' '/' '(' row_descriptor ')'
3274 $$ = makeRowExpr("/", $2, $6);
3276 | '(' row_descriptor ')' '*' '(' row_descriptor ')'
3278 $$ = makeRowExpr("*", $2, $6);
3280 | '(' row_descriptor ')' '<' '(' row_descriptor ')'
3282 $$ = makeRowExpr("<", $2, $6);
3284 | '(' row_descriptor ')' '>' '(' row_descriptor ')'
3286 $$ = makeRowExpr(">", $2, $6);
3288 | '(' row_descriptor ')' '=' '(' row_descriptor ')'
3290 $$ = makeRowExpr("=", $2, $6);
3294 row_descriptor: row_list ',' a_expr
3296 $$ = lappend($1, $3);
3300 row_list: row_list ',' a_expr
3302 $$ = lappend($1, $3);
3306 $$ = lcons($1, NIL);
3311 * This is the heart of the expression syntax.
3312 * Note that the BETWEEN clause looks similar to a boolean expression
3313 * and so we must define b_expr which is almost the same as a_expr
3314 * but without the boolean expressions.
3315 * All operations are allowed in a BETWEEN clause if surrounded by parens.
3318 a_expr: attr opt_indirection
3320 $1->indirection = $2;
3329 /* could be a column name or a relation_name */
3330 Ident *n = makeNode(Ident);
3332 n->indirection = NULL;
3335 | '-' a_expr %prec UMINUS
3336 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3338 { $$ = makeA_Expr(OP, "+", $1, $3); }
3340 { $$ = makeA_Expr(OP, "-", $1, $3); }
3342 { $$ = makeA_Expr(OP, "/", $1, $3); }
3344 { $$ = makeA_Expr(OP, "*", $1, $3); }
3346 { $$ = makeA_Expr(OP, "<", $1, $3); }
3348 { $$ = makeA_Expr(OP, ">", $1, $3); }
3350 { $$ = makeA_Expr(OP, "=", $1, $3); }
3352 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3354 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3356 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3357 | a_expr TYPECAST Typename
3360 /* AexprConst can be either A_Const or ParamNo */
3361 if (nodeTag($1) == T_A_Const) {
3362 ((A_Const *)$1)->typename = $3;
3363 } else if (nodeTag($1) == T_Param) {
3364 ((ParamNo *)$1)->typename = $3;
3365 /* otherwise, try to transform to a function call */
3367 FuncCall *n = makeNode(FuncCall);
3368 n->funcname = $3->name;
3369 n->args = lcons($1,NIL);
3373 | CAST '(' a_expr AS Typename ')'
3376 /* AexprConst can be either A_Const or ParamNo */
3377 if (nodeTag($3) == T_A_Const) {
3378 ((A_Const *)$3)->typename = $5;
3379 } else if (nodeTag($5) == T_Param) {
3380 ((ParamNo *)$3)->typename = $5;
3381 /* otherwise, try to transform to a function call */
3383 FuncCall *n = makeNode(FuncCall);
3384 n->funcname = $5->name;
3385 n->args = lcons($3,NIL);
3389 | '(' a_expr_or_null ')'
3392 { $$ = makeIndexable($2,$1,$3); }
3393 | a_expr LIKE a_expr
3394 { $$ = makeIndexable("~~", $1, $3); }
3395 | a_expr NOT LIKE a_expr
3396 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3398 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3400 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3401 | func_name '(' '*' ')'
3403 /* cheap hack for aggregate (eg. count) */
3404 FuncCall *n = makeNode(FuncCall);
3405 A_Const *star = makeNode(A_Const);
3407 star->val.type = T_String;
3408 star->val.val.str = "";
3410 n->args = lcons(star, NIL);
3415 FuncCall *n = makeNode(FuncCall);
3420 | func_name '(' expr_list ')'
3422 FuncCall *n = makeNode(FuncCall);
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("date");
3444 A_Const *n = makeNode(A_Const);
3445 TypeName *t = makeNode(TypeName);
3447 n->val.type = T_String;
3448 n->val.val.str = "now";
3451 t->name = xlateSqlType("time");
3457 | CURRENT_TIME '(' Iconst ')'
3459 FuncCall *n = makeNode(FuncCall);
3460 A_Const *s = makeNode(A_Const);
3461 TypeName *t = makeNode(TypeName);
3463 n->funcname = xlateSqlType("time");
3464 n->args = lcons(s, NIL);
3466 s->val.type = T_String;
3467 s->val.val.str = "now";
3470 t->name = xlateSqlType("time");
3475 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3481 A_Const *n = makeNode(A_Const);
3482 TypeName *t = makeNode(TypeName);
3484 n->val.type = T_String;
3485 n->val.val.str = "now";
3488 t->name = xlateSqlType("timestamp");
3494 | CURRENT_TIMESTAMP '(' Iconst ')'
3496 FuncCall *n = makeNode(FuncCall);
3497 A_Const *s = makeNode(A_Const);
3498 TypeName *t = makeNode(TypeName);
3500 n->funcname = xlateSqlType("timestamp");
3501 n->args = lcons(s, NIL);
3503 s->val.type = T_String;
3504 s->val.val.str = "now";
3507 t->name = xlateSqlType("timestamp");
3512 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3518 FuncCall *n = makeNode(FuncCall);
3519 n->funcname = "getpgusername";
3523 | EXISTS '(' SubSelect ')'
3525 SubLink *n = makeNode(SubLink);
3529 n->subLinkType = EXISTS_SUBLINK;
3533 | EXTRACT '(' extract_list ')'
3535 FuncCall *n = makeNode(FuncCall);
3536 n->funcname = "date_part";
3540 | POSITION '(' position_list ')'
3542 FuncCall *n = makeNode(FuncCall);
3543 n->funcname = "strpos";
3547 | SUBSTRING '(' substr_list ')'
3549 FuncCall *n = makeNode(FuncCall);
3550 n->funcname = "substr";
3554 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3555 | TRIM '(' BOTH trim_list ')'
3557 FuncCall *n = makeNode(FuncCall);
3558 n->funcname = "btrim";
3562 | TRIM '(' LEADING trim_list ')'
3564 FuncCall *n = makeNode(FuncCall);
3565 n->funcname = "ltrim";
3569 | TRIM '(' TRAILING trim_list ')'
3571 FuncCall *n = makeNode(FuncCall);
3572 n->funcname = "rtrim";
3576 | TRIM '(' trim_list ')'
3578 FuncCall *n = makeNode(FuncCall);
3579 n->funcname = "btrim";
3584 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3586 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3588 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3589 | a_expr IS NOT NULL_P
3590 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3591 /* IS TRUE, IS FALSE, etc used to be function calls
3592 * but let's make them expressions to allow the optimizer
3593 * a chance to eliminate them if a_expr is a constant string.
3594 * - thomas 1997-12-22
3598 A_Const *n = makeNode(A_Const);
3599 n->val.type = T_String;
3600 n->val.val.str = "t";
3601 n->typename = makeNode(TypeName);
3602 n->typename->name = xlateSqlType("bool");
3603 n->typename->typmod = -1;
3604 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3606 | a_expr IS NOT FALSE_P
3608 A_Const *n = makeNode(A_Const);
3609 n->val.type = T_String;
3610 n->val.val.str = "t";
3611 n->typename = makeNode(TypeName);
3612 n->typename->name = xlateSqlType("bool");
3613 n->typename->typmod = -1;
3614 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3618 A_Const *n = makeNode(A_Const);
3619 n->val.type = T_String;
3620 n->val.val.str = "f";
3621 n->typename = makeNode(TypeName);
3622 n->typename->name = xlateSqlType("bool");
3623 n->typename->typmod = -1;
3624 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3626 | a_expr IS NOT TRUE_P
3628 A_Const *n = makeNode(A_Const);
3629 n->val.type = T_String;
3630 n->val.val.str = "f";
3631 n->typename = makeNode(TypeName);
3632 n->typename->name = xlateSqlType("bool");
3633 n->typename->typmod = -1;
3634 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3636 | a_expr BETWEEN b_expr AND b_expr
3638 $$ = makeA_Expr(AND, NULL,
3639 makeA_Expr(OP, ">=", $1, $3),
3640 makeA_Expr(OP, "<=", $1, $5));
3642 | a_expr NOT BETWEEN b_expr AND b_expr
3644 $$ = makeA_Expr(OR, NULL,
3645 makeA_Expr(OP, "<", $1, $4),
3646 makeA_Expr(OP, ">", $1, $6));
3648 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3650 saved_In_Expr = lnext(saved_In_Expr);
3651 if (nodeTag($5) == T_SubLink)
3653 SubLink *n = (SubLink *)$5;
3654 n->lefthand = lcons($1, NIL);
3655 n->oper = lcons("=",NIL);
3657 n->subLinkType = ANY_SUBLINK;
3662 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
3664 saved_In_Expr = lnext(saved_In_Expr);
3665 if (nodeTag($6) == T_SubLink)
3667 SubLink *n = (SubLink *)$6;
3668 n->lefthand = lcons($1, NIL);
3669 n->oper = lcons("<>",NIL);
3671 n->subLinkType = ALL_SUBLINK;
3676 | a_expr Op '(' SubSelect ')'
3678 SubLink *n = makeNode(SubLink);
3679 n->lefthand = lcons($1, NULL);
3680 n->oper = lcons($2,NIL);
3682 n->subLinkType = EXPR_SUBLINK;
3686 | a_expr '+' '(' SubSelect ')'
3688 SubLink *n = makeNode(SubLink);
3689 n->lefthand = lcons($1, NULL);
3690 n->oper = lcons("+",NIL);
3692 n->subLinkType = EXPR_SUBLINK;
3696 | a_expr '-' '(' SubSelect ')'
3698 SubLink *n = makeNode(SubLink);
3699 n->lefthand = lcons($1, NULL);
3700 n->oper = lcons("-",NIL);
3702 n->subLinkType = EXPR_SUBLINK;
3706 | a_expr '/' '(' SubSelect ')'
3708 SubLink *n = makeNode(SubLink);
3709 n->lefthand = lcons($1, NULL);
3710 n->oper = lcons("/",NIL);
3712 n->subLinkType = EXPR_SUBLINK;
3716 | a_expr '*' '(' SubSelect ')'
3718 SubLink *n = makeNode(SubLink);
3719 n->lefthand = lcons($1, NULL);
3720 n->oper = lcons("*",NIL);
3722 n->subLinkType = EXPR_SUBLINK;
3726 | a_expr '<' '(' SubSelect ')'
3728 SubLink *n = makeNode(SubLink);
3729 n->lefthand = lcons($1, NULL);
3730 n->oper = lcons("<",NIL);
3732 n->subLinkType = EXPR_SUBLINK;
3736 | a_expr '>' '(' SubSelect ')'
3738 SubLink *n = makeNode(SubLink);
3739 n->lefthand = lcons($1, NULL);
3740 n->oper = lcons(">",NIL);
3742 n->subLinkType = EXPR_SUBLINK;
3746 | a_expr '=' '(' SubSelect ')'
3748 SubLink *n = makeNode(SubLink);
3749 n->lefthand = lcons($1, NULL);
3750 n->oper = lcons("=",NIL);
3752 n->subLinkType = EXPR_SUBLINK;
3756 | a_expr Op ANY '(' SubSelect ')'
3758 SubLink *n = makeNode(SubLink);
3759 n->lefthand = lcons($1,NIL);
3760 n->oper = lcons($2,NIL);
3762 n->subLinkType = ANY_SUBLINK;
3766 | a_expr '+' ANY '(' SubSelect ')'
3768 SubLink *n = makeNode(SubLink);
3769 n->lefthand = lcons($1,NIL);
3770 n->oper = lcons("+",NIL);
3772 n->subLinkType = ANY_SUBLINK;
3776 | a_expr '-' ANY '(' SubSelect ')'
3778 SubLink *n = makeNode(SubLink);
3779 n->lefthand = lcons($1,NIL);
3780 n->oper = lcons("-",NIL);
3782 n->subLinkType = ANY_SUBLINK;
3786 | a_expr '/' ANY '(' SubSelect ')'
3788 SubLink *n = makeNode(SubLink);
3789 n->lefthand = lcons($1,NIL);
3790 n->oper = lcons("/",NIL);
3792 n->subLinkType = ANY_SUBLINK;
3796 | a_expr '*' ANY '(' SubSelect ')'
3798 SubLink *n = makeNode(SubLink);
3799 n->lefthand = lcons($1,NIL);
3800 n->oper = lcons("*",NIL);
3802 n->subLinkType = ANY_SUBLINK;
3806 | a_expr '<' ANY '(' SubSelect ')'
3808 SubLink *n = makeNode(SubLink);
3809 n->lefthand = lcons($1,NIL);
3810 n->oper = lcons("<",NIL);
3812 n->subLinkType = ANY_SUBLINK;
3816 | a_expr '>' ANY '(' SubSelect ')'
3818 SubLink *n = makeNode(SubLink);
3819 n->lefthand = lcons($1,NIL);
3820 n->oper = lcons(">",NIL);
3822 n->subLinkType = ANY_SUBLINK;
3826 | a_expr '=' ANY '(' SubSelect ')'
3828 SubLink *n = makeNode(SubLink);
3829 n->lefthand = lcons($1,NIL);
3830 n->oper = lcons("=",NIL);
3832 n->subLinkType = ANY_SUBLINK;
3836 | a_expr Op ALL '(' SubSelect ')'
3838 SubLink *n = makeNode(SubLink);
3839 n->lefthand = lcons($1, NULL);
3840 n->oper = lcons($2,NIL);
3842 n->subLinkType = ALL_SUBLINK;
3846 | a_expr '+' ALL '(' SubSelect ')'
3848 SubLink *n = makeNode(SubLink);
3849 n->lefthand = lcons($1, NULL);
3850 n->oper = lcons("+",NIL);
3852 n->subLinkType = ALL_SUBLINK;
3856 | a_expr '-' ALL '(' SubSelect ')'
3858 SubLink *n = makeNode(SubLink);
3859 n->lefthand = lcons($1, NULL);
3860 n->oper = lcons("-",NIL);
3862 n->subLinkType = ALL_SUBLINK;
3866 | a_expr '/' ALL '(' SubSelect ')'
3868 SubLink *n = makeNode(SubLink);
3869 n->lefthand = lcons($1, NULL);
3870 n->oper = lcons("/",NIL);
3872 n->subLinkType = ALL_SUBLINK;
3876 | a_expr '*' ALL '(' SubSelect ')'
3878 SubLink *n = makeNode(SubLink);
3879 n->lefthand = lcons($1, NULL);
3880 n->oper = lcons("*",NIL);
3882 n->subLinkType = ALL_SUBLINK;
3886 | a_expr '<' ALL '(' SubSelect ')'
3888 SubLink *n = makeNode(SubLink);
3889 n->lefthand = lcons($1, NULL);
3890 n->oper = lcons("<",NIL);
3892 n->subLinkType = ALL_SUBLINK;
3896 | a_expr '>' ALL '(' SubSelect ')'
3898 SubLink *n = makeNode(SubLink);
3899 n->lefthand = lcons($1, NULL);
3900 n->oper = lcons(">",NIL);
3902 n->subLinkType = ALL_SUBLINK;
3906 | a_expr '=' ALL '(' SubSelect ')'
3908 SubLink *n = makeNode(SubLink);
3909 n->lefthand = lcons($1, NULL);
3910 n->oper = lcons("=",NIL);
3912 n->subLinkType = ALL_SUBLINK;
3917 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3919 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3921 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3925 * b_expr is a subset of the complete expression syntax
3926 * defined by a_expr. b_expr is used in BETWEEN clauses
3927 * to eliminate parser ambiguities stemming from the AND keyword.
3930 b_expr: attr opt_indirection
3932 $1->indirection = $2;
3939 /* could be a column name or a relation_name */
3940 Ident *n = makeNode(Ident);
3942 n->indirection = NULL;
3945 | '-' b_expr %prec UMINUS
3946 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3948 { $$ = makeA_Expr(OP, "+", $1, $3); }
3950 { $$ = makeA_Expr(OP, "-", $1, $3); }
3952 { $$ = makeA_Expr(OP, "/", $1, $3); }
3954 { $$ = makeA_Expr(OP, "*", $1, $3); }
3956 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3958 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3960 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3961 | b_expr TYPECAST Typename
3964 /* AexprConst can be either A_Const or ParamNo */
3965 if (nodeTag($1) == T_A_Const) {
3966 ((A_Const *)$1)->typename = $3;
3967 } else if (nodeTag($1) == T_Param) {
3968 ((ParamNo *)$1)->typename = $3;
3969 /* otherwise, try to transform to a function call */
3971 FuncCall *n = makeNode(FuncCall);
3972 n->funcname = $3->name;
3973 n->args = lcons($1,NIL);
3977 | CAST '(' b_expr AS Typename ')'
3980 /* AexprConst can be either A_Const or ParamNo */
3981 if (nodeTag($3) == T_A_Const) {
3982 ((A_Const *)$3)->typename = $5;
3983 } else if (nodeTag($3) == T_Param) {
3984 ((ParamNo *)$3)->typename = $5;
3985 /* otherwise, try to transform to a function call */
3987 FuncCall *n = makeNode(FuncCall);
3988 n->funcname = $5->name;
3989 n->args = lcons($3,NIL);
3996 { $$ = makeIndexable($2,$1,$3); }
3998 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4000 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4003 FuncCall *n = makeNode(FuncCall);
4008 | func_name '(' expr_list ')'
4010 FuncCall *n = makeNode(FuncCall);
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("date");
4032 A_Const *n = makeNode(A_Const);
4033 TypeName *t = makeNode(TypeName);
4035 n->val.type = T_String;
4036 n->val.val.str = "now";
4039 t->name = xlateSqlType("time");
4045 | CURRENT_TIME '(' Iconst ')'
4047 FuncCall *n = makeNode(FuncCall);
4048 A_Const *s = makeNode(A_Const);
4049 TypeName *t = makeNode(TypeName);
4051 n->funcname = xlateSqlType("time");
4052 n->args = lcons(s, NIL);
4054 s->val.type = T_String;
4055 s->val.val.str = "now";
4058 t->name = xlateSqlType("time");
4063 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4069 A_Const *n = makeNode(A_Const);
4070 TypeName *t = makeNode(TypeName);
4072 n->val.type = T_String;
4073 n->val.val.str = "now";
4076 t->name = xlateSqlType("timestamp");
4082 | CURRENT_TIMESTAMP '(' Iconst ')'
4084 FuncCall *n = makeNode(FuncCall);
4085 A_Const *s = makeNode(A_Const);
4086 TypeName *t = makeNode(TypeName);
4088 n->funcname = xlateSqlType("timestamp");
4089 n->args = lcons(s, NIL);
4091 s->val.type = T_String;
4092 s->val.val.str = "now";
4095 t->name = xlateSqlType("timestamp");
4100 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4106 FuncCall *n = makeNode(FuncCall);
4107 n->funcname = "getpgusername";
4111 | POSITION '(' position_list ')'
4113 FuncCall *n = makeNode(FuncCall);
4114 n->funcname = "strpos";
4118 | SUBSTRING '(' substr_list ')'
4120 FuncCall *n = makeNode(FuncCall);
4121 n->funcname = "substr";
4125 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4126 | TRIM '(' BOTH trim_list ')'
4128 FuncCall *n = makeNode(FuncCall);
4129 n->funcname = "btrim";
4133 | TRIM '(' LEADING trim_list ')'
4135 FuncCall *n = makeNode(FuncCall);
4136 n->funcname = "ltrim";
4140 | TRIM '(' TRAILING trim_list ')'
4142 FuncCall *n = makeNode(FuncCall);
4143 n->funcname = "rtrim";
4147 | TRIM '(' trim_list ')'
4149 FuncCall *n = makeNode(FuncCall);
4150 n->funcname = "btrim";
4156 opt_indirection: '[' a_expr ']' opt_indirection
4158 A_Indices *ai = makeNode(A_Indices);
4163 | '[' a_expr ':' a_expr ']' opt_indirection
4165 A_Indices *ai = makeNode(A_Indices);
4174 expr_list: a_expr_or_null
4175 { $$ = lcons($1, NIL); }
4176 | expr_list ',' a_expr_or_null
4177 { $$ = lappend($1, $3); }
4178 | expr_list USING a_expr
4179 { $$ = lappend($1, $3); }
4182 extract_list: extract_arg FROM a_expr
4184 A_Const *n = makeNode(A_Const);
4185 n->val.type = T_String;
4186 n->val.val.str = $1;
4187 $$ = lappend(lcons((Node *)n,NIL), $3);
4193 /* Add in TIMEZONE_HOUR and TIMEZONE_MINUTE for SQL92 compliance
4194 * for next release. Just set up extract_arg for now...
4195 * - thomas 1998-04-08
4197 extract_arg: datetime
4201 position_list: position_expr IN position_expr
4202 { $$ = makeList($3, $1, -1); }
4207 position_expr: attr opt_indirection
4209 $1->indirection = $2;
4214 | '-' position_expr %prec UMINUS
4215 { $$ = makeA_Expr(OP, "-", NULL, $2); }
4216 | position_expr '+' position_expr
4217 { $$ = makeA_Expr(OP, "+", $1, $3); }
4218 | position_expr '-' position_expr
4219 { $$ = makeA_Expr(OP, "-", $1, $3); }
4220 | position_expr '/' position_expr
4221 { $$ = makeA_Expr(OP, "/", $1, $3); }
4222 | position_expr '*' position_expr
4223 { $$ = makeA_Expr(OP, "*", $1, $3); }
4225 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4226 | position_expr TYPECAST Typename
4229 /* AexprConst can be either A_Const or ParamNo */
4230 if (nodeTag($1) == T_A_Const) {
4231 ((A_Const *)$1)->typename = $3;
4232 } else if (nodeTag($1) == T_Param) {
4233 ((ParamNo *)$1)->typename = $3;
4234 /* otherwise, try to transform to a function call */
4236 FuncCall *n = makeNode(FuncCall);
4237 n->funcname = $3->name;
4238 n->args = lcons($1,NIL);
4242 | CAST '(' position_expr AS Typename ')'
4245 /* AexprConst can be either A_Const or ParamNo */
4246 if (nodeTag($3) == T_A_Const) {
4247 ((A_Const *)$3)->typename = $5;
4248 } else if (nodeTag($3) == T_Param) {
4249 ((ParamNo *)$3)->typename = $5;
4250 /* otherwise, try to transform to a function call */
4252 FuncCall *n = makeNode(FuncCall);
4253 n->funcname = $5->name;
4254 n->args = lcons($3,NIL);
4258 | '(' position_expr ')'
4260 | position_expr Op position_expr
4261 { $$ = makeA_Expr(OP, $2, $1, $3); }
4263 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4265 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4268 /* could be a column name or a relation_name */
4269 Ident *n = makeNode(Ident);
4271 n->indirection = NULL;
4276 FuncCall *n = makeNode(FuncCall);
4281 | func_name '(' expr_list ')'
4283 FuncCall *n = makeNode(FuncCall);
4288 | POSITION '(' position_list ')'
4290 FuncCall *n = makeNode(FuncCall);
4291 n->funcname = "strpos";
4295 | SUBSTRING '(' substr_list ')'
4297 FuncCall *n = makeNode(FuncCall);
4298 n->funcname = "substr";
4302 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4303 | TRIM '(' BOTH trim_list ')'
4305 FuncCall *n = makeNode(FuncCall);
4306 n->funcname = "btrim";
4310 | TRIM '(' LEADING trim_list ')'
4312 FuncCall *n = makeNode(FuncCall);
4313 n->funcname = "ltrim";
4317 | TRIM '(' TRAILING trim_list ')'
4319 FuncCall *n = makeNode(FuncCall);
4320 n->funcname = "rtrim";
4324 | TRIM '(' trim_list ')'
4326 FuncCall *n = makeNode(FuncCall);
4327 n->funcname = "btrim";
4333 substr_list: expr_list substr_from substr_for
4335 $$ = nconc(nconc($1,$2),$3);
4341 substr_from: FROM expr_list
4345 A_Const *n = makeNode(A_Const);
4346 n->val.type = T_Integer;
4347 n->val.val.ival = 1;
4348 $$ = lcons((Node *)n,NIL);
4352 substr_for: FOR expr_list
4358 trim_list: a_expr FROM expr_list
4359 { $$ = lappend($3, $1); }
4368 SubLink *n = makeNode(SubLink);
4376 in_expr_nodes: AexprConst
4377 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4378 | in_expr_nodes ',' AexprConst
4379 { $$ = makeA_Expr(OR, NULL, $1,
4380 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4384 not_in_expr: SubSelect
4386 SubLink *n = makeNode(SubLink);
4394 not_in_expr_nodes: AexprConst
4395 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4396 | not_in_expr_nodes ',' AexprConst
4397 { $$ = makeA_Expr(AND, NULL, $1,
4398 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4402 attr: relation_name '.' attrs
4404 $$ = makeNode(Attr);
4408 $$->indirection = NULL;
4412 $$ = makeNode(Attr);
4416 $$->indirection = NULL;
4421 { $$ = lcons(makeString($1), NIL); }
4422 | attrs '.' attr_name
4423 { $$ = lappend($1, makeString($3)); }
4425 { $$ = lappend($1, makeString("*")); }
4429 /*****************************************************************************
4433 *****************************************************************************/
4435 res_target_list: res_target_list ',' res_target_el
4436 { $$ = lappend($1,$3); }
4438 { $$ = lcons($1, NIL); }
4441 ResTarget *rt = makeNode(ResTarget);
4442 Attr *att = makeNode(Attr);
4444 att->paramNo = NULL;
4446 att->indirection = NIL;
4448 rt->indirection = NULL;
4449 rt->val = (Node *)att;
4450 $$ = lcons(rt, NIL);
4454 res_target_el: ColId opt_indirection '=' a_expr_or_null
4456 $$ = makeNode(ResTarget);
4458 $$->indirection = $2;
4459 $$->val = (Node *)$4;
4461 | attr opt_indirection
4463 $$ = makeNode(ResTarget);
4465 $$->indirection = $2;
4466 $$->val = (Node *)$1;
4468 | relation_name '.' '*'
4470 Attr *att = makeNode(Attr);
4472 att->paramNo = NULL;
4473 att->attrs = lcons(makeString("*"), NIL);
4474 att->indirection = NIL;
4475 $$ = makeNode(ResTarget);
4477 $$->indirection = NULL;
4478 $$->val = (Node *)att;
4483 ** target list for select.
4484 ** should get rid of the other but is still needed by the defunct select into
4485 ** and update (uses a subset)
4487 res_target_list2: res_target_list2 ',' res_target_el2
4488 { $$ = lappend($1, $3); }
4490 { $$ = lcons($1, NIL); }
4493 /* AS is not optional because shift/red conflict with unary ops */
4494 res_target_el2: a_expr_or_null AS ColLabel
4496 $$ = makeNode(ResTarget);
4498 $$->indirection = NULL;
4499 $$->val = (Node *)$1;
4503 $$ = makeNode(ResTarget);
4505 $$->indirection = NULL;
4506 $$->val = (Node *)$1;
4508 | relation_name '.' '*'
4510 Attr *att = makeNode(Attr);
4512 att->paramNo = NULL;
4513 att->attrs = lcons(makeString("*"), NIL);
4514 att->indirection = NIL;
4515 $$ = makeNode(ResTarget);
4517 $$->indirection = NULL;
4518 $$->val = (Node *)att;
4522 Attr *att = makeNode(Attr);
4524 att->paramNo = NULL;
4526 att->indirection = NIL;
4527 $$ = makeNode(ResTarget);
4529 $$->indirection = NULL;
4530 $$->val = (Node *)att;
4534 opt_id: ColId { $$ = $1; }
4535 | /* EMPTY */ { $$ = NULL; }
4538 relation_name: SpecialRuleRelation
4541 StrNCpy(saved_relname, $1, NAMEDATALEN);
4545 /* disallow refs to variable system tables */
4546 if (strcmp(LogRelationName, $1) == 0
4547 || strcmp(VariableRelationName, $1) == 0)
4548 elog(ERROR,"%s cannot be accessed by users",$1);
4551 StrNCpy(saved_relname, $1, NAMEDATALEN);
4555 database_name: ColId { $$ = $1; };
4556 access_method: IDENT { $$ = $1; };
4557 attr_name: ColId { $$ = $1; };
4558 class: IDENT { $$ = $1; };
4559 index_name: ColId { $$ = $1; };
4562 * Include date/time keywords as SQL92 extension.
4563 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4565 name: ColId { $$ = $1; };
4566 func_name: ColId { $$ = xlateSqlFunc($1); };
4568 file_name: Sconst { $$ = $1; };
4569 recipe_name: IDENT { $$ = $1; };
4572 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4576 A_Const *n = makeNode(A_Const);
4577 n->val.type = T_Integer;
4578 n->val.val.ival = $1;
4583 A_Const *n = makeNode(A_Const);
4584 n->val.type = T_Float;
4585 n->val.val.dval = $1;
4590 A_Const *n = makeNode(A_Const);
4591 n->val.type = T_String;
4592 n->val.val.str = $1;
4597 A_Const *n = makeNode(A_Const);
4599 n->val.type = T_String;
4600 n->val.val.str = $2;
4604 { $$ = (Node *)$1; }
4607 A_Const *n = makeNode(A_Const);
4608 n->val.type = T_String;
4609 n->val.val.str = "t";
4610 n->typename = makeNode(TypeName);
4611 n->typename->name = xlateSqlType("bool");
4612 n->typename->typmod = -1;
4617 A_Const *n = makeNode(A_Const);
4618 n->val.type = T_String;
4619 n->val.val.str = "f";
4620 n->typename = makeNode(TypeName);
4621 n->typename->name = xlateSqlType("bool");
4622 n->typename->typmod = -1;
4629 $$ = makeNode(ParamNo);
4634 NumConst: Iconst { $$ = makeInteger($1); }
4635 | FCONST { $$ = makeFloat($1); }
4638 Iconst: ICONST { $$ = $1; };
4639 Sconst: SCONST { $$ = $1; };
4640 UserId: IDENT { $$ = $1; };
4642 /* Column and type identifier
4643 * Does not include explicit datetime types
4644 * since these must be decoupled in Typename syntax.
4645 * Use ColId for most identifiers. - thomas 1997-10-21
4648 { $$ = xlateSqlType($1); }
4650 { $$ = xlateSqlType($1); }
4652 { $$ = xlateSqlType($1); }
4654 /* Column identifier
4655 * Include date/time keywords as SQL92 extension.
4656 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4657 * Add other keywords. Note that as the syntax expands,
4658 * some of these keywords will have to be removed from this
4659 * list due to shift/reduce conflicts in yacc. If so, move
4660 * down to the ColLabel entity. - thomas 1997-11-06
4662 ColId: IDENT { $$ = $1; }
4663 | datetime { $$ = $1; }
4664 | ACTION { $$ = "action"; }
4665 | CACHE { $$ = "cache"; }
4666 | CYCLE { $$ = "cycle"; }
4667 | DATABASE { $$ = "database"; }
4668 | DELIMITERS { $$ = "delimiters"; }
4669 | DOUBLE { $$ = "double"; }
4670 | EACH { $$ = "each"; }
4671 | FUNCTION { $$ = "function"; }
4672 | INCREMENT { $$ = "increment"; }
4673 | INDEX { $$ = "index"; }
4674 | KEY { $$ = "key"; }
4675 | LANGUAGE { $$ = "language"; }
4676 | LOCATION { $$ = "location"; }
4677 | MATCH { $$ = "match"; }
4678 | MAXVALUE { $$ = "maxvalue"; }
4679 | MINVALUE { $$ = "minvalue"; }
4680 | OPERATOR { $$ = "operator"; }
4681 | OPTION { $$ = "option"; }
4682 | PASSWORD { $$ = "password"; }
4683 | PRIVILEGES { $$ = "privileges"; }
4684 | RECIPE { $$ = "recipe"; }
4685 | ROW { $$ = "row"; }
4686 | START { $$ = "start"; }
4687 | STATEMENT { $$ = "statement"; }
4688 | TIME { $$ = "time"; }
4689 | TRIGGER { $$ = "trigger"; }
4690 | TYPE_P { $$ = "type"; }
4691 | USER { $$ = "user"; }
4692 | VALID { $$ = "valid"; }
4693 | VERSION { $$ = "version"; }
4694 | ZONE { $$ = "zone"; }
4698 * Allowed labels in "AS" clauses.
4699 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4700 * compatibility. Cannot allow this for column names since the
4701 * syntax would not distinguish between the constant value and
4702 * a column name. - thomas 1997-10-24
4703 * Add other keywords to this list. Note that they appear here
4704 * rather than in ColId if there was a shift/reduce conflict
4705 * when used as a full identifier. - thomas 1997-11-06
4707 ColLabel: ColId { $$ = $1; }
4708 | ARCHIVE { $$ = "archive"; }
4709 | CLUSTER { $$ = "cluster"; }
4710 | CONSTRAINT { $$ = "constraint"; }
4711 | CROSS { $$ = "cross"; }
4712 | FOREIGN { $$ = "foreign"; }
4713 | GROUP { $$ = "group"; }
4714 | LOAD { $$ = "load"; }
4715 | ORDER { $$ = "order"; }
4716 | POSITION { $$ = "position"; }
4717 | PRECISION { $$ = "precision"; }
4718 | TABLE { $$ = "table"; }
4719 | TRANSACTION { $$ = "transaction"; }
4720 | TRUE_P { $$ = "true"; }
4721 | FALSE_P { $$ = "false"; }
4724 SpecialRuleRelation: CURRENT
4729 elog(ERROR,"CURRENT used in non-rule query");
4736 elog(ERROR,"NEW used in non-rule query");
4743 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
4745 A_Expr *a = makeNode(A_Expr);
4754 * Generate separate operator nodes for a single row descriptor expression.
4755 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
4758 makeRowExpr(char *opr, List *largs, List *rargs)
4763 if (length(largs) != length(rargs))
4764 elog(ERROR,"Unequal number of entries in row expression");
4766 if (lnext(largs) != NIL)
4767 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
4769 larg = lfirst(largs);
4770 rarg = lfirst(rargs);
4772 if ((strcmp(opr, "=") == 0)
4773 || (strcmp(opr, "<") == 0)
4774 || (strcmp(opr, "<=") == 0)
4775 || (strcmp(opr, ">") == 0)
4776 || (strcmp(opr, ">=") == 0))
4779 expr = makeA_Expr(OP, opr, larg, rarg);
4781 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4783 else if (strcmp(opr, "<>") == 0)
4786 expr = makeA_Expr(OP, opr, larg, rarg);
4788 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4792 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
4796 while ((largs != NIL) && (rargs != NIL))
4798 larg = lfirst(largs);
4799 rarg = lfirst(rargs);
4802 expr = makeA_Expr(OP, opr, larg, rarg);
4804 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4806 largs = lnext(largs);
4807 rargs = lnext(rargs);
4816 mapTargetColumns(List *src, List *dst)
4821 if (length(src) != length(dst))
4822 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
4824 while ((src != NIL) && (dst != NIL))
4826 s = (ColumnDef *)lfirst(src);
4827 d = (ResTarget *)lfirst(dst);
4829 d->name = s->colname;
4836 } /* mapTargetColumns() */
4838 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
4840 Node *result = NULL;
4842 /* we do this so indexes can be used */
4843 if (strcmp(opname,"~") == 0 ||
4844 strcmp(opname,"~*") == 0)
4846 if (nodeTag(rexpr) == T_A_Const &&
4847 ((A_Const *)rexpr)->val.type == T_String &&
4848 ((A_Const *)rexpr)->val.val.str[0] == '^')
4850 A_Const *n = (A_Const *)rexpr;
4851 char *match_least = palloc(strlen(n->val.val.str)+2);
4852 char *match_most = palloc(strlen(n->val.val.str)+2);
4853 int pos, match_pos=0;
4855 /* skip leading ^ */
4856 for (pos = 1; n->val.val.str[pos]; pos++)
4858 if (n->val.val.str[pos] == '.' ||
4859 n->val.val.str[pos] == '?' ||
4860 n->val.val.str[pos] == '*' ||
4861 n->val.val.str[pos] == '[' ||
4862 n->val.val.str[pos] == '$' ||
4863 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4865 if (n->val.val.str[pos] == '\\')
4867 match_least[match_pos] = n->val.val.str[pos];
4868 match_most[match_pos++] = n->val.val.str[pos];
4873 A_Const *least = makeNode(A_Const);
4874 A_Const *most = makeNode(A_Const);
4876 /* make strings to be used in index use */
4877 match_least[match_pos] = '\0';
4878 match_most[match_pos] = '\377';
4879 match_most[match_pos+1] = '\0';
4880 least->val.type = T_String;
4881 least->val.val.str = match_least;
4882 most->val.type = T_String;
4883 most->val.val.str = match_most;
4884 result = makeA_Expr(AND, NULL,
4885 makeA_Expr(OP, "~", lexpr, rexpr),
4886 makeA_Expr(AND, NULL,
4887 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4888 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4892 else if (strcmp(opname,"~~") == 0)
4894 if (nodeTag(rexpr) == T_A_Const &&
4895 ((A_Const *)rexpr)->val.type == T_String)
4897 A_Const *n = (A_Const *)rexpr;
4898 char *match_least = palloc(strlen(n->val.val.str)+2);
4899 char *match_most = palloc(strlen(n->val.val.str)+2);
4900 int pos, match_pos=0;
4902 for (pos = 0; n->val.val.str[pos]; pos++)
4904 if (n->val.val.str[pos] == '%' &&
4905 n->val.val.str[pos+1] != '%')
4907 if(n->val.val.str[pos] == '_')
4909 if (n->val.val.str[pos] == '\\' ||
4910 n->val.val.str[pos] == '%')
4912 if (n->val.val.str[pos] == '\0')
4914 match_least[match_pos] = n->val.val.str[pos];
4915 match_most[match_pos++] = n->val.val.str[pos];
4920 A_Const *least = makeNode(A_Const);
4921 A_Const *most = makeNode(A_Const);
4923 /* make strings to be used in index use */
4924 match_least[match_pos] = '\0';
4925 match_most[match_pos] = '\377';
4926 match_most[match_pos+1] = '\0';
4927 least->val.type = T_String;
4928 least->val.val.str = match_least;
4929 most->val.type = T_String;
4930 most->val.val.str = match_most;
4931 result = makeA_Expr(AND, NULL,
4932 makeA_Expr(OP, "~~", lexpr, rexpr),
4933 makeA_Expr(AND, NULL,
4934 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4935 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4941 result = makeA_Expr(OP, opname, lexpr, rexpr);
4943 } /* makeIndexable() */
4947 * Convert alternate type names to internal Postgres types.
4948 * Do not convert "float", since that is handled elsewhere
4949 * for FLOAT(p) syntax.
4952 xlateSqlFunc(char *name)
4954 if (!strcasecmp(name,"character_length")
4955 || !strcasecmp(name,"char_length"))
4959 } /* xlateSqlFunc() */
4962 * Convert alternate type names to internal Postgres types.
4965 xlateSqlType(char *name)
4967 if (!strcasecmp(name,"int")
4968 || !strcasecmp(name,"integer"))
4970 else if (!strcasecmp(name, "smallint"))
4972 else if (!strcasecmp(name, "real")
4973 || !strcasecmp(name, "float"))
4975 else if (!strcasecmp(name, "interval"))
4977 else if (!strcasecmp(name, "boolean"))
4981 } /* xlateSqlType() */
4984 void parser_init(Oid *typev, int nargs)
4986 QueryIsRule = FALSE;
4987 saved_relname[0]= '\0';
4988 saved_In_Expr = NULL;
4990 param_type_init(typev, nargs);
4994 /* FlattenStringList()
4995 * Traverse list of string nodes and convert to a single string.
4996 * Used for reconstructing string form of complex expressions.
4998 * Allocate at least one byte for terminator.
5001 FlattenStringList(List *list)
5009 nlist = length(list);
5012 v = (Value *)lfirst(l);
5019 s = (char*) palloc(len+1);
5024 v = (Value *)lfirst(l);
5028 if (l != NIL) strcat(s," ");
5033 printf( "flattened string is \"%s\"\n", s);
5037 } /* FlattenStringList() */
5040 /* makeConstantList()
5041 * Convert constant value node into string node.
5044 makeConstantList( A_Const *n)
5046 char *defval = NULL;
5047 if (nodeTag(n) != T_A_Const) {
5048 elog(ERROR,"Cannot handle non-constant parameter");
5050 } else if (n->val.type == T_Float) {
5051 defval = (char*) palloc(20+1);
5052 sprintf( defval, "%g", n->val.val.dval);
5054 } else if (n->val.type == T_Integer) {
5055 defval = (char*) palloc(20+1);
5056 sprintf( defval, "%ld", n->val.val.ival);
5058 } else if (n->val.type == T_String) {
5059 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
5060 strcpy( defval, "'");
5061 strcat( defval, ((A_Const *) n)->val.val.str);
5062 strcat( defval, "'");
5065 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
5069 printf( "AexprConst argument is \"%s\"\n", defval);
5072 return( lcons( makeString(defval), NIL));
5073 } /* makeConstantList() */
5077 * Check input string for non-lowercase/non-numeric characters.
5078 * Returns either input string or input surrounded by double quotes.
5085 for (cp = rawid; *cp != '\0'; cp++)
5086 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
5089 cp = palloc(strlen(rawid)+1);
5098 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
5107 * keep enough information around fill out the type of param nodes
5108 * used in postquel functions
5111 param_type_init(Oid *typev, int nargs)
5113 pfunc_num_args = nargs;
5114 param_type_info = typev;
5117 Oid param_type(int t)
5119 if ((t > pfunc_num_args) || (t == 0))
5121 return param_type_info[t - 1];