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.35 1997/08/12 20:15:33 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.
24 * if you use list, make sure the datum is a node so that the printing
28 * sometimes we assign constants to makeStrings. Make sure we don't free
31 *-------------------------------------------------------------------------
37 #include "nodes/parsenodes.h"
38 #include "parser/gramparse.h"
39 #include "parser/catalog_utils.h"
40 #include "parser/parse_query.h"
41 #include "storage/smgr.h"
42 #include "utils/acl.h"
43 #include "catalog/catname.h"
44 #include "utils/elog.h"
45 #include "access/xact.h"
47 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
48 static bool QueryIsRule = FALSE;
49 static Node *saved_In_Expr;
50 extern List *parsetree;
53 * If you need access to certain yacc-generated variables and find that
54 * they're static by default, uncomment the next line. (this is not a
57 /*#define __YYSCLASS*/
59 static char *xlateSqlType(char *);
60 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
62 /* old versions of flex define this as a macro */
85 SortGroupBy *sortgroupby;
102 AddAttrStmt, ClosePortalStmt,
103 CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
104 ExtendStmt, FetchStmt, GrantStmt,
105 IndexStmt, MoveStmt, ListenStmt, OptimizableStmt,
106 ProcedureStmt, PurgeStmt,
107 RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
108 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
109 CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
110 ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
111 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt
113 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
114 database_name, access_method_clause, access_method, attr_name,
115 class, index_name, name, file_name, recipe_name,
116 var_name, aggr_argtype
118 %type <str> opt_id, opt_portal_name,
119 before_clause, after_clause, all_Op, MathOp, opt_name, opt_unique,
120 result, OptUseOp, opt_class, opt_range_start, opt_range_end,
123 %type <str> privileges, operation_commalist, grantee
124 %type <chr> operation
126 %type <list> stmtblock, stmtmulti,
127 relation_name_list, OptTableElementList,
128 tableElementList, OptInherit, definition,
129 opt_with, def_args, def_name_list, func_argtypes,
130 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
131 opt_column_list, columnList, opt_va_list, va_list,
132 sort_clause, sortby_list, index_params, index_list,
133 name_list, from_clause, from_list, opt_array_bounds, nest_array_bounds,
134 expr_list, attrs, res_target_list, res_target_list2,
135 def_list, opt_indirection, group_clause, groupby_list
137 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
138 index_opt_unique, opt_verbose, opt_analyze
140 %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation,
141 def_type, opt_direction, remove_type, opt_column, event
143 %type <ival> OptLocation, opt_move_where, fetch_how_many
145 %type <list> OptSeqList
146 %type <defelt> OptSeqElem
148 %type <dstmt> def_rest
149 %type <pstmt> purge_quals
150 %type <astmt> insert_rest
152 %type <typnam> Typename, typname, opt_type
153 %type <coldef> columnDef
154 %type <defelt> def_elem
155 %type <node> def_arg, columnElem, where_clause,
156 a_expr, a_expr_or_null, AexprConst,
157 in_expr_nodes, not_in_expr_nodes,
159 %type <value> NumConst
160 %type <attr> event_object, attr
161 %type <sortgroupby> groupby
162 %type <sortgroupby> sortby
163 %type <ielem> index_elem, func_index
164 %type <range> from_val
165 %type <relexp> relation_expr
166 %type <trange> time_range
167 %type <target> res_target_el, res_target_el2
168 %type <paramno> ParamNo
172 %type <str> Id, date, var_value
176 * If you make any token changes, remember to:
177 * - use "yacc -d" and update parse.h
178 * - update the keyword table in parser/keywords.c
182 %token ABORT_TRANS, ACL, ADD, AFTER, AGGREGATE, ALL, ALTER, ANALYZE,
183 AND, APPEND, ARCHIVE, ARCH_STORE, AS, ASC,
184 BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BINARY, BY,
185 CAST, CHANGE, CLOSE, CLUSTER, COLUMN, COMMIT, COPY, CREATE,
186 CURRENT, CURSOR, DATABASE, DECLARE, DELETE, DELIMITERS, DESC,
187 DISTINCT, DO, DROP, END_TRANS,
188 EXTEND, FETCH, FOR, FORWARD, FROM, FUNCTION, GRANT, GROUP,
189 HAVING, HEAVY, IN, INDEX, INHERITS, INSERT, INSTEAD, INTO, IS,
190 ISNULL, LANGUAGE, LIGHT, LISTEN, LOAD, MERGE, MOVE, NEW,
191 NONE, NOT, NOTHING, NOTIFY, NOTNULL,
192 OIDS, ON, OPERATOR, OPTION, OR, ORDER,
193 PNULL, PRIVILEGES, PUBLIC, PURGE, P_TYPE,
194 RENAME, REPLACE, RESET, RETRIEVE, RETURNS, REVOKE, ROLLBACK, RULE,
195 SELECT, SET, SETOF, SHOW, STDIN, STDOUT, STORE,
196 TABLE, TO, TRANSACTION, UNIQUE, UPDATE, USING, VACUUM, VALUES
197 VERBOSE, VERSION, VIEW, WHERE, WITH, WORK
198 %token EXECUTE, RECIPE, EXPLAIN, LIKE, SEQUENCE
200 /* Special keywords, not in the query language - see the "lex" file */
201 %token <str> IDENT, SCONST, Op
202 %token <ival> ICONST, PARAM
205 /* these are not real. they are here so that they gets generated as #define's*/
222 %left '|' /* this is the relation union op, not logical or */
223 %right ':' /* Unary Operators */
224 %left ';' /* end of statement or natural log */
236 { parsetree = lcons($1,NIL); }
239 stmtmulti: stmtmulti stmt ';'
240 { $$ = lappend($1, $2); }
242 { $$ = lappend($1, $2); }
244 { $$ = lcons($1,NIL); }
284 /*****************************************************************************
286 * Set PG internal variable
287 * SET var_name TO 'var_value'
289 *****************************************************************************/
291 VariableSetStmt: SET var_name TO var_value
293 VariableSetStmt *n = makeNode(VariableSetStmt);
300 var_value: Sconst { $$ = $1; }
303 VariableShowStmt: SHOW var_name
305 VariableShowStmt *n = makeNode(VariableShowStmt);
311 VariableResetStmt: RESET var_name
313 VariableResetStmt *n = makeNode(VariableResetStmt);
319 /*****************************************************************************
322 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
324 *****************************************************************************/
326 AddAttrStmt: ALTER TABLE relation_name opt_inh_star ADD COLUMN columnDef
328 AddAttrStmt *n = makeNode(AddAttrStmt);
336 columnDef: Id Typename
338 $$ = makeNode(ColumnDef);
345 /*****************************************************************************
350 *****************************************************************************/
352 ClosePortalStmt: CLOSE opt_id
354 ClosePortalStmt *n = makeNode(ClosePortalStmt);
361 /*****************************************************************************
364 * COPY [BINARY] <relname> FROM/TO
365 * [USING DELIMITERS <delimiter>]
367 *****************************************************************************/
369 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
371 CopyStmt *n = makeNode(CopyStmt);
389 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
390 * used depends on the direction. (It really doesn't make sense to copy from
391 * stdout. We silently correct the "typo". - AY 9/94
393 copy_file_name: Sconst { $$ = $1; }
394 | STDIN { $$ = NULL; }
395 | STDOUT { $$ = NULL; }
398 opt_binary: BINARY { $$ = TRUE; }
399 | /*EMPTY*/ { $$ = FALSE; }
402 opt_with_copy: WITH OIDS { $$ = TRUE; }
403 | /* EMPTY */ { $$ = FALSE; }
407 * the default copy delimiter is tab but the user can configure it
409 copy_delimiter: USING DELIMITERS Sconst { $$ = $3;}
410 | /* EMPTY */ { $$ = "\t"; }
414 /*****************************************************************************
419 *****************************************************************************/
421 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
422 OptInherit OptArchiveType OptLocation OptArchiveLocation
424 CreateStmt *n = makeNode(CreateStmt);
435 OptTableElementList: tableElementList { $$ = $1; }
436 | /* EMPTY */ { $$ = NULL; }
440 tableElementList ',' columnDef
441 { $$ = lappend($1, $3); }
443 { $$ = lcons($1, NIL); }
447 OptArchiveType: ARCHIVE '=' archive_type { $$ = $3; }
448 | /*EMPTY*/ { $$ = ARCH_NONE; }
451 archive_type: HEAVY { $$ = ARCH_HEAVY; }
452 | LIGHT { $$ = ARCH_LIGHT; }
453 | NONE { $$ = ARCH_NONE; }
456 OptLocation: STORE '=' Sconst
462 OptArchiveLocation: ARCH_STORE '=' Sconst
468 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
469 | /*EMPTY*/ { $$ = NIL; }
473 /*****************************************************************************
476 * CREATE SEQUENCE seqname
478 *****************************************************************************/
480 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
482 CreateSeqStmt *n = makeNode(CreateSeqStmt);
490 OptSeqList OptSeqElem
491 { $$ = lappend($1, $2); }
495 OptSeqElem: IDENT NumConst
497 $$ = makeNode(DefElem);
499 $$->arg = (Node *)$2;
503 $$ = makeNode(DefElem);
505 $$->arg = (Node *)NULL;
510 /*****************************************************************************
513 * define (type,operator,aggregate)
515 *****************************************************************************/
517 DefineStmt: CREATE def_type def_rest
524 def_rest: def_name definition
526 $$ = makeNode(DefineStmt);
532 def_type: OPERATOR { $$ = OPERATOR; }
533 | Type { $$ = P_TYPE; }
534 | AGGREGATE { $$ = AGGREGATE; }
537 def_name: Id | MathOp | Op
541 definition: '(' def_list ')' { $$ = $2; }
546 { $$ = lcons($1, NIL); }
547 | def_list ',' def_elem
548 { $$ = lappend($1, $3); }
551 def_elem: def_name '=' def_arg
553 $$ = makeNode(DefElem);
555 $$->arg = (Node *)$3;
559 $$ = makeNode(DefElem);
561 $$->arg = (Node *)NULL;
565 def_arg: Id { $$ = (Node *)makeString($1); }
566 | all_Op { $$ = (Node *)makeString($1); }
567 | NumConst { $$ = (Node *)$1; /* already a Value */ }
568 | Sconst { $$ = (Node *)makeString($1); }
570 TypeName *n = makeNode(TypeName);
573 n->arrayBounds = NULL;
579 /*****************************************************************************
582 * destroy <relname1> [, <relname2> .. <relnameN> ]
584 *****************************************************************************/
586 DestroyStmt: DROP TABLE relation_name_list
588 DestroyStmt *n = makeNode(DestroyStmt);
593 | DROP SEQUENCE relation_name_list
595 DestroyStmt *n = makeNode(DestroyStmt);
603 /*****************************************************************************
606 * fetch [forward | backward] [number | all ] [ in <portalname> ]
608 *****************************************************************************/
610 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
612 FetchStmt *n = makeNode(FetchStmt);
620 opt_direction: FORWARD { $$ = FORWARD; }
621 | BACKWARD { $$ = BACKWARD; }
622 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
625 fetch_how_many: Iconst
627 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch"); }
628 | ALL { $$ = 0; /* 0 means fetch all tuples*/}
629 | /*EMPTY*/ { $$ = 1; /*default*/ }
632 /*****************************************************************************
635 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
637 *****************************************************************************/
639 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
641 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
647 privileges: ALL PRIVILEGES
649 $$ = aclmakepriv("rwaR",0);
653 $$ = aclmakepriv("rwaR",0);
655 | operation_commalist {
660 operation_commalist: operation {
661 $$ = aclmakepriv("",$1);
663 | operation_commalist ',' operation
665 $$ = aclmakepriv($1,$3);
671 $$ = ACL_MODE_RD_CHR;
674 $$ = ACL_MODE_AP_CHR;
677 $$ = ACL_MODE_WR_CHR;
680 $$ = ACL_MODE_WR_CHR;
683 $$ = ACL_MODE_RU_CHR;
688 $$ = aclmakeuser("A","");
691 $$ = aclmakeuser("G",$2);
694 $$ = aclmakeuser("U",$1);
698 opt_with_grant : /* empty */
701 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
704 /*****************************************************************************
707 * REVOKE [privileges] ON [relation_name] FROM [user]
709 *****************************************************************************/
711 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
713 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
719 /*****************************************************************************
722 * move [<dirn>] [<whereto>] [<portalname>]
724 *****************************************************************************/
726 MoveStmt: MOVE opt_direction opt_move_where opt_portal_name
728 MoveStmt *n = makeNode(MoveStmt);
735 | MOVE opt_direction TO Iconst opt_portal_name
737 MoveStmt *n = makeNode(MoveStmt);
746 opt_move_where: Iconst { $$ = $1; }
747 | /*EMPTY*/ { $$ = 1; /* default */ }
750 opt_portal_name: IN name { $$ = $2;}
751 | /*EMPTY*/ { $$ = NULL; }
755 /*****************************************************************************
758 * define [archive] index <indexname> on <relname>
759 * using <access> "(" (<col> with <op>)+ ")" [with
762 * [where <qual>] is not supported anymore
763 *****************************************************************************/
765 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
766 access_method_clause '(' index_params ')' opt_with
768 /* should check that access_method is valid,
769 etc ... but doesn't */
770 IndexStmt *n = makeNode(IndexStmt);
774 n->accessMethod = $7;
777 n->whereClause = NULL;
782 access_method_clause: USING access_method { $$ = $2; }
783 | /* empty -- 'btree' is default access method */
787 index_opt_unique: UNIQUE { $$ = TRUE; }
788 | /*empty*/ { $$ = FALSE; }
791 /*****************************************************************************
794 * extend index <indexname> [where <qual>]
796 *****************************************************************************/
798 ExtendStmt: EXTEND INDEX index_name where_clause
800 ExtendStmt *n = makeNode(ExtendStmt);
807 /*****************************************************************************
810 * execute recipe <recipeName>
812 *****************************************************************************/
814 RecipeStmt: EXECUTE RECIPE recipe_name
817 if (!IsTransactionBlock())
818 elog(WARN, "EXECUTE RECIPE may only be used in begin/end transaction blocks.");
820 n = makeNode(RecipeStmt);
827 /*****************************************************************************
830 * define function <fname>
831 * (language = <lang>, returntype = <typename>
832 * [, arch_pct = <percentage | pre-defined>]
833 * [, disk_pct = <percentage | pre-defined>]
834 * [, byte_pct = <percentage | pre-defined>]
835 * [, perbyte_cpu = <int | pre-defined>]
836 * [, percall_cpu = <int | pre-defined>]
838 * [arg is (<type-1> { , <type-n>})]
839 * as <filename or code in language as appropriate>
841 *****************************************************************************/
843 ProcedureStmt: CREATE FUNCTION def_name def_args
844 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
846 ProcedureStmt *n = makeNode(ProcedureStmt);
849 n->returnType = (Node *)$6;
856 opt_with: WITH definition { $$ = $2; }
857 | /* EMPTY */ { $$ = NIL; }
860 def_args: '(' def_name_list ')' { $$ = $2; }
861 | '(' ')' { $$ = NIL; }
864 def_name_list: name_list;
867 /*****************************************************************************
870 * purge <relname> [before <date>] [after <date>]
872 * purge <relname> [after<date>][before <date>]
874 *****************************************************************************/
876 PurgeStmt: PURGE relation_name purge_quals
883 purge_quals: before_clause
885 $$ = makeNode(PurgeStmt);
887 $$->afterDate = NULL;
891 $$ = makeNode(PurgeStmt);
892 $$->beforeDate = NULL;
895 | before_clause after_clause
897 $$ = makeNode(PurgeStmt);
901 | after_clause before_clause
903 $$ = makeNode(PurgeStmt);
909 $$ = makeNode(PurgeStmt);
910 $$->beforeDate = NULL;
911 $$->afterDate = NULL;
915 before_clause: BEFORE date { $$ = $2; }
916 after_clause: AFTER date { $$ = $2; }
919 /*****************************************************************************
923 * remove function <funcname>
924 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
925 * remove aggregate <aggname>
926 * (REMOVE AGGREGATE "aggname" "aggtype")
927 * remove operator <opname>
928 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
929 * remove type <typename>
930 * (REMOVE TYPE "typename")
931 * remove rule <rulename>
932 * (REMOVE RULE "rulename")
934 *****************************************************************************/
936 RemoveStmt: DROP remove_type name
938 RemoveStmt *n = makeNode(RemoveStmt);
945 remove_type: Type { $$ = P_TYPE; }
946 | INDEX { $$ = INDEX; }
947 | RULE { $$ = RULE; }
948 | VIEW { $$ = VIEW; }
951 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
953 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
960 aggr_argtype: name { $$ = $1; }
964 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
966 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
973 func_argtypes: name_list { $$ = $1; }
974 | /*EMPTY*/ { $$ = NIL; }
977 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
979 RemoveOperStmt *n = makeNode(RemoveOperStmt);
988 MathOp: '+' { $$ = "+"; }
999 elog(WARN, "parser: argument type missing (use NONE for unary operators)");
1002 { $$ = makeList(makeString($1), makeString($3), -1); }
1003 | NONE ',' name /* left unary */
1004 { $$ = makeList(NULL, makeString($3), -1); }
1005 | name ',' NONE /* right unary */
1006 { $$ = makeList(makeString($1), NULL, -1); }
1009 /*****************************************************************************
1012 * rename <attrname1> in <relname> [*] to <attrname2>
1013 * rename <relname1> to <relname2>
1015 *****************************************************************************/
1017 RenameStmt: ALTER TABLE relation_name opt_inh_star
1018 RENAME opt_column opt_name TO name
1020 RenameStmt *n = makeNode(RenameStmt);
1029 opt_name: name { $$ = $1; }
1030 | /*EMPTY*/ { $$ = NULL; }
1033 opt_column: COLUMN { $$ = COLUMN; }
1034 | /*EMPTY*/ { $$ = 0; }
1038 /*****************************************************************************
1040 * QUERY: Define Rewrite Rule , Define Tuple Rule
1041 * Define Rule <old rules >
1043 * only rewrite rule is supported -- ay 9/94
1045 *****************************************************************************/
1047 RuleStmt: CREATE RULE name AS
1048 { QueryIsRule=TRUE; }
1049 ON event TO event_object where_clause
1050 DO opt_instead OptStmtList
1052 RuleStmt *n = makeNode(RuleStmt);
1056 n->whereClause = $10;
1063 OptStmtList: NOTHING { $$ = NIL; }
1064 | OptimizableStmt { $$ = lcons($1, NIL); }
1065 | '[' OptStmtBlock ']' { $$ = $2; }
1068 OptStmtBlock: OptStmtMulti
1071 { $$ = lcons($1, NIL); }
1074 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1075 { $$ = lappend($1, $2); }
1076 | OptStmtMulti OptimizableStmt
1077 { $$ = lappend($1, $2); }
1078 | OptimizableStmt ';'
1079 { $$ = lcons($1, NIL); }
1082 event_object: relation_name '.' attr_name
1084 $$ = makeNode(Attr);
1087 $$->attrs = lcons(makeString($3), NIL);
1088 $$->indirection = NIL;
1092 $$ = makeNode(Attr);
1096 $$->indirection = NIL;
1100 /* change me to select, update, etc. some day */
1101 event: SELECT { $$ = CMD_SELECT; }
1102 | UPDATE { $$ = CMD_UPDATE; }
1103 | DELETE { $$ = CMD_DELETE; }
1104 | INSERT { $$ = CMD_INSERT; }
1107 opt_instead: INSTEAD { $$ = TRUE; }
1108 | /* EMPTY */ { $$ = FALSE; }
1112 /*****************************************************************************
1115 * NOTIFY <relation_name> can appear both in rule bodies and
1116 * as a query-level command
1118 *****************************************************************************/
1120 NotifyStmt: NOTIFY relation_name
1122 NotifyStmt *n = makeNode(NotifyStmt);
1128 ListenStmt: LISTEN relation_name
1130 ListenStmt *n = makeNode(ListenStmt);
1137 /*****************************************************************************
1148 *****************************************************************************/
1150 TransactionStmt: ABORT_TRANS TRANSACTION
1152 TransactionStmt *n = makeNode(TransactionStmt);
1153 n->command = ABORT_TRANS;
1156 | BEGIN_TRANS TRANSACTION
1158 TransactionStmt *n = makeNode(TransactionStmt);
1159 n->command = BEGIN_TRANS;
1164 TransactionStmt *n = makeNode(TransactionStmt);
1165 n->command = BEGIN_TRANS;
1170 TransactionStmt *n = makeNode(TransactionStmt);
1171 n->command = END_TRANS;
1174 | END_TRANS TRANSACTION
1176 TransactionStmt *n = makeNode(TransactionStmt);
1177 n->command = END_TRANS;
1182 TransactionStmt *n = makeNode(TransactionStmt);
1183 n->command = ABORT_TRANS;
1189 TransactionStmt *n = makeNode(TransactionStmt);
1190 n->command = ABORT_TRANS;
1195 TransactionStmt *n = makeNode(TransactionStmt);
1196 n->command = BEGIN_TRANS;
1201 TransactionStmt *n = makeNode(TransactionStmt);
1202 n->command = END_TRANS;
1208 TransactionStmt *n = makeNode(TransactionStmt);
1209 n->command = END_TRANS;
1214 TransactionStmt *n = makeNode(TransactionStmt);
1215 n->command = ABORT_TRANS;
1221 /*****************************************************************************
1224 * define view <viewname> '('target-list ')' [where <quals> ]
1226 *****************************************************************************/
1228 ViewStmt: CREATE VIEW name AS RetrieveStmt
1230 ViewStmt *n = makeNode(ViewStmt);
1232 n->query = (Query *)$5;
1238 /*****************************************************************************
1243 *****************************************************************************/
1245 LoadStmt: LOAD file_name
1247 LoadStmt *n = makeNode(LoadStmt);
1254 /*****************************************************************************
1259 *****************************************************************************/
1261 CreatedbStmt: CREATE DATABASE database_name
1263 CreatedbStmt *n = makeNode(CreatedbStmt);
1270 /*****************************************************************************
1275 *****************************************************************************/
1277 DestroydbStmt: DROP DATABASE database_name
1279 DestroydbStmt *n = makeNode(DestroydbStmt);
1286 /*****************************************************************************
1289 * cluster <index_name> on <relation_name>
1291 *****************************************************************************/
1293 ClusterStmt: CLUSTER index_name ON relation_name
1295 ClusterStmt *n = makeNode(ClusterStmt);
1302 /*****************************************************************************
1307 *****************************************************************************/
1309 VacuumStmt: VACUUM opt_verbose opt_analyze
1311 VacuumStmt *n = makeNode(VacuumStmt);
1318 | VACUUM opt_verbose relation_name opt_analyze opt_va_list
1320 VacuumStmt *n = makeNode(VacuumStmt);
1325 if ( $5 != NIL && !$4 )
1326 elog (WARN, "parser: syntax error at or near \"(\"");
1331 opt_verbose: VERBOSE { $$ = TRUE; }
1332 | /* EMPTY */ { $$ = FALSE; }
1335 opt_analyze: ANALYZE { $$ = TRUE; }
1336 | /* EMPTY */ { $$ = FALSE; }
1339 opt_va_list: '(' va_list ')'
1346 { $$=lcons($1,NIL); }
1348 { $$=lappend($1,$3); }
1351 /*****************************************************************************
1356 *****************************************************************************/
1358 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
1360 ExplainStmt *n = makeNode(ExplainStmt);
1362 n->query = (Query*)$3;
1367 /*****************************************************************************
1369 * Optimizable Stmts: *
1371 * one of the five queries processed by the planner *
1373 * [ultimately] produces query-trees as specified *
1374 * in the query-spec document in ~postgres/ref *
1376 *****************************************************************************/
1378 OptimizableStmt: RetrieveStmt
1383 | DeleteStmt /* by default all are $$=$1 */
1387 /*****************************************************************************
1392 *****************************************************************************/
1394 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
1402 insert_rest: VALUES '(' res_target_list2 ')'
1404 $$ = makeNode(AppendStmt);
1405 $$->targetList = $3;
1406 $$->fromClause = NIL;
1407 $$->whereClause = NULL;
1409 | SELECT res_target_list2 from_clause where_clause
1411 $$ = makeNode(AppendStmt);
1412 $$->targetList = $2;
1413 $$->fromClause = $3;
1414 $$->whereClause = $4;
1418 opt_column_list: '(' columnList ')' { $$ = $2; }
1419 | /*EMPTY*/ { $$ = NIL; }
1423 columnList ',' columnElem
1424 { $$ = lappend($1, $3); }
1426 { $$ = lcons($1, NIL); }
1429 columnElem: Id opt_indirection
1431 Ident *id = makeNode(Ident);
1433 id->indirection = $2;
1438 /*****************************************************************************
1443 *****************************************************************************/
1445 DeleteStmt: DELETE FROM relation_name
1448 DeleteStmt *n = makeNode(DeleteStmt);
1450 n->whereClause = $4;
1456 /*****************************************************************************
1459 * ReplaceStmt (UPDATE)
1461 *****************************************************************************/
1463 ReplaceStmt: UPDATE relation_name
1468 ReplaceStmt *n = makeNode(ReplaceStmt);
1472 n->whereClause = $6;
1478 /*****************************************************************************
1483 *****************************************************************************/
1485 CursorStmt: DECLARE name opt_binary CURSOR FOR
1486 SELECT opt_unique res_target_list2
1487 from_clause where_clause group_clause sort_clause
1489 CursorStmt *n = makeNode(CursorStmt);
1491 /* from PORTAL name */
1493 * 15 august 1991 -- since 3.0 postgres does locking
1494 * right, we discovered that portals were violating
1495 * locking protocol. portal locks cannot span xacts.
1496 * as a short-term fix, we installed the check here.
1499 if (!IsTransactionBlock())
1500 elog(WARN, "Named portals may only be used in begin/end transaction blocks.");
1507 n->whereClause = $10;
1508 n->groupClause = $11;
1509 n->sortClause = $12;
1515 /*****************************************************************************
1520 *****************************************************************************/
1522 RetrieveStmt: SELECT opt_unique res_target_list2
1523 result from_clause where_clause
1524 group_clause having_clause
1527 RetrieveStmt *n = makeNode(RetrieveStmt);
1532 n->whereClause = $6;
1533 n->groupClause = $7;
1534 n->havingClause = $8;
1540 result: INTO TABLE relation_name
1541 { $$= $3; /* should check for archive level */ }
1546 opt_unique: DISTINCT { $$ = "*"; }
1547 | DISTINCT ON Id { $$ = $3; }
1548 | /*EMPTY*/ { $$ = NULL;}
1551 sort_clause: ORDER BY sortby_list { $$ = $3; }
1552 | /*EMPTY*/ { $$ = NIL; }
1556 { $$ = lcons($1, NIL); }
1557 | sortby_list ',' sortby
1558 { $$ = lappend($1, $3); }
1563 $$ = makeNode(SortGroupBy);
1569 | Id '.' Id OptUseOp
1571 $$ = makeNode(SortGroupBy);
1579 $$ = makeNode(SortGroupBy);
1587 OptUseOp: USING Op { $$ = $2; }
1588 | USING '<' { $$ = "<"; }
1589 | USING '>' { $$ = ">"; }
1591 | DESC { $$ = ">"; }
1592 | /*EMPTY*/ { $$ = "<"; /*default*/ }
1595 index_params: index_list { $$ = $1; }
1596 | func_index { $$ = lcons($1,NIL); }
1600 index_list ',' index_elem
1601 { $$ = lappend($1, $3); }
1603 { $$ = lcons($1, NIL); }
1606 func_index: name '(' name_list ')' opt_type opt_class
1608 $$ = makeNode(IndexElem);
1616 index_elem: attr_name opt_type opt_class
1618 $$ = makeNode(IndexElem);
1626 opt_type: ':' Typename { $$ = $2;}
1627 | /*EMPTY*/ { $$ = NULL;}
1631 | WITH class { $$ = $2; }
1632 | /*EMPTY*/ { $$ = NULL; }
1636 * jimmy bell-style recursive queries aren't supported in the
1639 * ...however, recursive addattr and rename supported. make special
1642 * XXX i believe '*' should be the default behavior, but...
1644 opt_inh_star: '*' { $$ = TRUE; }
1645 | /*EMPTY*/ { $$ = FALSE; }
1648 relation_name_list: name_list ;
1651 { $$=lcons(makeString($1),NIL); }
1652 | name_list ',' name
1653 { $$=lappend($1,makeString($3)); }
1656 group_clause: GROUP BY groupby_list { $$ = $3; }
1657 | /*EMPTY*/ { $$ = NIL; }
1660 groupby_list: groupby { $$ = lcons($1, NIL); }
1661 | groupby_list ',' groupby { $$ = lappend($1, $3); }
1666 $$ = makeNode(SortGroupBy);
1674 $$ = makeNode(SortGroupBy);
1682 $$ = makeNode(SortGroupBy);
1690 having_clause: HAVING a_expr { $$ = $2; }
1691 | /*EMPTY*/ { $$ = NULL; }
1694 /*****************************************************************************
1696 * clauses common to all Optimizable Stmts:
1700 *****************************************************************************/
1702 from_clause: FROM from_list { $$ = $2; }
1703 | /*EMPTY*/ { $$ = NIL; }
1706 from_list: from_list ',' from_val
1707 { $$ = lappend($1, $3); }
1709 { $$ = lcons($1, NIL); }
1712 from_val: relation_expr AS var_name
1714 $$ = makeNode(RangeVar);
1718 | relation_expr var_name
1720 $$ = makeNode(RangeVar);
1726 $$ = makeNode(RangeVar);
1732 where_clause: WHERE a_expr { $$ = $2; }
1733 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
1736 relation_expr: relation_name
1738 /* normal relations */
1739 $$ = makeNode(RelExpr);
1742 $$->timeRange = NULL;
1744 | relation_name '*' %prec '='
1746 /* inheiritance query */
1747 $$ = makeNode(RelExpr);
1750 $$->timeRange = NULL;
1752 | relation_name time_range
1754 /* time-qualified query */
1755 $$ = makeNode(RelExpr);
1763 time_range: '[' opt_range_start ',' opt_range_end ']'
1765 $$ = makeNode(TimeRange);
1771 $$ = makeNode(TimeRange);
1777 opt_range_start: date
1778 | /*EMPTY*/ { $$ = "epoch"; }
1782 | /*EMPTY*/ { $$ = "now"; }
1785 opt_array_bounds: '[' ']' nest_array_bounds
1786 { $$ = lcons(makeInteger(-1), $3); }
1787 | '[' Iconst ']' nest_array_bounds
1788 { $$ = lcons(makeInteger($2), $4); }
1793 nest_array_bounds: '[' ']' nest_array_bounds
1794 { $$ = lcons(makeInteger(-1), $3); }
1795 | '[' Iconst ']' nest_array_bounds
1796 { $$ = lcons(makeInteger($2), $4); }
1803 char *tname = xlateSqlType($1);
1804 $$ = makeNode(TypeName);
1807 /* Is this the name of a complex type? If so, implement
1810 if (!strcmp(saved_relname, tname)) {
1811 /* This attr is the same type as the relation
1812 * being defined. The classic example: create
1813 * emp(name=text,mgr=emp)
1816 }else if (get_typrelid((Type)type(tname))
1818 /* (Eventually add in here that the set can only
1819 * contain one element.)
1828 $$ = makeNode(TypeName);
1834 Typename: typname opt_array_bounds
1837 $$->arrayBounds = $2;
1839 | name '(' Iconst ')'
1842 * The following implements char() and varchar().
1843 * We do it here instead of the 'typname:' production
1844 * because we don't want to allow arrays of varchar().
1845 * I haven't thought about whether that will work or not.
1848 $$ = makeNode(TypeName);
1849 if (!strcasecmp($1, "char")) {
1850 $$->name = "bpchar"; /* strdup("bpchar"); */
1851 } else if (!strcasecmp($1, "varchar")) {
1852 $$->name = "varchar"; /* strdup("varchar"); */
1854 yyerror("parse error");
1857 elog(WARN, "length for '%s' type must be at least 1",
1859 } else if ($3 > 4096) {
1860 /* we can store a char() of length up to the size
1861 of a page (8KB) - page headers and friends but
1862 just to be safe here... - ay 6/95 */
1863 elog(WARN, "length for '%s' type cannot exceed 4096",
1866 /* we actually implement this sort of like a varlen, so
1867 the first 4 bytes is the length. (the difference
1868 between this and "text" is that we blank-pad and
1869 truncate where necessary */
1870 $$->typlen = 4 + $3;
1875 /*****************************************************************************
1877 * expression grammar, still needs some cleanup
1879 *****************************************************************************/
1881 a_expr_or_null: a_expr
1885 A_Const *n = makeNode(A_Const);
1886 n->val.type = T_Null;
1890 a_expr: attr opt_indirection
1892 $1->indirection = $2;
1897 | '-' a_expr %prec UMINUS
1898 { $$ = makeA_Expr(OP, "-", NULL, $2); }
1900 { $$ = makeA_Expr(OP, "+", $1, $3); }
1902 { $$ = makeA_Expr(OP, "-", $1, $3); }
1904 { $$ = makeA_Expr(OP, "/", $1, $3); }
1906 { $$ = makeA_Expr(OP, "*", $1, $3); }
1908 { $$ = makeA_Expr(OP, "<", $1, $3); }
1910 { $$ = makeA_Expr(OP, ">", $1, $3); }
1912 { $$ = makeA_Expr(OP, "=", $1, $3); }
1914 { $$ = makeA_Expr(OP, ":", NULL, $2); }
1916 { $$ = makeA_Expr(OP, ";", NULL, $2); }
1918 { $$ = makeA_Expr(OP, "|", NULL, $2); }
1919 | AexprConst TYPECAST Typename
1921 /* AexprConst can be either A_Const or ParamNo */
1922 if (nodeTag($1) == T_A_Const) {
1923 ((A_Const *)$1)->typename = $3;
1925 ((ParamNo *)$1)->typename = $3;
1929 | CAST AexprConst AS Typename
1931 /* AexprConst can be either A_Const or ParamNo */
1932 if (nodeTag($2) == T_A_Const) {
1933 ((A_Const *)$2)->typename = $4;
1935 ((ParamNo *)$2)->typename = $4;
1939 | '(' a_expr_or_null ')'
1942 { $$ = makeA_Expr(OP, $2, $1, $3); }
1943 | a_expr LIKE a_expr
1944 { $$ = makeA_Expr(OP, "~~", $1, $3); }
1945 | a_expr NOT LIKE a_expr
1946 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
1948 { $$ = makeA_Expr(OP, $1, NULL, $2); }
1950 { $$ = makeA_Expr(OP, $2, $1, NULL); }
1952 { /* could be a column name or a relation_name */
1953 Ident *n = makeNode(Ident);
1955 n->indirection = NULL;
1960 FuncCall *n = makeNode(FuncCall);
1961 Ident *star = makeNode(Ident);
1963 /* cheap hack for aggregate (eg. count) */
1966 n->args = lcons(star, NIL);
1971 FuncCall *n = makeNode(FuncCall);
1976 | name '(' expr_list ')'
1978 FuncCall *n = makeNode(FuncCall);
1984 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
1986 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
1988 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
1989 | a_expr IS NOT PNULL
1990 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
1991 | a_expr BETWEEN AexprConst AND AexprConst
1992 { $$ = makeA_Expr(AND, NULL,
1993 makeA_Expr(OP, ">=", $1, $3),
1994 makeA_Expr(OP, "<=", $1,$5));
1996 | a_expr NOT BETWEEN AexprConst AND AexprConst
1997 { $$ = makeA_Expr(OR, NULL,
1998 makeA_Expr(OP, "<", $1, $4),
1999 makeA_Expr(OP, ">", $1, $6));
2001 | a_expr IN { saved_In_Expr = $1; } '(' in_expr_nodes ')'
2003 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr_nodes ')'
2006 { $$ = makeA_Expr(AND, NULL, $1, $3); }
2008 { $$ = makeA_Expr(OR, NULL, $1, $3); }
2010 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
2013 opt_indirection: '[' a_expr ']' opt_indirection
2015 A_Indices *ai = makeNode(A_Indices);
2020 | '[' a_expr ':' a_expr ']' opt_indirection
2022 A_Indices *ai = makeNode(A_Indices);
2031 expr_list: a_expr_or_null
2032 { $$ = lcons($1, NIL); }
2033 | expr_list ',' a_expr_or_null
2034 { $$ = lappend($1, $3); }
2037 in_expr_nodes: AexprConst
2038 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
2039 | in_expr_nodes ',' AexprConst
2040 { $$ = makeA_Expr(OR, NULL, $1,
2041 makeA_Expr(OP, "=", saved_In_Expr, $3));
2045 not_in_expr_nodes: AexprConst
2046 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
2047 | not_in_expr_nodes ',' AexprConst
2048 { $$ = makeA_Expr(AND, NULL, $1,
2049 makeA_Expr(OP, "<>", saved_In_Expr, $3));
2053 attr: relation_name '.' attrs
2055 $$ = makeNode(Attr);
2059 $$->indirection = NULL;
2063 $$ = makeNode(Attr);
2067 $$->indirection = NULL;
2072 { $$ = lcons(makeString($1), NIL); }
2073 | attrs '.' attr_name
2074 { $$ = lappend($1, makeString($3)); }
2076 { $$ = lappend($1, makeString("*")); }
2080 /*****************************************************************************
2084 *****************************************************************************/
2086 res_target_list: res_target_list ',' res_target_el
2087 { $$ = lappend($1,$3); }
2089 { $$ = lcons($1, NIL); }
2092 ResTarget *rt = makeNode(ResTarget);
2093 Attr *att = makeNode(Attr);
2095 att->paramNo = NULL;
2097 att->indirection = NIL;
2099 rt->indirection = NULL;
2100 rt->val = (Node *)att;
2101 $$ = lcons(rt, NIL);
2105 res_target_el: Id opt_indirection '=' a_expr_or_null
2107 $$ = makeNode(ResTarget);
2109 $$->indirection = $2;
2110 $$->val = (Node *)$4;
2112 | attr opt_indirection
2114 $$ = makeNode(ResTarget);
2116 $$->indirection = $2;
2117 $$->val = (Node *)$1;
2119 | relation_name '.' '*'
2121 Attr *att = makeNode(Attr);
2123 att->paramNo = NULL;
2124 att->attrs = lcons(makeString("*"), NIL);
2125 att->indirection = NIL;
2126 $$ = makeNode(ResTarget);
2128 $$->indirection = NULL;
2129 $$->val = (Node *)att;
2134 ** target list for select.
2135 ** should get rid of the other but is still needed by the defunct retrieve into
2136 ** and update (uses a subset)
2139 res_target_list2 ',' res_target_el2
2140 { $$ = lappend($1, $3); }
2142 { $$ = lcons($1, NIL); }
2145 /* AS is not optional because shift/red conflict with unary ops */
2146 res_target_el2: a_expr AS Id
2148 $$ = makeNode(ResTarget);
2150 $$->indirection = NULL;
2151 $$->val = (Node *)$1;
2155 $$ = makeNode(ResTarget);
2157 $$->indirection = NULL;
2158 $$->val = (Node *)$1;
2160 | relation_name '.' '*'
2162 Attr *att = makeNode(Attr);
2164 att->paramNo = NULL;
2165 att->attrs = lcons(makeString("*"), NIL);
2166 att->indirection = NIL;
2167 $$ = makeNode(ResTarget);
2169 $$->indirection = NULL;
2170 $$->val = (Node *)att;
2174 Attr *att = makeNode(Attr);
2176 att->paramNo = NULL;
2178 att->indirection = NIL;
2179 $$ = makeNode(ResTarget);
2181 $$->indirection = NULL;
2182 $$->val = (Node *)att;
2186 opt_id: Id { $$ = $1; }
2187 | /* EMPTY */ { $$ = NULL; }
2190 relation_name: SpecialRuleRelation
2193 strNcpy(saved_relname, $1, NAMEDATALEN-1);
2197 /* disallow refs to magic system tables */
2198 if (strcmp(LogRelationName, $1) == 0
2199 || strcmp(VariableRelationName, $1) == 0
2200 || strcmp(TimeRelationName, $1) == 0
2201 || strcmp(MagicRelationName, $1) == 0) {
2202 elog(WARN, "%s cannot be accessed by users", $1);
2206 strNcpy(saved_relname, $1, NAMEDATALEN-1);
2210 database_name: Id { $$ = $1; };
2211 access_method: Id { $$ = $1; };
2212 attr_name: Id { $$ = $1; };
2213 class: Id { $$ = $1; };
2214 index_name: Id { $$ = $1; };
2215 var_name: Id { $$ = $1; };
2216 name: Id { $$ = $1; };
2218 date: Sconst { $$ = $1; };
2219 file_name: Sconst { $$ = $1; };
2220 recipe_name: Id { $$ = $1; };
2224 A_Const *n = makeNode(A_Const);
2225 n->val.type = T_Integer;
2226 n->val.val.ival = $1;
2231 A_Const *n = makeNode(A_Const);
2232 n->val.type = T_Float;
2233 n->val.val.dval = $1;
2238 A_Const *n = makeNode(A_Const);
2239 n->val.type = T_String;
2240 n->val.val.str = $1;
2244 { $$ = (Node *)$1; }
2249 $$ = makeNode(ParamNo);
2254 NumConst: Iconst { $$ = makeInteger($1); }
2255 | FCONST { $$ = makeFloat($1); }
2258 Iconst: ICONST { $$ = $1; };
2259 Sconst: SCONST { $$ = $1; };
2261 Id: IDENT { $$ = $1; };
2263 SpecialRuleRelation: CURRENT
2268 elog(WARN,"CURRENT used in non-rule query");
2275 elog(WARN,"NEW used in non-rule query");
2285 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
2287 A_Expr *a = makeNode(A_Expr);
2296 xlateSqlType(char *name)
2298 if (!strcasecmp(name,"int") ||
2299 !strcasecmp(name,"integer"))
2300 return "int4"; /* strdup("int4") -- strdup leaks memory here */
2301 else if (!strcasecmp(name, "smallint"))
2303 else if (!strcasecmp(name, "float") ||
2304 !strcasecmp(name, "real"))
2310 void parser_init(Oid *typev, int nargs)
2312 QueryIsRule = false;
2313 saved_relname[0]= '\0';
2314 saved_In_Expr = NULL;
2316 param_type_init(typev, nargs);