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.39 1997/08/22 03:17:55 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;
721 def_arg: Id { $$ = (Node *)makeString($1); }
722 | all_Op { $$ = (Node *)makeString($1); }
723 | NumConst { $$ = (Node *)$1; /* already a Value */ }
724 | Sconst { $$ = (Node *)makeString($1); }
726 TypeName *n = makeNode(TypeName);
729 n->arrayBounds = NULL;
735 /*****************************************************************************
738 * destroy <relname1> [, <relname2> .. <relnameN> ]
740 *****************************************************************************/
742 DestroyStmt: DROP TABLE relation_name_list
744 DestroyStmt *n = makeNode(DestroyStmt);
749 | DROP SEQUENCE relation_name_list
751 DestroyStmt *n = makeNode(DestroyStmt);
759 /*****************************************************************************
762 * fetch [forward | backward] [number | all ] [ in <portalname> ]
764 *****************************************************************************/
766 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
768 FetchStmt *n = makeNode(FetchStmt);
776 opt_direction: FORWARD { $$ = FORWARD; }
777 | BACKWARD { $$ = BACKWARD; }
778 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
781 fetch_how_many: Iconst
783 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch"); }
784 | ALL { $$ = 0; /* 0 means fetch all tuples*/}
785 | /*EMPTY*/ { $$ = 1; /*default*/ }
788 /*****************************************************************************
791 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
793 *****************************************************************************/
795 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
797 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
803 privileges: ALL PRIVILEGES
805 $$ = aclmakepriv("rwaR",0);
809 $$ = aclmakepriv("rwaR",0);
811 | operation_commalist {
816 operation_commalist: operation {
817 $$ = aclmakepriv("",$1);
819 | operation_commalist ',' operation
821 $$ = aclmakepriv($1,$3);
827 $$ = ACL_MODE_RD_CHR;
830 $$ = ACL_MODE_AP_CHR;
833 $$ = ACL_MODE_WR_CHR;
836 $$ = ACL_MODE_WR_CHR;
839 $$ = ACL_MODE_RU_CHR;
844 $$ = aclmakeuser("A","");
847 $$ = aclmakeuser("G",$2);
850 $$ = aclmakeuser("U",$1);
854 opt_with_grant : /* empty */
857 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
860 /*****************************************************************************
863 * REVOKE [privileges] ON [relation_name] FROM [user]
865 *****************************************************************************/
867 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
869 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
875 /*****************************************************************************
878 * move [<dirn>] [<whereto>] [<portalname>]
880 *****************************************************************************/
882 MoveStmt: MOVE opt_direction opt_move_where opt_portal_name
884 MoveStmt *n = makeNode(MoveStmt);
891 | MOVE opt_direction TO Iconst opt_portal_name
893 MoveStmt *n = makeNode(MoveStmt);
902 opt_move_where: Iconst { $$ = $1; }
903 | /*EMPTY*/ { $$ = 1; /* default */ }
906 opt_portal_name: IN name { $$ = $2;}
907 | /*EMPTY*/ { $$ = NULL; }
911 /*****************************************************************************
914 * define [archive] index <indexname> on <relname>
915 * using <access> "(" (<col> with <op>)+ ")" [with
918 * [where <qual>] is not supported anymore
919 *****************************************************************************/
921 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
922 access_method_clause '(' index_params ')' opt_with
924 /* should check that access_method is valid,
925 etc ... but doesn't */
926 IndexStmt *n = makeNode(IndexStmt);
930 n->accessMethod = $7;
933 n->whereClause = NULL;
938 access_method_clause: USING access_method { $$ = $2; }
939 | /* empty -- 'btree' is default access method */
943 index_opt_unique: UNIQUE { $$ = TRUE; }
944 | /*empty*/ { $$ = FALSE; }
947 /*****************************************************************************
950 * extend index <indexname> [where <qual>]
952 *****************************************************************************/
954 ExtendStmt: EXTEND INDEX index_name where_clause
956 ExtendStmt *n = makeNode(ExtendStmt);
963 /*****************************************************************************
966 * execute recipe <recipeName>
968 *****************************************************************************/
970 RecipeStmt: EXECUTE RECIPE recipe_name
973 if (!IsTransactionBlock())
974 elog(WARN, "EXECUTE RECIPE may only be used in begin/end transaction blocks.");
976 n = makeNode(RecipeStmt);
983 /*****************************************************************************
986 * define function <fname>
987 * (language = <lang>, returntype = <typename>
988 * [, arch_pct = <percentage | pre-defined>]
989 * [, disk_pct = <percentage | pre-defined>]
990 * [, byte_pct = <percentage | pre-defined>]
991 * [, perbyte_cpu = <int | pre-defined>]
992 * [, percall_cpu = <int | pre-defined>]
994 * [arg is (<type-1> { , <type-n>})]
995 * as <filename or code in language as appropriate>
997 *****************************************************************************/
999 ProcedureStmt: CREATE FUNCTION def_name def_args
1000 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1002 ProcedureStmt *n = makeNode(ProcedureStmt);
1005 n->returnType = (Node *)$6;
1012 opt_with: WITH definition { $$ = $2; }
1013 | /* EMPTY */ { $$ = NIL; }
1016 def_args: '(' def_name_list ')' { $$ = $2; }
1017 | '(' ')' { $$ = NIL; }
1020 def_name_list: name_list;
1023 /*****************************************************************************
1026 * purge <relname> [before <date>] [after <date>]
1028 * purge <relname> [after<date>][before <date>]
1030 *****************************************************************************/
1032 PurgeStmt: PURGE relation_name purge_quals
1039 purge_quals: before_clause
1041 $$ = makeNode(PurgeStmt);
1042 $$->beforeDate = $1;
1043 $$->afterDate = NULL;
1047 $$ = makeNode(PurgeStmt);
1048 $$->beforeDate = NULL;
1051 | before_clause after_clause
1053 $$ = makeNode(PurgeStmt);
1054 $$->beforeDate = $1;
1057 | after_clause before_clause
1059 $$ = makeNode(PurgeStmt);
1060 $$->beforeDate = $2;
1065 $$ = makeNode(PurgeStmt);
1066 $$->beforeDate = NULL;
1067 $$->afterDate = NULL;
1071 before_clause: BEFORE date { $$ = $2; }
1072 after_clause: AFTER date { $$ = $2; }
1075 /*****************************************************************************
1079 * remove function <funcname>
1080 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1081 * remove aggregate <aggname>
1082 * (REMOVE AGGREGATE "aggname" "aggtype")
1083 * remove operator <opname>
1084 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1085 * remove type <typename>
1086 * (REMOVE TYPE "typename")
1087 * remove rule <rulename>
1088 * (REMOVE RULE "rulename")
1090 *****************************************************************************/
1092 RemoveStmt: DROP remove_type name
1094 RemoveStmt *n = makeNode(RemoveStmt);
1101 remove_type: Type { $$ = P_TYPE; }
1102 | INDEX { $$ = INDEX; }
1103 | RULE { $$ = RULE; }
1104 | VIEW { $$ = VIEW; }
1107 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1109 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1116 aggr_argtype: name { $$ = $1; }
1117 | '*' { $$ = NULL; }
1120 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1122 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1129 func_argtypes: name_list { $$ = $1; }
1130 | /*EMPTY*/ { $$ = NIL; }
1133 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1135 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1142 all_Op: Op | MathOp;
1144 MathOp: '+' { $$ = "+"; }
1155 elog(WARN, "parser: argument type missing (use NONE for unary operators)");
1158 { $$ = makeList(makeString($1), makeString($3), -1); }
1159 | NONE ',' name /* left unary */
1160 { $$ = makeList(NULL, makeString($3), -1); }
1161 | name ',' NONE /* right unary */
1162 { $$ = makeList(makeString($1), NULL, -1); }
1165 /*****************************************************************************
1168 * rename <attrname1> in <relname> [*] to <attrname2>
1169 * rename <relname1> to <relname2>
1171 *****************************************************************************/
1173 RenameStmt: ALTER TABLE relation_name opt_inh_star
1174 RENAME opt_column opt_name TO name
1176 RenameStmt *n = makeNode(RenameStmt);
1185 opt_name: name { $$ = $1; }
1186 | /*EMPTY*/ { $$ = NULL; }
1189 opt_column: COLUMN { $$ = COLUMN; }
1190 | /*EMPTY*/ { $$ = 0; }
1194 /*****************************************************************************
1196 * QUERY: Define Rewrite Rule , Define Tuple Rule
1197 * Define Rule <old rules >
1199 * only rewrite rule is supported -- ay 9/94
1201 *****************************************************************************/
1203 RuleStmt: CREATE RULE name AS
1204 { QueryIsRule=TRUE; }
1205 ON event TO event_object where_clause
1206 DO opt_instead OptStmtList
1208 RuleStmt *n = makeNode(RuleStmt);
1212 n->whereClause = $10;
1219 OptStmtList: NOTHING { $$ = NIL; }
1220 | OptimizableStmt { $$ = lcons($1, NIL); }
1221 | '[' OptStmtBlock ']' { $$ = $2; }
1224 OptStmtBlock: OptStmtMulti
1227 { $$ = lcons($1, NIL); }
1230 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1231 { $$ = lappend($1, $2); }
1232 | OptStmtMulti OptimizableStmt
1233 { $$ = lappend($1, $2); }
1234 | OptimizableStmt ';'
1235 { $$ = lcons($1, NIL); }
1238 event_object: relation_name '.' attr_name
1240 $$ = makeNode(Attr);
1243 $$->attrs = lcons(makeString($3), NIL);
1244 $$->indirection = NIL;
1248 $$ = makeNode(Attr);
1252 $$->indirection = NIL;
1256 /* change me to select, update, etc. some day */
1257 event: SELECT { $$ = CMD_SELECT; }
1258 | UPDATE { $$ = CMD_UPDATE; }
1259 | DELETE { $$ = CMD_DELETE; }
1260 | INSERT { $$ = CMD_INSERT; }
1263 opt_instead: INSTEAD { $$ = TRUE; }
1264 | /* EMPTY */ { $$ = FALSE; }
1268 /*****************************************************************************
1271 * NOTIFY <relation_name> can appear both in rule bodies and
1272 * as a query-level command
1274 *****************************************************************************/
1276 NotifyStmt: NOTIFY relation_name
1278 NotifyStmt *n = makeNode(NotifyStmt);
1284 ListenStmt: LISTEN relation_name
1286 ListenStmt *n = makeNode(ListenStmt);
1293 /*****************************************************************************
1304 *****************************************************************************/
1306 TransactionStmt: ABORT_TRANS TRANSACTION
1308 TransactionStmt *n = makeNode(TransactionStmt);
1309 n->command = ABORT_TRANS;
1312 | BEGIN_TRANS TRANSACTION
1314 TransactionStmt *n = makeNode(TransactionStmt);
1315 n->command = BEGIN_TRANS;
1320 TransactionStmt *n = makeNode(TransactionStmt);
1321 n->command = BEGIN_TRANS;
1326 TransactionStmt *n = makeNode(TransactionStmt);
1327 n->command = END_TRANS;
1330 | END_TRANS TRANSACTION
1332 TransactionStmt *n = makeNode(TransactionStmt);
1333 n->command = END_TRANS;
1338 TransactionStmt *n = makeNode(TransactionStmt);
1339 n->command = ABORT_TRANS;
1345 TransactionStmt *n = makeNode(TransactionStmt);
1346 n->command = ABORT_TRANS;
1351 TransactionStmt *n = makeNode(TransactionStmt);
1352 n->command = BEGIN_TRANS;
1357 TransactionStmt *n = makeNode(TransactionStmt);
1358 n->command = END_TRANS;
1364 TransactionStmt *n = makeNode(TransactionStmt);
1365 n->command = END_TRANS;
1370 TransactionStmt *n = makeNode(TransactionStmt);
1371 n->command = ABORT_TRANS;
1377 /*****************************************************************************
1380 * define view <viewname> '('target-list ')' [where <quals> ]
1382 *****************************************************************************/
1384 ViewStmt: CREATE VIEW name AS RetrieveStmt
1386 ViewStmt *n = makeNode(ViewStmt);
1388 n->query = (Query *)$5;
1394 /*****************************************************************************
1399 *****************************************************************************/
1401 LoadStmt: LOAD file_name
1403 LoadStmt *n = makeNode(LoadStmt);
1410 /*****************************************************************************
1415 *****************************************************************************/
1417 CreatedbStmt: CREATE DATABASE database_name
1419 CreatedbStmt *n = makeNode(CreatedbStmt);
1426 /*****************************************************************************
1431 *****************************************************************************/
1433 DestroydbStmt: DROP DATABASE database_name
1435 DestroydbStmt *n = makeNode(DestroydbStmt);
1442 /*****************************************************************************
1445 * cluster <index_name> on <relation_name>
1447 *****************************************************************************/
1449 ClusterStmt: CLUSTER index_name ON relation_name
1451 ClusterStmt *n = makeNode(ClusterStmt);
1458 /*****************************************************************************
1463 *****************************************************************************/
1465 VacuumStmt: VACUUM opt_verbose opt_analyze
1467 VacuumStmt *n = makeNode(VacuumStmt);
1474 | VACUUM opt_verbose relation_name opt_analyze opt_va_list
1476 VacuumStmt *n = makeNode(VacuumStmt);
1481 if ( $5 != NIL && !$4 )
1482 elog (WARN, "parser: syntax error at or near \"(\"");
1487 opt_verbose: VERBOSE { $$ = TRUE; }
1488 | /* EMPTY */ { $$ = FALSE; }
1491 opt_analyze: ANALYZE { $$ = TRUE; }
1492 | /* EMPTY */ { $$ = FALSE; }
1495 opt_va_list: '(' va_list ')'
1502 { $$=lcons($1,NIL); }
1504 { $$=lappend($1,$3); }
1507 /*****************************************************************************
1512 *****************************************************************************/
1514 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
1516 ExplainStmt *n = makeNode(ExplainStmt);
1518 n->query = (Query*)$3;
1523 /*****************************************************************************
1525 * Optimizable Stmts: *
1527 * one of the five queries processed by the planner *
1529 * [ultimately] produces query-trees as specified *
1530 * in the query-spec document in ~postgres/ref *
1532 *****************************************************************************/
1534 OptimizableStmt: RetrieveStmt
1539 | DeleteStmt /* by default all are $$=$1 */
1543 /*****************************************************************************
1548 *****************************************************************************/
1550 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
1558 insert_rest: VALUES '(' res_target_list2 ')'
1560 $$ = makeNode(AppendStmt);
1561 $$->targetList = $3;
1562 $$->fromClause = NIL;
1563 $$->whereClause = NULL;
1565 | SELECT res_target_list2 from_clause where_clause
1567 $$ = makeNode(AppendStmt);
1568 $$->targetList = $2;
1569 $$->fromClause = $3;
1570 $$->whereClause = $4;
1574 opt_column_list: '(' columnList ')' { $$ = $2; }
1575 | /*EMPTY*/ { $$ = NIL; }
1579 columnList ',' columnElem
1580 { $$ = lappend($1, $3); }
1582 { $$ = lcons($1, NIL); }
1585 columnElem: Id opt_indirection
1587 Ident *id = makeNode(Ident);
1589 id->indirection = $2;
1594 /*****************************************************************************
1599 *****************************************************************************/
1601 DeleteStmt: DELETE FROM relation_name
1604 DeleteStmt *n = makeNode(DeleteStmt);
1606 n->whereClause = $4;
1612 /*****************************************************************************
1615 * ReplaceStmt (UPDATE)
1617 *****************************************************************************/
1619 ReplaceStmt: UPDATE relation_name
1624 ReplaceStmt *n = makeNode(ReplaceStmt);
1628 n->whereClause = $6;
1634 /*****************************************************************************
1639 *****************************************************************************/
1641 CursorStmt: DECLARE name opt_binary CURSOR FOR
1642 SELECT opt_unique res_target_list2
1643 from_clause where_clause group_clause sort_clause
1645 CursorStmt *n = makeNode(CursorStmt);
1647 /* from PORTAL name */
1649 * 15 august 1991 -- since 3.0 postgres does locking
1650 * right, we discovered that portals were violating
1651 * locking protocol. portal locks cannot span xacts.
1652 * as a short-term fix, we installed the check here.
1655 if (!IsTransactionBlock())
1656 elog(WARN, "Named portals may only be used in begin/end transaction blocks.");
1663 n->whereClause = $10;
1664 n->groupClause = $11;
1665 n->sortClause = $12;
1671 /*****************************************************************************
1676 *****************************************************************************/
1678 RetrieveStmt: SELECT opt_unique res_target_list2
1679 result from_clause where_clause
1680 group_clause having_clause
1683 RetrieveStmt *n = makeNode(RetrieveStmt);
1688 n->whereClause = $6;
1689 n->groupClause = $7;
1690 n->havingClause = $8;
1696 result: INTO TABLE relation_name
1697 { $$= $3; /* should check for archive level */ }
1702 opt_unique: DISTINCT { $$ = "*"; }
1703 | DISTINCT ON Id { $$ = $3; }
1704 | /*EMPTY*/ { $$ = NULL;}
1707 sort_clause: ORDER BY sortby_list { $$ = $3; }
1708 | /*EMPTY*/ { $$ = NIL; }
1712 { $$ = lcons($1, NIL); }
1713 | sortby_list ',' sortby
1714 { $$ = lappend($1, $3); }
1719 $$ = makeNode(SortGroupBy);
1725 | Id '.' Id OptUseOp
1727 $$ = makeNode(SortGroupBy);
1735 $$ = makeNode(SortGroupBy);
1743 OptUseOp: USING Op { $$ = $2; }
1744 | USING '<' { $$ = "<"; }
1745 | USING '>' { $$ = ">"; }
1747 | DESC { $$ = ">"; }
1748 | /*EMPTY*/ { $$ = "<"; /*default*/ }
1751 index_params: index_list { $$ = $1; }
1752 | func_index { $$ = lcons($1,NIL); }
1756 index_list ',' index_elem
1757 { $$ = lappend($1, $3); }
1759 { $$ = lcons($1, NIL); }
1762 func_index: name '(' name_list ')' opt_type opt_class
1764 $$ = makeNode(IndexElem);
1772 index_elem: attr_name opt_type opt_class
1774 $$ = makeNode(IndexElem);
1782 opt_type: ':' Typename { $$ = $2;}
1783 | /*EMPTY*/ { $$ = NULL;}
1787 | WITH class { $$ = $2; }
1788 | /*EMPTY*/ { $$ = NULL; }
1792 * jimmy bell-style recursive queries aren't supported in the
1795 * ...however, recursive addattr and rename supported. make special
1798 * XXX i believe '*' should be the default behavior, but...
1800 opt_inh_star: '*' { $$ = TRUE; }
1801 | /*EMPTY*/ { $$ = FALSE; }
1804 relation_name_list: name_list ;
1807 { $$=lcons(makeString($1),NIL); }
1808 | name_list ',' name
1809 { $$=lappend($1,makeString($3)); }
1812 group_clause: GROUP BY groupby_list { $$ = $3; }
1813 | /*EMPTY*/ { $$ = NIL; }
1816 groupby_list: groupby { $$ = lcons($1, NIL); }
1817 | groupby_list ',' groupby { $$ = lappend($1, $3); }
1822 $$ = makeNode(SortGroupBy);
1830 $$ = makeNode(SortGroupBy);
1838 $$ = makeNode(SortGroupBy);
1846 having_clause: HAVING a_expr { $$ = $2; }
1847 | /*EMPTY*/ { $$ = NULL; }
1850 /*****************************************************************************
1852 * clauses common to all Optimizable Stmts:
1856 *****************************************************************************/
1858 from_clause: FROM from_list { $$ = $2; }
1859 | /*EMPTY*/ { $$ = NIL; }
1862 from_list: from_list ',' from_val
1863 { $$ = lappend($1, $3); }
1865 { $$ = lcons($1, NIL); }
1868 from_val: relation_expr AS var_name
1870 $$ = makeNode(RangeVar);
1874 | relation_expr var_name
1876 $$ = makeNode(RangeVar);
1882 $$ = makeNode(RangeVar);
1888 where_clause: WHERE a_expr { $$ = $2; }
1889 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
1892 relation_expr: relation_name
1894 /* normal relations */
1895 $$ = makeNode(RelExpr);
1898 $$->timeRange = NULL;
1900 | relation_name '*' %prec '='
1902 /* inheiritance query */
1903 $$ = makeNode(RelExpr);
1906 $$->timeRange = NULL;
1908 | relation_name time_range
1910 /* time-qualified query */
1911 $$ = makeNode(RelExpr);
1919 time_range: '[' opt_range_start ',' opt_range_end ']'
1921 $$ = makeNode(TimeRange);
1927 $$ = makeNode(TimeRange);
1933 opt_range_start: date
1934 | /*EMPTY*/ { $$ = "epoch"; }
1938 | /*EMPTY*/ { $$ = "now"; }
1941 opt_array_bounds: '[' ']' nest_array_bounds
1942 { $$ = lcons(makeInteger(-1), $3); }
1943 | '[' Iconst ']' nest_array_bounds
1944 { $$ = lcons(makeInteger($2), $4); }
1949 nest_array_bounds: '[' ']' nest_array_bounds
1950 { $$ = lcons(makeInteger(-1), $3); }
1951 | '[' Iconst ']' nest_array_bounds
1952 { $$ = lcons(makeInteger($2), $4); }
1959 char *tname = xlateSqlType($1);
1960 $$ = makeNode(TypeName);
1963 /* Is this the name of a complex type? If so, implement
1966 if (!strcmp(saved_relname, tname)) {
1967 /* This attr is the same type as the relation
1968 * being defined. The classic example: create
1969 * emp(name=text,mgr=emp)
1972 }else if (get_typrelid((Type)type(tname))
1974 /* (Eventually add in here that the set can only
1975 * contain one element.)
1984 $$ = makeNode(TypeName);
1990 Typename: typname opt_array_bounds
1993 $$->arrayBounds = $2;
1995 | name '(' Iconst ')'
1998 * The following implements char() and varchar().
1999 * We do it here instead of the 'typname:' production
2000 * because we don't want to allow arrays of varchar().
2001 * I haven't thought about whether that will work or not.
2004 $$ = makeNode(TypeName);
2005 if (!strcasecmp($1, "char")) {
2006 $$->name = "bpchar"; /* strdup("bpchar"); */
2007 } else if (!strcasecmp($1, "varchar")) {
2008 $$->name = "varchar"; /* strdup("varchar"); */
2010 yyerror("parse error");
2013 elog(WARN, "length for '%s' type must be at least 1",
2015 } else if ($3 > 4096) {
2016 /* we can store a char() of length up to the size
2017 of a page (8KB) - page headers and friends but
2018 just to be safe here... - ay 6/95 */
2019 elog(WARN, "length for '%s' type cannot exceed 4096",
2022 /* we actually implement this sort of like a varlen, so
2023 the first 4 bytes is the length. (the difference
2024 between this and "text" is that we blank-pad and
2025 truncate where necessary */
2026 $$->typlen = 4 + $3;
2031 /*****************************************************************************
2033 * expression grammar, still needs some cleanup
2035 *****************************************************************************/
2037 a_expr_or_null: a_expr
2041 A_Const *n = makeNode(A_Const);
2042 n->val.type = T_Null;
2046 a_expr: attr opt_indirection
2048 $1->indirection = $2;
2053 | '-' a_expr %prec UMINUS
2054 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2056 { $$ = makeA_Expr(OP, "+", $1, $3); }
2058 { $$ = makeA_Expr(OP, "-", $1, $3); }
2060 { $$ = makeA_Expr(OP, "/", $1, $3); }
2062 { $$ = makeA_Expr(OP, "*", $1, $3); }
2064 { $$ = makeA_Expr(OP, "<", $1, $3); }
2066 { $$ = makeA_Expr(OP, ">", $1, $3); }
2068 { $$ = makeA_Expr(OP, "=", $1, $3); }
2070 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2072 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2074 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2075 | AexprConst TYPECAST Typename
2077 /* AexprConst can be either A_Const or ParamNo */
2078 if (nodeTag($1) == T_A_Const) {
2079 ((A_Const *)$1)->typename = $3;
2081 ((ParamNo *)$1)->typename = $3;
2085 | CAST AexprConst AS Typename
2087 /* AexprConst can be either A_Const or ParamNo */
2088 if (nodeTag($2) == T_A_Const) {
2089 ((A_Const *)$2)->typename = $4;
2091 ((ParamNo *)$2)->typename = $4;
2095 | '(' a_expr_or_null ')'
2098 { $$ = makeA_Expr(OP, $2, $1, $3); }
2099 | a_expr LIKE a_expr
2100 { $$ = makeA_Expr(OP, "~~", $1, $3); }
2101 | a_expr NOT LIKE a_expr
2102 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
2104 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2106 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2108 { /* could be a column name or a relation_name */
2109 Ident *n = makeNode(Ident);
2111 n->indirection = NULL;
2116 FuncCall *n = makeNode(FuncCall);
2117 Ident *star = makeNode(Ident);
2119 /* cheap hack for aggregate (eg. count) */
2122 n->args = lcons(star, NIL);
2127 FuncCall *n = makeNode(FuncCall);
2132 | name '(' expr_list ')'
2134 FuncCall *n = makeNode(FuncCall);
2140 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2142 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2144 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2145 | a_expr IS NOT PNULL
2146 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2147 | a_expr BETWEEN AexprConst AND AexprConst
2148 { $$ = makeA_Expr(AND, NULL,
2149 makeA_Expr(OP, ">=", $1, $3),
2150 makeA_Expr(OP, "<=", $1,$5));
2152 | a_expr NOT BETWEEN AexprConst AND AexprConst
2153 { $$ = makeA_Expr(OR, NULL,
2154 makeA_Expr(OP, "<", $1, $4),
2155 makeA_Expr(OP, ">", $1, $6));
2157 | a_expr IN { saved_In_Expr = $1; } '(' in_expr_nodes ')'
2159 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr_nodes ')'
2162 { $$ = makeA_Expr(AND, NULL, $1, $3); }
2164 { $$ = makeA_Expr(OR, NULL, $1, $3); }
2166 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
2169 opt_indirection: '[' a_expr ']' opt_indirection
2171 A_Indices *ai = makeNode(A_Indices);
2176 | '[' a_expr ':' a_expr ']' opt_indirection
2178 A_Indices *ai = makeNode(A_Indices);
2187 expr_list: a_expr_or_null
2188 { $$ = lcons($1, NIL); }
2189 | expr_list ',' a_expr_or_null
2190 { $$ = lappend($1, $3); }
2193 in_expr_nodes: AexprConst
2194 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
2195 | in_expr_nodes ',' AexprConst
2196 { $$ = makeA_Expr(OR, NULL, $1,
2197 makeA_Expr(OP, "=", saved_In_Expr, $3));
2201 not_in_expr_nodes: AexprConst
2202 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
2203 | not_in_expr_nodes ',' AexprConst
2204 { $$ = makeA_Expr(AND, NULL, $1,
2205 makeA_Expr(OP, "<>", saved_In_Expr, $3));
2209 attr: relation_name '.' attrs
2211 $$ = makeNode(Attr);
2215 $$->indirection = NULL;
2219 $$ = makeNode(Attr);
2223 $$->indirection = NULL;
2228 { $$ = lcons(makeString($1), NIL); }
2229 | attrs '.' attr_name
2230 { $$ = lappend($1, makeString($3)); }
2232 { $$ = lappend($1, makeString("*")); }
2236 /*****************************************************************************
2240 *****************************************************************************/
2242 res_target_list: res_target_list ',' res_target_el
2243 { $$ = lappend($1,$3); }
2245 { $$ = lcons($1, NIL); }
2248 ResTarget *rt = makeNode(ResTarget);
2249 Attr *att = makeNode(Attr);
2251 att->paramNo = NULL;
2253 att->indirection = NIL;
2255 rt->indirection = NULL;
2256 rt->val = (Node *)att;
2257 $$ = lcons(rt, NIL);
2261 res_target_el: Id opt_indirection '=' a_expr_or_null
2263 $$ = makeNode(ResTarget);
2265 $$->indirection = $2;
2266 $$->val = (Node *)$4;
2268 | attr opt_indirection
2270 $$ = makeNode(ResTarget);
2272 $$->indirection = $2;
2273 $$->val = (Node *)$1;
2275 | relation_name '.' '*'
2277 Attr *att = makeNode(Attr);
2279 att->paramNo = NULL;
2280 att->attrs = lcons(makeString("*"), NIL);
2281 att->indirection = NIL;
2282 $$ = makeNode(ResTarget);
2284 $$->indirection = NULL;
2285 $$->val = (Node *)att;
2290 ** target list for select.
2291 ** should get rid of the other but is still needed by the defunct retrieve into
2292 ** and update (uses a subset)
2295 res_target_list2 ',' res_target_el2
2296 { $$ = lappend($1, $3); }
2298 { $$ = lcons($1, NIL); }
2301 /* AS is not optional because shift/red conflict with unary ops */
2302 res_target_el2: a_expr AS Id
2304 $$ = makeNode(ResTarget);
2306 $$->indirection = NULL;
2307 $$->val = (Node *)$1;
2311 $$ = makeNode(ResTarget);
2313 $$->indirection = NULL;
2314 $$->val = (Node *)$1;
2316 | relation_name '.' '*'
2318 Attr *att = makeNode(Attr);
2320 att->paramNo = NULL;
2321 att->attrs = lcons(makeString("*"), NIL);
2322 att->indirection = NIL;
2323 $$ = makeNode(ResTarget);
2325 $$->indirection = NULL;
2326 $$->val = (Node *)att;
2330 Attr *att = makeNode(Attr);
2332 att->paramNo = NULL;
2334 att->indirection = NIL;
2335 $$ = makeNode(ResTarget);
2337 $$->indirection = NULL;
2338 $$->val = (Node *)att;
2342 opt_id: Id { $$ = $1; }
2343 | /* EMPTY */ { $$ = NULL; }
2346 relation_name: SpecialRuleRelation
2349 strNcpy(saved_relname, $1, NAMEDATALEN-1);
2353 /* disallow refs to magic system tables */
2354 if (strcmp(LogRelationName, $1) == 0
2355 || strcmp(VariableRelationName, $1) == 0
2356 || strcmp(TimeRelationName, $1) == 0
2357 || strcmp(MagicRelationName, $1) == 0) {
2358 elog(WARN, "%s cannot be accessed by users", $1);
2362 strNcpy(saved_relname, $1, NAMEDATALEN-1);
2366 database_name: Id { $$ = $1; };
2367 access_method: Id { $$ = $1; };
2368 attr_name: Id { $$ = $1; };
2369 class: Id { $$ = $1; };
2370 index_name: Id { $$ = $1; };
2371 var_name: Id { $$ = $1; };
2372 name: Id { $$ = $1; };
2374 date: Sconst { $$ = $1; };
2375 file_name: Sconst { $$ = $1; };
2376 recipe_name: Id { $$ = $1; };
2380 A_Const *n = makeNode(A_Const);
2381 n->val.type = T_Integer;
2382 n->val.val.ival = $1;
2387 A_Const *n = makeNode(A_Const);
2388 n->val.type = T_Float;
2389 n->val.val.dval = $1;
2394 A_Const *n = makeNode(A_Const);
2395 n->val.type = T_String;
2396 n->val.val.str = $1;
2400 { $$ = (Node *)$1; }
2405 $$ = makeNode(ParamNo);
2410 NumConst: Iconst { $$ = makeInteger($1); }
2411 | FCONST { $$ = makeFloat($1); }
2414 Iconst: ICONST { $$ = $1; };
2415 Sconst: SCONST { $$ = $1; };
2417 Id: IDENT { $$ = $1; };
2419 SpecialRuleRelation: CURRENT
2424 elog(WARN,"CURRENT used in non-rule query");
2431 elog(WARN,"NEW used in non-rule query");
2441 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
2443 A_Expr *a = makeNode(A_Expr);
2452 xlateSqlType(char *name)
2454 if (!strcasecmp(name,"int") ||
2455 !strcasecmp(name,"integer"))
2456 return "int4"; /* strdup("int4") -- strdup leaks memory here */
2457 else if (!strcasecmp(name, "smallint"))
2459 else if (!strcasecmp(name, "float") ||
2460 !strcasecmp(name, "real"))
2466 void parser_init(Oid *typev, int nargs)
2468 QueryIsRule = false;
2469 saved_relname[0]= '\0';
2470 saved_In_Expr = NULL;
2472 param_type_init(typev, nargs);