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.40 1997/08/28 05:02:01 vadim 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;
52 extern int CurScanPosition(void);
53 extern int DefaultStartPosition;
54 extern int CheckStartPosition;
55 extern char *parseString;
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);
67 /* old versions of flex define this as a macro */
87 ConstraintDef *constrdef;
91 SortGroupBy *sortgroupby;
108 AddAttrStmt, ClosePortalStmt,
109 CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
110 ExtendStmt, FetchStmt, GrantStmt,
111 IndexStmt, MoveStmt, ListenStmt, OptimizableStmt,
112 ProcedureStmt, PurgeStmt,
113 RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
114 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
115 CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
116 ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
117 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt
119 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
120 database_name, access_method_clause, access_method, attr_name,
121 class, index_name, name, file_name, recipe_name,
122 var_name, aggr_argtype, OptDefault
124 %type <constrdef> ConstraintElem, ConstraintDef
126 %type <str> opt_id, opt_portal_name,
127 before_clause, after_clause, all_Op, MathOp, opt_name, opt_unique,
128 result, OptUseOp, opt_class, opt_range_start, opt_range_end,
131 %type <str> privileges, operation_commalist, grantee
132 %type <chr> operation
134 %type <list> stmtblock, stmtmulti,
135 relation_name_list, OptTableElementList, tableElementList,
136 OptInherit, OptConstraint, ConstraintList, definition,
137 opt_with, def_args, def_name_list, func_argtypes,
138 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
139 opt_column_list, columnList, opt_va_list, va_list,
140 sort_clause, sortby_list, index_params, index_list, name_list,
141 from_clause, from_list, opt_array_bounds, nest_array_bounds,
142 expr_list, default_expr_list, attrs, res_target_list, res_target_list2,
143 def_list, opt_indirection, group_clause, groupby_list
145 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
146 index_opt_unique, opt_verbose, opt_analyze, opt_null
148 %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation,
149 def_type, opt_direction, remove_type, opt_column, event
151 %type <ival> OptLocation, opt_move_where, fetch_how_many
153 %type <list> OptSeqList
154 %type <defelt> OptSeqElem
156 %type <dstmt> def_rest
157 %type <pstmt> purge_quals
158 %type <astmt> insert_rest
160 %type <typnam> Typename, typname, opt_type
161 %type <coldef> columnDef
162 %type <defelt> def_elem
163 %type <node> def_arg, columnElem, where_clause,
164 a_expr, a_expr_or_null, AexprConst,
165 default_expr, default_expr_or_null,
166 in_expr_nodes, not_in_expr_nodes,
168 %type <value> NumConst
169 %type <attr> event_object, attr
170 %type <sortgroupby> groupby
171 %type <sortgroupby> sortby
172 %type <ielem> index_elem, func_index
173 %type <range> from_val
174 %type <relexp> relation_expr
175 %type <trange> time_range
176 %type <target> res_target_el, res_target_el2
177 %type <paramno> ParamNo
181 %type <str> Id, date, var_value
185 * If you make any token changes, remember to:
186 * - use "yacc -d" and update parse.h
187 * - update the keyword table in parser/keywords.c
191 %token ABORT_TRANS, ACL, ADD, AFTER, AGGREGATE, ALL, ALTER, ANALYZE,
192 AND, APPEND, ARCHIVE, ARCH_STORE, AS, ASC,
193 BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BINARY, BY,
194 CAST, CHANGE, CHECK, CLOSE, CLUSTER, COLUMN, COMMIT, CONSTRAINT,
195 COPY, CREATE, CURRENT, CURSOR, DATABASE, DECLARE, DEFAULT, DELETE,
196 DELIMITERS, DESC, DISTINCT, DO, DROP, END_TRANS,
197 EXTEND, FETCH, FOR, FORWARD, FROM, FUNCTION, GRANT, GROUP,
198 HAVING, HEAVY, IN, INDEX, INHERITS, INSERT, INSTEAD, INTO, IS,
199 ISNULL, LANGUAGE, LIGHT, LISTEN, LOAD, MERGE, MOVE, NEW,
200 NONE, NOT, NOTHING, NOTIFY, NOTNULL,
201 OIDS, ON, OPERATOR, OPTION, OR, ORDER,
202 PNULL, PRIVILEGES, PUBLIC, PURGE, P_TYPE,
203 RENAME, REPLACE, RESET, RETRIEVE, RETURNS, REVOKE, ROLLBACK, RULE,
204 SELECT, SET, SETOF, SHOW, STDIN, STDOUT, STORE,
205 TABLE, TO, TRANSACTION, UNIQUE, UPDATE, USING, VACUUM, VALUES
206 VERBOSE, VERSION, VIEW, WHERE, WITH, WORK
207 %token EXECUTE, RECIPE, EXPLAIN, LIKE, SEQUENCE
209 /* Special keywords, not in the query language - see the "lex" file */
210 %token <str> IDENT, SCONST, Op
211 %token <ival> ICONST, PARAM
214 /* these are not real. they are here so that they gets generated as #define's*/
231 %left '|' /* this is the relation union op, not logical or */
232 %right ':' /* Unary Operators */
233 %left ';' /* end of statement or natural log */
245 { parsetree = lcons($1,NIL); }
248 stmtmulti: stmtmulti stmt ';'
249 { $$ = lappend($1, $2); }
251 { $$ = lappend($1, $2); }
253 { $$ = lcons($1,NIL); }
293 /*****************************************************************************
295 * Set PG internal variable
296 * SET var_name TO 'var_value'
298 *****************************************************************************/
300 VariableSetStmt: SET var_name TO var_value
302 VariableSetStmt *n = makeNode(VariableSetStmt);
309 var_value: Sconst { $$ = $1; }
312 VariableShowStmt: SHOW var_name
314 VariableShowStmt *n = makeNode(VariableShowStmt);
320 VariableResetStmt: RESET var_name
322 VariableResetStmt *n = makeNode(VariableResetStmt);
328 /*****************************************************************************
331 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
333 *****************************************************************************/
335 AddAttrStmt: ALTER TABLE relation_name opt_inh_star ADD COLUMN columnDef
337 AddAttrStmt *n = makeNode(AddAttrStmt);
345 columnDef: Id Typename OptDefault opt_null
347 $$ = makeNode(ColumnDef);
351 $$->is_not_null = $4;
355 OptDefault: DEFAULT default_expr
357 int deflen = CurScanPosition() - DefaultStartPosition;
360 defval = (char*) palloc (deflen + 1);
362 parseString + DefaultStartPosition,
367 | /*EMPTY*/ { $$ = NULL; }
370 default_expr_or_null: default_expr
374 A_Const *n = makeNode(A_Const);
375 n->val.type = T_Null;
379 default_expr: AexprConst
381 if (nodeTag($1) != T_A_Const)
382 elog (WARN, "Cannot handle parameter in DEFAULT");
385 | '-' default_expr %prec UMINUS
386 { $$ = makeA_Expr(OP, "-", NULL, $2); }
387 | default_expr '+' default_expr
388 { $$ = makeA_Expr(OP, "+", $1, $3); }
389 | default_expr '-' default_expr
390 { $$ = makeA_Expr(OP, "-", $1, $3); }
391 | default_expr '/' default_expr
392 { $$ = makeA_Expr(OP, "/", $1, $3); }
393 | default_expr '*' default_expr
394 { $$ = makeA_Expr(OP, "*", $1, $3); }
395 | default_expr '<' default_expr
396 { $$ = makeA_Expr(OP, "<", $1, $3); }
397 | default_expr '>' default_expr
398 { $$ = makeA_Expr(OP, ">", $1, $3); }
399 | default_expr '=' default_expr
400 { $$ = makeA_Expr(OP, "=", $1, $3); }
402 { $$ = makeA_Expr(OP, ":", NULL, $2); }
404 { $$ = makeA_Expr(OP, ";", NULL, $2); }
406 { $$ = makeA_Expr(OP, "|", NULL, $2); }
407 | AexprConst TYPECAST Typename
409 /* AexprConst can be either A_Const or ParamNo */
410 if (nodeTag($1) == T_A_Const) {
411 ((A_Const *)$1)->typename = $3;
413 elog (WARN, "Cannot handle parameter in DEFAULT");
417 | CAST AexprConst AS Typename
419 /* AexprConst can be either A_Const or ParamNo */
420 if (nodeTag($2) == T_A_Const) {
421 ((A_Const *)$2)->typename = $4;
423 elog (WARN, "Cannot handle parameter in DEFAULT");
427 | '(' default_expr ')'
429 | default_expr Op default_expr
430 { $$ = makeA_Expr(OP, $2, $1, $3); }
432 { $$ = makeA_Expr(OP, $1, NULL, $2); }
434 { $$ = makeA_Expr(OP, $2, $1, NULL); }
437 FuncCall *n = makeNode(FuncCall);
442 | name '(' default_expr_list ')'
444 FuncCall *n = makeNode(FuncCall);
451 default_expr_list: default_expr_or_null
452 { $$ = lcons($1, NIL); }
453 | default_expr_list ',' default_expr_or_null
454 { $$ = lappend($1, $3); }
457 opt_null: NOT PNULL { $$ = true; }
458 | NOTNULL { $$ = true; }
459 | /* EMPTY */ { $$ = false; }
463 /*****************************************************************************
468 *****************************************************************************/
470 ClosePortalStmt: CLOSE opt_id
472 ClosePortalStmt *n = makeNode(ClosePortalStmt);
479 /*****************************************************************************
482 * COPY [BINARY] <relname> FROM/TO
483 * [USING DELIMITERS <delimiter>]
485 *****************************************************************************/
487 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
489 CopyStmt *n = makeNode(CopyStmt);
507 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
508 * used depends on the direction. (It really doesn't make sense to copy from
509 * stdout. We silently correct the "typo". - AY 9/94
511 copy_file_name: Sconst { $$ = $1; }
512 | STDIN { $$ = NULL; }
513 | STDOUT { $$ = NULL; }
516 opt_binary: BINARY { $$ = TRUE; }
517 | /*EMPTY*/ { $$ = FALSE; }
520 opt_with_copy: WITH OIDS { $$ = TRUE; }
521 | /* EMPTY */ { $$ = FALSE; }
525 * the default copy delimiter is tab but the user can configure it
527 copy_delimiter: USING DELIMITERS Sconst { $$ = $3;}
528 | /* EMPTY */ { $$ = "\t"; }
532 /*****************************************************************************
537 *****************************************************************************/
539 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
540 OptInherit OptConstraint OptArchiveType OptLocation
543 CreateStmt *n = makeNode(CreateStmt);
555 OptTableElementList: tableElementList { $$ = $1; }
556 | /* EMPTY */ { $$ = NULL; }
560 tableElementList ',' columnDef
561 { $$ = lappend($1, $3); }
563 { $$ = lcons($1, NIL); }
567 OptArchiveType: ARCHIVE '=' archive_type { $$ = $3; }
568 | /*EMPTY*/ { $$ = ARCH_NONE; }
571 archive_type: HEAVY { $$ = ARCH_HEAVY; }
572 | LIGHT { $$ = ARCH_LIGHT; }
573 | NONE { $$ = ARCH_NONE; }
576 OptLocation: STORE '=' Sconst
582 OptArchiveLocation: ARCH_STORE '=' Sconst
588 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
589 | /*EMPTY*/ { $$ = NIL; }
592 OptConstraint: ConstraintList { $$ = $1; }
597 ConstraintList ',' ConstraintElem
598 { $$ = lappend($1, $3); }
600 { $$ = lcons($1, NIL); }
604 CONSTRAINT name ConstraintDef
609 | ConstraintDef { $$ = $1; }
612 ConstraintDef: CHECK a_expr {
613 ConstraintDef *constr = palloc (sizeof(ConstraintDef));
614 int chklen = CurScanPosition() - CheckStartPosition;
617 check = (char*) palloc (chklen + 1);
619 parseString + CheckStartPosition,
622 constr->type = CONSTR_CHECK;
624 constr->def = (void*) check;
629 /*****************************************************************************
632 * CREATE SEQUENCE seqname
634 *****************************************************************************/
636 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
638 CreateSeqStmt *n = makeNode(CreateSeqStmt);
646 OptSeqList OptSeqElem
647 { $$ = lappend($1, $2); }
651 OptSeqElem: IDENT NumConst
653 $$ = makeNode(DefElem);
655 $$->arg = (Node *)$2;
659 $$ = makeNode(DefElem);
661 $$->arg = (Node *)NULL;
666 /*****************************************************************************
669 * define (type,operator,aggregate)
671 *****************************************************************************/
673 DefineStmt: CREATE def_type def_rest
680 def_rest: def_name definition
682 $$ = makeNode(DefineStmt);
688 def_type: OPERATOR { $$ = OPERATOR; }
689 | Type { $$ = P_TYPE; }
690 | AGGREGATE { $$ = AGGREGATE; }
693 def_name: Id | MathOp | Op
697 definition: '(' def_list ')' { $$ = $2; }
702 { $$ = lcons($1, NIL); }
703 | def_list ',' def_elem
704 { $$ = lappend($1, $3); }
707 def_elem: def_name '=' def_arg
709 $$ = makeNode(DefElem);
711 $$->arg = (Node *)$3;
715 $$ = makeNode(DefElem);
717 $$->arg = (Node *)NULL;
719 | DEFAULT '=' def_arg
721 $$ = makeNode(DefElem);
722 $$->defname = (char*) palloc (8);
723 strcpy ($$->defname, "default");
724 $$->arg = (Node *)$3;
728 def_arg: Id { $$ = (Node *)makeString($1); }
729 | all_Op { $$ = (Node *)makeString($1); }
730 | NumConst { $$ = (Node *)$1; /* already a Value */ }
731 | Sconst { $$ = (Node *)makeString($1); }
733 TypeName *n = makeNode(TypeName);
736 n->arrayBounds = NULL;
742 /*****************************************************************************
745 * destroy <relname1> [, <relname2> .. <relnameN> ]
747 *****************************************************************************/
749 DestroyStmt: DROP TABLE relation_name_list
751 DestroyStmt *n = makeNode(DestroyStmt);
756 | DROP SEQUENCE relation_name_list
758 DestroyStmt *n = makeNode(DestroyStmt);
766 /*****************************************************************************
769 * fetch [forward | backward] [number | all ] [ in <portalname> ]
771 *****************************************************************************/
773 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
775 FetchStmt *n = makeNode(FetchStmt);
783 opt_direction: FORWARD { $$ = FORWARD; }
784 | BACKWARD { $$ = BACKWARD; }
785 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
788 fetch_how_many: Iconst
790 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch"); }
791 | ALL { $$ = 0; /* 0 means fetch all tuples*/}
792 | /*EMPTY*/ { $$ = 1; /*default*/ }
795 /*****************************************************************************
798 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
800 *****************************************************************************/
802 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
804 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
810 privileges: ALL PRIVILEGES
812 $$ = aclmakepriv("rwaR",0);
816 $$ = aclmakepriv("rwaR",0);
818 | operation_commalist {
823 operation_commalist: operation {
824 $$ = aclmakepriv("",$1);
826 | operation_commalist ',' operation
828 $$ = aclmakepriv($1,$3);
834 $$ = ACL_MODE_RD_CHR;
837 $$ = ACL_MODE_AP_CHR;
840 $$ = ACL_MODE_WR_CHR;
843 $$ = ACL_MODE_WR_CHR;
846 $$ = ACL_MODE_RU_CHR;
851 $$ = aclmakeuser("A","");
854 $$ = aclmakeuser("G",$2);
857 $$ = aclmakeuser("U",$1);
861 opt_with_grant : /* empty */
864 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
867 /*****************************************************************************
870 * REVOKE [privileges] ON [relation_name] FROM [user]
872 *****************************************************************************/
874 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
876 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
882 /*****************************************************************************
885 * move [<dirn>] [<whereto>] [<portalname>]
887 *****************************************************************************/
889 MoveStmt: MOVE opt_direction opt_move_where opt_portal_name
891 MoveStmt *n = makeNode(MoveStmt);
898 | MOVE opt_direction TO Iconst opt_portal_name
900 MoveStmt *n = makeNode(MoveStmt);
909 opt_move_where: Iconst { $$ = $1; }
910 | /*EMPTY*/ { $$ = 1; /* default */ }
913 opt_portal_name: IN name { $$ = $2;}
914 | /*EMPTY*/ { $$ = NULL; }
918 /*****************************************************************************
921 * define [archive] index <indexname> on <relname>
922 * using <access> "(" (<col> with <op>)+ ")" [with
925 * [where <qual>] is not supported anymore
926 *****************************************************************************/
928 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
929 access_method_clause '(' index_params ')' opt_with
931 /* should check that access_method is valid,
932 etc ... but doesn't */
933 IndexStmt *n = makeNode(IndexStmt);
937 n->accessMethod = $7;
940 n->whereClause = NULL;
945 access_method_clause: USING access_method { $$ = $2; }
946 | /* empty -- 'btree' is default access method */
950 index_opt_unique: UNIQUE { $$ = TRUE; }
951 | /*empty*/ { $$ = FALSE; }
954 /*****************************************************************************
957 * extend index <indexname> [where <qual>]
959 *****************************************************************************/
961 ExtendStmt: EXTEND INDEX index_name where_clause
963 ExtendStmt *n = makeNode(ExtendStmt);
970 /*****************************************************************************
973 * execute recipe <recipeName>
975 *****************************************************************************/
977 RecipeStmt: EXECUTE RECIPE recipe_name
980 if (!IsTransactionBlock())
981 elog(WARN, "EXECUTE RECIPE may only be used in begin/end transaction blocks.");
983 n = makeNode(RecipeStmt);
990 /*****************************************************************************
993 * define function <fname>
994 * (language = <lang>, returntype = <typename>
995 * [, arch_pct = <percentage | pre-defined>]
996 * [, disk_pct = <percentage | pre-defined>]
997 * [, byte_pct = <percentage | pre-defined>]
998 * [, perbyte_cpu = <int | pre-defined>]
999 * [, percall_cpu = <int | pre-defined>]
1001 * [arg is (<type-1> { , <type-n>})]
1002 * as <filename or code in language as appropriate>
1004 *****************************************************************************/
1006 ProcedureStmt: CREATE FUNCTION def_name def_args
1007 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1009 ProcedureStmt *n = makeNode(ProcedureStmt);
1012 n->returnType = (Node *)$6;
1019 opt_with: WITH definition { $$ = $2; }
1020 | /* EMPTY */ { $$ = NIL; }
1023 def_args: '(' def_name_list ')' { $$ = $2; }
1024 | '(' ')' { $$ = NIL; }
1027 def_name_list: name_list;
1030 /*****************************************************************************
1033 * purge <relname> [before <date>] [after <date>]
1035 * purge <relname> [after<date>][before <date>]
1037 *****************************************************************************/
1039 PurgeStmt: PURGE relation_name purge_quals
1046 purge_quals: before_clause
1048 $$ = makeNode(PurgeStmt);
1049 $$->beforeDate = $1;
1050 $$->afterDate = NULL;
1054 $$ = makeNode(PurgeStmt);
1055 $$->beforeDate = NULL;
1058 | before_clause after_clause
1060 $$ = makeNode(PurgeStmt);
1061 $$->beforeDate = $1;
1064 | after_clause before_clause
1066 $$ = makeNode(PurgeStmt);
1067 $$->beforeDate = $2;
1072 $$ = makeNode(PurgeStmt);
1073 $$->beforeDate = NULL;
1074 $$->afterDate = NULL;
1078 before_clause: BEFORE date { $$ = $2; }
1079 after_clause: AFTER date { $$ = $2; }
1082 /*****************************************************************************
1086 * remove function <funcname>
1087 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1088 * remove aggregate <aggname>
1089 * (REMOVE AGGREGATE "aggname" "aggtype")
1090 * remove operator <opname>
1091 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1092 * remove type <typename>
1093 * (REMOVE TYPE "typename")
1094 * remove rule <rulename>
1095 * (REMOVE RULE "rulename")
1097 *****************************************************************************/
1099 RemoveStmt: DROP remove_type name
1101 RemoveStmt *n = makeNode(RemoveStmt);
1108 remove_type: Type { $$ = P_TYPE; }
1109 | INDEX { $$ = INDEX; }
1110 | RULE { $$ = RULE; }
1111 | VIEW { $$ = VIEW; }
1114 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1116 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1123 aggr_argtype: name { $$ = $1; }
1124 | '*' { $$ = NULL; }
1127 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1129 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1136 func_argtypes: name_list { $$ = $1; }
1137 | /*EMPTY*/ { $$ = NIL; }
1140 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1142 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1149 all_Op: Op | MathOp;
1151 MathOp: '+' { $$ = "+"; }
1162 elog(WARN, "parser: argument type missing (use NONE for unary operators)");
1165 { $$ = makeList(makeString($1), makeString($3), -1); }
1166 | NONE ',' name /* left unary */
1167 { $$ = makeList(NULL, makeString($3), -1); }
1168 | name ',' NONE /* right unary */
1169 { $$ = makeList(makeString($1), NULL, -1); }
1172 /*****************************************************************************
1175 * rename <attrname1> in <relname> [*] to <attrname2>
1176 * rename <relname1> to <relname2>
1178 *****************************************************************************/
1180 RenameStmt: ALTER TABLE relation_name opt_inh_star
1181 RENAME opt_column opt_name TO name
1183 RenameStmt *n = makeNode(RenameStmt);
1192 opt_name: name { $$ = $1; }
1193 | /*EMPTY*/ { $$ = NULL; }
1196 opt_column: COLUMN { $$ = COLUMN; }
1197 | /*EMPTY*/ { $$ = 0; }
1201 /*****************************************************************************
1203 * QUERY: Define Rewrite Rule , Define Tuple Rule
1204 * Define Rule <old rules >
1206 * only rewrite rule is supported -- ay 9/94
1208 *****************************************************************************/
1210 RuleStmt: CREATE RULE name AS
1211 { QueryIsRule=TRUE; }
1212 ON event TO event_object where_clause
1213 DO opt_instead OptStmtList
1215 RuleStmt *n = makeNode(RuleStmt);
1219 n->whereClause = $10;
1226 OptStmtList: NOTHING { $$ = NIL; }
1227 | OptimizableStmt { $$ = lcons($1, NIL); }
1228 | '[' OptStmtBlock ']' { $$ = $2; }
1231 OptStmtBlock: OptStmtMulti
1234 { $$ = lcons($1, NIL); }
1237 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1238 { $$ = lappend($1, $2); }
1239 | OptStmtMulti OptimizableStmt
1240 { $$ = lappend($1, $2); }
1241 | OptimizableStmt ';'
1242 { $$ = lcons($1, NIL); }
1245 event_object: relation_name '.' attr_name
1247 $$ = makeNode(Attr);
1250 $$->attrs = lcons(makeString($3), NIL);
1251 $$->indirection = NIL;
1255 $$ = makeNode(Attr);
1259 $$->indirection = NIL;
1263 /* change me to select, update, etc. some day */
1264 event: SELECT { $$ = CMD_SELECT; }
1265 | UPDATE { $$ = CMD_UPDATE; }
1266 | DELETE { $$ = CMD_DELETE; }
1267 | INSERT { $$ = CMD_INSERT; }
1270 opt_instead: INSTEAD { $$ = TRUE; }
1271 | /* EMPTY */ { $$ = FALSE; }
1275 /*****************************************************************************
1278 * NOTIFY <relation_name> can appear both in rule bodies and
1279 * as a query-level command
1281 *****************************************************************************/
1283 NotifyStmt: NOTIFY relation_name
1285 NotifyStmt *n = makeNode(NotifyStmt);
1291 ListenStmt: LISTEN relation_name
1293 ListenStmt *n = makeNode(ListenStmt);
1300 /*****************************************************************************
1311 *****************************************************************************/
1313 TransactionStmt: ABORT_TRANS TRANSACTION
1315 TransactionStmt *n = makeNode(TransactionStmt);
1316 n->command = ABORT_TRANS;
1319 | BEGIN_TRANS TRANSACTION
1321 TransactionStmt *n = makeNode(TransactionStmt);
1322 n->command = BEGIN_TRANS;
1327 TransactionStmt *n = makeNode(TransactionStmt);
1328 n->command = BEGIN_TRANS;
1333 TransactionStmt *n = makeNode(TransactionStmt);
1334 n->command = END_TRANS;
1337 | END_TRANS TRANSACTION
1339 TransactionStmt *n = makeNode(TransactionStmt);
1340 n->command = END_TRANS;
1345 TransactionStmt *n = makeNode(TransactionStmt);
1346 n->command = ABORT_TRANS;
1352 TransactionStmt *n = makeNode(TransactionStmt);
1353 n->command = ABORT_TRANS;
1358 TransactionStmt *n = makeNode(TransactionStmt);
1359 n->command = BEGIN_TRANS;
1364 TransactionStmt *n = makeNode(TransactionStmt);
1365 n->command = END_TRANS;
1371 TransactionStmt *n = makeNode(TransactionStmt);
1372 n->command = END_TRANS;
1377 TransactionStmt *n = makeNode(TransactionStmt);
1378 n->command = ABORT_TRANS;
1384 /*****************************************************************************
1387 * define view <viewname> '('target-list ')' [where <quals> ]
1389 *****************************************************************************/
1391 ViewStmt: CREATE VIEW name AS RetrieveStmt
1393 ViewStmt *n = makeNode(ViewStmt);
1395 n->query = (Query *)$5;
1401 /*****************************************************************************
1406 *****************************************************************************/
1408 LoadStmt: LOAD file_name
1410 LoadStmt *n = makeNode(LoadStmt);
1417 /*****************************************************************************
1422 *****************************************************************************/
1424 CreatedbStmt: CREATE DATABASE database_name
1426 CreatedbStmt *n = makeNode(CreatedbStmt);
1433 /*****************************************************************************
1438 *****************************************************************************/
1440 DestroydbStmt: DROP DATABASE database_name
1442 DestroydbStmt *n = makeNode(DestroydbStmt);
1449 /*****************************************************************************
1452 * cluster <index_name> on <relation_name>
1454 *****************************************************************************/
1456 ClusterStmt: CLUSTER index_name ON relation_name
1458 ClusterStmt *n = makeNode(ClusterStmt);
1465 /*****************************************************************************
1470 *****************************************************************************/
1472 VacuumStmt: VACUUM opt_verbose opt_analyze
1474 VacuumStmt *n = makeNode(VacuumStmt);
1481 | VACUUM opt_verbose relation_name opt_analyze opt_va_list
1483 VacuumStmt *n = makeNode(VacuumStmt);
1488 if ( $5 != NIL && !$4 )
1489 elog (WARN, "parser: syntax error at or near \"(\"");
1494 opt_verbose: VERBOSE { $$ = TRUE; }
1495 | /* EMPTY */ { $$ = FALSE; }
1498 opt_analyze: ANALYZE { $$ = TRUE; }
1499 | /* EMPTY */ { $$ = FALSE; }
1502 opt_va_list: '(' va_list ')'
1509 { $$=lcons($1,NIL); }
1511 { $$=lappend($1,$3); }
1514 /*****************************************************************************
1519 *****************************************************************************/
1521 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
1523 ExplainStmt *n = makeNode(ExplainStmt);
1525 n->query = (Query*)$3;
1530 /*****************************************************************************
1532 * Optimizable Stmts: *
1534 * one of the five queries processed by the planner *
1536 * [ultimately] produces query-trees as specified *
1537 * in the query-spec document in ~postgres/ref *
1539 *****************************************************************************/
1541 OptimizableStmt: RetrieveStmt
1546 | DeleteStmt /* by default all are $$=$1 */
1550 /*****************************************************************************
1555 *****************************************************************************/
1557 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
1565 insert_rest: VALUES '(' res_target_list2 ')'
1567 $$ = makeNode(AppendStmt);
1568 $$->targetList = $3;
1569 $$->fromClause = NIL;
1570 $$->whereClause = NULL;
1572 | SELECT res_target_list2 from_clause where_clause
1574 $$ = makeNode(AppendStmt);
1575 $$->targetList = $2;
1576 $$->fromClause = $3;
1577 $$->whereClause = $4;
1581 opt_column_list: '(' columnList ')' { $$ = $2; }
1582 | /*EMPTY*/ { $$ = NIL; }
1586 columnList ',' columnElem
1587 { $$ = lappend($1, $3); }
1589 { $$ = lcons($1, NIL); }
1592 columnElem: Id opt_indirection
1594 Ident *id = makeNode(Ident);
1596 id->indirection = $2;
1601 /*****************************************************************************
1606 *****************************************************************************/
1608 DeleteStmt: DELETE FROM relation_name
1611 DeleteStmt *n = makeNode(DeleteStmt);
1613 n->whereClause = $4;
1619 /*****************************************************************************
1622 * ReplaceStmt (UPDATE)
1624 *****************************************************************************/
1626 ReplaceStmt: UPDATE relation_name
1631 ReplaceStmt *n = makeNode(ReplaceStmt);
1635 n->whereClause = $6;
1641 /*****************************************************************************
1646 *****************************************************************************/
1648 CursorStmt: DECLARE name opt_binary CURSOR FOR
1649 SELECT opt_unique res_target_list2
1650 from_clause where_clause group_clause sort_clause
1652 CursorStmt *n = makeNode(CursorStmt);
1654 /* from PORTAL name */
1656 * 15 august 1991 -- since 3.0 postgres does locking
1657 * right, we discovered that portals were violating
1658 * locking protocol. portal locks cannot span xacts.
1659 * as a short-term fix, we installed the check here.
1662 if (!IsTransactionBlock())
1663 elog(WARN, "Named portals may only be used in begin/end transaction blocks.");
1670 n->whereClause = $10;
1671 n->groupClause = $11;
1672 n->sortClause = $12;
1678 /*****************************************************************************
1683 *****************************************************************************/
1685 RetrieveStmt: SELECT opt_unique res_target_list2
1686 result from_clause where_clause
1687 group_clause having_clause
1690 RetrieveStmt *n = makeNode(RetrieveStmt);
1695 n->whereClause = $6;
1696 n->groupClause = $7;
1697 n->havingClause = $8;
1703 result: INTO TABLE relation_name
1704 { $$= $3; /* should check for archive level */ }
1709 opt_unique: DISTINCT { $$ = "*"; }
1710 | DISTINCT ON Id { $$ = $3; }
1711 | /*EMPTY*/ { $$ = NULL;}
1714 sort_clause: ORDER BY sortby_list { $$ = $3; }
1715 | /*EMPTY*/ { $$ = NIL; }
1719 { $$ = lcons($1, NIL); }
1720 | sortby_list ',' sortby
1721 { $$ = lappend($1, $3); }
1726 $$ = makeNode(SortGroupBy);
1732 | Id '.' Id OptUseOp
1734 $$ = makeNode(SortGroupBy);
1742 $$ = makeNode(SortGroupBy);
1750 OptUseOp: USING Op { $$ = $2; }
1751 | USING '<' { $$ = "<"; }
1752 | USING '>' { $$ = ">"; }
1754 | DESC { $$ = ">"; }
1755 | /*EMPTY*/ { $$ = "<"; /*default*/ }
1758 index_params: index_list { $$ = $1; }
1759 | func_index { $$ = lcons($1,NIL); }
1763 index_list ',' index_elem
1764 { $$ = lappend($1, $3); }
1766 { $$ = lcons($1, NIL); }
1769 func_index: name '(' name_list ')' opt_type opt_class
1771 $$ = makeNode(IndexElem);
1779 index_elem: attr_name opt_type opt_class
1781 $$ = makeNode(IndexElem);
1789 opt_type: ':' Typename { $$ = $2;}
1790 | /*EMPTY*/ { $$ = NULL;}
1794 | WITH class { $$ = $2; }
1795 | /*EMPTY*/ { $$ = NULL; }
1799 * jimmy bell-style recursive queries aren't supported in the
1802 * ...however, recursive addattr and rename supported. make special
1805 * XXX i believe '*' should be the default behavior, but...
1807 opt_inh_star: '*' { $$ = TRUE; }
1808 | /*EMPTY*/ { $$ = FALSE; }
1811 relation_name_list: name_list ;
1814 { $$=lcons(makeString($1),NIL); }
1815 | name_list ',' name
1816 { $$=lappend($1,makeString($3)); }
1819 group_clause: GROUP BY groupby_list { $$ = $3; }
1820 | /*EMPTY*/ { $$ = NIL; }
1823 groupby_list: groupby { $$ = lcons($1, NIL); }
1824 | groupby_list ',' groupby { $$ = lappend($1, $3); }
1829 $$ = makeNode(SortGroupBy);
1837 $$ = makeNode(SortGroupBy);
1845 $$ = makeNode(SortGroupBy);
1853 having_clause: HAVING a_expr { $$ = $2; }
1854 | /*EMPTY*/ { $$ = NULL; }
1857 /*****************************************************************************
1859 * clauses common to all Optimizable Stmts:
1863 *****************************************************************************/
1865 from_clause: FROM from_list { $$ = $2; }
1866 | /*EMPTY*/ { $$ = NIL; }
1869 from_list: from_list ',' from_val
1870 { $$ = lappend($1, $3); }
1872 { $$ = lcons($1, NIL); }
1875 from_val: relation_expr AS var_name
1877 $$ = makeNode(RangeVar);
1881 | relation_expr var_name
1883 $$ = makeNode(RangeVar);
1889 $$ = makeNode(RangeVar);
1895 where_clause: WHERE a_expr { $$ = $2; }
1896 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
1899 relation_expr: relation_name
1901 /* normal relations */
1902 $$ = makeNode(RelExpr);
1905 $$->timeRange = NULL;
1907 | relation_name '*' %prec '='
1909 /* inheiritance query */
1910 $$ = makeNode(RelExpr);
1913 $$->timeRange = NULL;
1915 | relation_name time_range
1917 /* time-qualified query */
1918 $$ = makeNode(RelExpr);
1926 time_range: '[' opt_range_start ',' opt_range_end ']'
1928 $$ = makeNode(TimeRange);
1934 $$ = makeNode(TimeRange);
1940 opt_range_start: date
1941 | /*EMPTY*/ { $$ = "epoch"; }
1945 | /*EMPTY*/ { $$ = "now"; }
1948 opt_array_bounds: '[' ']' nest_array_bounds
1949 { $$ = lcons(makeInteger(-1), $3); }
1950 | '[' Iconst ']' nest_array_bounds
1951 { $$ = lcons(makeInteger($2), $4); }
1956 nest_array_bounds: '[' ']' nest_array_bounds
1957 { $$ = lcons(makeInteger(-1), $3); }
1958 | '[' Iconst ']' nest_array_bounds
1959 { $$ = lcons(makeInteger($2), $4); }
1966 char *tname = xlateSqlType($1);
1967 $$ = makeNode(TypeName);
1970 /* Is this the name of a complex type? If so, implement
1973 if (!strcmp(saved_relname, tname)) {
1974 /* This attr is the same type as the relation
1975 * being defined. The classic example: create
1976 * emp(name=text,mgr=emp)
1979 }else if (get_typrelid((Type)type(tname))
1981 /* (Eventually add in here that the set can only
1982 * contain one element.)
1991 $$ = makeNode(TypeName);
1997 Typename: typname opt_array_bounds
2000 $$->arrayBounds = $2;
2002 | name '(' Iconst ')'
2005 * The following implements char() and varchar().
2006 * We do it here instead of the 'typname:' production
2007 * because we don't want to allow arrays of varchar().
2008 * I haven't thought about whether that will work or not.
2011 $$ = makeNode(TypeName);
2012 if (!strcasecmp($1, "char")) {
2013 $$->name = "bpchar"; /* strdup("bpchar"); */
2014 } else if (!strcasecmp($1, "varchar")) {
2015 $$->name = "varchar"; /* strdup("varchar"); */
2017 yyerror("parse error");
2020 elog(WARN, "length for '%s' type must be at least 1",
2022 } else if ($3 > 4096) {
2023 /* we can store a char() of length up to the size
2024 of a page (8KB) - page headers and friends but
2025 just to be safe here... - ay 6/95 */
2026 elog(WARN, "length for '%s' type cannot exceed 4096",
2029 /* we actually implement this sort of like a varlen, so
2030 the first 4 bytes is the length. (the difference
2031 between this and "text" is that we blank-pad and
2032 truncate where necessary */
2033 $$->typlen = 4 + $3;
2038 /*****************************************************************************
2040 * expression grammar, still needs some cleanup
2042 *****************************************************************************/
2044 a_expr_or_null: a_expr
2048 A_Const *n = makeNode(A_Const);
2049 n->val.type = T_Null;
2053 a_expr: attr opt_indirection
2055 $1->indirection = $2;
2060 | '-' a_expr %prec UMINUS
2061 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2063 { $$ = makeA_Expr(OP, "+", $1, $3); }
2065 { $$ = makeA_Expr(OP, "-", $1, $3); }
2067 { $$ = makeA_Expr(OP, "/", $1, $3); }
2069 { $$ = makeA_Expr(OP, "*", $1, $3); }
2071 { $$ = makeA_Expr(OP, "<", $1, $3); }
2073 { $$ = makeA_Expr(OP, ">", $1, $3); }
2075 { $$ = makeA_Expr(OP, "=", $1, $3); }
2077 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2079 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2081 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2082 | AexprConst TYPECAST Typename
2084 /* AexprConst can be either A_Const or ParamNo */
2085 if (nodeTag($1) == T_A_Const) {
2086 ((A_Const *)$1)->typename = $3;
2088 ((ParamNo *)$1)->typename = $3;
2092 | CAST AexprConst AS Typename
2094 /* AexprConst can be either A_Const or ParamNo */
2095 if (nodeTag($2) == T_A_Const) {
2096 ((A_Const *)$2)->typename = $4;
2098 ((ParamNo *)$2)->typename = $4;
2102 | '(' a_expr_or_null ')'
2105 { $$ = makeA_Expr(OP, $2, $1, $3); }
2106 | a_expr LIKE a_expr
2107 { $$ = makeA_Expr(OP, "~~", $1, $3); }
2108 | a_expr NOT LIKE a_expr
2109 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
2111 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2113 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2115 { /* could be a column name or a relation_name */
2116 Ident *n = makeNode(Ident);
2118 n->indirection = NULL;
2123 FuncCall *n = makeNode(FuncCall);
2124 Ident *star = makeNode(Ident);
2126 /* cheap hack for aggregate (eg. count) */
2129 n->args = lcons(star, NIL);
2134 FuncCall *n = makeNode(FuncCall);
2139 | name '(' expr_list ')'
2141 FuncCall *n = makeNode(FuncCall);
2147 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2149 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2151 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2152 | a_expr IS NOT PNULL
2153 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2154 | a_expr BETWEEN AexprConst AND AexprConst
2155 { $$ = makeA_Expr(AND, NULL,
2156 makeA_Expr(OP, ">=", $1, $3),
2157 makeA_Expr(OP, "<=", $1,$5));
2159 | a_expr NOT BETWEEN AexprConst AND AexprConst
2160 { $$ = makeA_Expr(OR, NULL,
2161 makeA_Expr(OP, "<", $1, $4),
2162 makeA_Expr(OP, ">", $1, $6));
2164 | a_expr IN { saved_In_Expr = $1; } '(' in_expr_nodes ')'
2166 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr_nodes ')'
2169 { $$ = makeA_Expr(AND, NULL, $1, $3); }
2171 { $$ = makeA_Expr(OR, NULL, $1, $3); }
2173 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
2176 opt_indirection: '[' a_expr ']' opt_indirection
2178 A_Indices *ai = makeNode(A_Indices);
2183 | '[' a_expr ':' a_expr ']' opt_indirection
2185 A_Indices *ai = makeNode(A_Indices);
2194 expr_list: a_expr_or_null
2195 { $$ = lcons($1, NIL); }
2196 | expr_list ',' a_expr_or_null
2197 { $$ = lappend($1, $3); }
2200 in_expr_nodes: AexprConst
2201 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
2202 | in_expr_nodes ',' AexprConst
2203 { $$ = makeA_Expr(OR, NULL, $1,
2204 makeA_Expr(OP, "=", saved_In_Expr, $3));
2208 not_in_expr_nodes: AexprConst
2209 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
2210 | not_in_expr_nodes ',' AexprConst
2211 { $$ = makeA_Expr(AND, NULL, $1,
2212 makeA_Expr(OP, "<>", saved_In_Expr, $3));
2216 attr: relation_name '.' attrs
2218 $$ = makeNode(Attr);
2222 $$->indirection = NULL;
2226 $$ = makeNode(Attr);
2230 $$->indirection = NULL;
2235 { $$ = lcons(makeString($1), NIL); }
2236 | attrs '.' attr_name
2237 { $$ = lappend($1, makeString($3)); }
2239 { $$ = lappend($1, makeString("*")); }
2243 /*****************************************************************************
2247 *****************************************************************************/
2249 res_target_list: res_target_list ',' res_target_el
2250 { $$ = lappend($1,$3); }
2252 { $$ = lcons($1, NIL); }
2255 ResTarget *rt = makeNode(ResTarget);
2256 Attr *att = makeNode(Attr);
2258 att->paramNo = NULL;
2260 att->indirection = NIL;
2262 rt->indirection = NULL;
2263 rt->val = (Node *)att;
2264 $$ = lcons(rt, NIL);
2268 res_target_el: Id opt_indirection '=' a_expr_or_null
2270 $$ = makeNode(ResTarget);
2272 $$->indirection = $2;
2273 $$->val = (Node *)$4;
2275 | attr opt_indirection
2277 $$ = makeNode(ResTarget);
2279 $$->indirection = $2;
2280 $$->val = (Node *)$1;
2282 | relation_name '.' '*'
2284 Attr *att = makeNode(Attr);
2286 att->paramNo = NULL;
2287 att->attrs = lcons(makeString("*"), NIL);
2288 att->indirection = NIL;
2289 $$ = makeNode(ResTarget);
2291 $$->indirection = NULL;
2292 $$->val = (Node *)att;
2297 ** target list for select.
2298 ** should get rid of the other but is still needed by the defunct retrieve into
2299 ** and update (uses a subset)
2302 res_target_list2 ',' res_target_el2
2303 { $$ = lappend($1, $3); }
2305 { $$ = lcons($1, NIL); }
2308 /* AS is not optional because shift/red conflict with unary ops */
2309 res_target_el2: a_expr AS Id
2311 $$ = makeNode(ResTarget);
2313 $$->indirection = NULL;
2314 $$->val = (Node *)$1;
2318 $$ = makeNode(ResTarget);
2320 $$->indirection = NULL;
2321 $$->val = (Node *)$1;
2323 | relation_name '.' '*'
2325 Attr *att = makeNode(Attr);
2327 att->paramNo = NULL;
2328 att->attrs = lcons(makeString("*"), NIL);
2329 att->indirection = NIL;
2330 $$ = makeNode(ResTarget);
2332 $$->indirection = NULL;
2333 $$->val = (Node *)att;
2337 Attr *att = makeNode(Attr);
2339 att->paramNo = NULL;
2341 att->indirection = NIL;
2342 $$ = makeNode(ResTarget);
2344 $$->indirection = NULL;
2345 $$->val = (Node *)att;
2349 opt_id: Id { $$ = $1; }
2350 | /* EMPTY */ { $$ = NULL; }
2353 relation_name: SpecialRuleRelation
2356 strNcpy(saved_relname, $1, NAMEDATALEN-1);
2360 /* disallow refs to magic system tables */
2361 if (strcmp(LogRelationName, $1) == 0
2362 || strcmp(VariableRelationName, $1) == 0
2363 || strcmp(TimeRelationName, $1) == 0
2364 || strcmp(MagicRelationName, $1) == 0) {
2365 elog(WARN, "%s cannot be accessed by users", $1);
2369 strNcpy(saved_relname, $1, NAMEDATALEN-1);
2373 database_name: Id { $$ = $1; };
2374 access_method: Id { $$ = $1; };
2375 attr_name: Id { $$ = $1; };
2376 class: Id { $$ = $1; };
2377 index_name: Id { $$ = $1; };
2378 var_name: Id { $$ = $1; };
2379 name: Id { $$ = $1; };
2381 date: Sconst { $$ = $1; };
2382 file_name: Sconst { $$ = $1; };
2383 recipe_name: Id { $$ = $1; };
2387 A_Const *n = makeNode(A_Const);
2388 n->val.type = T_Integer;
2389 n->val.val.ival = $1;
2394 A_Const *n = makeNode(A_Const);
2395 n->val.type = T_Float;
2396 n->val.val.dval = $1;
2401 A_Const *n = makeNode(A_Const);
2402 n->val.type = T_String;
2403 n->val.val.str = $1;
2407 { $$ = (Node *)$1; }
2412 $$ = makeNode(ParamNo);
2417 NumConst: Iconst { $$ = makeInteger($1); }
2418 | FCONST { $$ = makeFloat($1); }
2421 Iconst: ICONST { $$ = $1; };
2422 Sconst: SCONST { $$ = $1; };
2424 Id: IDENT { $$ = $1; };
2426 SpecialRuleRelation: CURRENT
2431 elog(WARN,"CURRENT used in non-rule query");
2438 elog(WARN,"NEW used in non-rule query");
2448 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
2450 A_Expr *a = makeNode(A_Expr);
2459 xlateSqlType(char *name)
2461 if (!strcasecmp(name,"int") ||
2462 !strcasecmp(name,"integer"))
2463 return "int4"; /* strdup("int4") -- strdup leaks memory here */
2464 else if (!strcasecmp(name, "smallint"))
2466 else if (!strcasecmp(name, "float") ||
2467 !strcasecmp(name, "real"))
2473 void parser_init(Oid *typev, int nargs)
2475 QueryIsRule = false;
2476 saved_relname[0]= '\0';
2477 saved_In_Expr = NULL;
2479 param_type_init(typev, nargs);