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.80 1997/12/23 19:47:32 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 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 Node *makeRowExpr(char *opr, List *largs, List *rargs);
67 void mapTargetColumns(List *source, List *target);
68 static List *makeConstantList( A_Const *node);
69 static char *FlattenStringList(List *list);
70 static char *fmtId(char *rawid);
71 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
72 static void param_type_init(Oid *typev, int nargs);
74 Oid param_type(int t); /* used in parse_expr.c */
76 /* old versions of flex define this as a macro */
90 bool* pboolean; /* for pg_user privileges */
100 SortGroupBy *sortgroupby;
115 AddAttrStmt, ClosePortalStmt,
116 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
117 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
118 CreatePLangStmt, DropPLangStmt,
119 IndexStmt, ListenStmt, OptimizableStmt,
120 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
121 RemoveFuncStmt, RemoveStmt,
122 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
123 CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
124 ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
125 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
126 CreateUserStmt, AlterUserStmt, DropUserStmt
128 %type <str> opt_database, location
130 %type <pboolean> user_createdb_clause, user_createuser_clause
131 %type <str> user_passwd_clause
132 %type <str> user_valid_clause
133 %type <list> user_group_list, user_group_clause
135 %type <node> SubSelect
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, 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, def_args, def_name_list, func_argtypes,
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 <list> union_clause, select_list
164 %type <list> join_list
167 %type <boolean> opt_union
169 %type <node> position_expr
170 %type <list> extract_list, position_list
171 %type <list> substr_list, substr_from, substr_for, trim_list
172 %type <list> opt_interval
174 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
175 index_opt_unique, opt_verbose, opt_analyze
177 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
180 %type <ival> fetch_how_many
182 %type <list> OptSeqList
183 %type <defelt> OptSeqElem
185 %type <dstmt> def_rest
186 %type <astmt> insert_rest
188 %type <node> OptTableElement, ConstraintElem
189 %type <node> columnDef, alter_clause
190 %type <defelt> def_elem
191 %type <node> def_arg, columnElem, where_clause,
192 a_expr, a_expr_or_null, AexprConst,
193 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
195 %type <list> row_descriptor, row_list
196 %type <node> row_expr
197 %type <list> OptCreateAs, CreateAsList
198 %type <node> CreateAsElement
199 %type <value> NumConst
200 %type <attr> event_object, attr
201 %type <sortgroupby> groupby
202 %type <sortgroupby> sortby
203 %type <ielem> index_elem, func_index
204 %type <range> from_val
205 %type <relexp> relation_expr
206 %type <target> res_target_el, res_target_el2
207 %type <paramno> ParamNo
209 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
210 %type <str> generic, character, datetime
211 %type <str> opt_charset, opt_collate
212 %type <str> opt_float, opt_numeric, opt_decimal
213 %type <boolean> opt_varying, opt_timezone
217 %type <str> Id, var_value, zone_value
218 %type <str> ColId, ColLabel
220 %type <node> TableConstraint
221 %type <list> constraint_list, constraint_expr
222 %type <list> default_list, default_expr
223 %type <list> ColQualList, ColQualifier
224 %type <node> ColConstraint, ColConstraintElem
225 %type <list> key_actions, key_action
226 %type <str> key_match, key_reference
229 * If you make any token changes, remember to:
230 * - use "yacc -d" and update parse.h
231 * - update the keyword table in parser/keywords.c
234 /* Reserved word tokens
235 * SQL92 syntax has many type-specific constructs.
236 * So, go ahead and make these types reserved words,
237 * and call-out the syntax explicitly.
238 * This gets annoying when trying to also retain Postgres' nice
239 * type-extensible features, but we don't really have a choice.
240 * - thomas 1997-10-11
243 /* Keywords (in SQL92 reserved words) */
244 %token ACTION, ADD, ALL, ALTER, AND, AS, ASC,
245 BEGIN_TRANS, BETWEEN, BOTH, BY,
246 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
247 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
248 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
249 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
250 END_TRANS, EXECUTE, EXISTS, EXTRACT,
251 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
252 GRANT, GROUP, HAVING, HOUR_P,
253 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
254 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
255 MATCH, MINUTE_P, MONTH_P,
256 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
257 ON, OPTION, OR, ORDER, OUTER_P,
258 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
259 REFERENCES, REVOKE, RIGHT, ROLLBACK,
260 SECOND_P, SELECT, SET, SUBSTRING,
261 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
262 UNION, UNIQUE, UPDATE, USING,
263 VALUES, VARCHAR, VARYING, VERBOSE, VERSION, VIEW,
264 WHERE, WITH, WORK, YEAR_P, ZONE
266 /* Keywords (in SQL3 reserved words) */
267 %token FALSE_P, TRIGGER, TRUE_P
269 /* Keywords (in SQL92 non-reserved words) */
272 /* Keywords for Postgres support (not in SQL92 reserved words) */
273 %token ABORT_TRANS, ACL, AFTER, AGGREGATE, ANALYZE,
274 APPEND, BACKWARD, BEFORE, BINARY, CHANGE, CLUSTER, COPY,
275 DATABASE, DELIMITERS, DO, EXPLAIN, EXTEND,
276 FORWARD, FUNCTION, HANDLER,
277 INDEX, INHERITS, INSTEAD, ISNULL,
278 LANCOMPILER, LISTEN, LOAD, LOCATION, MERGE, MOVE,
279 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
280 RECIPE, RENAME, REPLACE, RESET, RETRIEVE, RETURNS, RULE,
281 SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED,
282 VACUUM, VERBOSE, VERSION
284 /* Keywords (obsolete; retain temporarily for parser - thomas 1997-12-04) */
288 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
289 * when some sort of pg_privileges relation is introduced.
293 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
295 /* Special keywords, not in the query language - see the "lex" file */
296 %token <str> IDENT, SCONST, Op
297 %token <ival> ICONST, PARAM
300 /* these are not real. they are here so that they get generated as #define's*/
317 %left '|' /* this is the relation union op, not logical or */
318 /* Unary Operators */
320 %left ';' /* end of statement or natural log */
333 { parsetree = lcons($1,NIL); }
336 stmtmulti: stmtmulti stmt ';'
337 { $$ = lappend($1, $2); }
339 { $$ = lappend($1, $2); }
341 { $$ = lcons($1,NIL); }
387 /*****************************************************************************
389 * Create a new Postgres DBMS user
392 *****************************************************************************/
394 CreateUserStmt: CREATE USER Id user_passwd_clause user_createdb_clause
395 user_createuser_clause user_group_clause user_valid_clause
397 CreateUserStmt *n = makeNode(CreateUserStmt);
408 /*****************************************************************************
410 * Alter a postresql DBMS user
413 *****************************************************************************/
415 AlterUserStmt: ALTER USER Id user_passwd_clause user_createdb_clause
416 user_createuser_clause user_group_clause user_valid_clause
418 AlterUserStmt *n = makeNode(AlterUserStmt);
429 /*****************************************************************************
431 * Drop a postresql DBMS user
434 *****************************************************************************/
436 DropUserStmt: DROP USER Id
438 DropUserStmt *n = makeNode(DropUserStmt);
444 user_passwd_clause: WITH PASSWORD Id { $$ = $3; }
445 | /*EMPTY*/ { $$ = NULL; }
448 user_createdb_clause: CREATEDB
451 $$ = (b = (bool*)palloc(sizeof(bool)));
457 $$ = (b = (bool*)palloc(sizeof(bool)));
460 | /*EMPTY*/ { $$ = NULL; }
463 user_createuser_clause: CREATEUSER
466 $$ = (b = (bool*)palloc(sizeof(bool)));
472 $$ = (b = (bool*)palloc(sizeof(bool)));
475 | /*EMPTY*/ { $$ = NULL; }
478 user_group_list: user_group_list ',' Id
480 $$ = lcons((void*)makeString($3), $1);
484 $$ = lcons((void*)makeString($1), NIL);
488 user_group_clause: IN GROUP user_group_list { $$ = $3; }
489 | /*EMPTY*/ { $$ = NULL; }
492 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
493 | /*EMPTY*/ { $$ = NULL; }
496 /*****************************************************************************
498 * Set PG internal variable
499 * SET name TO 'var_value'
500 * Include SQL92 syntax (thomas 1997-10-22):
501 * SET TIME ZONE 'var_value'
503 *****************************************************************************/
505 VariableSetStmt: SET ColId TO var_value
507 VariableSetStmt *n = makeNode(VariableSetStmt);
512 | SET ColId '=' var_value
514 VariableSetStmt *n = makeNode(VariableSetStmt);
519 | SET TIME ZONE zone_value
521 VariableSetStmt *n = makeNode(VariableSetStmt);
522 n->name = "timezone";
528 var_value: Sconst { $$ = $1; }
529 | DEFAULT { $$ = NULL; }
532 zone_value: Sconst { $$ = $1; }
533 | DEFAULT { $$ = NULL; }
534 | LOCAL { $$ = "default"; }
537 VariableShowStmt: SHOW ColId
539 VariableShowStmt *n = makeNode(VariableShowStmt);
545 VariableShowStmt *n = makeNode(VariableShowStmt);
546 n->name = "timezone";
551 VariableResetStmt: RESET ColId
553 VariableResetStmt *n = makeNode(VariableResetStmt);
559 VariableResetStmt *n = makeNode(VariableResetStmt);
560 n->name = "timezone";
566 /*****************************************************************************
569 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
571 *****************************************************************************/
573 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
575 AddAttrStmt *n = makeNode(AddAttrStmt);
583 alter_clause: ADD opt_column columnDef
587 | ADD '(' OptTableElementList ')'
589 Node *lp = lfirst($3);
592 elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
595 | DROP opt_column ColId
596 { elog(WARN,"ALTER TABLE/DROP COLUMN not yet implemented",NULL); }
597 | ALTER opt_column ColId SET DEFAULT default_expr
598 { elog(WARN,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented",NULL); }
599 | ALTER opt_column ColId DROP DEFAULT
600 { elog(WARN,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented",NULL); }
602 { elog(WARN,"ALTER TABLE/ADD CONSTRAINT not yet implemented",NULL); }
606 /*****************************************************************************
611 *****************************************************************************/
613 ClosePortalStmt: CLOSE opt_id
615 ClosePortalStmt *n = makeNode(ClosePortalStmt);
622 /*****************************************************************************
625 * COPY [BINARY] <relname> FROM/TO
626 * [USING DELIMITERS <delimiter>]
628 *****************************************************************************/
630 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
632 CopyStmt *n = makeNode(CopyStmt);
650 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
651 * used depends on the direction. (It really doesn't make sense to copy from
652 * stdout. We silently correct the "typo". - AY 9/94
654 copy_file_name: Sconst { $$ = $1; }
655 | STDIN { $$ = NULL; }
656 | STDOUT { $$ = NULL; }
659 opt_binary: BINARY { $$ = TRUE; }
660 | /*EMPTY*/ { $$ = FALSE; }
663 opt_with_copy: WITH OIDS { $$ = TRUE; }
664 | /*EMPTY*/ { $$ = FALSE; }
668 * the default copy delimiter is tab but the user can configure it
670 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
671 | /*EMPTY*/ { $$ = "\t"; }
675 /*****************************************************************************
680 *****************************************************************************/
682 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
683 OptInherit OptArchiveType
685 CreateStmt *n = makeNode(CreateStmt);
689 n->constraints = NIL;
694 OptTableElementList: OptTableElementList ',' OptTableElement
695 { $$ = lappend($1, $3); }
696 | OptTableElement { $$ = lcons($1, NIL); }
697 | /*EMPTY*/ { $$ = NULL; }
700 OptTableElement: columnDef { $$ = $1; }
701 | TableConstraint { $$ = $1; }
704 columnDef: ColId Typename ColQualifier
706 ColumnDef *n = makeNode(ColumnDef);
710 n->is_not_null = FALSE;
716 ColQualifier: ColQualList { $$ = $1; }
717 | /*EMPTY*/ { $$ = NULL; }
720 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
721 | ColConstraint { $$ = lcons($1, NIL); }
725 CONSTRAINT name ColConstraintElem
727 Constraint *n = (Constraint *)$3;
735 ColConstraintElem: CHECK '(' constraint_expr ')'
737 Constraint *n = makeNode(Constraint);
738 n->contype = CONSTR_CHECK;
740 n->def = FlattenStringList($3);
744 | DEFAULT default_expr
746 Constraint *n = makeNode(Constraint);
747 n->contype = CONSTR_DEFAULT;
749 n->def = FlattenStringList($2);
755 Constraint *n = makeNode(Constraint);
756 n->contype = CONSTR_NOTNULL;
764 Constraint *n = makeNode(Constraint);
765 n->contype = CONSTR_UNIQUE;
773 Constraint *n = makeNode(Constraint);
774 n->contype = CONSTR_PRIMARY;
780 | REFERENCES ColId opt_column_list key_match key_actions
782 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL);
787 default_list: default_list ',' default_expr
789 $$ = lappend($1,makeString(","));
798 default_expr: AexprConst
799 { $$ = makeConstantList((A_Const *) $1); }
801 { $$ = lcons( makeString("NULL"), NIL); }
802 | '-' default_expr %prec UMINUS
803 { $$ = lcons( makeString( "-"), $2); }
804 | default_expr '+' default_expr
805 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
806 | default_expr '-' default_expr
807 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
808 | default_expr '/' default_expr
809 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
810 | default_expr '*' default_expr
811 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
812 | default_expr '=' default_expr
813 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
814 | default_expr '<' default_expr
815 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
816 | default_expr '>' default_expr
817 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
819 { $$ = lcons( makeString( ":"), $2); }
821 { $$ = lcons( makeString( ";"), $2); }
823 { $$ = lcons( makeString( "|"), $2); }
824 | default_expr TYPECAST Typename
826 $3->name = fmtId($3->name);
827 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
829 | CAST default_expr AS Typename
831 $4->name = fmtId($4->name);
832 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
834 | '(' default_expr ')'
835 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
838 $$ = makeList( makeString($1), makeString("("), -1);
839 $$ = lappend( $$, makeString(")"));
841 | name '(' default_list ')'
843 $$ = makeList( makeString($1), makeString("("), -1);
845 $$ = lappend( $$, makeString(")"));
847 | default_expr Op default_expr
849 if (!strcmp("<=", $2) || !strcmp(">=", $2))
850 elog(WARN,"boolean expressions not supported in DEFAULT",NULL);
851 $$ = nconc( $1, lcons( makeString( $2), $3));
854 { $$ = lcons( makeString( $1), $2); }
856 { $$ = lappend( $1, makeString( $2)); }
857 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
859 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
861 { $$ = lcons( makeString( "'now'::time"), NIL); }
862 | CURRENT_TIME '(' Iconst ')'
865 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
866 $$ = lcons( makeString( "'now'::time"), NIL);
869 { $$ = lcons( makeString( "now()"), NIL); }
870 | CURRENT_TIMESTAMP '(' Iconst ')'
873 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
874 $$ = lcons( makeString( "now()"), NIL);
877 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
880 /* ConstraintElem specifies constraint syntax which is not embedded into
881 * a column definition. ColConstraintElem specifies the embedded form.
882 * - thomas 1997-12-03
884 TableConstraint: CONSTRAINT name ConstraintElem
886 Constraint *n = (Constraint *)$3;
894 ConstraintElem: CHECK '(' constraint_expr ')'
896 Constraint *n = makeNode(Constraint);
897 n->contype = CONSTR_CHECK;
899 n->def = FlattenStringList($3);
902 | UNIQUE '(' columnList ')'
904 Constraint *n = makeNode(Constraint);
905 n->contype = CONSTR_UNIQUE;
911 | PRIMARY KEY '(' columnList ')'
913 Constraint *n = makeNode(Constraint);
914 n->contype = CONSTR_PRIMARY;
920 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
921 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented",NULL); }
924 constraint_list: constraint_list ',' constraint_expr
926 $$ = lappend($1,makeString(","));
935 constraint_expr: AexprConst
936 { $$ = makeConstantList((A_Const *) $1); }
938 { $$ = lcons( makeString("NULL"), NIL); }
941 $$ = lcons( makeString(fmtId($1)), NIL);
943 | '-' constraint_expr %prec UMINUS
944 { $$ = lcons( makeString( "-"), $2); }
945 | constraint_expr '+' constraint_expr
946 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
947 | constraint_expr '-' constraint_expr
948 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
949 | constraint_expr '/' constraint_expr
950 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
951 | constraint_expr '*' constraint_expr
952 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
953 | constraint_expr '=' constraint_expr
954 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
955 | constraint_expr '<' constraint_expr
956 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
957 | constraint_expr '>' constraint_expr
958 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
959 | ':' constraint_expr
960 { $$ = lcons( makeString( ":"), $2); }
961 | ';' constraint_expr
962 { $$ = lcons( makeString( ";"), $2); }
963 | '|' constraint_expr
964 { $$ = lcons( makeString( "|"), $2); }
965 | constraint_expr TYPECAST Typename
967 $3->name = fmtId($3->name);
968 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
970 | CAST constraint_expr AS Typename
972 $4->name = fmtId($4->name);
973 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
975 | '(' constraint_expr ')'
976 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
979 $$ = makeList( makeString($1), makeString("("), -1);
980 $$ = lappend( $$, makeString(")"));
982 | name '(' constraint_list ')'
984 $$ = makeList( makeString($1), makeString("("), -1);
986 $$ = lappend( $$, makeString(")"));
988 | constraint_expr Op constraint_expr
989 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
990 | constraint_expr AND constraint_expr
991 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
992 | constraint_expr OR constraint_expr
993 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
994 | NOT constraint_expr
995 { $$ = lcons( makeString( "NOT"), $2); }
997 { $$ = lcons( makeString( $1), $2); }
999 { $$ = lappend( $1, makeString( $2)); }
1000 | constraint_expr ISNULL
1001 { $$ = lappend( $1, makeString( "IS NULL")); }
1002 | constraint_expr IS NULL_P
1003 { $$ = lappend( $1, makeString( "IS NULL")); }
1004 | constraint_expr NOTNULL
1005 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1006 | constraint_expr IS NOT NULL_P
1007 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1008 | constraint_expr IS TRUE_P
1009 { $$ = lappend( $1, makeString( "IS TRUE")); }
1010 | constraint_expr IS FALSE_P
1011 { $$ = lappend( $1, makeString( "IS FALSE")); }
1012 | constraint_expr IS NOT TRUE_P
1013 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1014 | constraint_expr IS NOT FALSE_P
1015 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1018 key_match: MATCH FULL { $$ = NULL; }
1019 | MATCH PARTIAL { $$ = NULL; }
1020 | /*EMPTY*/ { $$ = NULL; }
1023 key_actions: key_action key_action { $$ = NIL; }
1024 | key_action { $$ = NIL; }
1025 | /*EMPTY*/ { $$ = NIL; }
1028 key_action: ON DELETE key_reference { $$ = NIL; }
1029 | ON UPDATE key_reference { $$ = NIL; }
1032 key_reference: NO ACTION { $$ = NULL; }
1033 | CASCADE { $$ = NULL; }
1034 | SET DEFAULT { $$ = NULL; }
1035 | SET NULL_P { $$ = NULL; }
1038 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1039 | /*EMPTY*/ { $$ = NIL; }
1043 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1044 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1046 OptArchiveType: ARCHIVE '=' NONE { }
1050 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1052 RetrieveStmt *n = makeNode(RetrieveStmt);
1053 SubSelect *s = (SubSelect *)$6;
1054 n->unique = s->unique;
1055 n->targetList = s->targetList;
1057 mapTargetColumns($4, n->targetList);
1059 n->fromClause = s->fromClause;
1060 n->whereClause = s->whereClause;
1061 n->groupClause = s->groupClause;
1062 n->havingClause = s->havingClause;
1063 n->unionClause = NULL;
1064 n->sortClause = NULL;
1069 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1070 | /*EMPTY*/ { $$ = NULL; }
1073 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1074 | CreateAsElement { $$ = lcons($1, NIL); }
1077 CreateAsElement: ColId
1079 ColumnDef *n = makeNode(ColumnDef);
1083 n->is_not_null = FALSE;
1084 n->constraints = NULL;
1090 /*****************************************************************************
1093 * CREATE SEQUENCE seqname
1095 *****************************************************************************/
1097 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1099 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1107 OptSeqList OptSeqElem
1108 { $$ = lappend($1, $2); }
1112 OptSeqElem: IDENT NumConst
1114 $$ = makeNode(DefElem);
1116 $$->arg = (Node *)$2;
1120 $$ = makeNode(DefElem);
1122 $$->arg = (Node *)NULL;
1126 /*****************************************************************************
1129 * CREATE PROCEDURAL LANGUAGE ...
1130 * DROP PROCEDURAL LANGUAGE ...
1132 *****************************************************************************/
1134 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1135 HANDLER def_name LANCOMPILER Sconst
1137 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1146 PLangTrusted: TRUSTED { $$ = TRUE; }
1149 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1151 DropPLangStmt *n = makeNode(DropPLangStmt);
1157 /*****************************************************************************
1160 * CREATE TRIGGER ...
1163 *****************************************************************************/
1165 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1166 relation_name TriggerForSpec EXECUTE PROCEDURE
1167 name '(' TriggerFuncArgs ')'
1169 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1176 memcpy (n->actions, $5, 4);
1181 TriggerActionTime: BEFORE { $$ = TRUE; }
1182 | AFTER { $$ = FALSE; }
1185 TriggerEvents: TriggerOneEvent
1187 char *e = palloc (4);
1188 e[0] = $1; e[1] = 0; $$ = e;
1190 | TriggerOneEvent OR TriggerOneEvent
1192 char *e = palloc (4);
1193 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1195 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1197 char *e = palloc (4);
1198 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1203 TriggerOneEvent: INSERT { $$ = 'i'; }
1204 | DELETE { $$ = 'd'; }
1205 | UPDATE { $$ = 'u'; }
1208 TriggerForSpec: FOR name name
1210 if ( strcmp ($2, "each") != 0 )
1211 elog(WARN,"parser: syntax error near %s",$2);
1212 if ( strcmp ($3, "row") == 0 )
1214 else if ( strcmp ($3, "statement") == 0 )
1217 elog(WARN,"parser: syntax error near %s",$3);
1221 TriggerFuncArgs: TriggerFuncArg
1222 { $$ = lcons($1, NIL); }
1223 | TriggerFuncArgs ',' TriggerFuncArg
1224 { $$ = lappend($1, $3); }
1229 TriggerFuncArg: ICONST
1231 char *s = (char *) palloc (256);
1232 sprintf (s, "%d", $1);
1237 char *s = (char *) palloc (256);
1238 sprintf (s, "%g", $1);
1241 | Sconst { $$ = $1; }
1242 | IDENT { $$ = $1; }
1245 DropTrigStmt: DROP TRIGGER name ON relation_name
1247 DropTrigStmt *n = makeNode(DropTrigStmt);
1255 /*****************************************************************************
1258 * define (type,operator,aggregate)
1260 *****************************************************************************/
1262 DefineStmt: CREATE def_type def_rest
1269 def_rest: def_name definition
1271 $$ = makeNode(DefineStmt);
1273 $$->definition = $2;
1277 def_type: OPERATOR { $$ = OPERATOR; }
1278 | TYPE_P { $$ = TYPE_P; }
1279 | AGGREGATE { $$ = AGGREGATE; }
1282 def_name: PROCEDURE { $$ = "procedure"; }
1283 | JOIN { $$ = "join"; }
1284 | ColId { $$ = $1; }
1285 | MathOp { $$ = $1; }
1289 definition: '(' def_list ')' { $$ = $2; }
1292 def_list: def_elem { $$ = lcons($1, NIL); }
1293 | def_list ',' def_elem { $$ = lappend($1, $3); }
1296 def_elem: def_name '=' def_arg
1298 $$ = makeNode(DefElem);
1300 $$->arg = (Node *)$3;
1304 $$ = makeNode(DefElem);
1306 $$->arg = (Node *)NULL;
1308 | DEFAULT '=' def_arg
1310 $$ = makeNode(DefElem);
1311 $$->defname = "default";
1312 $$->arg = (Node *)$3;
1316 def_arg: ColId { $$ = (Node *)makeString($1); }
1317 | all_Op { $$ = (Node *)makeString($1); }
1318 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1319 | Sconst { $$ = (Node *)makeString($1); }
1322 TypeName *n = makeNode(TypeName);
1325 n->arrayBounds = NULL;
1328 | DOUBLE { $$ = (Node *)makeString("double"); }
1332 /*****************************************************************************
1335 * destroy <relname1> [, <relname2> .. <relnameN> ]
1337 *****************************************************************************/
1339 DestroyStmt: DROP TABLE relation_name_list
1341 DestroyStmt *n = makeNode(DestroyStmt);
1343 n->sequence = FALSE;
1346 | DROP SEQUENCE relation_name_list
1348 DestroyStmt *n = makeNode(DestroyStmt);
1356 /*****************************************************************************
1359 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1361 *****************************************************************************/
1363 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1365 FetchStmt *n = makeNode(FetchStmt);
1372 | MOVE opt_direction fetch_how_many opt_portal_name
1374 FetchStmt *n = makeNode(FetchStmt);
1383 opt_direction: FORWARD { $$ = FORWARD; }
1384 | BACKWARD { $$ = BACKWARD; }
1385 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1388 fetch_how_many: Iconst
1390 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch",NULL); }
1391 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1392 | /*EMPTY*/ { $$ = 1; /*default*/ }
1395 opt_portal_name: IN name { $$ = $2; }
1396 | /*EMPTY*/ { $$ = NULL; }
1400 /*****************************************************************************
1403 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1405 *****************************************************************************/
1407 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1409 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1415 privileges: ALL PRIVILEGES
1417 $$ = aclmakepriv("rwaR",0);
1421 $$ = aclmakepriv("rwaR",0);
1423 | operation_commalist
1429 operation_commalist: operation
1431 $$ = aclmakepriv("",$1);
1433 | operation_commalist ',' operation
1435 $$ = aclmakepriv($1,$3);
1442 $$ = ACL_MODE_RD_CHR;
1446 $$ = ACL_MODE_AP_CHR;
1450 $$ = ACL_MODE_WR_CHR;
1454 $$ = ACL_MODE_WR_CHR;
1458 $$ = ACL_MODE_RU_CHR;
1464 $$ = aclmakeuser("A","");
1468 $$ = aclmakeuser("G",$2);
1472 $$ = aclmakeuser("U",$1);
1476 opt_with_grant: WITH GRANT OPTION
1478 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1484 /*****************************************************************************
1487 * REVOKE [privileges] ON [relation_name] FROM [user]
1489 *****************************************************************************/
1491 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1493 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1500 /*****************************************************************************
1503 * create index <indexname> on <relname>
1504 * using <access> "(" (<col> with <op>)+ ")" [with
1507 * [where <qual>] is not supported anymore
1508 *****************************************************************************/
1510 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1511 access_method_clause '(' index_params ')' opt_with
1513 /* should check that access_method is valid,
1514 etc ... but doesn't */
1515 IndexStmt *n = makeNode(IndexStmt);
1519 n->accessMethod = $7;
1520 n->indexParams = $9;
1521 n->withClause = $11;
1522 n->whereClause = NULL;
1527 index_opt_unique: UNIQUE { $$ = TRUE; }
1528 | /*EMPTY*/ { $$ = FALSE; }
1531 access_method_clause: USING access_method { $$ = $2; }
1532 | /*EMPTY*/ { $$ = "btree"; }
1535 index_params: index_list { $$ = $1; }
1536 | func_index { $$ = lcons($1,NIL); }
1539 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1540 | index_elem { $$ = lcons($1, NIL); }
1543 func_index: name '(' name_list ')' opt_type opt_class
1545 $$ = makeNode(IndexElem);
1553 index_elem: attr_name opt_type opt_class
1555 $$ = makeNode(IndexElem);
1563 opt_type: ':' Typename { $$ = $2; }
1564 | FOR Typename { $$ = $2; }
1565 | /*EMPTY*/ { $$ = NULL; }
1568 /* opt_class "WITH class" conflicts with preceeding opt_type
1569 * for Typename of "TIMESTAMP WITH TIME ZONE"
1570 * So, remove "WITH class" from the syntax. OK??
1571 * - thomas 1997-10-12
1572 * | WITH class { $$ = $2; }
1574 opt_class: class { $$ = $1; }
1575 | USING class { $$ = $2; }
1576 | /*EMPTY*/ { $$ = NULL; }
1580 /*****************************************************************************
1583 * extend index <indexname> [where <qual>]
1585 *****************************************************************************/
1587 ExtendStmt: EXTEND INDEX index_name where_clause
1589 ExtendStmt *n = makeNode(ExtendStmt);
1591 n->whereClause = $4;
1597 /*****************************************************************************
1600 * execute recipe <recipeName>
1602 *****************************************************************************/
1604 RecipeStmt: EXECUTE RECIPE recipe_name
1607 if (!IsTransactionBlock())
1608 elog(WARN,"EXECUTE RECIPE may only be used in begin/end transaction blocks",NULL);
1610 n = makeNode(RecipeStmt);
1617 /*****************************************************************************
1620 * define function <fname>
1621 * (language = <lang>, returntype = <typename>
1622 * [, arch_pct = <percentage | pre-defined>]
1623 * [, disk_pct = <percentage | pre-defined>]
1624 * [, byte_pct = <percentage | pre-defined>]
1625 * [, perbyte_cpu = <int | pre-defined>]
1626 * [, percall_cpu = <int | pre-defined>]
1628 * [arg is (<type-1> { , <type-n>})]
1629 * as <filename or code in language as appropriate>
1631 *****************************************************************************/
1633 ProcedureStmt: CREATE FUNCTION def_name def_args
1634 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1636 ProcedureStmt *n = makeNode(ProcedureStmt);
1639 n->returnType = (Node *)$6;
1646 opt_with: WITH definition { $$ = $2; }
1647 | /*EMPTY*/ { $$ = NIL; }
1650 def_args: '(' def_name_list ')' { $$ = $2; }
1651 | '(' ')' { $$ = NIL; }
1654 def_name_list: name_list;
1656 /*****************************************************************************
1660 * remove function <funcname>
1661 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1662 * remove aggregate <aggname>
1663 * (REMOVE AGGREGATE "aggname" "aggtype")
1664 * remove operator <opname>
1665 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1666 * remove type <typename>
1667 * (REMOVE TYPE "typename")
1668 * remove rule <rulename>
1669 * (REMOVE RULE "rulename")
1671 *****************************************************************************/
1673 RemoveStmt: DROP remove_type name
1675 RemoveStmt *n = makeNode(RemoveStmt);
1682 remove_type: TYPE_P { $$ = TYPE_P; }
1683 | INDEX { $$ = INDEX; }
1684 | RULE { $$ = RULE; }
1685 | VIEW { $$ = VIEW; }
1688 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1690 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1697 aggr_argtype: name { $$ = $1; }
1698 | '*' { $$ = NULL; }
1701 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1703 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1710 func_argtypes: name_list { $$ = $1; }
1711 | /*EMPTY*/ { $$ = NIL; }
1714 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1716 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1723 all_Op: Op | MathOp;
1725 MathOp: '+' { $$ = "+"; }
1736 elog(WARN,"parser: argument type missing (use NONE for unary operators)",NULL);
1739 { $$ = makeList(makeString($1), makeString($3), -1); }
1740 | NONE ',' name /* left unary */
1741 { $$ = makeList(NULL, makeString($3), -1); }
1742 | name ',' NONE /* right unary */
1743 { $$ = makeList(makeString($1), NULL, -1); }
1747 /*****************************************************************************
1750 * rename <attrname1> in <relname> [*] to <attrname2>
1751 * rename <relname1> to <relname2>
1753 *****************************************************************************/
1755 RenameStmt: ALTER TABLE relation_name opt_inh_star
1756 RENAME opt_column opt_name TO name
1758 RenameStmt *n = makeNode(RenameStmt);
1767 opt_name: name { $$ = $1; }
1768 | /*EMPTY*/ { $$ = NULL; }
1771 opt_column: COLUMN { $$ = COLUMN; }
1772 | /*EMPTY*/ { $$ = 0; }
1776 /*****************************************************************************
1778 * QUERY: Define Rewrite Rule , Define Tuple Rule
1779 * Define Rule <old rules >
1781 * only rewrite rule is supported -- ay 9/94
1783 *****************************************************************************/
1785 RuleStmt: CREATE RULE name AS
1786 { QueryIsRule=TRUE; }
1787 ON event TO event_object where_clause
1788 DO opt_instead OptStmtList
1790 RuleStmt *n = makeNode(RuleStmt);
1794 n->whereClause = $10;
1801 OptStmtList: NOTHING { $$ = NIL; }
1802 | OptimizableStmt { $$ = lcons($1, NIL); }
1803 | '[' OptStmtBlock ']' { $$ = $2; }
1806 OptStmtBlock: OptStmtMulti
1809 { $$ = lcons($1, NIL); }
1812 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1813 { $$ = lappend($1, $2); }
1814 | OptStmtMulti OptimizableStmt
1815 { $$ = lappend($1, $2); }
1816 | OptimizableStmt ';'
1817 { $$ = lcons($1, NIL); }
1820 event_object: relation_name '.' attr_name
1822 $$ = makeNode(Attr);
1825 $$->attrs = lcons(makeString($3), NIL);
1826 $$->indirection = NIL;
1830 $$ = makeNode(Attr);
1834 $$->indirection = NIL;
1838 /* change me to select, update, etc. some day */
1839 event: SELECT { $$ = CMD_SELECT; }
1840 | UPDATE { $$ = CMD_UPDATE; }
1841 | DELETE { $$ = CMD_DELETE; }
1842 | INSERT { $$ = CMD_INSERT; }
1845 opt_instead: INSTEAD { $$ = TRUE; }
1846 | /*EMPTY*/ { $$ = FALSE; }
1850 /*****************************************************************************
1853 * NOTIFY <relation_name> can appear both in rule bodies and
1854 * as a query-level command
1856 *****************************************************************************/
1858 NotifyStmt: NOTIFY relation_name
1860 NotifyStmt *n = makeNode(NotifyStmt);
1866 ListenStmt: LISTEN relation_name
1868 ListenStmt *n = makeNode(ListenStmt);
1875 /*****************************************************************************
1886 *****************************************************************************/
1888 TransactionStmt: ABORT_TRANS TRANSACTION
1890 TransactionStmt *n = makeNode(TransactionStmt);
1891 n->command = ABORT_TRANS;
1894 | BEGIN_TRANS TRANSACTION
1896 TransactionStmt *n = makeNode(TransactionStmt);
1897 n->command = BEGIN_TRANS;
1902 TransactionStmt *n = makeNode(TransactionStmt);
1903 n->command = BEGIN_TRANS;
1908 TransactionStmt *n = makeNode(TransactionStmt);
1909 n->command = END_TRANS;
1912 | END_TRANS TRANSACTION
1914 TransactionStmt *n = makeNode(TransactionStmt);
1915 n->command = END_TRANS;
1920 TransactionStmt *n = makeNode(TransactionStmt);
1921 n->command = ABORT_TRANS;
1927 TransactionStmt *n = makeNode(TransactionStmt);
1928 n->command = ABORT_TRANS;
1933 TransactionStmt *n = makeNode(TransactionStmt);
1934 n->command = BEGIN_TRANS;
1939 TransactionStmt *n = makeNode(TransactionStmt);
1940 n->command = END_TRANS;
1946 TransactionStmt *n = makeNode(TransactionStmt);
1947 n->command = END_TRANS;
1952 TransactionStmt *n = makeNode(TransactionStmt);
1953 n->command = ABORT_TRANS;
1959 /*****************************************************************************
1962 * define view <viewname> '('target-list ')' [where <quals> ]
1964 *****************************************************************************/
1966 ViewStmt: CREATE VIEW name AS RetrieveStmt
1968 ViewStmt *n = makeNode(ViewStmt);
1970 n->query = (Query *)$5;
1976 /*****************************************************************************
1981 *****************************************************************************/
1983 LoadStmt: LOAD file_name
1985 LoadStmt *n = makeNode(LoadStmt);
1992 /*****************************************************************************
1997 *****************************************************************************/
1999 CreatedbStmt: CREATE DATABASE database_name opt_database
2001 CreatedbStmt *n = makeNode(CreatedbStmt);
2008 opt_database: WITH LOCATION '=' location { $$ = $4; }
2009 | /*EMPTY*/ { $$ = NULL; }
2012 location: Sconst { $$ = $1; }
2013 | DEFAULT { $$ = NULL; }
2014 | /*EMPTY*/ { $$ = NULL; }
2017 /*****************************************************************************
2022 *****************************************************************************/
2024 DestroydbStmt: DROP DATABASE database_name
2026 DestroydbStmt *n = makeNode(DestroydbStmt);
2033 /*****************************************************************************
2036 * cluster <index_name> on <relation_name>
2038 *****************************************************************************/
2040 ClusterStmt: CLUSTER index_name ON relation_name
2042 ClusterStmt *n = makeNode(ClusterStmt);
2050 /*****************************************************************************
2055 *****************************************************************************/
2057 VacuumStmt: VACUUM opt_verbose opt_analyze
2059 VacuumStmt *n = makeNode(VacuumStmt);
2066 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2068 VacuumStmt *n = makeNode(VacuumStmt);
2073 if ( $5 != NIL && !$4 )
2074 elog(WARN,"parser: syntax error at or near \"(\"",NULL);
2079 opt_verbose: VERBOSE { $$ = TRUE; }
2080 | /*EMPTY*/ { $$ = FALSE; }
2083 opt_analyze: ANALYZE { $$ = TRUE; }
2084 | /*EMPTY*/ { $$ = FALSE; }
2087 opt_va_list: '(' va_list ')'
2094 { $$=lcons($1,NIL); }
2096 { $$=lappend($1,$3); }
2100 /*****************************************************************************
2105 *****************************************************************************/
2107 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2109 ExplainStmt *n = makeNode(ExplainStmt);
2111 n->query = (Query*)$3;
2117 /*****************************************************************************
2119 * Optimizable Stmts: *
2121 * one of the five queries processed by the planner *
2123 * [ultimately] produces query-trees as specified *
2124 * in the query-spec document in ~postgres/ref *
2126 *****************************************************************************/
2128 OptimizableStmt: RetrieveStmt
2133 | DeleteStmt /* by default all are $$=$1 */
2137 /*****************************************************************************
2142 *****************************************************************************/
2144 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
2152 insert_rest: VALUES '(' res_target_list2 ')'
2154 $$ = makeNode(AppendStmt);
2155 $$->targetList = $3;
2156 $$->fromClause = NIL;
2157 $$->whereClause = NULL;
2159 | SELECT res_target_list2 from_clause where_clause
2161 $$ = makeNode(AppendStmt);
2162 $$->targetList = $2;
2163 $$->fromClause = $3;
2164 $$->whereClause = $4;
2168 opt_column_list: '(' columnList ')' { $$ = $2; }
2169 | /*EMPTY*/ { $$ = NIL; }
2173 columnList ',' columnElem
2174 { $$ = lappend($1, $3); }
2176 { $$ = lcons($1, NIL); }
2179 columnElem: ColId opt_indirection
2181 Ident *id = makeNode(Ident);
2183 id->indirection = $2;
2189 /*****************************************************************************
2194 *****************************************************************************/
2196 DeleteStmt: DELETE FROM relation_name
2199 DeleteStmt *n = makeNode(DeleteStmt);
2201 n->whereClause = $4;
2207 /*****************************************************************************
2210 * ReplaceStmt (UPDATE)
2212 *****************************************************************************/
2214 ReplaceStmt: UPDATE relation_name
2219 ReplaceStmt *n = makeNode(ReplaceStmt);
2223 n->whereClause = $6;
2229 /*****************************************************************************
2234 *****************************************************************************/
2236 CursorStmt: DECLARE name opt_binary CURSOR FOR
2237 SELECT opt_unique res_target_list2
2238 from_clause where_clause group_clause sort_clause
2240 CursorStmt *n = makeNode(CursorStmt);
2242 /* from PORTAL name */
2244 * 15 august 1991 -- since 3.0 postgres does locking
2245 * right, we discovered that portals were violating
2246 * locking protocol. portal locks cannot span xacts.
2247 * as a short-term fix, we installed the check here.
2250 if (!IsTransactionBlock())
2251 elog(WARN,"Named portals may only be used in begin/end transaction blocks",NULL);
2258 n->whereClause = $10;
2259 n->groupClause = $11;
2260 n->sortClause = $12;
2266 /*****************************************************************************
2271 *****************************************************************************/
2273 RetrieveStmt: SELECT opt_unique res_target_list2
2274 result from_clause where_clause
2275 group_clause having_clause
2276 union_clause sort_clause
2278 RetrieveStmt *n = makeNode(RetrieveStmt);
2283 n->whereClause = $6;
2284 n->groupClause = $7;
2285 n->havingClause = $8;
2286 n->unionClause = $9;
2287 n->sortClause = $10;
2292 union_clause: UNION opt_union select_list
2294 SubSelect *n = lfirst($3);
2302 select_list: select_list UNION opt_union SubSelect
2304 SubSelect *n = (SubSelect *)$4;
2306 $$ = lappend($1, $4);
2309 { $$ = lcons($1, NIL); }
2312 SubSelect: SELECT opt_unique res_target_list2
2313 from_clause where_clause
2314 group_clause having_clause
2316 SubSelect *n = makeNode(SubSelect);
2318 n->unionall = FALSE;
2321 n->whereClause = $5;
2322 n->groupClause = $6;
2323 n->havingClause = $7;
2328 result: INTO TABLE relation_name
2334 opt_union: ALL { $$ = TRUE; }
2335 | /*EMPTY*/ { $$ = FALSE; }
2338 opt_unique: DISTINCT { $$ = "*"; }
2339 | DISTINCT ON ColId { $$ = $3; }
2340 | ALL { $$ = NULL; }
2341 | /*EMPTY*/ { $$ = NULL; }
2344 sort_clause: ORDER BY sortby_list { $$ = $3; }
2345 | /*EMPTY*/ { $$ = NIL; }
2348 sortby_list: sortby { $$ = lcons($1, NIL); }
2349 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2352 sortby: ColId OptUseOp
2354 $$ = makeNode(SortGroupBy);
2360 | ColId '.' ColId OptUseOp
2362 $$ = makeNode(SortGroupBy);
2370 $$ = makeNode(SortGroupBy);
2378 OptUseOp: USING Op { $$ = $2; }
2379 | USING '<' { $$ = "<"; }
2380 | USING '>' { $$ = ">"; }
2382 | DESC { $$ = ">"; }
2383 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2387 * jimmy bell-style recursive queries aren't supported in the
2390 * ...however, recursive addattr and rename supported. make special
2393 * XXX i believe '*' should be the default behavior, but...
2395 opt_inh_star: '*' { $$ = TRUE; }
2396 | /*EMPTY*/ { $$ = FALSE; }
2399 relation_name_list: name_list;
2402 { $$ = lcons(makeString($1),NIL); }
2403 | name_list ',' name
2404 { $$ = lappend($1,makeString($3)); }
2407 group_clause: GROUP BY groupby_list { $$ = $3; }
2408 | /*EMPTY*/ { $$ = NIL; }
2411 groupby_list: groupby { $$ = lcons($1, NIL); }
2412 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2417 $$ = makeNode(SortGroupBy);
2425 $$ = makeNode(SortGroupBy);
2433 $$ = makeNode(SortGroupBy);
2441 having_clause: HAVING a_expr { $$ = $2; }
2442 | /*EMPTY*/ { $$ = NULL; }
2446 /*****************************************************************************
2448 * clauses common to all Optimizable Stmts:
2452 *****************************************************************************/
2454 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2457 elog(WARN,"JOIN not yet implemented",NULL);
2459 | FROM from_list { $$ = $2; }
2460 | /*EMPTY*/ { $$ = NIL; }
2463 from_list: from_list ',' from_val
2464 { $$ = lappend($1, $3); }
2465 | from_val CROSS JOIN from_val
2466 { elog(WARN,"CROSS JOIN not yet implemented",NULL); }
2468 { $$ = lcons($1, NIL); }
2471 from_val: relation_expr AS ColLabel
2473 $$ = makeNode(RangeVar);
2477 | relation_expr ColId
2479 $$ = makeNode(RangeVar);
2485 $$ = makeNode(RangeVar);
2491 join_expr: NATURAL join_expr { $$ = NULL; }
2493 { elog(WARN,"FULL OUTER JOIN not yet implemented",NULL); }
2495 { elog(WARN,"LEFT OUTER JOIN not yet implemented",NULL); }
2497 { elog(WARN,"RIGHT OUTER JOIN not yet implemented",NULL); }
2499 { elog(WARN,"OUTER JOIN not yet implemented",NULL); }
2501 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2503 { elog(WARN,"UNION JOIN not yet implemented",NULL); }
2505 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2508 join_outer: OUTER_P { $$ = NULL; }
2509 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2512 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2513 | USING '(' join_list ')' { $$ = NULL; }
2514 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2517 join_list: join_using { $$ = lcons($1, NIL); }
2518 | join_list ',' join_using { $$ = lappend($1, $3); }
2523 $$ = makeNode(SortGroupBy);
2531 $$ = makeNode(SortGroupBy);
2539 $$ = makeNode(SortGroupBy);
2547 where_clause: WHERE a_expr { $$ = $2; }
2548 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2551 relation_expr: relation_name
2553 /* normal relations */
2554 $$ = makeNode(RelExpr);
2558 | relation_name '*' %prec '='
2560 /* inheritance query */
2561 $$ = makeNode(RelExpr);
2566 opt_array_bounds: '[' ']' nest_array_bounds
2567 { $$ = lcons(makeInteger(-1), $3); }
2568 | '[' Iconst ']' nest_array_bounds
2569 { $$ = lcons(makeInteger($2), $4); }
2574 nest_array_bounds: '[' ']' nest_array_bounds
2575 { $$ = lcons(makeInteger(-1), $3); }
2576 | '[' Iconst ']' nest_array_bounds
2577 { $$ = lcons(makeInteger($2), $4); }
2583 /*****************************************************************************
2586 * SQL92 introduces a large amount of type-specific syntax.
2587 * Define individual clauses to handle these cases, and use
2588 * the generic case to handle regular type-extensible Postgres syntax.
2589 * - thomas 1997-10-10
2591 *****************************************************************************/
2593 Typename: Array opt_array_bounds
2596 $$->arrayBounds = $2;
2598 /* Is this the name of a complex type? If so, implement
2601 if (!strcmp(saved_relname, $$->name))
2602 /* This attr is the same type as the relation
2603 * being defined. The classic example: create
2604 * emp(name=text,mgr=emp)
2607 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2608 /* (Eventually add in here that the set can only
2609 * contain one element.)
2630 $$ = makeNode(TypeName);
2631 $$->name = xlateSqlType($1);
2635 generic: Id { $$ = $1; }
2636 | TYPE_P { $$ = xlateSqlType("type"); }
2637 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2640 /* SQL92 numeric data types
2641 * Check FLOAT() precision limits assuming IEEE floating types.
2642 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2643 * by checking parameters and making sure they match what is possible with INTEGER.
2644 * - thomas 1997-09-18
2646 Numeric: FLOAT opt_float
2648 $$ = makeNode(TypeName);
2649 $$->name = xlateSqlType($2);
2651 | DECIMAL opt_decimal
2653 $$ = makeNode(TypeName);
2654 $$->name = xlateSqlType("integer");
2656 | NUMERIC opt_numeric
2658 $$ = makeNode(TypeName);
2659 $$->name = xlateSqlType("integer");
2663 opt_float: '(' Iconst ')'
2666 elog(WARN,"precision for FLOAT must be at least 1",NULL);
2668 $$ = xlateSqlType("float4");
2670 $$ = xlateSqlType("float8");
2672 elog(WARN,"precision for FLOAT must be less than 16",NULL);
2676 $$ = xlateSqlType("float8");
2680 opt_numeric: '(' Iconst ',' Iconst ')'
2683 elog(WARN,"NUMERIC precision %d must be 9",$2);
2685 elog(WARN,"NUMERIC scale %d must be zero",$4);
2690 elog(WARN,"NUMERIC precision %d must be 9",$2);
2698 opt_decimal: '(' Iconst ',' Iconst ')'
2701 elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2703 elog(WARN,"DECIMAL scale %d must be zero",$4);
2709 elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2718 /* SQL92 character data types
2719 * The following implements CHAR() and VARCHAR().
2720 * We do it here instead of the 'Generic' production
2721 * because we don't want to allow arrays of VARCHAR().
2722 * I haven't thought about whether that will work or not.
2725 Character: character '(' Iconst ')'
2727 $$ = makeNode(TypeName);
2728 if (!strcasecmp($1, "char"))
2729 $$->name = xlateSqlType("bpchar");
2730 else if (!strcasecmp($1, "varchar"))
2731 $$->name = xlateSqlType("varchar");
2733 yyerror("parse error");
2735 elog(WARN,"length for '%s' type must be at least 1",$1);
2737 /* we can store a char() of length up to the size
2738 * of a page (8KB) - page headers and friends but
2739 * just to be safe here... - ay 6/95
2740 * XXX note this hardcoded limit - thomas 1997-07-13
2742 elog(WARN,"length for type '%s' cannot exceed 4096",$1);
2744 /* we actually implement this sort of like a varlen, so
2745 * the first 4 bytes is the length. (the difference
2746 * between this and "text" is that we blank-pad and
2747 * truncate where necessary
2749 $$->typlen = VARHDRSZ + $3;
2753 $$ = makeNode(TypeName);
2754 $$->name = xlateSqlType($1);
2758 character: CHARACTER opt_varying opt_charset opt_collate
2761 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2762 if ($2) type = xlateSqlType("varchar");
2763 else type = xlateSqlType("char");
2766 c = palloc(strlen("var") + strlen($3) + 1);
2769 type = xlateSqlType(c);
2771 type = xlateSqlType($3);
2775 elog(WARN,"COLLATE %s not yet implemented",$4);
2778 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2779 | VARCHAR { $$ = xlateSqlType("varchar"); }
2780 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2781 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2784 opt_varying: VARYING { $$ = TRUE; }
2785 | /*EMPTY*/ { $$ = FALSE; }
2788 opt_charset: CHARACTER SET ColId { $$ = $3; }
2789 | /*EMPTY*/ { $$ = NULL; }
2792 opt_collate: COLLATE ColId { $$ = $2; }
2793 | /*EMPTY*/ { $$ = NULL; }
2798 $$ = makeNode(TypeName);
2799 $$->name = xlateSqlType($1);
2801 | TIMESTAMP opt_timezone
2803 $$ = makeNode(TypeName);
2804 $$->name = xlateSqlType("timestamp");
2809 $$ = makeNode(TypeName);
2810 $$->name = xlateSqlType("time");
2812 | INTERVAL opt_interval
2814 $$ = makeNode(TypeName);
2815 $$->name = xlateSqlType("interval");
2819 datetime: YEAR_P { $$ = "year"; }
2820 | MONTH_P { $$ = "month"; }
2821 | DAY_P { $$ = "day"; }
2822 | HOUR_P { $$ = "hour"; }
2823 | MINUTE_P { $$ = "minute"; }
2824 | SECOND_P { $$ = "second"; }
2827 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2828 | /*EMPTY*/ { $$ = FALSE; }
2831 opt_interval: datetime { $$ = lcons($1, NIL); }
2832 | YEAR_P TO MONTH_P { $$ = NIL; }
2833 | DAY_P TO HOUR_P { $$ = NIL; }
2834 | DAY_P TO MINUTE_P { $$ = NIL; }
2835 | DAY_P TO SECOND_P { $$ = NIL; }
2836 | HOUR_P TO MINUTE_P { $$ = NIL; }
2837 | HOUR_P TO SECOND_P { $$ = NIL; }
2838 | /*EMPTY*/ { $$ = NIL; }
2842 /*****************************************************************************
2844 * expression grammar, still needs some cleanup
2846 *****************************************************************************/
2848 a_expr_or_null: a_expr
2852 A_Const *n = makeNode(A_Const);
2853 n->val.type = T_Null;
2858 /* Expressions using row descriptors
2859 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2860 * with singleton expressions.
2862 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2866 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
2870 | '(' row_descriptor ')' '=' '(' row_descriptor ')'
2872 $$ = makeRowExpr("=", $2, $6);
2874 | '(' row_descriptor ')' '<' '(' row_descriptor ')'
2876 $$ = makeRowExpr("<", $2, $6);
2878 | '(' row_descriptor ')' '>' '(' row_descriptor ')'
2880 $$ = makeRowExpr("<", $2, $6);
2882 | '(' row_descriptor ')' Op '(' row_descriptor ')'
2884 $$ = makeRowExpr($4, $2, $6);
2888 row_descriptor: row_list ',' a_expr
2890 $$ = lappend($1, $3);
2894 row_list: row_list ',' a_expr
2896 $$ = lappend($1, $3);
2900 $$ = lcons($1, NIL);
2904 a_expr: attr opt_indirection
2906 $1->indirection = $2;
2913 | '-' a_expr %prec UMINUS
2914 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2916 { $$ = makeA_Expr(OP, "+", $1, $3); }
2918 { $$ = makeA_Expr(OP, "-", $1, $3); }
2920 { $$ = makeA_Expr(OP, "/", $1, $3); }
2922 { $$ = makeA_Expr(OP, "*", $1, $3); }
2924 { $$ = makeA_Expr(OP, "<", $1, $3); }
2926 { $$ = makeA_Expr(OP, ">", $1, $3); }
2928 { $$ = makeA_Expr(OP, "=", $1, $3); }
2930 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2932 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2934 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2935 | a_expr TYPECAST Typename
2938 /* AexprConst can be either A_Const or ParamNo */
2939 if (nodeTag($1) == T_A_Const) {
2940 ((A_Const *)$1)->typename = $3;
2941 } else if (nodeTag($1) == T_Param) {
2942 ((ParamNo *)$1)->typename = $3;
2943 /* otherwise, try to transform to a function call */
2945 FuncCall *n = makeNode(FuncCall);
2946 n->funcname = $3->name;
2947 n->args = lcons($1,NIL);
2951 | CAST a_expr AS Typename
2954 /* AexprConst can be either A_Const or ParamNo */
2955 if (nodeTag($2) == T_A_Const) {
2956 ((A_Const *)$2)->typename = $4;
2957 } else if (nodeTag($2) == T_Param) {
2958 ((ParamNo *)$2)->typename = $4;
2959 /* otherwise, try to transform to a function call */
2961 FuncCall *n = makeNode(FuncCall);
2962 n->funcname = $4->name;
2963 n->args = lcons($2,NIL);
2967 | '(' a_expr_or_null ')'
2970 { $$ = makeIndexable($2,$1,$3); }
2971 | a_expr LIKE a_expr
2972 { $$ = makeIndexable("~~", $1, $3); }
2973 | a_expr NOT LIKE a_expr
2974 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
2976 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2978 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2981 /* could be a column name or a relation_name */
2982 Ident *n = makeNode(Ident);
2984 n->indirection = NULL;
2989 FuncCall *n = makeNode(FuncCall);
2990 Ident *star = makeNode(Ident);
2992 /* cheap hack for aggregate (eg. count) */
2995 n->args = lcons(star, NIL);
3000 FuncCall *n = makeNode(FuncCall);
3005 | name '(' expr_list ')'
3007 FuncCall *n = makeNode(FuncCall);
3014 A_Const *n = makeNode(A_Const);
3015 TypeName *t = makeNode(TypeName);
3017 n->val.type = T_String;
3018 n->val.val.str = "now";
3021 t->name = xlateSqlType("date");
3028 A_Const *n = makeNode(A_Const);
3029 TypeName *t = makeNode(TypeName);
3031 n->val.type = T_String;
3032 n->val.val.str = "now";
3035 t->name = xlateSqlType("time");
3040 | CURRENT_TIME '(' Iconst ')'
3042 FuncCall *n = makeNode(FuncCall);
3043 A_Const *s = makeNode(A_Const);
3044 TypeName *t = makeNode(TypeName);
3046 n->funcname = xlateSqlType("time");
3047 n->args = lcons(s, NIL);
3049 s->val.type = T_String;
3050 s->val.val.str = "now";
3053 t->name = xlateSqlType("time");
3057 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3063 A_Const *n = makeNode(A_Const);
3064 TypeName *t = makeNode(TypeName);
3066 n->val.type = T_String;
3067 n->val.val.str = "now";
3070 t->name = xlateSqlType("timestamp");
3075 | CURRENT_TIMESTAMP '(' Iconst ')'
3077 FuncCall *n = makeNode(FuncCall);
3078 A_Const *s = makeNode(A_Const);
3079 TypeName *t = makeNode(TypeName);
3081 n->funcname = xlateSqlType("timestamp");
3082 n->args = lcons(s, NIL);
3084 s->val.type = T_String;
3085 s->val.val.str = "now";
3088 t->name = xlateSqlType("timestamp");
3092 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3098 FuncCall *n = makeNode(FuncCall);
3099 n->funcname = "getpgusername";
3103 /* We probably need to define an "exists" node,
3104 * since the optimizer could choose to find only one match.
3105 * Perhaps the first implementation could just check for
3106 * count(*) > 0? - thomas 1997-07-19
3108 | EXISTS '(' SubSelect ')'
3110 elog(WARN,"EXISTS not yet implemented",NULL);
3113 | EXTRACT '(' extract_list ')'
3115 FuncCall *n = makeNode(FuncCall);
3116 n->funcname = "date_part";
3120 | POSITION '(' position_list ')'
3122 FuncCall *n = makeNode(FuncCall);
3123 n->funcname = "strpos";
3127 | SUBSTRING '(' substr_list ')'
3129 FuncCall *n = makeNode(FuncCall);
3130 n->funcname = "substr";
3134 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3135 | TRIM '(' BOTH trim_list ')'
3137 FuncCall *n = makeNode(FuncCall);
3138 n->funcname = "btrim";
3142 | TRIM '(' LEADING trim_list ')'
3144 FuncCall *n = makeNode(FuncCall);
3145 n->funcname = "ltrim";
3149 | TRIM '(' TRAILING trim_list ')'
3151 FuncCall *n = makeNode(FuncCall);
3152 n->funcname = "rtrim";
3156 | TRIM '(' trim_list ')'
3158 FuncCall *n = makeNode(FuncCall);
3159 n->funcname = "btrim";
3164 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3166 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3168 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3169 | a_expr IS NOT NULL_P
3170 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3171 /* IS TRUE, IS FALSE, etc used to be function calls
3172 * but let's make them expressions to allow the optimizer
3173 * a chance to eliminate them if a_expr is a constant string.
3174 * - thomas 1997-12-22
3178 A_Const *n = makeNode(A_Const);
3179 n->val.type = T_String;
3180 n->val.val.str = "t";
3181 n->typename = makeNode(TypeName);
3182 n->typename->name = xlateSqlType("bool");
3183 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3185 | a_expr IS NOT FALSE_P
3187 A_Const *n = makeNode(A_Const);
3188 n->val.type = T_String;
3189 n->val.val.str = "t";
3190 n->typename = makeNode(TypeName);
3191 n->typename->name = xlateSqlType("bool");
3192 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3196 A_Const *n = makeNode(A_Const);
3197 n->val.type = T_String;
3198 n->val.val.str = "f";
3199 n->typename = makeNode(TypeName);
3200 n->typename->name = xlateSqlType("bool");
3201 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3203 | a_expr IS NOT TRUE_P
3205 A_Const *n = makeNode(A_Const);
3206 n->val.type = T_String;
3207 n->val.val.str = "f";
3208 n->typename = makeNode(TypeName);
3209 n->typename->name = xlateSqlType("bool");
3210 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3212 | a_expr BETWEEN AexprConst AND AexprConst
3214 $$ = makeA_Expr(AND, NULL,
3215 makeA_Expr(OP, ">=", $1, $3),
3216 makeA_Expr(OP, "<=", $1, $5));
3218 | a_expr NOT BETWEEN AexprConst AND AexprConst
3220 $$ = makeA_Expr(OR, NULL,
3221 makeA_Expr(OP, "<", $1, $4),
3222 makeA_Expr(OP, ">", $1, $6));
3224 | a_expr IN { saved_In_Expr = $1; } '(' in_expr ')'
3226 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr ')'
3229 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3231 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3233 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3236 opt_indirection: '[' a_expr ']' opt_indirection
3238 A_Indices *ai = makeNode(A_Indices);
3243 | '[' a_expr ':' a_expr ']' opt_indirection
3245 A_Indices *ai = makeNode(A_Indices);
3254 expr_list: a_expr_or_null
3255 { $$ = lcons($1, NIL); }
3256 | expr_list ',' a_expr_or_null
3257 { $$ = lappend($1, $3); }
3258 | expr_list USING a_expr
3259 { $$ = lappend($1, $3); }
3262 extract_list: datetime FROM a_expr
3264 A_Const *n = makeNode(A_Const);
3265 n->val.type = T_String;
3266 n->val.val.str = $1;
3267 $$ = lappend(lcons((Node *)n,NIL), $3);
3273 position_list: position_expr IN position_expr
3274 { $$ = makeList($3, $1, -1); }
3279 position_expr: attr opt_indirection
3281 $1->indirection = $2;
3286 | '-' position_expr %prec UMINUS
3287 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3288 | position_expr '+' position_expr
3289 { $$ = makeA_Expr(OP, "+", $1, $3); }
3290 | position_expr '-' position_expr
3291 { $$ = makeA_Expr(OP, "-", $1, $3); }
3292 | position_expr '/' position_expr
3293 { $$ = makeA_Expr(OP, "/", $1, $3); }
3294 | position_expr '*' position_expr
3295 { $$ = makeA_Expr(OP, "*", $1, $3); }
3297 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3298 | position_expr TYPECAST Typename
3301 /* AexprConst can be either A_Const or ParamNo */
3302 if (nodeTag($1) == T_A_Const) {
3303 ((A_Const *)$1)->typename = $3;
3304 } else if (nodeTag($1) == T_Param) {
3305 ((ParamNo *)$1)->typename = $3;
3306 /* otherwise, try to transform to a function call */
3308 FuncCall *n = makeNode(FuncCall);
3309 n->funcname = $3->name;
3310 n->args = lcons($1,NIL);
3314 | CAST position_expr AS Typename
3317 /* AexprConst can be either A_Const or ParamNo */
3318 if (nodeTag($2) == T_A_Const) {
3319 ((A_Const *)$2)->typename = $4;
3320 } else if (nodeTag($2) == T_Param) {
3321 ((ParamNo *)$2)->typename = $4;
3322 /* otherwise, try to transform to a function call */
3324 FuncCall *n = makeNode(FuncCall);
3325 n->funcname = $4->name;
3326 n->args = lcons($2,NIL);
3330 | '(' position_expr ')'
3332 | position_expr Op position_expr
3333 { $$ = makeA_Expr(OP, $2, $1, $3); }
3335 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3337 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3340 /* could be a column name or a relation_name */
3341 Ident *n = makeNode(Ident);
3343 n->indirection = NULL;
3348 FuncCall *n = makeNode(FuncCall);
3353 | name '(' expr_list ')'
3355 FuncCall *n = makeNode(FuncCall);
3360 | POSITION '(' position_list ')'
3362 FuncCall *n = makeNode(FuncCall);
3363 n->funcname = "strpos";
3367 | SUBSTRING '(' substr_list ')'
3369 FuncCall *n = makeNode(FuncCall);
3370 n->funcname = "substr";
3374 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3375 | TRIM '(' BOTH trim_list ')'
3377 FuncCall *n = makeNode(FuncCall);
3378 n->funcname = "btrim";
3382 | TRIM '(' LEADING trim_list ')'
3384 FuncCall *n = makeNode(FuncCall);
3385 n->funcname = "ltrim";
3389 | TRIM '(' TRAILING trim_list ')'
3391 FuncCall *n = makeNode(FuncCall);
3392 n->funcname = "rtrim";
3396 | TRIM '(' trim_list ')'
3398 FuncCall *n = makeNode(FuncCall);
3399 n->funcname = "btrim";
3405 substr_list: expr_list substr_from substr_for
3407 $$ = nconc(nconc($1,$2),$3);
3413 substr_from: FROM expr_list
3417 A_Const *n = makeNode(A_Const);
3418 n->val.type = T_Integer;
3419 n->val.val.ival = 1;
3420 $$ = lcons((Node *)n,NIL);
3424 substr_for: FOR expr_list
3430 trim_list: a_expr FROM expr_list
3431 { $$ = lappend($3, $1); }
3440 elog(WARN,"IN (SUBSELECT) not yet implemented",NULL);
3447 in_expr_nodes: AexprConst
3448 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
3449 | in_expr_nodes ',' AexprConst
3450 { $$ = makeA_Expr(OR, NULL, $1,
3451 makeA_Expr(OP, "=", saved_In_Expr, $3));
3455 not_in_expr: SubSelect
3457 elog(WARN,"NOT IN (SUBSELECT) not yet implemented",NULL);
3464 not_in_expr_nodes: AexprConst
3465 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
3466 | not_in_expr_nodes ',' AexprConst
3467 { $$ = makeA_Expr(AND, NULL, $1,
3468 makeA_Expr(OP, "<>", saved_In_Expr, $3));
3472 attr: relation_name '.' attrs
3474 $$ = makeNode(Attr);
3478 $$->indirection = NULL;
3482 $$ = makeNode(Attr);
3486 $$->indirection = NULL;
3491 { $$ = lcons(makeString($1), NIL); }
3492 | attrs '.' attr_name
3493 { $$ = lappend($1, makeString($3)); }
3495 { $$ = lappend($1, makeString("*")); }
3499 /*****************************************************************************
3503 *****************************************************************************/
3505 res_target_list: res_target_list ',' res_target_el
3506 { $$ = lappend($1,$3); }
3508 { $$ = lcons($1, NIL); }
3511 ResTarget *rt = makeNode(ResTarget);
3512 Attr *att = makeNode(Attr);
3514 att->paramNo = NULL;
3516 att->indirection = NIL;
3518 rt->indirection = NULL;
3519 rt->val = (Node *)att;
3520 $$ = lcons(rt, NIL);
3524 res_target_el: ColId opt_indirection '=' a_expr_or_null
3526 $$ = makeNode(ResTarget);
3528 $$->indirection = $2;
3529 $$->val = (Node *)$4;
3531 | attr opt_indirection
3533 $$ = makeNode(ResTarget);
3535 $$->indirection = $2;
3536 $$->val = (Node *)$1;
3538 | relation_name '.' '*'
3540 Attr *att = makeNode(Attr);
3542 att->paramNo = NULL;
3543 att->attrs = lcons(makeString("*"), NIL);
3544 att->indirection = NIL;
3545 $$ = makeNode(ResTarget);
3547 $$->indirection = NULL;
3548 $$->val = (Node *)att;
3553 ** target list for select.
3554 ** should get rid of the other but is still needed by the defunct retrieve into
3555 ** and update (uses a subset)
3557 res_target_list2: res_target_list2 ',' res_target_el2
3558 { $$ = lappend($1, $3); }
3560 { $$ = lcons($1, NIL); }
3563 /* AS is not optional because shift/red conflict with unary ops */
3564 res_target_el2: a_expr_or_null AS ColLabel
3566 $$ = makeNode(ResTarget);
3568 $$->indirection = NULL;
3569 $$->val = (Node *)$1;
3573 $$ = makeNode(ResTarget);
3575 $$->indirection = NULL;
3576 $$->val = (Node *)$1;
3578 | relation_name '.' '*'
3580 Attr *att = makeNode(Attr);
3582 att->paramNo = NULL;
3583 att->attrs = lcons(makeString("*"), NIL);
3584 att->indirection = NIL;
3585 $$ = makeNode(ResTarget);
3587 $$->indirection = NULL;
3588 $$->val = (Node *)att;
3592 Attr *att = makeNode(Attr);
3594 att->paramNo = NULL;
3596 att->indirection = NIL;
3597 $$ = makeNode(ResTarget);
3599 $$->indirection = NULL;
3600 $$->val = (Node *)att;
3604 opt_id: ColId { $$ = $1; }
3605 | /* EMPTY */ { $$ = NULL; }
3608 relation_name: SpecialRuleRelation
3611 StrNCpy(saved_relname, $1, NAMEDATALEN);
3615 /* disallow refs to variable system tables */
3616 if (strcmp(LogRelationName, $1) == 0
3617 || strcmp(VariableRelationName, $1) == 0)
3618 elog(WARN,"%s cannot be accessed by users",$1);
3621 StrNCpy(saved_relname, $1, NAMEDATALEN);
3625 database_name: ColId { $$ = $1; };
3626 access_method: Id { $$ = $1; };
3627 attr_name: ColId { $$ = $1; };
3628 class: Id { $$ = $1; };
3629 index_name: ColId { $$ = $1; };
3632 * Include date/time keywords as SQL92 extension.
3633 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3635 name: ColId { $$ = $1; };
3637 file_name: Sconst { $$ = $1; };
3638 recipe_name: Id { $$ = $1; };
3641 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
3645 A_Const *n = makeNode(A_Const);
3646 n->val.type = T_Integer;
3647 n->val.val.ival = $1;
3652 A_Const *n = makeNode(A_Const);
3653 n->val.type = T_Float;
3654 n->val.val.dval = $1;
3659 A_Const *n = makeNode(A_Const);
3660 n->val.type = T_String;
3661 n->val.val.str = $1;
3666 A_Const *n = makeNode(A_Const);
3668 n->val.type = T_String;
3669 n->val.val.str = $2;
3673 { $$ = (Node *)$1; }
3676 A_Const *n = makeNode(A_Const);
3677 n->val.type = T_String;
3678 n->val.val.str = "t";
3679 n->typename = makeNode(TypeName);
3680 n->typename->name = xlateSqlType("bool");
3685 A_Const *n = makeNode(A_Const);
3686 n->val.type = T_String;
3687 n->val.val.str = "f";
3688 n->typename = makeNode(TypeName);
3689 n->typename->name = xlateSqlType("bool");
3696 $$ = makeNode(ParamNo);
3701 NumConst: Iconst { $$ = makeInteger($1); }
3702 | FCONST { $$ = makeFloat($1); }
3705 Iconst: ICONST { $$ = $1; };
3706 Sconst: SCONST { $$ = $1; };
3708 /* Column and type identifier
3709 * Does not include explicit datetime types
3710 * since these must be decoupled in Typename syntax.
3711 * Use ColId for most identifiers. - thomas 1997-10-21
3713 Id: IDENT { $$ = $1; };
3715 /* Column identifier
3716 * Include date/time keywords as SQL92 extension.
3717 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3718 * Add other keywords. Note that as the syntax expands,
3719 * some of these keywords will have to be removed from this
3720 * list due to shift/reduce conflicts in yacc. If so, move
3721 * down to the ColLabel entity. - thomas 1997-11-06
3723 ColId: Id { $$ = $1; }
3724 | datetime { $$ = $1; }
3725 | ACTION { $$ = "action"; }
3726 | DATABASE { $$ = "database"; }
3727 | DELIMITERS { $$ = "delimiters"; }
3728 | FUNCTION { $$ = "function"; }
3729 | INDEX { $$ = "index"; }
3730 | KEY { $$ = "key"; }
3731 | LANGUAGE { $$ = "language"; }
3732 | LOCATION { $$ = "location"; }
3733 | MATCH { $$ = "match"; }
3734 | OPERATOR { $$ = "operator"; }
3735 | OPTION { $$ = "option"; }
3736 | PRIVILEGES { $$ = "privileges"; }
3737 | RECIPE { $$ = "recipe"; }
3738 | TIME { $$ = "time"; }
3739 | TRIGGER { $$ = "trigger"; }
3740 | TYPE_P { $$ = "type"; }
3741 | VERSION { $$ = "version"; }
3742 | ZONE { $$ = "zone"; }
3746 * Allowed labels in "AS" clauses.
3747 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
3748 * compatibility. Cannot allow this for column names since the
3749 * syntax would not distinguish between the constant value and
3750 * a column name. - thomas 1997-10-24
3751 * Add other keywords to this list. Note that they appear here
3752 * rather than in ColId if there was a shift/reduce conflict
3753 * when used as a full identifier. - thomas 1997-11-06
3755 ColLabel: ColId { $$ = $1; }
3756 | ARCHIVE { $$ = "archive"; }
3757 | CLUSTER { $$ = "cluster"; }
3758 | CONSTRAINT { $$ = "constraint"; }
3759 | CROSS { $$ = "cross"; }
3760 | FOREIGN { $$ = "foreign"; }
3761 | GROUP { $$ = "group"; }
3762 | LOAD { $$ = "load"; }
3763 | ORDER { $$ = "order"; }
3764 | POSITION { $$ = "position"; }
3765 | PRECISION { $$ = "precision"; }
3766 | TABLE { $$ = "table"; }
3767 | TRANSACTION { $$ = "transaction"; }
3768 | TRUE_P { $$ = "true"; }
3769 | FALSE_P { $$ = "false"; }
3772 SpecialRuleRelation: CURRENT
3777 elog(WARN,"CURRENT used in non-rule query",NULL);
3784 elog(WARN,"NEW used in non-rule query",NULL);
3791 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
3793 A_Expr *a = makeNode(A_Expr);
3802 * Generate separate operator nodes for a single row descriptor expression.
3803 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
3806 makeRowExpr(char *opr, List *largs, List *rargs)
3811 if (length(largs) != length(rargs))
3812 elog(WARN,"Unequal number of entries in row expression",NULL);
3814 if (lnext(largs) != NIL)
3815 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
3817 larg = lfirst(largs);
3818 rarg = lfirst(rargs);
3820 if ((strcmp(opr, "=") == 0)
3821 || (strcmp(opr, "<") == 0)
3822 || (strcmp(opr, "<=") == 0)
3823 || (strcmp(opr, ">") == 0)
3824 || (strcmp(opr, ">=") == 0))
3827 expr = makeA_Expr(OP, opr, larg, rarg);
3829 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3831 else if (strcmp(opr, "<>") == 0)
3834 expr = makeA_Expr(OP, opr, larg, rarg);
3836 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3840 elog(WARN,"Operator '%s' not implemented for row expressions",opr);
3844 while ((largs != NIL) && (rargs != NIL))
3846 larg = lfirst(largs);
3847 rarg = lfirst(rargs);
3850 expr = makeA_Expr(OP, opr, larg, rarg);
3852 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3854 largs = lnext(largs);
3855 rargs = lnext(rargs);
3861 } /* makeRowExpr() */
3864 mapTargetColumns(List *src, List *dst)
3869 if (length(src) != length(dst))
3870 elog(WARN,"CREATE TABLE/AS SELECT has mismatched column count",NULL);
3872 while ((src != NIL) && (dst != NIL))
3874 s = (ColumnDef *)lfirst(src);
3875 d = (ResTarget *)lfirst(dst);
3877 d->name = s->colname;
3884 } /* mapTargetColumns() */
3886 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
3888 Node *result = NULL;
3890 /* we do this so indexes can be used */
3891 if (strcmp(opname,"~") == 0 ||
3892 strcmp(opname,"~*") == 0)
3894 if (nodeTag(rexpr) == T_A_Const &&
3895 ((A_Const *)rexpr)->val.type == T_String &&
3896 ((A_Const *)rexpr)->val.val.str[0] == '^')
3898 A_Const *n = (A_Const *)rexpr;
3899 char *match_least = palloc(strlen(n->val.val.str)+2);
3900 char *match_most = palloc(strlen(n->val.val.str)+2);
3901 int pos, match_pos=0;
3903 /* skip leading ^ */
3904 for (pos = 1; n->val.val.str[pos]; pos++)
3906 if (n->val.val.str[pos] == '.' ||
3907 n->val.val.str[pos] == '?' ||
3908 n->val.val.str[pos] == '*' ||
3909 n->val.val.str[pos] == '[' ||
3910 n->val.val.str[pos] == '$' ||
3911 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
3913 if (n->val.val.str[pos] == '\\')
3915 match_least[match_pos] = n->val.val.str[pos];
3916 match_most[match_pos++] = n->val.val.str[pos];
3921 A_Const *least = makeNode(A_Const);
3922 A_Const *most = makeNode(A_Const);
3924 /* make strings to be used in index use */
3925 match_least[match_pos] = '\0';
3926 match_most[match_pos] = '\377';
3927 match_most[match_pos+1] = '\0';
3928 least->val.type = T_String;
3929 least->val.val.str = match_least;
3930 most->val.type = T_String;
3931 most->val.val.str = match_most;
3932 result = makeA_Expr(AND, NULL,
3933 makeA_Expr(OP, "~", lexpr, rexpr),
3934 makeA_Expr(AND, NULL,
3935 makeA_Expr(OP, ">=", lexpr, (Node *)least),
3936 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
3940 else if (strcmp(opname,"~~") == 0)
3942 if (nodeTag(rexpr) == T_A_Const &&
3943 ((A_Const *)rexpr)->val.type == T_String)
3945 A_Const *n = (A_Const *)rexpr;
3946 char *match_least = palloc(strlen(n->val.val.str)+2);
3947 char *match_most = palloc(strlen(n->val.val.str)+2);
3948 int pos, match_pos=0;
3950 for (pos = 0; n->val.val.str[pos]; pos++)
3952 if ((n->val.val.str[pos] == '%' &&
3953 n->val.val.str[pos+1] != '%') ||
3954 (n->val.val.str[pos] == '_' &&
3955 n->val.val.str[pos+1] != '_'))
3957 if (n->val.val.str[pos] == '%' ||
3958 n->val.val.str[pos] == '_' ||
3959 n->val.val.str[pos] == '\\')
3961 match_least[match_pos] = n->val.val.str[pos];
3962 match_most[match_pos++] = n->val.val.str[pos];
3967 A_Const *least = makeNode(A_Const);
3968 A_Const *most = makeNode(A_Const);
3970 /* make strings to be used in index use */
3971 match_least[match_pos] = '\0';
3972 match_most[match_pos] = '\377';
3973 match_most[match_pos+1] = '\0';
3974 least->val.type = T_String;
3975 least->val.val.str = match_least;
3976 most->val.type = T_String;
3977 most->val.val.str = match_most;
3978 result = makeA_Expr(AND, NULL,
3979 makeA_Expr(OP, "~~", lexpr, rexpr),
3980 makeA_Expr(AND, NULL,
3981 makeA_Expr(OP, ">=", lexpr, (Node *)least),
3982 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
3988 result = makeA_Expr(OP, opname, lexpr, rexpr);
3990 } /* makeIndexable() */
3994 * Convert alternate type names to internal Postgres types.
3995 * Do not convert "float", since that is handled elsewhere
3996 * for FLOAT(p) syntax.
3999 xlateSqlType(char *name)
4001 if (!strcasecmp(name,"int")
4002 || !strcasecmp(name,"integer"))
4004 else if (!strcasecmp(name, "smallint"))
4006 else if (!strcasecmp(name, "real"))
4008 else if (!strcasecmp(name, "interval"))
4010 else if (!strcasecmp(name, "boolean"))
4014 } /* xlateSqlName() */
4017 void parser_init(Oid *typev, int nargs)
4019 QueryIsRule = FALSE;
4020 saved_relname[0]= '\0';
4021 saved_In_Expr = NULL;
4023 param_type_init(typev, nargs);
4027 /* FlattenStringList()
4028 * Traverse list of string nodes and convert to a single string.
4029 * Used for reconstructing string form of complex expressions.
4031 * Allocate at least one byte for terminator.
4034 FlattenStringList(List *list)
4042 nlist = length(list);
4045 v = (Value *)lfirst(l);
4052 s = (char*) palloc(len+1);
4057 v = (Value *)lfirst(l);
4061 if (l != NIL) strcat(s," ");
4066 printf( "flattened string is \"%s\"\n", s);
4070 } /* FlattenStringList() */
4073 /* makeConstantList()
4074 * Convert constant value node into string node.
4077 makeConstantList( A_Const *n)
4079 char *defval = NULL;
4080 if (nodeTag(n) != T_A_Const) {
4081 elog(WARN,"Cannot handle non-constant parameter",NULL);
4083 } else if (n->val.type == T_Float) {
4084 defval = (char*) palloc(20+1);
4085 sprintf( defval, "%g", n->val.val.dval);
4087 } else if (n->val.type == T_Integer) {
4088 defval = (char*) palloc(20+1);
4089 sprintf( defval, "%ld", n->val.val.ival);
4091 } else if (n->val.type == T_String) {
4092 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
4093 strcpy( defval, "'");
4094 strcat( defval, ((A_Const *) n)->val.val.str);
4095 strcat( defval, "'");
4098 elog(WARN,"Internal error in makeConstantList(): cannot encode node",NULL);
4102 printf( "AexprConst argument is \"%s\"\n", defval);
4105 return( lcons( makeString(defval), NIL));
4106 } /* makeConstantList() */
4110 * Check input string for non-lowercase/non-numeric characters.
4111 * Returns either input string or input surrounded by double quotes.
4118 for (cp = rawid; *cp != '\0'; cp++)
4119 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
4122 cp = palloc(strlen(rawid)+1);
4131 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
4140 * keep enough information around fill out the type of param nodes
4141 * used in postquel functions
4144 param_type_init(Oid *typev, int nargs)
4146 pfunc_num_args = nargs;
4147 param_type_info = typev;
4150 Oid param_type(int t)
4152 if ((t > pfunc_num_args) || (t == 0))
4154 return param_type_info[t - 1];