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.49 1997/09/24 08:31:04 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 "nodes/print.h"
39 #include "parser/gramparse.h"
40 #include "parser/catalog_utils.h"
41 #include "parser/parse_query.h"
42 #include "storage/smgr.h"
43 #include "utils/acl.h"
44 #include "catalog/catname.h"
45 #include "utils/elog.h"
46 #include "access/xact.h"
48 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
49 static bool QueryIsRule = FALSE;
50 static Node *saved_In_Expr;
51 extern List *parsetree;
54 * If you need access to certain yacc-generated variables and find that
55 * they're static by default, uncomment the next line. (this is not a
58 /*#define __YYSCLASS*/
60 static char *xlateSqlType(char *);
61 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
62 static List *makeConstantList( A_Const *node);
63 static char *FlattenStringList(List *list);
65 /* old versions of flex define this as a macro */
86 ConstraintDef *constrdef;
90 SortGroupBy *sortgroupby;
107 AddAttrStmt, ClosePortalStmt,
108 CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
109 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
110 IndexStmt, MoveStmt, ListenStmt, OptimizableStmt,
111 ProcedureStmt, PurgeStmt,
112 RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
113 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
114 CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
115 ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
116 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt
118 %type <str> txname, char_type
119 %type <node> SubSelect
120 %type <str> join_expr, join_outer, join_spec
121 %type <boolean> TriggerActionTime, TriggerForSpec
123 %type <str> DateTime, TriggerEvents, TriggerFuncArg
125 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
126 database_name, access_method_clause, access_method, attr_name,
127 class, index_name, name, file_name, recipe_name, aggr_argtype
129 %type <constrdef> ConstraintElem, ConstraintDef
131 %type <str> opt_id, opt_portal_name,
132 before_clause, after_clause, all_Op, MathOp, opt_name, opt_unique,
133 result, OptUseOp, opt_class, opt_range_start, opt_range_end,
136 %type <str> privileges, operation_commalist, grantee
137 %type <chr> operation, TriggerOneEvent
139 %type <list> stmtblock, stmtmulti,
140 relation_name_list, OptTableElementList, tableElementList,
141 OptInherit, OptConstraint, ConstraintList, definition,
142 opt_with, def_args, def_name_list, func_argtypes,
143 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
144 opt_column_list, columnList, opt_va_list, va_list,
145 sort_clause, sortby_list, index_params, index_list, name_list,
146 from_clause, from_list, opt_array_bounds, nest_array_bounds,
147 expr_list, attrs, res_target_list, res_target_list2,
148 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
150 %type <list> union_clause, select_list
151 %type <list> join_list
152 %type <sortgroupby> join_using
154 %type <node> position_expr
155 %type <list> extract_list, position_list
156 %type <list> substr_list, substr_from, substr_for, trim_list
157 %type <list> interval_opts
159 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_col, opt_with_copy,
160 index_opt_unique, opt_verbose, opt_analyze, opt_null
162 %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation,
163 def_type, opt_direction, remove_type, opt_column, event
165 %type <ival> OptLocation, opt_move_where, fetch_how_many
167 %type <list> OptSeqList
168 %type <defelt> OptSeqElem
170 %type <dstmt> def_rest
171 %type <pstmt> purge_quals
172 %type <astmt> insert_rest
174 %type <typnam> Typename, typname, opt_type
175 %type <coldef> columnDef, alter_clause
176 %type <defelt> def_elem
177 %type <node> def_arg, columnElem, where_clause,
178 a_expr, a_expr_or_null, AexprConst,
179 in_expr_nodes, not_in_expr_nodes,
181 %type <value> NumConst
182 %type <attr> event_object, attr
183 %type <sortgroupby> groupby
184 %type <sortgroupby> sortby
185 %type <ielem> index_elem, func_index
186 %type <range> from_val
187 %type <relexp> relation_expr
188 %type <trange> time_range
189 %type <target> res_target_el, res_target_el2
190 %type <paramno> ParamNo
194 %type <str> Id, date, var_value, zone_value
197 %type <list> default_expr
198 %type <str> opt_default
199 %type <list> constraint_elem
202 * If you make any token changes, remember to:
203 * - use "yacc -d" and update parse.h
204 * - update the keyword table in parser/keywords.c
208 %token ABORT_TRANS, ACL, ADD, AFTER, AGGREGATE, ALL, ALTER, ANALYZE,
209 AND, APPEND, ARCHIVE, ARCH_STORE, AS, ASC,
210 BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BINARY, BY,
211 CAST, CHANGE, CHECK, CLOSE, CLUSTER, COLUMN,
212 COMMIT, CONSTRAINT, COPY, CREATE, CROSS, CURRENT, CURSOR,
213 DATABASE, DECLARE, DEFAULT, DELETE, DELIMITERS, DESC,
214 DISTINCT, DO, DROP, END_TRANS, EXISTS, EXTEND,
215 FETCH, FOR, FORWARD, FROM, FULL, FUNCTION, GRANT, GROUP, HAVING, HEAVY,
216 IN, INDEX, INHERITS, INNERJOIN, INSERT, INSTEAD, INTO, IS, ISNULL,
217 JOIN, LANGUAGE, LEFT, LIGHT, LISTEN, LOAD, LOCAL, MERGE, MOVE,
218 NATURAL, NEW, NONE, NOT, NOTHING, NOTIFY, NOTNULL,
219 OIDS, ON, OPERATOR, OPTION, OR, ORDER, OUTERJOIN,
220 PNULL, PRIVILEGES, PROCEDURE, PUBLIC, PURGE, P_TYPE,
221 RENAME, REPLACE, RESET, RETRIEVE, RETURNS, REVOKE, RIGHT, ROLLBACK, RULE,
222 SELECT, SET, SETOF, SHOW, STDIN, STDOUT, STORE,
223 TABLE, TO, TRANSACTION, TRIGGER,
224 UNION, UNIQUE, UPDATE, USING, VACUUM, VALUES,
225 VERBOSE, VERSION, VIEW, WHERE, WITH, WORK
226 %token EXECUTE, RECIPE, EXPLAIN, LIKE, SEQUENCE
229 %token INTERVAL, TIME, ZONE
230 %token DAYINTERVAL, HOURINTERVAL, MINUTEINTERVAL, MONTHINTERVAL,
231 SECONDINTERVAL, YEARINTERVAL
232 %token BOTH, LEADING, TRAILING,
233 %token EXTRACT, POSITION, SUBSTRING, TRIM
234 %token DOUBLE, PRECISION, FLOAT
235 %token CHARACTER, VARYING
237 /* Special keywords, not in the query language - see the "lex" file */
238 %token <str> IDENT, SCONST, Op
239 %token <ival> ICONST, PARAM
242 /* these are not real. they are here so that they get generated as #define's*/
259 %left '|' /* this is the relation union op, not logical or */
260 %right ':' /* Unary Operators */
261 %left ';' /* end of statement or natural log */
274 { parsetree = lcons($1,NIL); }
277 stmtmulti: stmtmulti stmt ';'
278 { $$ = lappend($1, $2); }
280 { $$ = lappend($1, $2); }
282 { $$ = lcons($1,NIL); }
324 /*****************************************************************************
326 * Set PG internal variable
327 * SET name TO 'var_value'
329 *****************************************************************************/
331 VariableSetStmt: SET Id TO var_value
333 VariableSetStmt *n = makeNode(VariableSetStmt);
338 | SET Id '=' var_value
340 VariableSetStmt *n = makeNode(VariableSetStmt);
345 | SET TIME ZONE zone_value
347 VariableSetStmt *n = makeNode(VariableSetStmt);
348 n->name = "timezone";
354 var_value: Sconst { $$ = $1; }
357 zone_value: Sconst { $$ = $1; }
358 | LOCAL { $$ = NULL; }
361 VariableShowStmt: SHOW Id
363 VariableShowStmt *n = makeNode(VariableShowStmt);
369 VariableResetStmt: RESET Id
371 VariableResetStmt *n = makeNode(VariableResetStmt);
377 /*****************************************************************************
380 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
382 *****************************************************************************/
384 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
386 AddAttrStmt *n = makeNode(AddAttrStmt);
394 alter_clause: ADD opt_column columnDef
398 | ADD '(' tableElementList ')'
400 ColumnDef *lp = lfirst($3);
403 elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
405 printf( "list has %d elements\n", length($3));
410 { elog(WARN,"ALTER TABLE/DROP COLUMN not yet implemented",NULL); }
411 | ALTER opt_column Id SET opt_default
412 { elog(WARN,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented",NULL); }
413 | ALTER opt_column Id DROP DEFAULT
414 { elog(WARN,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented",NULL); }
416 { elog(WARN,"ALTER TABLE/ADD CONSTRAINT not yet implemented",NULL); }
419 /* Column definition might include WITH TIME ZONE, but only for the data types
420 * called out in SQL92 date/time definitions. So, check explicitly for "timestamp"
421 * and "time". - thomas 1997-07-14
423 columnDef: Id Typename opt_with_col opt_default opt_null
425 $$ = makeNode(ColumnDef);
428 $$->typename->timezone = $3;
430 $$->is_not_null = $5;
431 if ($$->typename->timezone
432 && (strcasecmp($$->typename->name, "timestamp")
433 && strcasecmp($$->typename->name, "time")))
434 elog(NOTICE,"%s does not use WITH TIME ZONE",$$->typename->name);
438 opt_default: DEFAULT default_expr
440 $$ = FlattenStringList($2);
442 | /*EMPTY*/ { $$ = NULL; }
445 default_expr: AexprConst
446 { $$ = makeConstantList((A_Const *) $1); }
448 { $$ = lcons( makeString("NULL"), NIL); }
449 | '-' default_expr %prec UMINUS
450 { $$ = lcons( makeString( "-"), $2); }
451 | default_expr '+' default_expr
452 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
453 | default_expr '-' default_expr
454 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
455 | default_expr '/' default_expr
456 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
457 | default_expr '*' default_expr
458 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
459 | default_expr '=' default_expr
460 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
461 | default_expr '<' default_expr
462 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
463 | default_expr '>' default_expr
464 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
466 { $$ = lcons( makeString( ":"), $2); }
468 { $$ = lcons( makeString( ";"), $2); }
470 { $$ = lcons( makeString( "|"), $2); }
471 | default_expr TYPECAST Typename
473 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
475 | CAST default_expr AS Typename
477 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
479 | '(' default_expr ')'
480 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
481 | name '(' default_expr ')'
483 $$ = makeList( makeString($1), makeString("("), -1);
485 $$ = lappend( $$, makeString(")"));
489 $$ = makeList( makeString($1), makeString("("), -1);
490 $$ = lappend( $$, makeString(")"));
492 | default_expr Op default_expr
494 if (!strcmp("<=", $2) || !strcmp(">=", $2))
495 elog(WARN,"boolean expressions not supported in DEFAULT",NULL);
496 $$ = nconc( $1, lcons( makeString( $2), $3));
499 { $$ = lcons( makeString( $1), $2); }
501 { $$ = lappend( $1, makeString( $2)); }
504 opt_null: NOT PNULL { $$ = TRUE; }
505 | NOTNULL { $$ = TRUE; }
506 | /* EMPTY */ { $$ = FALSE; }
509 opt_with_col: WITH TIME ZONE { $$ = TRUE; }
510 | /* EMPTY */ { $$ = FALSE; }
513 /*****************************************************************************
518 *****************************************************************************/
520 ClosePortalStmt: CLOSE opt_id
522 ClosePortalStmt *n = makeNode(ClosePortalStmt);
529 /*****************************************************************************
532 * COPY [BINARY] <relname> FROM/TO
533 * [USING DELIMITERS <delimiter>]
535 *****************************************************************************/
537 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
539 CopyStmt *n = makeNode(CopyStmt);
557 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
558 * used depends on the direction. (It really doesn't make sense to copy from
559 * stdout. We silently correct the "typo". - AY 9/94
561 copy_file_name: Sconst { $$ = $1; }
562 | STDIN { $$ = NULL; }
563 | STDOUT { $$ = NULL; }
566 opt_binary: BINARY { $$ = TRUE; }
567 | /*EMPTY*/ { $$ = FALSE; }
570 opt_with_copy: WITH OIDS { $$ = TRUE; }
571 | /* EMPTY */ { $$ = FALSE; }
575 * the default copy delimiter is tab but the user can configure it
577 copy_delimiter: USING DELIMITERS Sconst { $$ = $3;}
578 | /* EMPTY */ { $$ = "\t"; }
582 /*****************************************************************************
587 *****************************************************************************/
589 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
590 OptInherit OptConstraint OptArchiveType OptLocation
593 CreateStmt *n = makeNode(CreateStmt);
605 OptTableElementList: tableElementList { $$ = $1; }
606 | /* EMPTY */ { $$ = NULL; }
610 tableElementList ',' columnDef
611 { $$ = lappend($1, $3); }
613 { $$ = lcons($1, NIL); }
617 OptArchiveType: ARCHIVE '=' archive_type { $$ = $3; }
618 | /*EMPTY*/ { $$ = ARCH_NONE; }
621 archive_type: HEAVY { $$ = ARCH_HEAVY; }
622 | LIGHT { $$ = ARCH_LIGHT; }
623 | NONE { $$ = ARCH_NONE; }
626 OptLocation: STORE '=' Sconst
632 OptArchiveLocation: ARCH_STORE '=' Sconst
638 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
639 | /*EMPTY*/ { $$ = NIL; }
642 OptConstraint: ConstraintList { $$ = $1; }
643 | /*EMPTY*/ { $$ = NULL; }
647 ConstraintList ',' ConstraintElem
648 { $$ = lappend($1, $3); }
650 { $$ = lcons($1, NIL); }
654 CONSTRAINT name ConstraintDef
659 | ConstraintDef { $$ = $1; }
662 ConstraintDef: CHECK constraint_elem
664 ConstraintDef *constr = palloc (sizeof(ConstraintDef));
666 printf("in ConstraintDef\n");
668 constr->type = CONSTR_CHECK;
670 constr->def = FlattenStringList($2);
672 printf("ConstraintDef: string is %s\n", (char *) constr->def);
678 constraint_elem: AexprConst
679 { $$ = makeConstantList((A_Const *) $1); }
681 { $$ = lcons( makeString("NULL"), NIL); }
685 printf( "Id is %s\n", $1);
687 $$ = lcons( makeString($1), NIL);
689 | '-' constraint_elem %prec UMINUS
690 { $$ = lcons( makeString( "-"), $2); }
691 | constraint_elem '+' constraint_elem
692 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
693 | constraint_elem '-' constraint_elem
694 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
695 | constraint_elem '/' constraint_elem
696 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
697 | constraint_elem '*' constraint_elem
698 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
699 | constraint_elem '=' constraint_elem
700 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
701 | constraint_elem '<' constraint_elem
702 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
703 | constraint_elem '>' constraint_elem
704 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
705 | ':' constraint_elem
706 { $$ = lcons( makeString( ":"), $2); }
707 | ';' constraint_elem
708 { $$ = lcons( makeString( ";"), $2); }
709 | '|' constraint_elem
710 { $$ = lcons( makeString( "|"), $2); }
711 | constraint_elem TYPECAST Typename
713 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
715 | CAST constraint_elem AS Typename
717 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
719 | '(' constraint_elem ')'
720 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
721 | name '(' constraint_elem ')'
723 $$ = makeList( makeString($1), makeString("("), -1);
725 $$ = lappend( $$, makeString(")"));
727 | constraint_elem Op constraint_elem
728 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
729 | constraint_elem AND constraint_elem
730 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
731 | constraint_elem OR constraint_elem
732 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
734 { $$ = lcons( makeString( $1), $2); }
736 { $$ = lappend( $1, makeString( $2)); }
740 /*****************************************************************************
743 * CREATE SEQUENCE seqname
745 *****************************************************************************/
747 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
749 CreateSeqStmt *n = makeNode(CreateSeqStmt);
757 OptSeqList OptSeqElem
758 { $$ = lappend($1, $2); }
762 OptSeqElem: IDENT NumConst
764 $$ = makeNode(DefElem);
766 $$->arg = (Node *)$2;
770 $$ = makeNode(DefElem);
772 $$->arg = (Node *)NULL;
777 /*****************************************************************************
783 *****************************************************************************/
785 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
786 relation_name TriggerForSpec EXECUTE PROCEDURE
787 name '(' TriggerFuncArgs ')'
789 CreateTrigStmt *n = makeNode(CreateTrigStmt);
796 memcpy (n->actions, $5, 4);
801 TriggerActionTime: BEFORE { $$ = TRUE; }
802 | AFTER { $$ = FALSE; }
805 TriggerEvents: TriggerOneEvent
807 char *e = palloc (4);
808 e[0] = $1; e[1] = 0; $$ = e;
810 | TriggerOneEvent OR TriggerOneEvent
812 char *e = palloc (4);
813 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
815 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
817 char *e = palloc (4);
818 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
823 TriggerOneEvent: INSERT { $$ = 'i'; }
824 | DELETE { $$ = 'd'; }
825 | UPDATE { $$ = 'u'; }
828 TriggerForSpec: FOR name name
830 if ( strcmp ($2, "each") != 0 )
831 elog(WARN,"parser: syntax error near %s",$2);
832 if ( strcmp ($3, "row") == 0 )
834 else if ( strcmp ($3, "statement") == 0 )
837 elog(WARN,"parser: syntax error near %s",$3);
841 TriggerFuncArgs: TriggerFuncArg
842 { $$ = lcons($1, NIL); }
843 | TriggerFuncArgs ',' TriggerFuncArg
844 { $$ = lappend($1, $3); }
845 | /* EMPTY */ { $$ = NIL; }
848 TriggerFuncArg: ICONST
850 char *s = (char *) palloc (256);
851 sprintf (s, "%d", $1);
856 char *s = (char *) palloc (256);
857 sprintf (s, "%g", $1);
860 | Sconst { $$ = $1; }
864 DropTrigStmt: DROP TRIGGER name ON relation_name
866 DropTrigStmt *n = makeNode(DropTrigStmt);
873 /*****************************************************************************
876 * define (type,operator,aggregate)
878 *****************************************************************************/
880 DefineStmt: CREATE def_type def_rest
887 def_rest: def_name definition
889 $$ = makeNode(DefineStmt);
892 printf("def_rest: defname is %s\n", $1);
898 def_type: OPERATOR { $$ = OPERATOR; }
902 printf("def_type: decoding P_TYPE\n");
906 | AGGREGATE { $$ = AGGREGATE; }
909 def_name: PROCEDURE { $$ = "procedure"; }
911 | MathOp { $$ = $1; }
915 definition: '(' def_list ')' { $$ = $2; }
918 def_list: def_elem { $$ = lcons($1, NIL); }
919 | def_list ',' def_elem { $$ = lappend($1, $3); }
922 def_elem: def_name '=' def_arg
925 printf("def_elem: decoding %s =\n", $1);
928 $$ = makeNode(DefElem);
930 $$->arg = (Node *)$3;
935 printf("def_elem: decoding %s\n", $1);
937 $$ = makeNode(DefElem);
939 $$->arg = (Node *)NULL;
941 | DEFAULT '=' def_arg
944 printf("def_elem: decoding DEFAULT =\n");
947 $$ = makeNode(DefElem);
948 $$->defname = "default";
949 $$->arg = (Node *)$3;
953 def_arg: Id { $$ = (Node *)makeString($1); }
954 | all_Op { $$ = (Node *)makeString($1); }
955 | NumConst { $$ = (Node *)$1; /* already a Value */ }
956 | Sconst { $$ = (Node *)makeString($1); }
959 TypeName *n = makeNode(TypeName);
962 n->arrayBounds = NULL;
965 | DOUBLE { $$ = (Node *)makeString("double"); }
969 /*****************************************************************************
972 * destroy <relname1> [, <relname2> .. <relnameN> ]
974 *****************************************************************************/
976 DestroyStmt: DROP TABLE relation_name_list
978 DestroyStmt *n = makeNode(DestroyStmt);
983 | DROP SEQUENCE relation_name_list
985 DestroyStmt *n = makeNode(DestroyStmt);
993 /*****************************************************************************
996 * fetch [forward | backward] [number | all ] [ in <portalname> ]
998 *****************************************************************************/
1000 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1002 FetchStmt *n = makeNode(FetchStmt);
1010 opt_direction: FORWARD { $$ = FORWARD; }
1011 | BACKWARD { $$ = BACKWARD; }
1012 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1015 fetch_how_many: Iconst
1017 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch",NULL); }
1018 | ALL { $$ = 0; /* 0 means fetch all tuples*/}
1019 | /*EMPTY*/ { $$ = 1; /*default*/ }
1022 /*****************************************************************************
1025 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1027 *****************************************************************************/
1029 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1031 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1037 privileges: ALL PRIVILEGES
1039 $$ = aclmakepriv("rwaR",0);
1043 $$ = aclmakepriv("rwaR",0);
1045 | operation_commalist
1051 operation_commalist: operation
1053 $$ = aclmakepriv("",$1);
1055 | operation_commalist ',' operation
1057 $$ = aclmakepriv($1,$3);
1064 $$ = ACL_MODE_RD_CHR;
1068 $$ = ACL_MODE_AP_CHR;
1072 $$ = ACL_MODE_WR_CHR;
1076 $$ = ACL_MODE_WR_CHR;
1080 $$ = ACL_MODE_RU_CHR;
1086 $$ = aclmakeuser("A","");
1090 $$ = aclmakeuser("G",$2);
1094 $$ = aclmakeuser("U",$1);
1098 opt_with_grant : /* empty */
1101 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1105 /*****************************************************************************
1108 * REVOKE [privileges] ON [relation_name] FROM [user]
1110 *****************************************************************************/
1112 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1114 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1120 /*****************************************************************************
1123 * move [<dirn>] [<whereto>] [<portalname>]
1125 *****************************************************************************/
1127 MoveStmt: MOVE opt_direction opt_move_where opt_portal_name
1129 MoveStmt *n = makeNode(MoveStmt);
1136 | MOVE opt_direction TO Iconst opt_portal_name
1138 MoveStmt *n = makeNode(MoveStmt);
1147 opt_move_where: Iconst { $$ = $1; }
1148 | /*EMPTY*/ { $$ = 1; /* default */ }
1151 opt_portal_name: IN name { $$ = $2;}
1152 | /*EMPTY*/ { $$ = NULL; }
1156 /*****************************************************************************
1159 * define [archive] index <indexname> on <relname>
1160 * using <access> "(" (<col> with <op>)+ ")" [with
1163 * [where <qual>] is not supported anymore
1164 *****************************************************************************/
1166 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1167 access_method_clause '(' index_params ')' opt_with
1169 /* should check that access_method is valid,
1170 etc ... but doesn't */
1171 IndexStmt *n = makeNode(IndexStmt);
1175 n->accessMethod = $7;
1176 n->indexParams = $9;
1177 n->withClause = $11;
1178 n->whereClause = NULL;
1183 access_method_clause: USING access_method { $$ = $2; }
1184 | /* empty -- 'btree' is default access method */
1188 index_opt_unique: UNIQUE { $$ = TRUE; }
1189 | /*empty*/ { $$ = FALSE; }
1192 /*****************************************************************************
1195 * extend index <indexname> [where <qual>]
1197 *****************************************************************************/
1199 ExtendStmt: EXTEND INDEX index_name where_clause
1201 ExtendStmt *n = makeNode(ExtendStmt);
1203 n->whereClause = $4;
1208 /*****************************************************************************
1211 * execute recipe <recipeName>
1213 *****************************************************************************/
1215 RecipeStmt: EXECUTE RECIPE recipe_name
1218 if (!IsTransactionBlock())
1219 elog(WARN,"EXECUTE RECIPE may only be used in begin/end transaction blocks",NULL);
1221 n = makeNode(RecipeStmt);
1228 /*****************************************************************************
1231 * define function <fname>
1232 * (language = <lang>, returntype = <typename>
1233 * [, arch_pct = <percentage | pre-defined>]
1234 * [, disk_pct = <percentage | pre-defined>]
1235 * [, byte_pct = <percentage | pre-defined>]
1236 * [, perbyte_cpu = <int | pre-defined>]
1237 * [, percall_cpu = <int | pre-defined>]
1239 * [arg is (<type-1> { , <type-n>})]
1240 * as <filename or code in language as appropriate>
1242 *****************************************************************************/
1244 ProcedureStmt: CREATE FUNCTION def_name def_args
1245 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1247 ProcedureStmt *n = makeNode(ProcedureStmt);
1250 n->returnType = (Node *)$6;
1257 opt_with: WITH definition { $$ = $2; }
1258 | /* EMPTY */ { $$ = NIL; }
1261 def_args: '(' def_name_list ')' { $$ = $2; }
1262 | '(' ')' { $$ = NIL; }
1265 def_name_list: name_list;
1268 /*****************************************************************************
1271 * purge <relname> [before <date>] [after <date>]
1273 * purge <relname> [after <date>] [before <date>]
1275 *****************************************************************************/
1277 PurgeStmt: PURGE relation_name purge_quals
1284 purge_quals: before_clause
1286 $$ = makeNode(PurgeStmt);
1287 $$->beforeDate = $1;
1288 $$->afterDate = NULL;
1292 $$ = makeNode(PurgeStmt);
1293 $$->beforeDate = NULL;
1296 | before_clause after_clause
1298 $$ = makeNode(PurgeStmt);
1299 $$->beforeDate = $1;
1302 | after_clause before_clause
1304 $$ = makeNode(PurgeStmt);
1305 $$->beforeDate = $2;
1310 $$ = makeNode(PurgeStmt);
1311 $$->beforeDate = NULL;
1312 $$->afterDate = NULL;
1316 before_clause: BEFORE date { $$ = $2; }
1317 after_clause: AFTER date { $$ = $2; }
1320 /*****************************************************************************
1324 * remove function <funcname>
1325 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1326 * remove aggregate <aggname>
1327 * (REMOVE AGGREGATE "aggname" "aggtype")
1328 * remove operator <opname>
1329 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1330 * remove type <typename>
1331 * (REMOVE TYPE "typename")
1332 * remove rule <rulename>
1333 * (REMOVE RULE "rulename")
1335 *****************************************************************************/
1337 RemoveStmt: DROP remove_type name
1339 RemoveStmt *n = makeNode(RemoveStmt);
1346 remove_type: Type { $$ = P_TYPE; }
1347 | INDEX { $$ = INDEX; }
1348 | RULE { $$ = RULE; }
1349 | VIEW { $$ = VIEW; }
1352 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1354 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1361 aggr_argtype: name { $$ = $1; }
1362 | '*' { $$ = NULL; }
1365 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1367 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1374 func_argtypes: name_list { $$ = $1; }
1375 | /*EMPTY*/ { $$ = NIL; }
1378 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1380 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1387 all_Op: Op | MathOp;
1389 MathOp: '+' { $$ = "+"; }
1400 elog(WARN,"parser: argument type missing (use NONE for unary operators)",NULL);
1403 { $$ = makeList(makeString($1), makeString($3), -1); }
1404 | NONE ',' name /* left unary */
1405 { $$ = makeList(NULL, makeString($3), -1); }
1406 | name ',' NONE /* right unary */
1407 { $$ = makeList(makeString($1), NULL, -1); }
1410 /*****************************************************************************
1413 * rename <attrname1> in <relname> [*] to <attrname2>
1414 * rename <relname1> to <relname2>
1416 *****************************************************************************/
1418 RenameStmt: ALTER TABLE relation_name opt_inh_star
1419 RENAME opt_column opt_name TO name
1421 RenameStmt *n = makeNode(RenameStmt);
1430 opt_name: name { $$ = $1; }
1431 | /*EMPTY*/ { $$ = NULL; }
1434 opt_column: COLUMN { $$ = COLUMN; }
1435 | /*EMPTY*/ { $$ = 0; }
1439 /*****************************************************************************
1441 * QUERY: Define Rewrite Rule , Define Tuple Rule
1442 * Define Rule <old rules >
1444 * only rewrite rule is supported -- ay 9/94
1446 *****************************************************************************/
1448 RuleStmt: CREATE RULE name AS
1449 { QueryIsRule=TRUE; }
1450 ON event TO event_object where_clause
1451 DO opt_instead OptStmtList
1453 RuleStmt *n = makeNode(RuleStmt);
1457 n->whereClause = $10;
1464 OptStmtList: NOTHING { $$ = NIL; }
1465 | OptimizableStmt { $$ = lcons($1, NIL); }
1466 | '[' OptStmtBlock ']' { $$ = $2; }
1469 OptStmtBlock: OptStmtMulti
1472 { $$ = lcons($1, NIL); }
1475 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1476 { $$ = lappend($1, $2); }
1477 | OptStmtMulti OptimizableStmt
1478 { $$ = lappend($1, $2); }
1479 | OptimizableStmt ';'
1480 { $$ = lcons($1, NIL); }
1483 event_object: relation_name '.' attr_name
1485 $$ = makeNode(Attr);
1488 $$->attrs = lcons(makeString($3), NIL);
1489 $$->indirection = NIL;
1493 $$ = makeNode(Attr);
1497 $$->indirection = NIL;
1501 /* change me to select, update, etc. some day */
1502 event: SELECT { $$ = CMD_SELECT; }
1503 | UPDATE { $$ = CMD_UPDATE; }
1504 | DELETE { $$ = CMD_DELETE; }
1505 | INSERT { $$ = CMD_INSERT; }
1508 opt_instead: INSTEAD { $$ = TRUE; }
1509 | /* EMPTY */ { $$ = FALSE; }
1513 /*****************************************************************************
1516 * NOTIFY <relation_name> can appear both in rule bodies and
1517 * as a query-level command
1519 *****************************************************************************/
1521 NotifyStmt: NOTIFY relation_name
1523 NotifyStmt *n = makeNode(NotifyStmt);
1529 ListenStmt: LISTEN relation_name
1531 ListenStmt *n = makeNode(ListenStmt);
1538 /*****************************************************************************
1549 *****************************************************************************/
1551 TransactionStmt: ABORT_TRANS TRANSACTION
1553 TransactionStmt *n = makeNode(TransactionStmt);
1554 n->command = ABORT_TRANS;
1557 | BEGIN_TRANS TRANSACTION
1559 TransactionStmt *n = makeNode(TransactionStmt);
1560 n->command = BEGIN_TRANS;
1565 TransactionStmt *n = makeNode(TransactionStmt);
1566 n->command = BEGIN_TRANS;
1571 TransactionStmt *n = makeNode(TransactionStmt);
1572 n->command = END_TRANS;
1575 | END_TRANS TRANSACTION
1577 TransactionStmt *n = makeNode(TransactionStmt);
1578 n->command = END_TRANS;
1583 TransactionStmt *n = makeNode(TransactionStmt);
1584 n->command = ABORT_TRANS;
1590 TransactionStmt *n = makeNode(TransactionStmt);
1591 n->command = ABORT_TRANS;
1596 TransactionStmt *n = makeNode(TransactionStmt);
1597 n->command = BEGIN_TRANS;
1602 TransactionStmt *n = makeNode(TransactionStmt);
1603 n->command = END_TRANS;
1609 TransactionStmt *n = makeNode(TransactionStmt);
1610 n->command = END_TRANS;
1615 TransactionStmt *n = makeNode(TransactionStmt);
1616 n->command = ABORT_TRANS;
1622 /*****************************************************************************
1625 * define view <viewname> '('target-list ')' [where <quals> ]
1627 *****************************************************************************/
1629 ViewStmt: CREATE VIEW name AS RetrieveStmt
1631 ViewStmt *n = makeNode(ViewStmt);
1633 n->query = (Query *)$5;
1639 /*****************************************************************************
1644 *****************************************************************************/
1646 LoadStmt: LOAD file_name
1648 LoadStmt *n = makeNode(LoadStmt);
1655 /*****************************************************************************
1660 *****************************************************************************/
1662 CreatedbStmt: CREATE DATABASE database_name
1664 CreatedbStmt *n = makeNode(CreatedbStmt);
1671 /*****************************************************************************
1676 *****************************************************************************/
1678 DestroydbStmt: DROP DATABASE database_name
1680 DestroydbStmt *n = makeNode(DestroydbStmt);
1687 /*****************************************************************************
1690 * cluster <index_name> on <relation_name>
1692 *****************************************************************************/
1694 ClusterStmt: CLUSTER index_name ON relation_name
1696 ClusterStmt *n = makeNode(ClusterStmt);
1703 /*****************************************************************************
1708 *****************************************************************************/
1710 VacuumStmt: VACUUM opt_verbose opt_analyze
1712 VacuumStmt *n = makeNode(VacuumStmt);
1719 | VACUUM opt_verbose relation_name opt_analyze opt_va_list
1721 VacuumStmt *n = makeNode(VacuumStmt);
1726 if ( $5 != NIL && !$4 )
1727 elog(WARN,"parser: syntax error at or near \"(\"",NULL);
1732 opt_verbose: VERBOSE { $$ = TRUE; }
1733 | /* EMPTY */ { $$ = FALSE; }
1736 opt_analyze: ANALYZE { $$ = TRUE; }
1737 | /* EMPTY */ { $$ = FALSE; }
1740 opt_va_list: '(' va_list ')'
1747 { $$=lcons($1,NIL); }
1749 { $$=lappend($1,$3); }
1752 /*****************************************************************************
1757 *****************************************************************************/
1759 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
1761 ExplainStmt *n = makeNode(ExplainStmt);
1763 n->query = (Query*)$3;
1768 /*****************************************************************************
1770 * Optimizable Stmts: *
1772 * one of the five queries processed by the planner *
1774 * [ultimately] produces query-trees as specified *
1775 * in the query-spec document in ~postgres/ref *
1777 *****************************************************************************/
1779 OptimizableStmt: RetrieveStmt
1784 | DeleteStmt /* by default all are $$=$1 */
1788 /*****************************************************************************
1793 *****************************************************************************/
1795 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
1803 insert_rest: VALUES '(' res_target_list2 ')'
1805 $$ = makeNode(AppendStmt);
1806 $$->targetList = $3;
1807 $$->fromClause = NIL;
1808 $$->whereClause = NULL;
1810 | SELECT res_target_list2 from_clause where_clause
1812 $$ = makeNode(AppendStmt);
1813 $$->targetList = $2;
1814 $$->fromClause = $3;
1815 $$->whereClause = $4;
1819 opt_column_list: '(' columnList ')' { $$ = $2; }
1820 | /*EMPTY*/ { $$ = NIL; }
1824 columnList ',' columnElem
1825 { $$ = lappend($1, $3); }
1827 { $$ = lcons($1, NIL); }
1830 columnElem: Id opt_indirection
1832 Ident *id = makeNode(Ident);
1834 id->indirection = $2;
1839 /*****************************************************************************
1844 *****************************************************************************/
1846 DeleteStmt: DELETE FROM relation_name
1849 DeleteStmt *n = makeNode(DeleteStmt);
1851 n->whereClause = $4;
1857 /*****************************************************************************
1860 * ReplaceStmt (UPDATE)
1862 *****************************************************************************/
1864 ReplaceStmt: UPDATE relation_name
1869 ReplaceStmt *n = makeNode(ReplaceStmt);
1873 n->whereClause = $6;
1879 /*****************************************************************************
1884 *****************************************************************************/
1886 CursorStmt: DECLARE name opt_binary CURSOR FOR
1887 SELECT opt_unique res_target_list2
1888 from_clause where_clause group_clause sort_clause
1890 CursorStmt *n = makeNode(CursorStmt);
1892 /* from PORTAL name */
1894 * 15 august 1991 -- since 3.0 postgres does locking
1895 * right, we discovered that portals were violating
1896 * locking protocol. portal locks cannot span xacts.
1897 * as a short-term fix, we installed the check here.
1900 if (!IsTransactionBlock())
1901 elog(WARN,"Named portals may only be used in begin/end transaction blocks",NULL);
1908 n->whereClause = $10;
1909 n->groupClause = $11;
1910 n->sortClause = $12;
1916 /*****************************************************************************
1921 *****************************************************************************/
1923 /******************************************************************************
1924 RetrieveStmt: SELECT opt_unique res_target_list2
1925 result from_clause where_clause
1926 group_clause having_clause
1929 RetrieveStmt *n = makeNode(RetrieveStmt);
1934 n->whereClause = $6;
1935 n->groupClause = $7;
1936 n->havingClause = $8;
1942 RetrieveStmt: Select UNION select_list sort_clause
1943 | Select sort_clause
1944 Select: SELECT opt_unique res_target_list2
1945 result from_clause where_clause
1946 group_clause having_clause
1948 Select *n = makeNode(Select);
1953 n->whereClause = $6;
1954 n->groupClause = $7;
1955 n->havingClause = $8;
1959 ******************************************************************************/
1961 RetrieveStmt: SELECT opt_unique res_target_list2
1962 result from_clause where_clause
1963 group_clause having_clause
1964 union_clause sort_clause
1966 RetrieveStmt *n = makeNode(RetrieveStmt);
1971 n->whereClause = $6;
1972 n->groupClause = $7;
1973 n->havingClause = $8;
1974 n->selectClause = $9;
1975 n->sortClause = $10;
1980 union_clause: UNION select_list { $$ = $2; }
1981 | /*EMPTY*/ { $$ = NIL; }
1984 select_list: select_list UNION SubSelect
1985 { $$ = lappend($1, $3); }
1987 { $$ = lcons($1, NIL); }
1990 SubSelect: SELECT opt_unique res_target_list2
1991 result from_clause where_clause
1992 group_clause having_clause
1994 SubSelect *n = makeNode(SubSelect);
1998 n->whereClause = $6;
1999 n->groupClause = $7;
2000 n->havingClause = $8;
2005 result: INTO TABLE relation_name
2006 { $$= $3; /* should check for archive level */ }
2011 opt_unique: DISTINCT { $$ = "*"; }
2012 | DISTINCT ON Id { $$ = $3; }
2013 | /*EMPTY*/ { $$ = NULL;}
2016 sort_clause: ORDER BY sortby_list { $$ = $3; }
2017 | /*EMPTY*/ { $$ = NIL; }
2021 { $$ = lcons($1, NIL); }
2022 | sortby_list ',' sortby
2023 { $$ = lappend($1, $3); }
2028 $$ = makeNode(SortGroupBy);
2034 | Id '.' Id OptUseOp
2036 $$ = makeNode(SortGroupBy);
2044 $$ = makeNode(SortGroupBy);
2052 OptUseOp: USING Op { $$ = $2; }
2053 | USING '<' { $$ = "<"; }
2054 | USING '>' { $$ = ">"; }
2056 | DESC { $$ = ">"; }
2057 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2060 index_params: index_list { $$ = $1; }
2061 | func_index { $$ = lcons($1,NIL); }
2065 index_list ',' index_elem
2066 { $$ = lappend($1, $3); }
2068 { $$ = lcons($1, NIL); }
2071 func_index: name '(' name_list ')' opt_type opt_class
2073 $$ = makeNode(IndexElem);
2081 index_elem: attr_name opt_type opt_class
2083 $$ = makeNode(IndexElem);
2091 opt_type: ':' Typename { $$ = $2;}
2092 | /*EMPTY*/ { $$ = NULL;}
2096 | WITH class { $$ = $2; }
2097 | /*EMPTY*/ { $$ = NULL; }
2101 * jimmy bell-style recursive queries aren't supported in the
2104 * ...however, recursive addattr and rename supported. make special
2107 * XXX i believe '*' should be the default behavior, but...
2109 opt_inh_star: '*' { $$ = TRUE; }
2110 | /*EMPTY*/ { $$ = FALSE; }
2113 relation_name_list: name_list;
2116 { $$ = lcons(makeString($1),NIL); }
2117 | name_list ',' name
2118 { $$ = lappend($1,makeString($3)); }
2121 group_clause: GROUP BY groupby_list { $$ = $3; }
2122 | /*EMPTY*/ { $$ = NIL; }
2125 groupby_list: groupby { $$ = lcons($1, NIL); }
2126 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2131 $$ = makeNode(SortGroupBy);
2139 $$ = makeNode(SortGroupBy);
2147 $$ = makeNode(SortGroupBy);
2155 having_clause: HAVING a_expr { $$ = $2; }
2156 | /*EMPTY*/ { $$ = NULL; }
2159 /*****************************************************************************
2161 * clauses common to all Optimizable Stmts:
2165 *****************************************************************************/
2167 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2170 elog(WARN,"JOIN not yet implemented",NULL);
2172 | FROM from_list { $$ = $2; }
2173 | /*EMPTY*/ { $$ = NIL; }
2176 from_list: from_list ',' from_val
2177 { $$ = lappend($1, $3); }
2178 | from_val CROSS JOIN from_val
2179 { elog(WARN,"CROSS JOIN not yet implemented",NULL); }
2181 { $$ = lcons($1, NIL); }
2184 from_val: relation_expr AS Id
2186 $$ = makeNode(RangeVar);
2192 $$ = makeNode(RangeVar);
2198 $$ = makeNode(RangeVar);
2204 join_expr: NATURAL join_expr { $$ = NULL; }
2206 { elog(WARN,"FULL OUTER JOIN not yet implemented",NULL); }
2208 { elog(WARN,"LEFT OUTER JOIN not yet implemented",NULL); }
2210 { elog(WARN,"RIGHT OUTER JOIN not yet implemented",NULL); }
2212 { elog(WARN,"OUTER JOIN not yet implemented",NULL); }
2214 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2216 { elog(WARN,"UNION JOIN not yet implemented",NULL); }
2218 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2221 join_outer: OUTERJOIN { $$ = NULL; }
2222 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2225 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2226 | USING '(' join_list ')' { $$ = NULL; }
2227 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2230 join_list: join_using { $$ = lcons($1, NIL); }
2231 | join_list ',' join_using { $$ = lappend($1, $3); }
2236 $$ = makeNode(SortGroupBy);
2244 $$ = makeNode(SortGroupBy);
2252 $$ = makeNode(SortGroupBy);
2260 where_clause: WHERE a_expr { $$ = $2; }
2261 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2264 relation_expr: relation_name
2266 /* normal relations */
2267 $$ = makeNode(RelExpr);
2270 $$->timeRange = NULL;
2272 | relation_name '*' %prec '='
2274 /* inheiritance query */
2275 $$ = makeNode(RelExpr);
2278 $$->timeRange = NULL;
2280 | relation_name time_range
2282 /* time-qualified query */
2283 $$ = makeNode(RelExpr);
2291 time_range: '[' opt_range_start ',' opt_range_end ']'
2293 $$ = makeNode(TimeRange);
2299 $$ = makeNode(TimeRange);
2305 opt_range_start: date
2306 | /*EMPTY*/ { $$ = "epoch"; }
2310 | /*EMPTY*/ { $$ = "now"; }
2313 opt_array_bounds: '[' ']' nest_array_bounds
2314 { $$ = lcons(makeInteger(-1), $3); }
2315 | '[' Iconst ']' nest_array_bounds
2316 { $$ = lcons(makeInteger($2), $4); }
2321 nest_array_bounds: '[' ']' nest_array_bounds
2322 { $$ = lcons(makeInteger(-1), $3); }
2323 | '[' Iconst ']' nest_array_bounds
2324 { $$ = lcons(makeInteger($2), $4); }
2330 * typname handles types without trailing parens for size specification.
2331 * Typename uses either typname or explicit txname(size).
2332 * So, must handle float in both places. - thomas 1997-09-20
2338 $$ = makeNode(TypeName);
2340 if (!strcasecmp($1, "float"))
2341 tname = xlateSqlType("float8");
2343 tname = xlateSqlType($1);
2346 /* Is this the name of a complex type? If so, implement
2349 if (!strcmp(saved_relname, tname))
2350 /* This attr is the same type as the relation
2351 * being defined. The classic example: create
2352 * emp(name=text,mgr=emp)
2355 else if (get_typrelid((Type)type(tname)) != InvalidOid)
2356 /* (Eventually add in here that the set can only
2357 * contain one element.)
2365 char *tname = xlateSqlType($2);
2366 $$ = makeNode(TypeName);
2372 txname: Id { $$ = $1; }
2373 | TIME { $$ = xlateSqlType("time"); }
2374 | INTERVAL interval_opts { $$ = xlateSqlType("interval"); }
2375 | CHARACTER char_type { $$ = $2; }
2376 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2377 | FLOAT { $$ = xlateSqlType("float"); }
2380 char_type: VARYING { $$ = xlateSqlType("varchar"); }
2381 | /*EMPTY*/ { $$ = xlateSqlType("char"); }
2384 interval_opts: YEARINTERVAL { $$ = lcons("year", NIL); }
2385 | MONTHINTERVAL { $$ = NIL; }
2386 | DAYINTERVAL { $$ = NIL; }
2387 | HOURINTERVAL { $$ = NIL; }
2388 | MINUTEINTERVAL { $$ = NIL; }
2389 | SECONDINTERVAL { $$ = NIL; }
2390 | YEARINTERVAL TO MONTHINTERVAL { $$ = NIL; }
2391 | DAYINTERVAL TO HOURINTERVAL { $$ = NIL; }
2392 | DAYINTERVAL TO MINUTEINTERVAL { $$ = NIL; }
2393 | DAYINTERVAL TO SECONDINTERVAL { $$ = NIL; }
2394 | HOURINTERVAL TO MINUTEINTERVAL { $$ = NIL; }
2395 | HOURINTERVAL TO SECONDINTERVAL { $$ = NIL; }
2396 | /* EMPTY */ { $$ = NIL; }
2399 Typename: typname opt_array_bounds
2402 $$->arrayBounds = $2;
2403 if (!strcasecmp($1->name, "varchar"))
2406 | txname '(' Iconst ')'
2409 * The following implements CHAR() and VARCHAR().
2410 * We do it here instead of the 'typname:' production
2411 * because we don't want to allow arrays of VARCHAR().
2412 * I haven't thought about whether that will work or not.
2414 * Also implements FLOAT() - thomas 1997-09-18
2416 $$ = makeNode(TypeName);
2417 if (!strcasecmp($1, "float")) {
2419 elog(WARN,"precision for '%s' type must be at least 1",$1);
2421 $$->name = xlateSqlType("float4");
2423 $$->name = xlateSqlType("float8");
2425 elog(WARN,"precision for '%s' type must be less than 14",$1);
2428 if (!strcasecmp($1, "char"))
2429 $$->name = xlateSqlType("bpchar");
2430 else if (!strcasecmp($1, "varchar"))
2431 $$->name = xlateSqlType("varchar");
2433 yyerror("parse error");
2435 elog(WARN,"length for '%s' type must be at least 1",$1);
2437 /* we can store a char() of length up to the size
2438 * of a page (8KB) - page headers and friends but
2439 * just to be safe here... - ay 6/95
2440 * XXX note this hardcoded limit - thomas 1997-07-13
2442 elog(WARN,"length for '%s' type cannot exceed 4096",$1);
2444 /* we actually implement this sort of like a varlen, so
2445 * the first 4 bytes is the length. (the difference
2446 * between this and "text" is that we blank-pad and
2447 * truncate where necessary
2449 $$->typlen = 4 + $3;
2455 /*****************************************************************************
2457 * expression grammar, still needs some cleanup
2459 *****************************************************************************/
2461 a_expr_or_null: a_expr
2465 A_Const *n = makeNode(A_Const);
2466 n->val.type = T_Null;
2470 a_expr: attr opt_indirection
2472 $1->indirection = $2;
2477 | '-' a_expr %prec UMINUS
2478 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2480 { $$ = makeA_Expr(OP, "+", $1, $3); }
2482 { $$ = makeA_Expr(OP, "-", $1, $3); }
2484 { $$ = makeA_Expr(OP, "/", $1, $3); }
2486 { $$ = makeA_Expr(OP, "*", $1, $3); }
2488 { $$ = makeA_Expr(OP, "<", $1, $3); }
2490 { $$ = makeA_Expr(OP, ">", $1, $3); }
2492 { $$ = makeA_Expr(OP, "=", $1, $3); }
2494 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2496 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2498 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2499 | AexprConst TYPECAST Typename
2501 /* AexprConst can be either A_Const or ParamNo */
2502 if (nodeTag($1) == T_A_Const)
2503 ((A_Const *)$1)->typename = $3;
2505 ((ParamNo *)$1)->typename = $3;
2508 | CAST AexprConst AS Typename
2510 /* AexprConst can be either A_Const or ParamNo */
2511 if (nodeTag($2) == T_A_Const)
2512 ((A_Const *)$2)->typename = $4;
2514 ((ParamNo *)$2)->typename = $4;
2517 | '(' a_expr_or_null ')'
2520 { $$ = makeA_Expr(OP, $2, $1, $3); }
2521 | a_expr LIKE a_expr
2522 { $$ = makeA_Expr(OP, "~~", $1, $3); }
2523 | a_expr NOT LIKE a_expr
2524 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
2526 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2528 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2531 /* could be a column name or a relation_name */
2532 Ident *n = makeNode(Ident);
2534 n->indirection = NULL;
2539 FuncCall *n = makeNode(FuncCall);
2540 Ident *star = makeNode(Ident);
2542 /* cheap hack for aggregate (eg. count) */
2545 n->args = lcons(star, NIL);
2550 FuncCall *n = makeNode(FuncCall);
2555 /* We probably need to define an "exists" node,
2556 * since the optimizer could choose to find only one match.
2557 * Perhaps the first implementation could just check for
2558 * count(*) > 0? - thomas 1997-07-19
2560 | EXISTS '(' SubSelect ')'
2562 elog(WARN,"EXISTS not yet supported",NULL);
2565 | EXTRACT '(' extract_list ')'
2567 FuncCall *n = makeNode(FuncCall);
2568 n->funcname = "date_part";
2572 | POSITION '(' position_list ')'
2574 FuncCall *n = makeNode(FuncCall);
2575 n->funcname = "strpos";
2579 | SUBSTRING '(' substr_list ')'
2581 FuncCall *n = makeNode(FuncCall);
2582 n->funcname = "substr";
2586 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
2587 | TRIM '(' BOTH trim_list ')'
2589 FuncCall *n = makeNode(FuncCall);
2590 n->funcname = "btrim";
2594 | TRIM '(' LEADING trim_list ')'
2596 FuncCall *n = makeNode(FuncCall);
2597 n->funcname = "ltrim";
2601 | TRIM '(' TRAILING trim_list ')'
2603 FuncCall *n = makeNode(FuncCall);
2604 n->funcname = "rtrim";
2608 | TRIM '(' trim_list ')'
2610 FuncCall *n = makeNode(FuncCall);
2611 n->funcname = "btrim";
2615 | name '(' expr_list ')'
2617 FuncCall *n = makeNode(FuncCall);
2623 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2625 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2627 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2628 | a_expr IS NOT PNULL
2629 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2630 | a_expr BETWEEN AexprConst AND AexprConst
2632 $$ = makeA_Expr(AND, NULL,
2633 makeA_Expr(OP, ">=", $1, $3),
2634 makeA_Expr(OP, "<=", $1, $5));
2636 | a_expr NOT BETWEEN AexprConst AND AexprConst
2638 $$ = makeA_Expr(OR, NULL,
2639 makeA_Expr(OP, "<", $1, $4),
2640 makeA_Expr(OP, ">", $1, $6));
2642 | a_expr IN { saved_In_Expr = $1; } '(' in_expr_nodes ')'
2644 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr_nodes ')'
2647 { $$ = makeA_Expr(AND, NULL, $1, $3); }
2649 { $$ = makeA_Expr(OR, NULL, $1, $3); }
2651 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
2654 opt_indirection: '[' a_expr ']' opt_indirection
2656 A_Indices *ai = makeNode(A_Indices);
2661 | '[' a_expr ':' a_expr ']' opt_indirection
2663 A_Indices *ai = makeNode(A_Indices);
2672 expr_list: a_expr_or_null
2673 { $$ = lcons($1, NIL); }
2674 | expr_list ',' a_expr_or_null
2675 { $$ = lappend($1, $3); }
2676 | expr_list USING a_expr
2677 { $$ = lappend($1, $3); }
2680 extract_list: DateTime FROM a_expr
2682 A_Const *n = makeNode(A_Const);
2683 n->val.type = T_String;
2684 n->val.val.str = $1;
2686 printf( "string is %s\n", $1);
2688 $$ = lappend(lcons((Node *)n,NIL), $3);
2694 position_list: position_expr IN position_expr
2695 { $$ = makeList($3, $1, -1); }
2700 position_expr: attr opt_indirection
2702 $1->indirection = $2;
2707 | '-' position_expr %prec UMINUS
2708 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2709 | position_expr '+' position_expr
2710 { $$ = makeA_Expr(OP, "+", $1, $3); }
2711 | position_expr '-' position_expr
2712 { $$ = makeA_Expr(OP, "-", $1, $3); }
2713 | position_expr '/' position_expr
2714 { $$ = makeA_Expr(OP, "/", $1, $3); }
2715 | position_expr '*' position_expr
2716 { $$ = makeA_Expr(OP, "*", $1, $3); }
2718 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2719 | AexprConst TYPECAST Typename
2721 /* AexprConst can be either A_Const or ParamNo */
2722 if (nodeTag($1) == T_A_Const)
2723 ((A_Const *)$1)->typename = $3;
2725 ((ParamNo *)$1)->typename = $3;
2728 | CAST AexprConst AS Typename
2730 /* AexprConst can be either A_Const or ParamNo */
2731 if (nodeTag($2) == T_A_Const)
2732 ((A_Const *)$2)->typename = $4;
2734 ((ParamNo *)$2)->typename = $4;
2737 | '(' position_expr ')'
2739 | position_expr Op position_expr
2740 { $$ = makeA_Expr(OP, $2, $1, $3); }
2742 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2744 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2747 /* could be a column name or a relation_name */
2748 Ident *n = makeNode(Ident);
2750 n->indirection = NULL;
2755 FuncCall *n = makeNode(FuncCall);
2760 | POSITION '(' position_list ')'
2762 FuncCall *n = makeNode(FuncCall);
2763 n->funcname = "strpos";
2767 | SUBSTRING '(' substr_list ')'
2769 FuncCall *n = makeNode(FuncCall);
2770 n->funcname = "substr";
2774 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
2775 | TRIM '(' BOTH trim_list ')'
2777 FuncCall *n = makeNode(FuncCall);
2778 n->funcname = "btrim";
2782 | TRIM '(' LEADING trim_list ')'
2784 FuncCall *n = makeNode(FuncCall);
2785 n->funcname = "ltrim";
2789 | TRIM '(' TRAILING trim_list ')'
2791 FuncCall *n = makeNode(FuncCall);
2792 n->funcname = "rtrim";
2796 | TRIM '(' trim_list ')'
2798 FuncCall *n = makeNode(FuncCall);
2799 n->funcname = "btrim";
2803 | name '(' expr_list ')'
2805 FuncCall *n = makeNode(FuncCall);
2812 substr_list: expr_list substr_from substr_for
2815 if ($2 != NULL) $$ = lappend($$, $2);
2816 if ($3 != NULL) $$ = lappend($$, $3);
2822 substr_from: FROM expr_list
2828 substr_for: FOR expr_list
2834 trim_list: a_expr FROM expr_list
2835 { $$ = lappend($3, $1); }
2842 in_expr_nodes: AexprConst
2843 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
2844 | in_expr_nodes ',' AexprConst
2845 { $$ = makeA_Expr(OR, NULL, $1,
2846 makeA_Expr(OP, "=", saved_In_Expr, $3));
2850 not_in_expr_nodes: AexprConst
2851 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
2852 | not_in_expr_nodes ',' AexprConst
2853 { $$ = makeA_Expr(AND, NULL, $1,
2854 makeA_Expr(OP, "<>", saved_In_Expr, $3));
2858 attr: relation_name '.' attrs
2860 $$ = makeNode(Attr);
2864 $$->indirection = NULL;
2868 $$ = makeNode(Attr);
2872 $$->indirection = NULL;
2877 { $$ = lcons(makeString($1), NIL); }
2878 | attrs '.' attr_name
2879 { $$ = lappend($1, makeString($3)); }
2881 { $$ = lappend($1, makeString("*")); }
2884 DateTime: YEARINTERVAL { $$ = "year"; }
2885 | MONTHINTERVAL { $$ = "month"; }
2886 | DAYINTERVAL { $$ = "day"; }
2887 | HOURINTERVAL { $$ = "hour"; }
2888 | MINUTEINTERVAL { $$ = "minute"; }
2889 | SECONDINTERVAL { $$ = "second"; }
2892 /*****************************************************************************
2896 *****************************************************************************/
2898 res_target_list: res_target_list ',' res_target_el
2899 { $$ = lappend($1,$3); }
2901 { $$ = lcons($1, NIL); }
2904 ResTarget *rt = makeNode(ResTarget);
2905 Attr *att = makeNode(Attr);
2907 att->paramNo = NULL;
2909 att->indirection = NIL;
2911 rt->indirection = NULL;
2912 rt->val = (Node *)att;
2913 $$ = lcons(rt, NIL);
2917 res_target_el: Id opt_indirection '=' a_expr_or_null
2919 $$ = makeNode(ResTarget);
2921 $$->indirection = $2;
2922 $$->val = (Node *)$4;
2924 | attr opt_indirection
2926 $$ = makeNode(ResTarget);
2928 $$->indirection = $2;
2929 $$->val = (Node *)$1;
2931 | relation_name '.' '*'
2933 Attr *att = makeNode(Attr);
2935 att->paramNo = NULL;
2936 att->attrs = lcons(makeString("*"), NIL);
2937 att->indirection = NIL;
2938 $$ = makeNode(ResTarget);
2940 $$->indirection = NULL;
2941 $$->val = (Node *)att;
2946 ** target list for select.
2947 ** should get rid of the other but is still needed by the defunct retrieve into
2948 ** and update (uses a subset)
2950 res_target_list2: res_target_list2 ',' res_target_el2
2951 { $$ = lappend($1, $3); }
2953 { $$ = lcons($1, NIL); }
2956 /* AS is not optional because shift/red conflict with unary ops */
2957 res_target_el2: a_expr_or_null AS ColId
2959 $$ = makeNode(ResTarget);
2961 $$->indirection = NULL;
2962 $$->val = (Node *)$1;
2966 $$ = makeNode(ResTarget);
2968 $$->indirection = NULL;
2969 $$->val = (Node *)$1;
2971 | relation_name '.' '*'
2973 Attr *att = makeNode(Attr);
2975 att->paramNo = NULL;
2976 att->attrs = lcons(makeString("*"), NIL);
2977 att->indirection = NIL;
2978 $$ = makeNode(ResTarget);
2980 $$->indirection = NULL;
2981 $$->val = (Node *)att;
2985 Attr *att = makeNode(Attr);
2987 att->paramNo = NULL;
2989 att->indirection = NIL;
2990 $$ = makeNode(ResTarget);
2992 $$->indirection = NULL;
2993 $$->val = (Node *)att;
2997 opt_id: Id { $$ = $1; }
2998 | /* EMPTY */ { $$ = NULL; }
3001 relation_name: SpecialRuleRelation
3004 strNcpy(saved_relname, $1, NAMEDATALEN-1);
3008 /* disallow refs to magic system tables */
3009 if (strcmp(LogRelationName, $1) == 0
3010 || strcmp(VariableRelationName, $1) == 0
3011 || strcmp(TimeRelationName, $1) == 0
3012 || strcmp(MagicRelationName, $1) == 0)
3013 elog(WARN,"%s cannot be accessed by users",$1);
3016 strNcpy(saved_relname, $1, NAMEDATALEN-1);
3020 database_name: Id { $$ = $1; };
3021 access_method: Id { $$ = $1; };
3022 attr_name: ColId { $$ = $1; };
3023 class: Id { $$ = $1; };
3024 index_name: Id { $$ = $1; };
3025 name: Id { $$ = $1; };
3027 date: Sconst { $$ = $1; };
3028 file_name: Sconst { $$ = $1; };
3029 recipe_name: Id { $$ = $1; };
3033 A_Const *n = makeNode(A_Const);
3034 n->val.type = T_Integer;
3035 n->val.val.ival = $1;
3040 A_Const *n = makeNode(A_Const);
3041 n->val.type = T_Float;
3042 n->val.val.dval = $1;
3047 A_Const *n = makeNode(A_Const);
3048 n->val.type = T_String;
3049 n->val.val.str = $1;
3053 { $$ = (Node *)$1; }
3058 $$ = makeNode(ParamNo);
3063 NumConst: Iconst { $$ = makeInteger($1); }
3064 | FCONST { $$ = makeFloat($1); }
3067 Iconst: ICONST { $$ = $1; };
3068 Sconst: SCONST { $$ = $1; };
3070 Id: IDENT { $$ = $1; };
3072 ColId: Id { $$ = $1; }
3073 | DateTime { $$ = $1; }
3076 SpecialRuleRelation: CURRENT
3081 elog(WARN,"CURRENT used in non-rule query",NULL);
3088 elog(WARN,"NEW used in non-rule query",NULL);
3098 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
3100 A_Expr *a = makeNode(A_Expr);
3109 * Convert alternate type names to internal Postgres types.
3110 * Do not convert "float", since that is handled elsewhere
3111 * for FLOAT(p) syntax.
3114 xlateSqlType(char *name)
3116 if (!strcasecmp(name,"int") ||
3117 !strcasecmp(name,"integer"))
3118 return "int4"; /* strdup("int4") -- strdup leaks memory here */
3119 else if (!strcasecmp(name, "smallint"))
3121 else if (!strcasecmp(name, "real"))
3123 else if (!strcasecmp(name, "interval"))
3129 void parser_init(Oid *typev, int nargs)
3131 QueryIsRule = FALSE;
3132 saved_relname[0]= '\0';
3133 saved_In_Expr = NULL;
3135 param_type_init(typev, nargs);
3138 /* FlattenStringList()
3139 * Traverse list of string nodes and convert to a single string.
3140 * Used for reconstructing string form of complex expressions.
3143 FlattenStringList(List *list)
3150 nlist = length(list);
3152 printf( "list has %d elements\n", nlist);
3157 sp = (char *)(lp->elem.ptr_value);
3160 printf( "length of %s is %d\n", sp, strlen(sp));
3162 len += strlen(sp)+1;
3165 s = (char*) palloc(len);
3171 sp = (char *)(lp->elem.ptr_value);
3174 printf( "length of %s is %d\n", sp, strlen(sp));
3182 printf( "flattened string is \"%s\"\n", s);
3186 } /* FlattenStringList() */
3188 /* makeConstantList()
3189 * Convert constant value node into string node.
3192 makeConstantList( A_Const *n)
3194 char *defval = NULL;
3196 printf( "in AexprConst\n");
3198 if (nodeTag(n) != T_A_Const) {
3199 elog(WARN,"Cannot handle non-constant parameter",NULL);
3201 } else if (n->val.type == T_Float) {
3203 printf( "AexprConst float is %f\n", n->val.val.dval);
3205 defval = (char*) palloc(20+1);
3206 sprintf( defval, "%g", n->val.val.dval);
3208 } else if (n->val.type == T_Integer) {
3210 printf( "AexprConst integer is %ld\n", n->val.val.ival);
3212 defval = (char*) palloc(20+1);
3213 sprintf( defval, "%ld", n->val.val.ival);
3215 } else if (n->val.type == T_String) {
3218 printf( "AexprConst string is \"%s\"\n", n->val.val.str);
3221 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
3222 strcpy( defval, "'");
3223 strcat( defval, ((A_Const *) n)->val.val.str);
3224 strcat( defval, "'");
3227 elog(WARN,"Internal error: cannot encode node",NULL);
3231 printf( "AexprConst argument is \"%s\"\n", defval);
3234 return( lcons( makeString(defval), NIL));
3235 } /* makeConstantList() */