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 1.78 1997/12/06 22:56:42 momjian Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static Node *saved_In_Expr;
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 *xlateSqlType(char *);
65 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
66 static List *makeConstantList( A_Const *node);
67 static char *FlattenStringList(List *list);
68 static char *fmtId(char *rawid);
69 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
70 static void param_type_init(Oid *typev, int nargs);
72 Oid param_type(int t); /* used in parse_expr.c */
74 /* old versions of flex define this as a macro */
88 bool* pboolean; /* for pg_user privileges */
98 SortGroupBy *sortgroupby;
113 AddAttrStmt, ClosePortalStmt,
114 CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
115 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
116 CreatePLangStmt, DropPLangStmt,
117 IndexStmt, ListenStmt, OptimizableStmt,
118 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
119 RemoveFuncStmt, RemoveStmt,
120 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
121 CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
122 ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
123 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
124 CreateUserStmt, AlterUserStmt, DropUserStmt
126 %type <str> opt_database, location
128 %type <pboolean> user_createdb_clause, user_createuser_clause
129 %type <str> user_passwd_clause
130 %type <str> user_valid_clause
131 %type <list> user_group_list, user_group_clause
133 %type <node> SubSelect
134 %type <str> join_expr, join_outer, join_spec
135 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
137 %type <str> TriggerEvents, TriggerFuncArg
139 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
140 database_name, access_method_clause, access_method, attr_name,
141 class, index_name, name, file_name, recipe_name, aggr_argtype
143 %type <str> opt_id, opt_portal_name,
144 all_Op, MathOp, opt_name, opt_unique,
145 result, OptUseOp, opt_class, SpecialRuleRelation
147 %type <str> privileges, operation_commalist, grantee
148 %type <chr> operation, TriggerOneEvent
150 %type <list> stmtblock, stmtmulti,
151 relation_name_list, OptTableElementList,
152 OptInherit, definition,
153 opt_with, def_args, def_name_list, func_argtypes,
154 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
155 opt_column_list, columnList, opt_va_list, va_list,
156 sort_clause, sortby_list, index_params, index_list, name_list,
157 from_clause, from_list, opt_array_bounds, nest_array_bounds,
158 expr_list, attrs, res_target_list, res_target_list2,
159 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
161 %type <list> union_clause, select_list
162 %type <list> join_list
165 %type <boolean> opt_union
167 %type <node> position_expr
168 %type <list> extract_list, position_list
169 %type <list> substr_list, substr_from, substr_for, trim_list
170 %type <list> opt_interval
172 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
173 index_opt_unique, opt_verbose, opt_analyze
175 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
178 %type <ival> fetch_how_many
180 %type <list> OptSeqList
181 %type <defelt> OptSeqElem
183 %type <dstmt> def_rest
184 %type <astmt> insert_rest
186 %type <node> OptTableElement, ConstraintElem
187 %type <node> columnDef, alter_clause
188 %type <defelt> def_elem
189 %type <node> def_arg, columnElem, where_clause,
190 a_expr, a_expr_or_null, AexprConst,
191 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
193 %type <value> NumConst
194 %type <attr> event_object, attr
195 %type <sortgroupby> groupby
196 %type <sortgroupby> sortby
197 %type <ielem> index_elem, func_index
198 %type <range> from_val
199 %type <relexp> relation_expr
200 %type <target> res_target_el, res_target_el2
201 %type <paramno> ParamNo
203 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
204 %type <str> generic, character, datetime
205 %type <str> opt_charset, opt_collate
206 %type <str> opt_float, opt_numeric, opt_decimal
207 %type <boolean> opt_varying, opt_timezone
211 %type <str> Id, var_value, zone_value
212 %type <str> ColId, ColLabel
214 %type <node> TableConstraint
215 %type <list> constraint_expr
216 %type <list> default_expr
217 %type <list> ColQualList
218 %type <node> ColConstraint, ColConstraintElem
219 %type <list> key_actions, key_action
220 %type <str> key_match, key_reference
223 * If you make any token changes, remember to:
224 * - use "yacc -d" and update parse.h
225 * - update the keyword table in parser/keywords.c
228 /* Reserved word tokens
229 * SQL92 syntax has many type-specific constructs.
230 * So, go ahead and make these types reserved words,
231 * and call-out the syntax explicitly.
232 * This gets annoying when trying to also retain Postgres' nice
233 * type-extensible features, but we don't really have a choice.
234 * - thomas 1997-10-11
237 /* Keywords (in SQL92 reserved words) */
238 %token ACTION, ADD, ALL, ALTER, AND, AS, ASC,
239 BEGIN_TRANS, BETWEEN, BOTH, BY,
240 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
241 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
242 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
243 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
244 END_TRANS, EXECUTE, EXISTS, EXTRACT,
245 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
246 GRANT, GROUP, HAVING, HOUR_P,
247 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
248 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
249 MATCH, MINUTE_P, MONTH_P,
250 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NOTNULL, NULL_P, NUMERIC,
251 ON, OPTION, OR, ORDER, OUTER_P,
252 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
253 REFERENCES, REVOKE, RIGHT, ROLLBACK,
254 SECOND_P, SELECT, SET, SUBSTRING,
255 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
256 UNION, UNIQUE, UPDATE, USING,
257 VALUES, VARCHAR, VARYING, VERBOSE, VERSION, VIEW,
258 WHERE, WITH, WORK, YEAR_P, ZONE
260 /* Keywords (in SQL3 reserved words) */
261 %token FALSE_P, TRIGGER, TRUE_P
263 /* Keywords (in SQL92 non-reserved words) */
266 /* Keywords for Postgres support (not in SQL92 reserved words) */
267 %token ABORT_TRANS, ACL, AFTER, AGGREGATE, ANALYZE,
268 APPEND, BACKWARD, BEFORE, BINARY, CHANGE, CLUSTER, COPY,
269 DATABASE, DELIMITERS, DO, EXPLAIN, EXTEND,
270 FORWARD, FUNCTION, HANDLER,
271 INDEX, INHERITS, INSTEAD, ISNULL,
272 LANCOMPILER, LISTEN, LOAD, LOCATION, MERGE, MOVE,
273 NEW, NONE, NOTHING, OIDS, OPERATOR, PROCEDURAL,
274 RECIPE, RENAME, REPLACE, RESET, RETRIEVE, RETURNS, RULE,
275 SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED,
276 VACUUM, VERBOSE, VERSION
278 /* Keywords (obsolete; retain temporarily for parser - thomas 1997-12-04) */
282 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
283 * when some sort of pg_privileges relation is introduced.
287 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
289 /* Special keywords, not in the query language - see the "lex" file */
290 %token <str> IDENT, SCONST, Op
291 %token <ival> ICONST, PARAM
294 /* these are not real. they are here so that they get generated as #define's*/
311 %left '|' /* this is the relation union op, not logical or */
312 /* Unary Operators */
314 %left ';' /* end of statement or natural log */
327 { parsetree = lcons($1,NIL); }
330 stmtmulti: stmtmulti stmt ';'
331 { $$ = lappend($1, $2); }
333 { $$ = lappend($1, $2); }
335 { $$ = lcons($1,NIL); }
380 /*****************************************************************************
382 * Create a new postresql DBMS user
385 *****************************************************************************/
387 CreateUserStmt: CREATE USER Id
390 user_createuser_clause
393 { CreateUserStmt *n = makeNode(CreateUserStmt);
404 /*****************************************************************************
406 * Alter a postresql DBMS user
409 *****************************************************************************/
411 AlterUserStmt: ALTER USER Id
414 user_createuser_clause
417 { AlterUserStmt *n = makeNode(AlterUserStmt);
428 /*****************************************************************************
430 * Drop a postresql DBMS user
433 *****************************************************************************/
435 DropUserStmt: DROP USER Id
436 { DropUserStmt *n = makeNode(DropUserStmt);
442 user_passwd_clause: WITH PASSWORD Id { $$ = $3; }
443 | /*EMPTY*/ { $$ = NULL; }
446 user_createdb_clause: CREATEDB { bool* b;
447 $$ = (b = (bool*)palloc(sizeof(bool)));
450 | NOCREATEDB { bool* b;
451 $$ = (b = (bool*)palloc(sizeof(bool)));
454 | /*EMPTY*/ { $$ = NULL; }
457 user_createuser_clause: CREATEUSER { bool* b;
458 $$ = (b = (bool*)palloc(sizeof(bool)));
461 | NOCREATEUSER { bool* b;
462 $$ = (b = (bool*)palloc(sizeof(bool)));
465 | /*EMPTY*/ { $$ = NULL; }
468 user_group_list: user_group_list ',' Id { $$ = lcons((void*)makeString($3), $1); }
469 | Id { $$ = makeList((void*)makeString($1), NULL); }
472 user_group_clause: IN GROUP user_group_list { $$ = $3; }
473 | /*EMPTY*/ { $$ = NULL; }
476 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
477 | /*EMPTY*/ { $$ = NULL; }
480 /*****************************************************************************
482 * Set PG internal variable
483 * SET name TO 'var_value'
484 * Include SQL92 syntax (thomas 1997-10-22):
485 * SET TIME ZONE 'var_value'
487 *****************************************************************************/
489 VariableSetStmt: SET ColId TO var_value
491 VariableSetStmt *n = makeNode(VariableSetStmt);
496 | SET ColId '=' var_value
498 VariableSetStmt *n = makeNode(VariableSetStmt);
503 | SET TIME ZONE zone_value
505 VariableSetStmt *n = makeNode(VariableSetStmt);
506 n->name = "timezone";
512 var_value: Sconst { $$ = $1; }
513 | DEFAULT { $$ = NULL; }
516 zone_value: Sconst { $$ = $1; }
517 | DEFAULT { $$ = NULL; }
518 | LOCAL { $$ = "default"; }
521 VariableShowStmt: SHOW ColId
523 VariableShowStmt *n = makeNode(VariableShowStmt);
529 VariableShowStmt *n = makeNode(VariableShowStmt);
530 n->name = "timezone";
535 VariableResetStmt: RESET ColId
537 VariableResetStmt *n = makeNode(VariableResetStmt);
543 VariableResetStmt *n = makeNode(VariableResetStmt);
544 n->name = "timezone";
550 /*****************************************************************************
553 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
555 *****************************************************************************/
557 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
559 AddAttrStmt *n = makeNode(AddAttrStmt);
567 alter_clause: ADD opt_column columnDef
571 | ADD '(' OptTableElementList ')'
573 Node *lp = lfirst($3);
576 elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
579 | DROP opt_column ColId
580 { elog(WARN,"ALTER TABLE/DROP COLUMN not yet implemented",NULL); }
581 | ALTER opt_column ColId SET DEFAULT default_expr
582 { elog(WARN,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented",NULL); }
583 | ALTER opt_column ColId DROP DEFAULT
584 { elog(WARN,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented",NULL); }
586 { elog(WARN,"ALTER TABLE/ADD CONSTRAINT not yet implemented",NULL); }
590 /*****************************************************************************
595 *****************************************************************************/
597 ClosePortalStmt: CLOSE opt_id
599 ClosePortalStmt *n = makeNode(ClosePortalStmt);
606 /*****************************************************************************
609 * COPY [BINARY] <relname> FROM/TO
610 * [USING DELIMITERS <delimiter>]
612 *****************************************************************************/
614 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
616 CopyStmt *n = makeNode(CopyStmt);
634 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
635 * used depends on the direction. (It really doesn't make sense to copy from
636 * stdout. We silently correct the "typo". - AY 9/94
638 copy_file_name: Sconst { $$ = $1; }
639 | STDIN { $$ = NULL; }
640 | STDOUT { $$ = NULL; }
643 opt_binary: BINARY { $$ = TRUE; }
644 | /*EMPTY*/ { $$ = FALSE; }
647 opt_with_copy: WITH OIDS { $$ = TRUE; }
648 | /* EMPTY */ { $$ = FALSE; }
652 * the default copy delimiter is tab but the user can configure it
654 copy_delimiter: USING DELIMITERS Sconst { $$ = $3;}
655 | /* EMPTY */ { $$ = "\t"; }
659 /*****************************************************************************
664 *****************************************************************************/
666 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
667 OptInherit OptArchiveType
669 CreateStmt *n = makeNode(CreateStmt);
673 n->constraints = NIL;
678 OptTableElementList: OptTableElementList ',' OptTableElement
679 { $$ = lappend($1, $3); }
680 | OptTableElement { $$ = lcons($1, NIL); }
681 | /*EMPTY*/ { $$ = NULL; }
684 OptTableElement: columnDef { $$ = $1; }
685 | TableConstraint { $$ = $1; }
688 columnDef: ColId Typename ColQualList
690 ColumnDef *n = makeNode(ColumnDef);
694 n->is_not_null = FALSE;
700 /* ColQualList decodes column-specific qualifiers.
701 * Seem to need to specify the explicit combinations
702 * to eliminate reduce/reduce conflicts.
703 * I think this is because there are no explicit delimiters
704 * (like commas) between clauses.
705 * - thomas 1997-12-03
707 ColQualList: ColConstraint ColConstraint ColConstraint ColConstraint
708 { $$ = lappend(lappend(lappend(lcons($1, NIL), $2), $3), $4); }
709 | ColConstraint ColConstraint ColConstraint
710 { $$ = lappend(lappend(lcons($1, NIL), $2), $3); }
711 | ColConstraint ColConstraint { $$ = lappend(lcons($1, NIL), $2); }
712 | ColConstraint { $$ = lcons($1, NIL); }
713 | /*EMPTY*/ { $$ = NULL; }
717 CONSTRAINT name ColConstraintElem
719 Constraint *n = (Constraint *)$3;
727 ColConstraintElem: CHECK '(' constraint_expr ')'
729 Constraint *n = makeNode(Constraint);
730 n->contype = CONSTR_CHECK;
732 n->def = FlattenStringList($3);
736 | DEFAULT default_expr
738 Constraint *n = makeNode(Constraint);
739 n->contype = CONSTR_DEFAULT;
741 n->def = FlattenStringList($2);
747 Constraint *n = makeNode(Constraint);
748 n->contype = CONSTR_NOTNULL;
756 Constraint *n = makeNode(Constraint);
757 n->contype = CONSTR_NOTNULL;
765 Constraint *n = makeNode(Constraint);
766 n->contype = CONSTR_UNIQUE;
774 Constraint *n = makeNode(Constraint);
775 n->contype = CONSTR_PRIMARY;
781 | REFERENCES ColId opt_column_list key_match key_actions
783 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL);
788 default_expr: AexprConst
789 { $$ = makeConstantList((A_Const *) $1); }
791 { $$ = lcons( makeString("NULL"), NIL); }
792 | '-' default_expr %prec UMINUS
793 { $$ = lcons( makeString( "-"), $2); }
794 | default_expr '+' default_expr
795 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
796 | default_expr '-' default_expr
797 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
798 | default_expr '/' default_expr
799 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
800 | default_expr '*' default_expr
801 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
802 | default_expr '=' default_expr
803 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
804 | default_expr '<' default_expr
805 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
806 | default_expr '>' default_expr
807 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
809 { $$ = lcons( makeString( ":"), $2); }
811 { $$ = lcons( makeString( ";"), $2); }
813 { $$ = lcons( makeString( "|"), $2); }
814 | default_expr TYPECAST Typename
816 $3->name = fmtId($3->name);
817 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
819 | CAST default_expr AS Typename
821 $4->name = fmtId($4->name);
822 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
824 | '(' default_expr ')'
825 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
826 | name '(' default_expr ')'
828 $$ = makeList( makeString($1), makeString("("), -1);
830 $$ = lappend( $$, makeString(")"));
834 $$ = makeList( makeString($1), makeString("("), -1);
835 $$ = lappend( $$, makeString(")"));
837 | default_expr Op default_expr
839 if (!strcmp("<=", $2) || !strcmp(">=", $2))
840 elog(WARN,"boolean expressions not supported in DEFAULT",NULL);
841 $$ = nconc( $1, lcons( makeString( $2), $3));
844 { $$ = lcons( makeString( $1), $2); }
846 { $$ = lappend( $1, makeString( $2)); }
847 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
849 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
851 { $$ = lcons( makeString( "'now'::time"), NIL); }
852 | CURRENT_TIME '(' Iconst ')'
855 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
856 $$ = lcons( makeString( "'now'::time"), NIL);
859 { $$ = lcons( makeString( "now()"), NIL); }
860 | CURRENT_TIMESTAMP '(' Iconst ')'
863 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
864 $$ = lcons( makeString( "now()"), NIL);
867 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
870 /* ConstraintElem specifies constraint syntax which is not embedded into
871 * a column definition. ColConstraintElem specifies the embedded form.
872 * - thomas 1997-12-03
874 TableConstraint: CONSTRAINT name ConstraintElem
876 Constraint *n = (Constraint *)$3;
884 ConstraintElem: CHECK '(' constraint_expr ')'
886 Constraint *n = makeNode(Constraint);
887 n->contype = CONSTR_CHECK;
889 n->def = FlattenStringList($3);
892 | UNIQUE '(' columnList ')'
894 Constraint *n = makeNode(Constraint);
895 n->contype = CONSTR_UNIQUE;
901 | PRIMARY KEY '(' columnList ')'
903 Constraint *n = makeNode(Constraint);
904 n->contype = CONSTR_PRIMARY;
910 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
911 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL); }
914 constraint_expr: AexprConst
915 { $$ = makeConstantList((A_Const *) $1); }
917 { $$ = lcons( makeString("NULL"), NIL); }
920 $$ = lcons( makeString(fmtId($1)), NIL);
922 | '-' constraint_expr %prec UMINUS
923 { $$ = lcons( makeString( "-"), $2); }
924 | constraint_expr '+' constraint_expr
925 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
926 | constraint_expr '-' constraint_expr
927 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
928 | constraint_expr '/' constraint_expr
929 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
930 | constraint_expr '*' constraint_expr
931 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
932 | constraint_expr '=' constraint_expr
933 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
934 | constraint_expr '<' constraint_expr
935 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
936 | constraint_expr '>' constraint_expr
937 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
938 | ':' constraint_expr
939 { $$ = lcons( makeString( ":"), $2); }
940 | ';' constraint_expr
941 { $$ = lcons( makeString( ";"), $2); }
942 | '|' constraint_expr
943 { $$ = lcons( makeString( "|"), $2); }
944 | constraint_expr TYPECAST Typename
946 $3->name = fmtId($3->name);
947 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
949 | CAST constraint_expr AS Typename
951 $4->name = fmtId($4->name);
952 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
954 | '(' constraint_expr ')'
955 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
956 | name '(' constraint_expr ')'
958 $$ = makeList( makeString($1), makeString("("), -1);
960 $$ = lappend( $$, makeString(")"));
962 | constraint_expr Op constraint_expr
963 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
964 | constraint_expr AND constraint_expr
965 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
966 | constraint_expr OR constraint_expr
967 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
969 { $$ = lcons( makeString( $1), $2); }
971 { $$ = lappend( $1, makeString( $2)); }
972 | constraint_expr IS TRUE_P
973 { $$ = lappend( $1, makeString( "IS TRUE")); }
974 | constraint_expr IS FALSE_P
975 { $$ = lappend( $1, makeString( "IS FALSE")); }
976 | constraint_expr IS NOT TRUE_P
977 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
978 | constraint_expr IS NOT FALSE_P
979 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
982 key_match: MATCH FULL { $$ = NULL; }
983 | MATCH PARTIAL { $$ = NULL; }
984 | /*EMPTY*/ { $$ = NULL; }
987 key_actions: key_action key_action { $$ = NIL; }
988 | key_action { $$ = NIL; }
989 | /*EMPTY*/ { $$ = NIL; }
992 key_action: ON DELETE key_reference { $$ = NIL; }
993 | ON UPDATE key_reference { $$ = NIL; }
996 key_reference: NO ACTION { $$ = NULL; }
997 | CASCADE { $$ = NULL; }
998 | SET DEFAULT { $$ = NULL; }
999 | SET NULL_P { $$ = NULL; }
1002 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1003 | /*EMPTY*/ { $$ = NIL; }
1007 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1008 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1010 OptArchiveType: ARCHIVE '=' NONE { }
1015 /*****************************************************************************
1018 * CREATE SEQUENCE seqname
1020 *****************************************************************************/
1022 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1024 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1032 OptSeqList OptSeqElem
1033 { $$ = lappend($1, $2); }
1037 OptSeqElem: IDENT NumConst
1039 $$ = makeNode(DefElem);
1041 $$->arg = (Node *)$2;
1045 $$ = makeNode(DefElem);
1047 $$->arg = (Node *)NULL;
1051 /*****************************************************************************
1054 * CREATE PROCEDURAL LANGUAGE ...
1055 * DROP PROCEDURAL LANGUAGE ...
1057 *****************************************************************************/
1059 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1060 HANDLER def_name LANCOMPILER Sconst
1062 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1071 PLangTrusted: TRUSTED { $$ = TRUE; }
1074 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1076 DropPLangStmt *n = makeNode(DropPLangStmt);
1082 /*****************************************************************************
1085 * CREATE TRIGGER ...
1088 *****************************************************************************/
1090 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1091 relation_name TriggerForSpec EXECUTE PROCEDURE
1092 name '(' TriggerFuncArgs ')'
1094 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1101 memcpy (n->actions, $5, 4);
1106 TriggerActionTime: BEFORE { $$ = TRUE; }
1107 | AFTER { $$ = FALSE; }
1110 TriggerEvents: TriggerOneEvent
1112 char *e = palloc (4);
1113 e[0] = $1; e[1] = 0; $$ = e;
1115 | TriggerOneEvent OR TriggerOneEvent
1117 char *e = palloc (4);
1118 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1120 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1122 char *e = palloc (4);
1123 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1128 TriggerOneEvent: INSERT { $$ = 'i'; }
1129 | DELETE { $$ = 'd'; }
1130 | UPDATE { $$ = 'u'; }
1133 TriggerForSpec: FOR name name
1135 if ( strcmp ($2, "each") != 0 )
1136 elog(WARN,"parser: syntax error near %s",$2);
1137 if ( strcmp ($3, "row") == 0 )
1139 else if ( strcmp ($3, "statement") == 0 )
1142 elog(WARN,"parser: syntax error near %s",$3);
1146 TriggerFuncArgs: TriggerFuncArg
1147 { $$ = lcons($1, NIL); }
1148 | TriggerFuncArgs ',' TriggerFuncArg
1149 { $$ = lappend($1, $3); }
1154 TriggerFuncArg: ICONST
1156 char *s = (char *) palloc (256);
1157 sprintf (s, "%d", $1);
1162 char *s = (char *) palloc (256);
1163 sprintf (s, "%g", $1);
1166 | Sconst { $$ = $1; }
1167 | IDENT { $$ = $1; }
1170 DropTrigStmt: DROP TRIGGER name ON relation_name
1172 DropTrigStmt *n = makeNode(DropTrigStmt);
1180 /*****************************************************************************
1183 * define (type,operator,aggregate)
1185 *****************************************************************************/
1187 DefineStmt: CREATE def_type def_rest
1194 def_rest: def_name definition
1196 $$ = makeNode(DefineStmt);
1198 $$->definition = $2;
1202 def_type: OPERATOR { $$ = OPERATOR; }
1203 | TYPE_P { $$ = TYPE_P; }
1204 | AGGREGATE { $$ = AGGREGATE; }
1207 def_name: PROCEDURE { $$ = "procedure"; }
1208 | JOIN { $$ = "join"; }
1209 | ColId { $$ = $1; }
1210 | MathOp { $$ = $1; }
1214 definition: '(' def_list ')' { $$ = $2; }
1217 def_list: def_elem { $$ = lcons($1, NIL); }
1218 | def_list ',' def_elem { $$ = lappend($1, $3); }
1221 def_elem: def_name '=' def_arg
1223 $$ = makeNode(DefElem);
1225 $$->arg = (Node *)$3;
1229 $$ = makeNode(DefElem);
1231 $$->arg = (Node *)NULL;
1233 | DEFAULT '=' def_arg
1235 $$ = makeNode(DefElem);
1236 $$->defname = "default";
1237 $$->arg = (Node *)$3;
1241 def_arg: ColId { $$ = (Node *)makeString($1); }
1242 | all_Op { $$ = (Node *)makeString($1); }
1243 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1244 | Sconst { $$ = (Node *)makeString($1); }
1247 TypeName *n = makeNode(TypeName);
1250 n->arrayBounds = NULL;
1253 | DOUBLE { $$ = (Node *)makeString("double"); }
1257 /*****************************************************************************
1260 * destroy <relname1> [, <relname2> .. <relnameN> ]
1262 *****************************************************************************/
1264 DestroyStmt: DROP TABLE relation_name_list
1266 DestroyStmt *n = makeNode(DestroyStmt);
1268 n->sequence = FALSE;
1271 | DROP SEQUENCE relation_name_list
1273 DestroyStmt *n = makeNode(DestroyStmt);
1281 /*****************************************************************************
1284 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1286 *****************************************************************************/
1288 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1290 FetchStmt *n = makeNode(FetchStmt);
1297 | MOVE opt_direction fetch_how_many opt_portal_name
1299 FetchStmt *n = makeNode(FetchStmt);
1308 opt_direction: FORWARD { $$ = FORWARD; }
1309 | BACKWARD { $$ = BACKWARD; }
1310 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1313 fetch_how_many: Iconst
1315 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch",NULL); }
1316 | ALL { $$ = 0; /* 0 means fetch all tuples*/}
1317 | /*EMPTY*/ { $$ = 1; /*default*/ }
1320 opt_portal_name: IN name { $$ = $2;}
1321 | /*EMPTY*/ { $$ = NULL; }
1325 /*****************************************************************************
1328 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1330 *****************************************************************************/
1332 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1334 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1340 privileges: ALL PRIVILEGES
1342 $$ = aclmakepriv("rwaR",0);
1346 $$ = aclmakepriv("rwaR",0);
1348 | operation_commalist
1354 operation_commalist: operation
1356 $$ = aclmakepriv("",$1);
1358 | operation_commalist ',' operation
1360 $$ = aclmakepriv($1,$3);
1367 $$ = ACL_MODE_RD_CHR;
1371 $$ = ACL_MODE_AP_CHR;
1375 $$ = ACL_MODE_WR_CHR;
1379 $$ = ACL_MODE_WR_CHR;
1383 $$ = ACL_MODE_RU_CHR;
1389 $$ = aclmakeuser("A","");
1393 $$ = aclmakeuser("G",$2);
1397 $$ = aclmakeuser("U",$1);
1401 opt_with_grant: WITH GRANT OPTION
1403 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1409 /*****************************************************************************
1412 * REVOKE [privileges] ON [relation_name] FROM [user]
1414 *****************************************************************************/
1416 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1418 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1425 /*****************************************************************************
1428 * create index <indexname> on <relname>
1429 * using <access> "(" (<col> with <op>)+ ")" [with
1432 * [where <qual>] is not supported anymore
1433 *****************************************************************************/
1435 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1436 access_method_clause '(' index_params ')' opt_with
1438 /* should check that access_method is valid,
1439 etc ... but doesn't */
1440 IndexStmt *n = makeNode(IndexStmt);
1444 n->accessMethod = $7;
1445 n->indexParams = $9;
1446 n->withClause = $11;
1447 n->whereClause = NULL;
1452 index_opt_unique: UNIQUE { $$ = TRUE; }
1453 | /*EMPTY*/ { $$ = FALSE; }
1456 access_method_clause: USING access_method { $$ = $2; }
1457 | /*EMPTY*/ { $$ = "btree"; }
1460 index_params: index_list { $$ = $1; }
1461 | func_index { $$ = lcons($1,NIL); }
1464 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1465 | index_elem { $$ = lcons($1, NIL); }
1468 func_index: name '(' name_list ')' opt_type opt_class
1470 $$ = makeNode(IndexElem);
1478 index_elem: attr_name opt_type opt_class
1480 $$ = makeNode(IndexElem);
1488 opt_type: ':' Typename { $$ = $2;}
1489 | FOR Typename { $$ = $2;}
1490 | /*EMPTY*/ { $$ = NULL;}
1493 /* opt_class "WITH class" conflicts with preceeding opt_type
1494 * for Typename of "TIMESTAMP WITH TIME ZONE"
1495 * So, remove "WITH class" from the syntax. OK??
1496 * - thomas 1997-10-12
1497 * | WITH class { $$ = $2; }
1499 opt_class: class { $$ = $1; }
1500 | USING class { $$ = $2; }
1501 | /*EMPTY*/ { $$ = NULL; }
1505 /*****************************************************************************
1508 * extend index <indexname> [where <qual>]
1510 *****************************************************************************/
1512 ExtendStmt: EXTEND INDEX index_name where_clause
1514 ExtendStmt *n = makeNode(ExtendStmt);
1516 n->whereClause = $4;
1522 /*****************************************************************************
1525 * execute recipe <recipeName>
1527 *****************************************************************************/
1529 RecipeStmt: EXECUTE RECIPE recipe_name
1532 if (!IsTransactionBlock())
1533 elog(WARN,"EXECUTE RECIPE may only be used in begin/end transaction blocks",NULL);
1535 n = makeNode(RecipeStmt);
1542 /*****************************************************************************
1545 * define function <fname>
1546 * (language = <lang>, returntype = <typename>
1547 * [, arch_pct = <percentage | pre-defined>]
1548 * [, disk_pct = <percentage | pre-defined>]
1549 * [, byte_pct = <percentage | pre-defined>]
1550 * [, perbyte_cpu = <int | pre-defined>]
1551 * [, percall_cpu = <int | pre-defined>]
1553 * [arg is (<type-1> { , <type-n>})]
1554 * as <filename or code in language as appropriate>
1556 *****************************************************************************/
1558 ProcedureStmt: CREATE FUNCTION def_name def_args
1559 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1561 ProcedureStmt *n = makeNode(ProcedureStmt);
1564 n->returnType = (Node *)$6;
1571 opt_with: WITH definition { $$ = $2; }
1572 | /* EMPTY */ { $$ = NIL; }
1575 def_args: '(' def_name_list ')' { $$ = $2; }
1576 | '(' ')' { $$ = NIL; }
1579 def_name_list: name_list;
1581 /*****************************************************************************
1585 * remove function <funcname>
1586 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1587 * remove aggregate <aggname>
1588 * (REMOVE AGGREGATE "aggname" "aggtype")
1589 * remove operator <opname>
1590 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1591 * remove type <typename>
1592 * (REMOVE TYPE "typename")
1593 * remove rule <rulename>
1594 * (REMOVE RULE "rulename")
1596 *****************************************************************************/
1598 RemoveStmt: DROP remove_type name
1600 RemoveStmt *n = makeNode(RemoveStmt);
1607 remove_type: TYPE_P { $$ = TYPE_P; }
1608 | INDEX { $$ = INDEX; }
1609 | RULE { $$ = RULE; }
1610 | VIEW { $$ = VIEW; }
1613 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1615 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1622 aggr_argtype: name { $$ = $1; }
1623 | '*' { $$ = NULL; }
1626 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1628 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1635 func_argtypes: name_list { $$ = $1; }
1636 | /*EMPTY*/ { $$ = NIL; }
1639 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1641 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1648 all_Op: Op | MathOp;
1650 MathOp: '+' { $$ = "+"; }
1661 elog(WARN,"parser: argument type missing (use NONE for unary operators)",NULL);
1664 { $$ = makeList(makeString($1), makeString($3), -1); }
1665 | NONE ',' name /* left unary */
1666 { $$ = makeList(NULL, makeString($3), -1); }
1667 | name ',' NONE /* right unary */
1668 { $$ = makeList(makeString($1), NULL, -1); }
1672 /*****************************************************************************
1675 * rename <attrname1> in <relname> [*] to <attrname2>
1676 * rename <relname1> to <relname2>
1678 *****************************************************************************/
1680 RenameStmt: ALTER TABLE relation_name opt_inh_star
1681 RENAME opt_column opt_name TO name
1683 RenameStmt *n = makeNode(RenameStmt);
1692 opt_name: name { $$ = $1; }
1693 | /*EMPTY*/ { $$ = NULL; }
1696 opt_column: COLUMN { $$ = COLUMN; }
1697 | /*EMPTY*/ { $$ = 0; }
1701 /*****************************************************************************
1703 * QUERY: Define Rewrite Rule , Define Tuple Rule
1704 * Define Rule <old rules >
1706 * only rewrite rule is supported -- ay 9/94
1708 *****************************************************************************/
1710 RuleStmt: CREATE RULE name AS
1711 { QueryIsRule=TRUE; }
1712 ON event TO event_object where_clause
1713 DO opt_instead OptStmtList
1715 RuleStmt *n = makeNode(RuleStmt);
1719 n->whereClause = $10;
1726 OptStmtList: NOTHING { $$ = NIL; }
1727 | OptimizableStmt { $$ = lcons($1, NIL); }
1728 | '[' OptStmtBlock ']' { $$ = $2; }
1731 OptStmtBlock: OptStmtMulti
1734 { $$ = lcons($1, NIL); }
1737 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1738 { $$ = lappend($1, $2); }
1739 | OptStmtMulti OptimizableStmt
1740 { $$ = lappend($1, $2); }
1741 | OptimizableStmt ';'
1742 { $$ = lcons($1, NIL); }
1745 event_object: relation_name '.' attr_name
1747 $$ = makeNode(Attr);
1750 $$->attrs = lcons(makeString($3), NIL);
1751 $$->indirection = NIL;
1755 $$ = makeNode(Attr);
1759 $$->indirection = NIL;
1763 /* change me to select, update, etc. some day */
1764 event: SELECT { $$ = CMD_SELECT; }
1765 | UPDATE { $$ = CMD_UPDATE; }
1766 | DELETE { $$ = CMD_DELETE; }
1767 | INSERT { $$ = CMD_INSERT; }
1770 opt_instead: INSTEAD { $$ = TRUE; }
1771 | /* EMPTY */ { $$ = FALSE; }
1775 /*****************************************************************************
1778 * NOTIFY <relation_name> can appear both in rule bodies and
1779 * as a query-level command
1781 *****************************************************************************/
1783 NotifyStmt: NOTIFY relation_name
1785 NotifyStmt *n = makeNode(NotifyStmt);
1791 ListenStmt: LISTEN relation_name
1793 ListenStmt *n = makeNode(ListenStmt);
1800 /*****************************************************************************
1811 *****************************************************************************/
1813 TransactionStmt: ABORT_TRANS TRANSACTION
1815 TransactionStmt *n = makeNode(TransactionStmt);
1816 n->command = ABORT_TRANS;
1819 | BEGIN_TRANS TRANSACTION
1821 TransactionStmt *n = makeNode(TransactionStmt);
1822 n->command = BEGIN_TRANS;
1827 TransactionStmt *n = makeNode(TransactionStmt);
1828 n->command = BEGIN_TRANS;
1833 TransactionStmt *n = makeNode(TransactionStmt);
1834 n->command = END_TRANS;
1837 | END_TRANS TRANSACTION
1839 TransactionStmt *n = makeNode(TransactionStmt);
1840 n->command = END_TRANS;
1845 TransactionStmt *n = makeNode(TransactionStmt);
1846 n->command = ABORT_TRANS;
1852 TransactionStmt *n = makeNode(TransactionStmt);
1853 n->command = ABORT_TRANS;
1858 TransactionStmt *n = makeNode(TransactionStmt);
1859 n->command = BEGIN_TRANS;
1864 TransactionStmt *n = makeNode(TransactionStmt);
1865 n->command = END_TRANS;
1871 TransactionStmt *n = makeNode(TransactionStmt);
1872 n->command = END_TRANS;
1877 TransactionStmt *n = makeNode(TransactionStmt);
1878 n->command = ABORT_TRANS;
1884 /*****************************************************************************
1887 * define view <viewname> '('target-list ')' [where <quals> ]
1889 *****************************************************************************/
1891 ViewStmt: CREATE VIEW name AS RetrieveStmt
1893 ViewStmt *n = makeNode(ViewStmt);
1895 n->query = (Query *)$5;
1901 /*****************************************************************************
1906 *****************************************************************************/
1908 LoadStmt: LOAD file_name
1910 LoadStmt *n = makeNode(LoadStmt);
1917 /*****************************************************************************
1922 *****************************************************************************/
1924 CreatedbStmt: CREATE DATABASE database_name opt_database
1926 CreatedbStmt *n = makeNode(CreatedbStmt);
1933 opt_database: WITH LOCATION '=' location { $$ = $4; }
1934 | /*EMPTY*/ { $$ = NULL; }
1937 location: Sconst { $$ = $1; }
1938 | DEFAULT { $$ = NULL; }
1939 | /*EMPTY*/ { $$ = NULL; }
1942 /*****************************************************************************
1947 *****************************************************************************/
1949 DestroydbStmt: DROP DATABASE database_name
1951 DestroydbStmt *n = makeNode(DestroydbStmt);
1958 /*****************************************************************************
1961 * cluster <index_name> on <relation_name>
1963 *****************************************************************************/
1965 ClusterStmt: CLUSTER index_name ON relation_name
1967 ClusterStmt *n = makeNode(ClusterStmt);
1975 /*****************************************************************************
1980 *****************************************************************************/
1982 VacuumStmt: VACUUM opt_verbose opt_analyze
1984 VacuumStmt *n = makeNode(VacuumStmt);
1991 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
1993 VacuumStmt *n = makeNode(VacuumStmt);
1998 if ( $5 != NIL && !$4 )
1999 elog(WARN,"parser: syntax error at or near \"(\"",NULL);
2004 opt_verbose: VERBOSE { $$ = TRUE; }
2005 | /* EMPTY */ { $$ = FALSE; }
2008 opt_analyze: ANALYZE { $$ = TRUE; }
2009 | /* EMPTY */ { $$ = FALSE; }
2012 opt_va_list: '(' va_list ')'
2019 { $$=lcons($1,NIL); }
2021 { $$=lappend($1,$3); }
2025 /*****************************************************************************
2030 *****************************************************************************/
2032 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2034 ExplainStmt *n = makeNode(ExplainStmt);
2036 n->query = (Query*)$3;
2042 /*****************************************************************************
2044 * Optimizable Stmts: *
2046 * one of the five queries processed by the planner *
2048 * [ultimately] produces query-trees as specified *
2049 * in the query-spec document in ~postgres/ref *
2051 *****************************************************************************/
2053 OptimizableStmt: RetrieveStmt
2058 | DeleteStmt /* by default all are $$=$1 */
2062 /*****************************************************************************
2067 *****************************************************************************/
2069 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
2077 insert_rest: VALUES '(' res_target_list2 ')'
2079 $$ = makeNode(AppendStmt);
2080 $$->targetList = $3;
2081 $$->fromClause = NIL;
2082 $$->whereClause = NULL;
2084 | SELECT res_target_list2 from_clause where_clause
2086 $$ = makeNode(AppendStmt);
2087 $$->targetList = $2;
2088 $$->fromClause = $3;
2089 $$->whereClause = $4;
2093 opt_column_list: '(' columnList ')' { $$ = $2; }
2094 | /*EMPTY*/ { $$ = NIL; }
2098 columnList ',' columnElem
2099 { $$ = lappend($1, $3); }
2101 { $$ = lcons($1, NIL); }
2104 columnElem: ColId opt_indirection
2106 Ident *id = makeNode(Ident);
2108 id->indirection = $2;
2114 /*****************************************************************************
2119 *****************************************************************************/
2121 DeleteStmt: DELETE FROM relation_name
2124 DeleteStmt *n = makeNode(DeleteStmt);
2126 n->whereClause = $4;
2132 /*****************************************************************************
2135 * ReplaceStmt (UPDATE)
2137 *****************************************************************************/
2139 ReplaceStmt: UPDATE relation_name
2144 ReplaceStmt *n = makeNode(ReplaceStmt);
2148 n->whereClause = $6;
2154 /*****************************************************************************
2159 *****************************************************************************/
2161 CursorStmt: DECLARE name opt_binary CURSOR FOR
2162 SELECT opt_unique res_target_list2
2163 from_clause where_clause group_clause sort_clause
2165 CursorStmt *n = makeNode(CursorStmt);
2167 /* from PORTAL name */
2169 * 15 august 1991 -- since 3.0 postgres does locking
2170 * right, we discovered that portals were violating
2171 * locking protocol. portal locks cannot span xacts.
2172 * as a short-term fix, we installed the check here.
2175 if (!IsTransactionBlock())
2176 elog(WARN,"Named portals may only be used in begin/end transaction blocks",NULL);
2183 n->whereClause = $10;
2184 n->groupClause = $11;
2185 n->sortClause = $12;
2191 /*****************************************************************************
2196 *****************************************************************************/
2198 RetrieveStmt: SELECT opt_unique res_target_list2
2199 result from_clause where_clause
2200 group_clause having_clause
2201 union_clause sort_clause
2203 RetrieveStmt *n = makeNode(RetrieveStmt);
2208 n->whereClause = $6;
2209 n->groupClause = $7;
2210 n->havingClause = $8;
2211 n->selectClause = $9;
2212 n->sortClause = $10;
2217 union_clause: UNION opt_union select_list { $$ = $3; }
2218 | /*EMPTY*/ { $$ = NIL; }
2221 select_list: select_list UNION opt_union SubSelect
2222 { $$ = lappend($1, $4); }
2224 { $$ = lcons($1, NIL); }
2227 SubSelect: SELECT opt_unique res_target_list2
2228 from_clause where_clause
2229 group_clause having_clause
2231 SubSelect *n = makeNode(SubSelect);
2235 n->whereClause = $5;
2236 n->groupClause = $6;
2237 n->havingClause = $7;
2242 result: INTO TABLE relation_name
2248 opt_union: ALL { $$ = TRUE; }
2249 | /*EMPTY*/ { $$ = FALSE; }
2252 opt_unique: DISTINCT { $$ = "*"; }
2253 | DISTINCT ON ColId { $$ = $3; }
2254 | ALL { $$ = NULL; }
2255 | /*EMPTY*/ { $$ = NULL; }
2258 sort_clause: ORDER BY sortby_list { $$ = $3; }
2259 | /*EMPTY*/ { $$ = NIL; }
2262 sortby_list: sortby { $$ = lcons($1, NIL); }
2263 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2266 sortby: ColId OptUseOp
2268 $$ = makeNode(SortGroupBy);
2274 | ColId '.' ColId OptUseOp
2276 $$ = makeNode(SortGroupBy);
2284 $$ = makeNode(SortGroupBy);
2292 OptUseOp: USING Op { $$ = $2; }
2293 | USING '<' { $$ = "<"; }
2294 | USING '>' { $$ = ">"; }
2296 | DESC { $$ = ">"; }
2297 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2301 * jimmy bell-style recursive queries aren't supported in the
2304 * ...however, recursive addattr and rename supported. make special
2307 * XXX i believe '*' should be the default behavior, but...
2309 opt_inh_star: '*' { $$ = TRUE; }
2310 | /*EMPTY*/ { $$ = FALSE; }
2313 relation_name_list: name_list;
2316 { $$ = lcons(makeString($1),NIL); }
2317 | name_list ',' name
2318 { $$ = lappend($1,makeString($3)); }
2321 group_clause: GROUP BY groupby_list { $$ = $3; }
2322 | /*EMPTY*/ { $$ = NIL; }
2325 groupby_list: groupby { $$ = lcons($1, NIL); }
2326 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2331 $$ = makeNode(SortGroupBy);
2339 $$ = makeNode(SortGroupBy);
2347 $$ = makeNode(SortGroupBy);
2355 having_clause: HAVING a_expr { $$ = $2; }
2356 | /*EMPTY*/ { $$ = NULL; }
2360 /*****************************************************************************
2362 * clauses common to all Optimizable Stmts:
2366 *****************************************************************************/
2368 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2371 elog(WARN,"JOIN not yet implemented",NULL);
2373 | FROM from_list { $$ = $2; }
2374 | /*EMPTY*/ { $$ = NIL; }
2377 from_list: from_list ',' from_val
2378 { $$ = lappend($1, $3); }
2379 | from_val CROSS JOIN from_val
2380 { elog(WARN,"CROSS JOIN not yet implemented",NULL); }
2382 { $$ = lcons($1, NIL); }
2385 from_val: relation_expr AS ColLabel
2387 $$ = makeNode(RangeVar);
2391 | relation_expr ColId
2393 $$ = makeNode(RangeVar);
2399 $$ = makeNode(RangeVar);
2405 join_expr: NATURAL join_expr { $$ = NULL; }
2407 { elog(WARN,"FULL OUTER JOIN not yet implemented",NULL); }
2409 { elog(WARN,"LEFT OUTER JOIN not yet implemented",NULL); }
2411 { elog(WARN,"RIGHT OUTER JOIN not yet implemented",NULL); }
2413 { elog(WARN,"OUTER JOIN not yet implemented",NULL); }
2415 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2417 { elog(WARN,"UNION JOIN not yet implemented",NULL); }
2419 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2422 join_outer: OUTER_P { $$ = NULL; }
2423 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2426 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2427 | USING '(' join_list ')' { $$ = NULL; }
2428 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2431 join_list: join_using { $$ = lcons($1, NIL); }
2432 | join_list ',' join_using { $$ = lappend($1, $3); }
2437 $$ = makeNode(SortGroupBy);
2445 $$ = makeNode(SortGroupBy);
2453 $$ = makeNode(SortGroupBy);
2461 where_clause: WHERE a_expr { $$ = $2; }
2462 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2465 relation_expr: relation_name
2467 /* normal relations */
2468 $$ = makeNode(RelExpr);
2472 | relation_name '*' %prec '='
2474 /* inheiritance query */
2475 $$ = makeNode(RelExpr);
2480 opt_array_bounds: '[' ']' nest_array_bounds
2481 { $$ = lcons(makeInteger(-1), $3); }
2482 | '[' Iconst ']' nest_array_bounds
2483 { $$ = lcons(makeInteger($2), $4); }
2488 nest_array_bounds: '[' ']' nest_array_bounds
2489 { $$ = lcons(makeInteger(-1), $3); }
2490 | '[' Iconst ']' nest_array_bounds
2491 { $$ = lcons(makeInteger($2), $4); }
2497 /*****************************************************************************
2500 * SQL92 introduces a large amount of type-specific syntax.
2501 * Define individual clauses to handle these cases, and use
2502 * the generic case to handle regular type-extensible Postgres syntax.
2503 * - thomas 1997-10-10
2505 *****************************************************************************/
2507 Typename: Array opt_array_bounds
2510 $$->arrayBounds = $2;
2512 /* Is this the name of a complex type? If so, implement
2515 if (!strcmp(saved_relname, $$->name))
2516 /* This attr is the same type as the relation
2517 * being defined. The classic example: create
2518 * emp(name=text,mgr=emp)
2521 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2522 /* (Eventually add in here that the set can only
2523 * contain one element.)
2544 $$ = makeNode(TypeName);
2545 $$->name = xlateSqlType($1);
2549 generic: Id { $$ = $1; }
2550 | TYPE_P { $$ = xlateSqlType("type"); }
2551 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2554 /* SQL92 numeric data types
2555 * Check FLOAT() precision limits assuming IEEE floating types.
2556 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2557 * by checking parameters and making sure they match what is possible with INTEGER.
2558 * - thomas 1997-09-18
2560 Numeric: FLOAT opt_float
2562 $$ = makeNode(TypeName);
2563 $$->name = xlateSqlType($2);
2565 | DECIMAL opt_decimal
2567 $$ = makeNode(TypeName);
2568 $$->name = xlateSqlType("integer");
2570 | NUMERIC opt_numeric
2572 $$ = makeNode(TypeName);
2573 $$->name = xlateSqlType("integer");
2577 opt_float: '(' Iconst ')'
2580 elog(WARN,"precision for FLOAT must be at least 1",NULL);
2582 $$ = xlateSqlType("float4");
2584 $$ = xlateSqlType("float8");
2586 elog(WARN,"precision for FLOAT must be less than 16",NULL);
2590 $$ = xlateSqlType("float8");
2594 opt_numeric: '(' Iconst ',' Iconst ')'
2597 elog(WARN,"NUMERIC precision %d must be 9",$2);
2599 elog(WARN,"NUMERIC scale %d must be zero",$4);
2604 elog(WARN,"NUMERIC precision %d must be 9",$2);
2612 opt_decimal: '(' Iconst ',' Iconst ')'
2615 elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2617 elog(WARN,"DECIMAL scale %d must be zero",$4);
2623 elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2632 /* SQL92 character data types
2633 * The following implements CHAR() and VARCHAR().
2634 * We do it here instead of the 'Generic' production
2635 * because we don't want to allow arrays of VARCHAR().
2636 * I haven't thought about whether that will work or not.
2639 Character: character '(' Iconst ')'
2641 $$ = makeNode(TypeName);
2642 if (!strcasecmp($1, "char"))
2643 $$->name = xlateSqlType("bpchar");
2644 else if (!strcasecmp($1, "varchar"))
2645 $$->name = xlateSqlType("varchar");
2647 yyerror("parse error");
2649 elog(WARN,"length for '%s' type must be at least 1",$1);
2651 /* we can store a char() of length up to the size
2652 * of a page (8KB) - page headers and friends but
2653 * just to be safe here... - ay 6/95
2654 * XXX note this hardcoded limit - thomas 1997-07-13
2656 elog(WARN,"length for type '%s' cannot exceed 4096",$1);
2658 /* we actually implement this sort of like a varlen, so
2659 * the first 4 bytes is the length. (the difference
2660 * between this and "text" is that we blank-pad and
2661 * truncate where necessary
2663 $$->typlen = VARHDRSZ + $3;
2667 $$ = makeNode(TypeName);
2668 $$->name = xlateSqlType($1);
2672 character: CHARACTER opt_varying opt_charset opt_collate
2675 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2676 if ($2) type = xlateSqlType("varchar");
2677 else type = xlateSqlType("char");
2680 c = palloc(strlen("var") + strlen($3) + 1);
2683 type = xlateSqlType(c);
2685 type = xlateSqlType($3);
2689 elog(WARN,"COLLATE %s not yet implemented",$4);
2692 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2693 | VARCHAR { $$ = xlateSqlType("varchar"); }
2694 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2695 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2698 opt_varying: VARYING { $$ = TRUE; }
2699 | /*EMPTY*/ { $$ = FALSE; }
2702 opt_charset: CHARACTER SET ColId { $$ = $3; }
2703 | /*EMPTY*/ { $$ = NULL; }
2706 opt_collate: COLLATE ColId { $$ = $2; }
2707 | /*EMPTY*/ { $$ = NULL; }
2712 $$ = makeNode(TypeName);
2713 $$->name = xlateSqlType($1);
2715 | TIMESTAMP opt_timezone
2717 $$ = makeNode(TypeName);
2718 $$->name = xlateSqlType("timestamp");
2723 $$ = makeNode(TypeName);
2724 $$->name = xlateSqlType("time");
2726 | INTERVAL opt_interval
2728 $$ = makeNode(TypeName);
2729 $$->name = xlateSqlType("interval");
2733 datetime: YEAR_P { $$ = "year"; }
2734 | MONTH_P { $$ = "month"; }
2735 | DAY_P { $$ = "day"; }
2736 | HOUR_P { $$ = "hour"; }
2737 | MINUTE_P { $$ = "minute"; }
2738 | SECOND_P { $$ = "second"; }
2741 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2742 | /*EMPTY*/ { $$ = FALSE; }
2745 opt_interval: datetime { $$ = lcons($1, NIL); }
2746 | YEAR_P TO MONTH_P { $$ = NIL; }
2747 | DAY_P TO HOUR_P { $$ = NIL; }
2748 | DAY_P TO MINUTE_P { $$ = NIL; }
2749 | DAY_P TO SECOND_P { $$ = NIL; }
2750 | HOUR_P TO MINUTE_P { $$ = NIL; }
2751 | HOUR_P TO SECOND_P { $$ = NIL; }
2752 | /* EMPTY */ { $$ = NIL; }
2756 /*****************************************************************************
2758 * expression grammar, still needs some cleanup
2760 *****************************************************************************/
2762 a_expr_or_null: a_expr
2766 A_Const *n = makeNode(A_Const);
2767 n->val.type = T_Null;
2771 a_expr: attr opt_indirection
2773 $1->indirection = $2;
2778 | '-' a_expr %prec UMINUS
2779 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2781 { $$ = makeA_Expr(OP, "+", $1, $3); }
2783 { $$ = makeA_Expr(OP, "-", $1, $3); }
2785 { $$ = makeA_Expr(OP, "/", $1, $3); }
2787 { $$ = makeA_Expr(OP, "*", $1, $3); }
2789 { $$ = makeA_Expr(OP, "<", $1, $3); }
2791 { $$ = makeA_Expr(OP, ">", $1, $3); }
2793 { $$ = makeA_Expr(OP, "=", $1, $3); }
2795 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2797 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2799 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2800 | a_expr TYPECAST Typename
2803 /* AexprConst can be either A_Const or ParamNo */
2804 if (nodeTag($1) == T_A_Const) {
2805 ((A_Const *)$1)->typename = $3;
2806 } else if (nodeTag($1) == T_Param) {
2807 ((ParamNo *)$1)->typename = $3;
2808 /* otherwise, try to transform to a function call */
2810 FuncCall *n = makeNode(FuncCall);
2811 n->funcname = $3->name;
2812 n->args = lcons($1,NIL);
2816 | CAST a_expr AS Typename
2819 /* AexprConst can be either A_Const or ParamNo */
2820 if (nodeTag($2) == T_A_Const) {
2821 ((A_Const *)$2)->typename = $4;
2822 } else if (nodeTag($2) == T_Param) {
2823 ((ParamNo *)$2)->typename = $4;
2824 /* otherwise, try to transform to a function call */
2826 FuncCall *n = makeNode(FuncCall);
2827 n->funcname = $4->name;
2828 n->args = lcons($2,NIL);
2832 | '(' a_expr_or_null ')'
2835 { $$ = makeIndexable($2,$1,$3); }
2836 | a_expr LIKE a_expr
2837 { $$ = makeIndexable("~~", $1, $3); }
2838 | a_expr NOT LIKE a_expr
2839 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
2841 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2843 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2846 /* could be a column name or a relation_name */
2847 Ident *n = makeNode(Ident);
2849 n->indirection = NULL;
2854 FuncCall *n = makeNode(FuncCall);
2855 Ident *star = makeNode(Ident);
2857 /* cheap hack for aggregate (eg. count) */
2860 n->args = lcons(star, NIL);
2865 FuncCall *n = makeNode(FuncCall);
2872 A_Const *n = makeNode(A_Const);
2873 TypeName *t = makeNode(TypeName);
2875 n->val.type = T_String;
2876 n->val.val.str = "now";
2879 t->name = xlateSqlType("date");
2886 A_Const *n = makeNode(A_Const);
2887 TypeName *t = makeNode(TypeName);
2889 n->val.type = T_String;
2890 n->val.val.str = "now";
2893 t->name = xlateSqlType("time");
2898 | CURRENT_TIME '(' Iconst ')'
2900 FuncCall *n = makeNode(FuncCall);
2901 A_Const *s = makeNode(A_Const);
2902 TypeName *t = makeNode(TypeName);
2904 n->funcname = xlateSqlType("time");
2905 n->args = lcons(s, NIL);
2907 s->val.type = T_String;
2908 s->val.val.str = "now";
2911 t->name = xlateSqlType("time");
2915 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
2921 A_Const *n = makeNode(A_Const);
2922 TypeName *t = makeNode(TypeName);
2924 n->val.type = T_String;
2925 n->val.val.str = "now";
2928 t->name = xlateSqlType("timestamp");
2933 | CURRENT_TIMESTAMP '(' Iconst ')'
2935 FuncCall *n = makeNode(FuncCall);
2936 A_Const *s = makeNode(A_Const);
2937 TypeName *t = makeNode(TypeName);
2939 n->funcname = xlateSqlType("timestamp");
2940 n->args = lcons(s, NIL);
2942 s->val.type = T_String;
2943 s->val.val.str = "now";
2946 t->name = xlateSqlType("timestamp");
2950 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
2956 FuncCall *n = makeNode(FuncCall);
2957 n->funcname = "getpgusername";
2961 /* We probably need to define an "exists" node,
2962 * since the optimizer could choose to find only one match.
2963 * Perhaps the first implementation could just check for
2964 * count(*) > 0? - thomas 1997-07-19
2966 | EXISTS '(' SubSelect ')'
2968 elog(WARN,"EXISTS not yet implemented",NULL);
2971 | EXTRACT '(' extract_list ')'
2973 FuncCall *n = makeNode(FuncCall);
2974 n->funcname = "date_part";
2978 | POSITION '(' position_list ')'
2980 FuncCall *n = makeNode(FuncCall);
2981 n->funcname = "strpos";
2985 | SUBSTRING '(' substr_list ')'
2987 FuncCall *n = makeNode(FuncCall);
2988 n->funcname = "substr";
2992 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
2993 | TRIM '(' BOTH trim_list ')'
2995 FuncCall *n = makeNode(FuncCall);
2996 n->funcname = "btrim";
3000 | TRIM '(' LEADING trim_list ')'
3002 FuncCall *n = makeNode(FuncCall);
3003 n->funcname = "ltrim";
3007 | TRIM '(' TRAILING trim_list ')'
3009 FuncCall *n = makeNode(FuncCall);
3010 n->funcname = "rtrim";
3014 | TRIM '(' trim_list ')'
3016 FuncCall *n = makeNode(FuncCall);
3017 n->funcname = "btrim";
3021 | name '(' expr_list ')'
3023 FuncCall *n = makeNode(FuncCall);
3029 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3031 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3033 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3034 | a_expr IS NOT NULL_P
3035 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3038 FuncCall *n = makeNode(FuncCall);
3039 n->funcname = "istrue";
3040 n->args = lcons($1,NIL);
3045 FuncCall *n = makeNode(FuncCall);
3046 n->funcname = "isfalse";
3047 n->args = lcons($1,NIL);
3050 | a_expr IS NOT TRUE_P
3052 FuncCall *n = makeNode(FuncCall);
3053 n->funcname = "isfalse";
3054 n->args = lcons($1,NIL);
3057 | a_expr IS NOT FALSE_P
3059 FuncCall *n = makeNode(FuncCall);
3060 n->funcname = "istrue";
3061 n->args = lcons($1,NIL);
3064 | a_expr BETWEEN AexprConst AND AexprConst
3066 $$ = makeA_Expr(AND, NULL,
3067 makeA_Expr(OP, ">=", $1, $3),
3068 makeA_Expr(OP, "<=", $1, $5));
3070 | a_expr NOT BETWEEN AexprConst AND AexprConst
3072 $$ = makeA_Expr(OR, NULL,
3073 makeA_Expr(OP, "<", $1, $4),
3074 makeA_Expr(OP, ">", $1, $6));
3076 | a_expr IN { saved_In_Expr = $1; } '(' in_expr ')'
3078 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr ')'
3081 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3083 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3085 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3088 opt_indirection: '[' a_expr ']' opt_indirection
3090 A_Indices *ai = makeNode(A_Indices);
3095 | '[' a_expr ':' a_expr ']' opt_indirection
3097 A_Indices *ai = makeNode(A_Indices);
3106 expr_list: a_expr_or_null
3107 { $$ = lcons($1, NIL); }
3108 | expr_list ',' a_expr_or_null
3109 { $$ = lappend($1, $3); }
3110 | expr_list USING a_expr
3111 { $$ = lappend($1, $3); }
3114 extract_list: datetime FROM a_expr
3116 A_Const *n = makeNode(A_Const);
3117 n->val.type = T_String;
3118 n->val.val.str = $1;
3119 $$ = lappend(lcons((Node *)n,NIL), $3);
3125 position_list: position_expr IN position_expr
3126 { $$ = makeList($3, $1, -1); }
3131 position_expr: attr opt_indirection
3133 $1->indirection = $2;
3138 | '-' position_expr %prec UMINUS
3139 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3140 | position_expr '+' position_expr
3141 { $$ = makeA_Expr(OP, "+", $1, $3); }
3142 | position_expr '-' position_expr
3143 { $$ = makeA_Expr(OP, "-", $1, $3); }
3144 | position_expr '/' position_expr
3145 { $$ = makeA_Expr(OP, "/", $1, $3); }
3146 | position_expr '*' position_expr
3147 { $$ = makeA_Expr(OP, "*", $1, $3); }
3149 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3150 | position_expr TYPECAST Typename
3153 /* AexprConst can be either A_Const or ParamNo */
3154 if (nodeTag($1) == T_A_Const) {
3155 ((A_Const *)$1)->typename = $3;
3156 } else if (nodeTag($1) == T_Param) {
3157 ((ParamNo *)$1)->typename = $3;
3158 /* otherwise, try to transform to a function call */
3160 FuncCall *n = makeNode(FuncCall);
3161 n->funcname = $3->name;
3162 n->args = lcons($1,NIL);
3166 | CAST position_expr AS Typename
3169 /* AexprConst can be either A_Const or ParamNo */
3170 if (nodeTag($2) == T_A_Const) {
3171 ((A_Const *)$2)->typename = $4;
3172 } else if (nodeTag($2) == T_Param) {
3173 ((ParamNo *)$2)->typename = $4;
3174 /* otherwise, try to transform to a function call */
3176 FuncCall *n = makeNode(FuncCall);
3177 n->funcname = $4->name;
3178 n->args = lcons($2,NIL);
3182 | '(' position_expr ')'
3184 | position_expr Op position_expr
3185 { $$ = makeA_Expr(OP, $2, $1, $3); }
3187 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3189 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3192 /* could be a column name or a relation_name */
3193 Ident *n = makeNode(Ident);
3195 n->indirection = NULL;
3200 FuncCall *n = makeNode(FuncCall);
3205 | POSITION '(' position_list ')'
3207 FuncCall *n = makeNode(FuncCall);
3208 n->funcname = "strpos";
3212 | SUBSTRING '(' substr_list ')'
3214 FuncCall *n = makeNode(FuncCall);
3215 n->funcname = "substr";
3219 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3220 | TRIM '(' BOTH trim_list ')'
3222 FuncCall *n = makeNode(FuncCall);
3223 n->funcname = "btrim";
3227 | TRIM '(' LEADING trim_list ')'
3229 FuncCall *n = makeNode(FuncCall);
3230 n->funcname = "ltrim";
3234 | TRIM '(' TRAILING trim_list ')'
3236 FuncCall *n = makeNode(FuncCall);
3237 n->funcname = "rtrim";
3241 | TRIM '(' trim_list ')'
3243 FuncCall *n = makeNode(FuncCall);
3244 n->funcname = "btrim";
3248 | name '(' expr_list ')'
3250 FuncCall *n = makeNode(FuncCall);
3257 substr_list: expr_list substr_from substr_for
3259 $$ = nconc(nconc($1,$2),$3);
3265 substr_from: FROM expr_list
3269 A_Const *n = makeNode(A_Const);
3270 n->val.type = T_Integer;
3271 n->val.val.ival = 1;
3272 $$ = lcons((Node *)n,NIL);
3276 substr_for: FOR expr_list
3282 trim_list: a_expr FROM expr_list
3283 { $$ = lappend($3, $1); }
3292 elog(WARN,"IN (SUBSELECT) not yet implemented",NULL);
3299 in_expr_nodes: AexprConst
3300 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
3301 | in_expr_nodes ',' AexprConst
3302 { $$ = makeA_Expr(OR, NULL, $1,
3303 makeA_Expr(OP, "=", saved_In_Expr, $3));
3307 not_in_expr: SubSelect
3309 elog(WARN,"NOT IN (SUBSELECT) not yet implemented",NULL);
3316 not_in_expr_nodes: AexprConst
3317 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
3318 | not_in_expr_nodes ',' AexprConst
3319 { $$ = makeA_Expr(AND, NULL, $1,
3320 makeA_Expr(OP, "<>", saved_In_Expr, $3));
3324 attr: relation_name '.' attrs
3326 $$ = makeNode(Attr);
3330 $$->indirection = NULL;
3334 $$ = makeNode(Attr);
3338 $$->indirection = NULL;
3343 { $$ = lcons(makeString($1), NIL); }
3344 | attrs '.' attr_name
3345 { $$ = lappend($1, makeString($3)); }
3347 { $$ = lappend($1, makeString("*")); }
3351 /*****************************************************************************
3355 *****************************************************************************/
3357 res_target_list: res_target_list ',' res_target_el
3358 { $$ = lappend($1,$3); }
3360 { $$ = lcons($1, NIL); }
3363 ResTarget *rt = makeNode(ResTarget);
3364 Attr *att = makeNode(Attr);
3366 att->paramNo = NULL;
3368 att->indirection = NIL;
3370 rt->indirection = NULL;
3371 rt->val = (Node *)att;
3372 $$ = lcons(rt, NIL);
3376 res_target_el: ColId opt_indirection '=' a_expr_or_null
3378 $$ = makeNode(ResTarget);
3380 $$->indirection = $2;
3381 $$->val = (Node *)$4;
3383 | attr opt_indirection
3385 $$ = makeNode(ResTarget);
3387 $$->indirection = $2;
3388 $$->val = (Node *)$1;
3390 | relation_name '.' '*'
3392 Attr *att = makeNode(Attr);
3394 att->paramNo = NULL;
3395 att->attrs = lcons(makeString("*"), NIL);
3396 att->indirection = NIL;
3397 $$ = makeNode(ResTarget);
3399 $$->indirection = NULL;
3400 $$->val = (Node *)att;
3405 ** target list for select.
3406 ** should get rid of the other but is still needed by the defunct retrieve into
3407 ** and update (uses a subset)
3409 res_target_list2: res_target_list2 ',' res_target_el2
3410 { $$ = lappend($1, $3); }
3412 { $$ = lcons($1, NIL); }
3415 /* AS is not optional because shift/red conflict with unary ops */
3416 res_target_el2: a_expr_or_null AS ColLabel
3418 $$ = makeNode(ResTarget);
3420 $$->indirection = NULL;
3421 $$->val = (Node *)$1;
3425 $$ = makeNode(ResTarget);
3427 $$->indirection = NULL;
3428 $$->val = (Node *)$1;
3430 | relation_name '.' '*'
3432 Attr *att = makeNode(Attr);
3434 att->paramNo = NULL;
3435 att->attrs = lcons(makeString("*"), NIL);
3436 att->indirection = NIL;
3437 $$ = makeNode(ResTarget);
3439 $$->indirection = NULL;
3440 $$->val = (Node *)att;
3444 Attr *att = makeNode(Attr);
3446 att->paramNo = NULL;
3448 att->indirection = NIL;
3449 $$ = makeNode(ResTarget);
3451 $$->indirection = NULL;
3452 $$->val = (Node *)att;
3456 opt_id: ColId { $$ = $1; }
3457 | /* EMPTY */ { $$ = NULL; }
3460 relation_name: SpecialRuleRelation
3463 StrNCpy(saved_relname, $1, NAMEDATALEN);
3467 /* disallow refs to variable system tables */
3468 if (strcmp(LogRelationName, $1) == 0
3469 || strcmp(VariableRelationName, $1) == 0)
3470 elog(WARN,"%s cannot be accessed by users",$1);
3473 StrNCpy(saved_relname, $1, NAMEDATALEN);
3477 database_name: ColId { $$ = $1; };
3478 access_method: Id { $$ = $1; };
3479 attr_name: ColId { $$ = $1; };
3480 class: Id { $$ = $1; };
3481 index_name: ColId { $$ = $1; };
3484 * Include date/time keywords as SQL92 extension.
3485 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3487 name: ColId { $$ = $1; };
3489 file_name: Sconst { $$ = $1; };
3490 recipe_name: Id { $$ = $1; };
3493 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
3497 A_Const *n = makeNode(A_Const);
3498 n->val.type = T_Integer;
3499 n->val.val.ival = $1;
3504 A_Const *n = makeNode(A_Const);
3505 n->val.type = T_Float;
3506 n->val.val.dval = $1;
3511 A_Const *n = makeNode(A_Const);
3512 n->val.type = T_String;
3513 n->val.val.str = $1;
3518 A_Const *n = makeNode(A_Const);
3520 n->val.type = T_String;
3521 n->val.val.str = $2;
3525 { $$ = (Node *)$1; }
3528 A_Const *n = makeNode(A_Const);
3529 n->val.type = T_String;
3530 n->val.val.str = "t";
3535 A_Const *n = makeNode(A_Const);
3536 n->val.type = T_String;
3537 n->val.val.str = "f";
3544 $$ = makeNode(ParamNo);
3549 NumConst: Iconst { $$ = makeInteger($1); }
3550 | FCONST { $$ = makeFloat($1); }
3553 Iconst: ICONST { $$ = $1; };
3554 Sconst: SCONST { $$ = $1; };
3556 /* Column and type identifier
3557 * Does not include explicit datetime types
3558 * since these must be decoupled in Typename syntax.
3559 * Use ColId for most identifiers. - thomas 1997-10-21
3561 Id: IDENT { $$ = $1; };
3563 /* Column identifier
3564 * Include date/time keywords as SQL92 extension.
3565 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3566 * Add other keywords. Note that as the syntax expands,
3567 * some of these keywords will have to be removed from this
3568 * list due to shift/reduce conflicts in yacc. If so, move
3569 * down to the ColLabel entity. - thomas 1997-11-06
3571 ColId: Id { $$ = $1; }
3572 | datetime { $$ = $1; }
3573 | ACTION { $$ = "action"; }
3574 | DATABASE { $$ = "database"; }
3575 | DELIMITERS { $$ = "delimiters"; }
3576 | FUNCTION { $$ = "function"; }
3577 | INDEX { $$ = "index"; }
3578 | KEY { $$ = "key"; }
3579 | LANGUAGE { $$ = "language"; }
3580 | LOCATION { $$ = "location"; }
3581 | MATCH { $$ = "match"; }
3582 | OPERATOR { $$ = "operator"; }
3583 | OPTION { $$ = "option"; }
3584 | PRIVILEGES { $$ = "privileges"; }
3585 | RECIPE { $$ = "recipe"; }
3586 | TIME { $$ = "time"; }
3587 | TRIGGER { $$ = "trigger"; }
3588 | TYPE_P { $$ = "type"; }
3589 | VERSION { $$ = "version"; }
3590 | ZONE { $$ = "zone"; }
3594 * Allowed labels in "AS" clauses.
3595 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
3596 * compatibility. Cannot allow this for column names since the
3597 * syntax would not distinguish between the constant value and
3598 * a column name. - thomas 1997-10-24
3599 * Add other keywords to this list. Note that they appear here
3600 * rather than in ColId if there was a shift/reduce conflict
3601 * when used as a full identifier. - thomas 1997-11-06
3603 ColLabel: ColId { $$ = $1; }
3604 | ARCHIVE { $$ = "archive"; }
3605 | CLUSTER { $$ = "cluster"; }
3606 | CONSTRAINT { $$ = "constraint"; }
3607 | CROSS { $$ = "cross"; }
3608 | FOREIGN { $$ = "foreign"; }
3609 | GROUP { $$ = "group"; }
3610 | LOAD { $$ = "load"; }
3611 | ORDER { $$ = "order"; }
3612 | POSITION { $$ = "position"; }
3613 | PRECISION { $$ = "precision"; }
3614 | TABLE { $$ = "table"; }
3615 | TRANSACTION { $$ = "transaction"; }
3616 | TRUE_P { $$ = "true"; }
3617 | FALSE_P { $$ = "false"; }
3620 SpecialRuleRelation: CURRENT
3625 elog(WARN,"CURRENT used in non-rule query",NULL);
3632 elog(WARN,"NEW used in non-rule query",NULL);
3638 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
3640 A_Expr *a = makeNode(A_Expr);
3649 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
3651 Node *result = NULL;
3653 /* we do this so indexes can be used */
3654 if (strcmp(opname,"~") == 0 ||
3655 strcmp(opname,"~*") == 0)
3657 if (nodeTag(rexpr) == T_A_Const &&
3658 ((A_Const *)rexpr)->val.type == T_String &&
3659 ((A_Const *)rexpr)->val.val.str[0] == '^')
3661 A_Const *n = (A_Const *)rexpr;
3662 char *match_least = palloc(strlen(n->val.val.str)+2);
3663 char *match_most = palloc(strlen(n->val.val.str)+2);
3664 int pos, match_pos=0;
3666 /* skip leading ^ */
3667 for (pos = 1; n->val.val.str[pos]; pos++)
3669 if (n->val.val.str[pos] == '.' ||
3670 n->val.val.str[pos] == '?' ||
3671 n->val.val.str[pos] == '*' ||
3672 n->val.val.str[pos] == '[' ||
3673 n->val.val.str[pos] == '$' ||
3674 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
3676 if (n->val.val.str[pos] == '\\')
3678 match_least[match_pos] = n->val.val.str[pos];
3679 match_most[match_pos++] = n->val.val.str[pos];
3684 A_Const *least = makeNode(A_Const);
3685 A_Const *most = makeNode(A_Const);
3687 /* make strings to be used in index use */
3688 match_least[match_pos] = '\0';
3689 match_most[match_pos] = '\377';
3690 match_most[match_pos+1] = '\0';
3691 least->val.type = T_String;
3692 least->val.val.str = match_least;
3693 most->val.type = T_String;
3694 most->val.val.str = match_most;
3695 result = makeA_Expr(AND, NULL,
3696 makeA_Expr(OP, "~", lexpr, rexpr),
3697 makeA_Expr(AND, NULL,
3698 makeA_Expr(OP, ">=", lexpr, (Node *)least),
3699 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
3703 else if (strcmp(opname,"~~") == 0)
3705 if (nodeTag(rexpr) == T_A_Const &&
3706 ((A_Const *)rexpr)->val.type == T_String)
3708 A_Const *n = (A_Const *)rexpr;
3709 char *match_least = palloc(strlen(n->val.val.str)+2);
3710 char *match_most = palloc(strlen(n->val.val.str)+2);
3711 int pos, match_pos=0;
3713 for (pos = 0; n->val.val.str[pos]; pos++)
3715 if ((n->val.val.str[pos] == '%' &&
3716 n->val.val.str[pos+1] != '%') ||
3717 (n->val.val.str[pos] == '_' &&
3718 n->val.val.str[pos+1] != '_'))
3720 if (n->val.val.str[pos] == '%' ||
3721 n->val.val.str[pos] == '_' ||
3722 n->val.val.str[pos] == '\\')
3724 match_least[match_pos] = n->val.val.str[pos];
3725 match_most[match_pos++] = n->val.val.str[pos];
3730 A_Const *least = makeNode(A_Const);
3731 A_Const *most = makeNode(A_Const);
3733 /* make strings to be used in index use */
3734 match_least[match_pos] = '\0';
3735 match_most[match_pos] = '\377';
3736 match_most[match_pos+1] = '\0';
3737 least->val.type = T_String;
3738 least->val.val.str = match_least;
3739 most->val.type = T_String;
3740 most->val.val.str = match_most;
3741 result = makeA_Expr(AND, NULL,
3742 makeA_Expr(OP, "~~", lexpr, rexpr),
3743 makeA_Expr(AND, NULL,
3744 makeA_Expr(OP, ">=", lexpr, (Node *)least),
3745 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
3751 result = makeA_Expr(OP, opname, lexpr, rexpr);
3753 } /* makeIndexable() */
3757 * Convert alternate type names to internal Postgres types.
3758 * Do not convert "float", since that is handled elsewhere
3759 * for FLOAT(p) syntax.
3762 xlateSqlType(char *name)
3764 if (!strcasecmp(name,"int")
3765 || !strcasecmp(name,"integer"))
3767 else if (!strcasecmp(name, "smallint"))
3769 else if (!strcasecmp(name, "real"))
3771 else if (!strcasecmp(name, "interval"))
3773 else if (!strcasecmp(name, "boolean"))
3777 } /* xlateSqlName() */
3780 void parser_init(Oid *typev, int nargs)
3782 QueryIsRule = FALSE;
3783 saved_relname[0]= '\0';
3784 saved_In_Expr = NULL;
3786 param_type_init(typev, nargs);
3790 /* FlattenStringList()
3791 * Traverse list of string nodes and convert to a single string.
3792 * Used for reconstructing string form of complex expressions.
3794 * Allocate at least one byte for terminator.
3797 FlattenStringList(List *list)
3805 nlist = length(list);
3808 v = (Value *)lfirst(l);
3815 s = (char*) palloc(len+1);
3820 v = (Value *)lfirst(l);
3824 if (l != NIL) strcat(s," ");
3829 printf( "flattened string is \"%s\"\n", s);
3833 } /* FlattenStringList() */
3836 /* makeConstantList()
3837 * Convert constant value node into string node.
3840 makeConstantList( A_Const *n)
3842 char *defval = NULL;
3843 if (nodeTag(n) != T_A_Const) {
3844 elog(WARN,"Cannot handle non-constant parameter",NULL);
3846 } else if (n->val.type == T_Float) {
3847 defval = (char*) palloc(20+1);
3848 sprintf( defval, "%g", n->val.val.dval);
3850 } else if (n->val.type == T_Integer) {
3851 defval = (char*) palloc(20+1);
3852 sprintf( defval, "%ld", n->val.val.ival);
3854 } else if (n->val.type == T_String) {
3855 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
3856 strcpy( defval, "'");
3857 strcat( defval, ((A_Const *) n)->val.val.str);
3858 strcat( defval, "'");
3861 elog(WARN,"Internal error in makeConstantList(): cannot encode node",NULL);
3865 printf( "AexprConst argument is \"%s\"\n", defval);
3868 return( lcons( makeString(defval), NIL));
3869 } /* makeConstantList() */
3873 * Check input string for non-lowercase/non-numeric characters.
3874 * Returns either input string or input surrounded by double quotes.
3881 for (cp = rawid; *cp != '\0'; cp++)
3882 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
3885 cp = palloc(strlen(rawid)+1);
3894 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
3903 * keep enough information around fill out the type of param nodes
3904 * used in postquel functions
3907 param_type_init(Oid *typev, int nargs)
3909 pfunc_num_args = nargs;
3910 param_type_info = typev;
3913 Oid param_type(int t)
3915 if ((t > pfunc_num_args) || (t == 0))
3917 return param_type_info[t - 1];