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.104 1998/02/04 06:11:46 thomas Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlType(char *);
65 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
66 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
67 void mapTargetColumns(List *source, List *target);
68 static List *makeConstantList( A_Const *node);
69 static char *FlattenStringList(List *list);
70 static char *fmtId(char *rawid);
71 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
72 static void param_type_init(Oid *typev, int nargs);
74 Oid param_type(int t); /* used in parse_expr.c */
76 /* old versions of flex define this as a macro */
90 bool* pboolean; /* for pg_user privileges */
100 SortGroupBy *sortgroupby;
115 AddAttrStmt, ClosePortalStmt,
116 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
117 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
118 CreatePLangStmt, DropPLangStmt,
119 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
120 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
121 RemoveFuncStmt, RemoveStmt,
122 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
123 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
124 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
125 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
126 CreateUserStmt, AlterUserStmt, DropUserStmt
128 %type <str> opt_database, location
130 %type <pboolean> user_createdb_clause, user_createuser_clause
131 %type <str> user_passwd_clause
132 %type <str> user_valid_clause
133 %type <list> user_group_list, user_group_clause
135 %type <str> join_expr, join_outer, join_spec
136 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
138 %type <str> TriggerEvents, TriggerFuncArg
140 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
141 database_name, access_method_clause, access_method, attr_name,
142 class, index_name, name, file_name, recipe_name, aggr_argtype
144 %type <str> opt_id, opt_portal_name,
145 all_Op, MathOp, opt_name, opt_unique,
146 result, OptUseOp, opt_class, SpecialRuleRelation
148 %type <str> privileges, operation_commalist, grantee
149 %type <chr> operation, TriggerOneEvent
151 %type <list> stmtblock, stmtmulti,
152 relation_name_list, OptTableElementList,
153 OptInherit, definition,
154 opt_with, def_args, def_name_list, func_argtypes,
155 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
156 opt_column_list, columnList, opt_va_list, va_list,
157 sort_clause, sortby_list, index_params, index_list, name_list,
158 from_clause, from_list, opt_array_bounds, nest_array_bounds,
159 expr_list, attrs, res_target_list, res_target_list2,
160 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
162 %type <list> union_clause, select_list
163 %type <list> join_list
166 %type <boolean> opt_union
168 %type <node> position_expr
169 %type <list> extract_list, position_list
170 %type <list> substr_list, substr_from, substr_for, trim_list
171 %type <list> opt_interval
173 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
174 index_opt_unique, opt_verbose, opt_analyze
176 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
179 %type <ival> fetch_how_many
181 %type <list> OptSeqList
182 %type <defelt> OptSeqElem
184 %type <dstmt> def_rest
185 %type <astmt> insert_rest
187 %type <node> OptTableElement, ConstraintElem
188 %type <node> columnDef, alter_clause
189 %type <defelt> def_elem
190 %type <node> def_arg, columnElem, where_clause,
191 a_expr, a_expr_or_null, b_expr, AexprConst,
192 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
194 %type <list> row_descriptor, row_list
195 %type <node> row_expr
196 %type <list> OptCreateAs, CreateAsList
197 %type <node> CreateAsElement
198 %type <value> NumConst
199 %type <attr> event_object, attr
200 %type <sortgroupby> groupby
201 %type <sortgroupby> sortby
202 %type <ielem> index_elem, func_index
203 %type <range> from_val
204 %type <relexp> relation_expr
205 %type <target> res_target_el, res_target_el2
206 %type <paramno> ParamNo
208 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
209 %type <str> generic, character, datetime
210 %type <str> opt_charset, opt_collate
211 %type <str> opt_float, opt_numeric, opt_decimal
212 %type <boolean> opt_varying, opt_timezone
216 %type <str> Id, var_value, zone_value
217 %type <str> ColId, ColLabel
219 %type <node> TableConstraint
220 %type <list> constraint_list, constraint_expr
221 %type <list> default_list, default_expr
222 %type <list> ColQualList, ColQualifier
223 %type <node> ColConstraint, ColConstraintElem
224 %type <list> key_actions, key_action
225 %type <str> key_match, key_reference
228 * If you make any token changes, remember to:
229 * - use "yacc -d" and update parse.h
230 * - update the keyword table in parser/keywords.c
233 /* Reserved word tokens
234 * SQL92 syntax has many type-specific constructs.
235 * So, go ahead and make these types reserved words,
236 * and call-out the syntax explicitly.
237 * This gets annoying when trying to also retain Postgres' nice
238 * type-extensible features, but we don't really have a choice.
239 * - thomas 1997-10-11
242 /* Keywords (in SQL92 reserved words) */
243 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
244 BEGIN_TRANS, BETWEEN, BOTH, BY,
245 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
246 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
247 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
248 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
249 END_TRANS, EXECUTE, EXISTS, EXTRACT,
250 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
251 GRANT, GROUP, HAVING, HOUR_P,
252 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
253 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
254 MATCH, MINUTE_P, MONTH_P,
255 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
256 ON, OPTION, OR, ORDER, OUTER_P,
257 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
258 REFERENCES, REVOKE, RIGHT, ROLLBACK,
259 SECOND_P, SELECT, SET, SUBSTRING,
260 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
261 UNION, UNIQUE, UPDATE, USING,
262 VALUES, VARCHAR, VARYING, VIEW,
263 WHERE, WITH, WORK, YEAR_P, ZONE
265 /* Keywords (in SQL3 reserved words) */
266 %token FALSE_P, TRIGGER, TRUE_P
268 /* Keywords (in SQL92 non-reserved words) */
271 /* Keywords for Postgres support (not in SQL92 reserved words) */
272 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
273 BACKWARD, BEFORE, BINARY, CLUSTER, COPY,
274 DATABASE, DELIMITERS, DO, EXPLAIN, EXTEND,
275 FORWARD, FUNCTION, HANDLER,
276 INDEX, INHERITS, INSTEAD, ISNULL,
277 LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MOVE,
278 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
279 RECIPE, RENAME, RESET, RETURNS, RULE,
280 SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED,
281 VACUUM, VERBOSE, VERSION
283 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
287 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
288 * when some sort of pg_privileges relation is introduced.
292 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
294 /* Special keywords, not in the query language - see the "lex" file */
295 %token <str> IDENT, SCONST, Op
296 %token <ival> ICONST, PARAM
299 /* these are not real. they are here so that they get generated as #define's*/
311 %nonassoc Op /* multi-character ops and user-defined operators */
317 %left '|' /* this is the relation union op, not logical or */
318 /* Unary Operators */
320 %left ';' /* end of statement or natural log */
332 { parsetree = lcons($1,NIL); }
335 stmtmulti: stmtmulti stmt ';'
336 { $$ = lappend($1, $2); }
338 { $$ = lappend($1, $2); }
340 { $$ = lcons($1,NIL); }
387 /*****************************************************************************
389 * Create a new Postgres DBMS user
392 *****************************************************************************/
394 CreateUserStmt: CREATE USER Id user_passwd_clause user_createdb_clause
395 user_createuser_clause user_group_clause user_valid_clause
397 CreateUserStmt *n = makeNode(CreateUserStmt);
408 /*****************************************************************************
410 * Alter a postresql DBMS user
413 *****************************************************************************/
415 AlterUserStmt: ALTER USER Id user_passwd_clause user_createdb_clause
416 user_createuser_clause user_group_clause user_valid_clause
418 AlterUserStmt *n = makeNode(AlterUserStmt);
429 /*****************************************************************************
431 * Drop a postresql DBMS user
434 *****************************************************************************/
436 DropUserStmt: DROP USER Id
438 DropUserStmt *n = makeNode(DropUserStmt);
444 user_passwd_clause: WITH PASSWORD Id { $$ = $3; }
445 | /*EMPTY*/ { $$ = NULL; }
448 user_createdb_clause: CREATEDB
451 $$ = (b = (bool*)palloc(sizeof(bool)));
457 $$ = (b = (bool*)palloc(sizeof(bool)));
460 | /*EMPTY*/ { $$ = NULL; }
463 user_createuser_clause: CREATEUSER
466 $$ = (b = (bool*)palloc(sizeof(bool)));
472 $$ = (b = (bool*)palloc(sizeof(bool)));
475 | /*EMPTY*/ { $$ = NULL; }
478 user_group_list: user_group_list ',' Id
480 $$ = lcons((void*)makeString($3), $1);
484 $$ = lcons((void*)makeString($1), NIL);
488 user_group_clause: IN GROUP user_group_list { $$ = $3; }
489 | /*EMPTY*/ { $$ = NULL; }
492 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
493 | /*EMPTY*/ { $$ = NULL; }
496 /*****************************************************************************
498 * Set PG internal variable
499 * SET name TO 'var_value'
500 * Include SQL92 syntax (thomas 1997-10-22):
501 * SET TIME ZONE 'var_value'
503 *****************************************************************************/
505 VariableSetStmt: SET ColId TO var_value
507 VariableSetStmt *n = makeNode(VariableSetStmt);
512 | SET ColId '=' var_value
514 VariableSetStmt *n = makeNode(VariableSetStmt);
519 | SET TIME ZONE zone_value
521 VariableSetStmt *n = makeNode(VariableSetStmt);
522 n->name = "timezone";
528 var_value: Sconst { $$ = $1; }
529 | DEFAULT { $$ = NULL; }
532 zone_value: Sconst { $$ = $1; }
533 | DEFAULT { $$ = NULL; }
534 | LOCAL { $$ = "default"; }
537 VariableShowStmt: SHOW ColId
539 VariableShowStmt *n = makeNode(VariableShowStmt);
545 VariableShowStmt *n = makeNode(VariableShowStmt);
546 n->name = "timezone";
551 VariableResetStmt: RESET ColId
553 VariableResetStmt *n = makeNode(VariableResetStmt);
559 VariableResetStmt *n = makeNode(VariableResetStmt);
560 n->name = "timezone";
566 /*****************************************************************************
569 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
571 *****************************************************************************/
573 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
575 AddAttrStmt *n = makeNode(AddAttrStmt);
583 alter_clause: ADD opt_column columnDef
587 | ADD '(' OptTableElementList ')'
589 Node *lp = lfirst($3);
592 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
595 | DROP opt_column ColId
596 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
597 | ALTER opt_column ColId SET DEFAULT default_expr
598 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
599 | ALTER opt_column ColId DROP DEFAULT
600 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
602 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
606 /*****************************************************************************
611 *****************************************************************************/
613 ClosePortalStmt: CLOSE opt_id
615 ClosePortalStmt *n = makeNode(ClosePortalStmt);
622 /*****************************************************************************
625 * COPY [BINARY] <relname> FROM/TO
626 * [USING DELIMITERS <delimiter>]
628 *****************************************************************************/
630 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
632 CopyStmt *n = makeNode(CopyStmt);
650 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
651 * used depends on the direction. (It really doesn't make sense to copy from
652 * stdout. We silently correct the "typo". - AY 9/94
654 copy_file_name: Sconst { $$ = $1; }
655 | STDIN { $$ = NULL; }
656 | STDOUT { $$ = NULL; }
659 opt_binary: BINARY { $$ = TRUE; }
660 | /*EMPTY*/ { $$ = FALSE; }
663 opt_with_copy: WITH OIDS { $$ = TRUE; }
664 | /*EMPTY*/ { $$ = FALSE; }
668 * the default copy delimiter is tab but the user can configure it
670 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
671 | /*EMPTY*/ { $$ = "\t"; }
675 /*****************************************************************************
680 *****************************************************************************/
682 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
683 OptInherit OptArchiveType
685 CreateStmt *n = makeNode(CreateStmt);
689 n->constraints = NIL;
694 OptTableElementList: OptTableElementList ',' OptTableElement
695 { $$ = lappend($1, $3); }
696 | OptTableElement { $$ = lcons($1, NIL); }
697 | /*EMPTY*/ { $$ = NULL; }
700 OptTableElement: columnDef { $$ = $1; }
701 | TableConstraint { $$ = $1; }
704 columnDef: ColId Typename ColQualifier
706 ColumnDef *n = makeNode(ColumnDef);
710 n->is_not_null = FALSE;
716 ColQualifier: ColQualList { $$ = $1; }
717 | /*EMPTY*/ { $$ = NULL; }
720 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
721 | ColConstraint { $$ = lcons($1, NIL); }
725 CONSTRAINT name ColConstraintElem
727 Constraint *n = (Constraint *)$3;
735 ColConstraintElem: CHECK '(' constraint_expr ')'
737 Constraint *n = makeNode(Constraint);
738 n->contype = CONSTR_CHECK;
740 n->def = FlattenStringList($3);
744 | DEFAULT default_expr
746 Constraint *n = makeNode(Constraint);
747 n->contype = CONSTR_DEFAULT;
749 n->def = FlattenStringList($2);
755 Constraint *n = makeNode(Constraint);
756 n->contype = CONSTR_NOTNULL;
764 Constraint *n = makeNode(Constraint);
765 n->contype = CONSTR_UNIQUE;
773 Constraint *n = makeNode(Constraint);
774 n->contype = CONSTR_PRIMARY;
780 | REFERENCES ColId opt_column_list key_match key_actions
782 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
787 default_list: default_list ',' default_expr
789 $$ = lappend($1,makeString(","));
798 default_expr: AexprConst
799 { $$ = makeConstantList((A_Const *) $1); }
801 { $$ = lcons( makeString("NULL"), NIL); }
802 | '-' default_expr %prec UMINUS
803 { $$ = lcons( makeString( "-"), $2); }
804 | default_expr '+' default_expr
805 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
806 | default_expr '-' default_expr
807 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
808 | default_expr '/' default_expr
809 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
810 | default_expr '*' default_expr
811 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
812 | default_expr '=' default_expr
813 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
814 | default_expr '<' default_expr
815 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
816 | default_expr '>' default_expr
817 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
819 { $$ = lcons( makeString( ":"), $2); }
821 { $$ = lcons( makeString( ";"), $2); }
823 { $$ = lcons( makeString( "|"), $2); }
824 | default_expr TYPECAST Typename
826 $3->name = fmtId($3->name);
827 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
829 | CAST default_expr AS Typename
831 $4->name = fmtId($4->name);
832 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
834 | '(' default_expr ')'
835 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
838 $$ = makeList( makeString($1), makeString("("), -1);
839 $$ = lappend( $$, makeString(")"));
841 | name '(' default_list ')'
843 $$ = makeList( makeString($1), makeString("("), -1);
845 $$ = lappend( $$, makeString(")"));
847 | default_expr Op default_expr
849 if (!strcmp("<=", $2) || !strcmp(">=", $2))
850 elog(ERROR,"boolean expressions not supported in DEFAULT");
851 $$ = nconc( $1, lcons( makeString( $2), $3));
854 { $$ = lcons( makeString( $1), $2); }
856 { $$ = lappend( $1, makeString( $2)); }
857 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
859 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
861 { $$ = lcons( makeString( "'now'::time"), NIL); }
862 | CURRENT_TIME '(' Iconst ')'
865 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
866 $$ = lcons( makeString( "'now'::time"), NIL);
869 { $$ = lcons( makeString( "now()"), NIL); }
870 | CURRENT_TIMESTAMP '(' Iconst ')'
873 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
874 $$ = lcons( makeString( "now()"), NIL);
877 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
880 /* ConstraintElem specifies constraint syntax which is not embedded into
881 * a column definition. ColConstraintElem specifies the embedded form.
882 * - thomas 1997-12-03
884 TableConstraint: CONSTRAINT name ConstraintElem
886 Constraint *n = (Constraint *)$3;
894 ConstraintElem: CHECK '(' constraint_expr ')'
896 Constraint *n = makeNode(Constraint);
897 n->contype = CONSTR_CHECK;
899 n->def = FlattenStringList($3);
902 | UNIQUE '(' columnList ')'
904 Constraint *n = makeNode(Constraint);
905 n->contype = CONSTR_UNIQUE;
911 | PRIMARY KEY '(' columnList ')'
913 Constraint *n = makeNode(Constraint);
914 n->contype = CONSTR_PRIMARY;
920 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
921 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented"); }
924 constraint_list: constraint_list ',' constraint_expr
926 $$ = lappend($1,makeString(","));
935 constraint_expr: AexprConst
936 { $$ = makeConstantList((A_Const *) $1); }
938 { $$ = lcons( makeString("NULL"), NIL); }
941 $$ = lcons( makeString(fmtId($1)), NIL);
943 | '-' constraint_expr %prec UMINUS
944 { $$ = lcons( makeString( "-"), $2); }
945 | constraint_expr '+' constraint_expr
946 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
947 | constraint_expr '-' constraint_expr
948 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
949 | constraint_expr '/' constraint_expr
950 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
951 | constraint_expr '*' constraint_expr
952 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
953 | constraint_expr '=' constraint_expr
954 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
955 | constraint_expr '<' constraint_expr
956 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
957 | constraint_expr '>' constraint_expr
958 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
959 | ':' constraint_expr
960 { $$ = lcons( makeString( ":"), $2); }
961 | ';' constraint_expr
962 { $$ = lcons( makeString( ";"), $2); }
963 | '|' constraint_expr
964 { $$ = lcons( makeString( "|"), $2); }
965 | constraint_expr TYPECAST Typename
967 $3->name = fmtId($3->name);
968 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
970 | CAST constraint_expr AS Typename
972 $4->name = fmtId($4->name);
973 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
975 | '(' constraint_expr ')'
976 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
979 $$ = makeList( makeString($1), makeString("("), -1);
980 $$ = lappend( $$, makeString(")"));
982 | name '(' constraint_list ')'
984 $$ = makeList( makeString($1), makeString("("), -1);
986 $$ = lappend( $$, makeString(")"));
988 | constraint_expr Op constraint_expr
989 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
990 | constraint_expr AND constraint_expr
991 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
992 | constraint_expr OR constraint_expr
993 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
994 | NOT constraint_expr
995 { $$ = lcons( makeString( "NOT"), $2); }
997 { $$ = lcons( makeString( $1), $2); }
999 { $$ = lappend( $1, makeString( $2)); }
1000 | constraint_expr ISNULL
1001 { $$ = lappend( $1, makeString( "IS NULL")); }
1002 | constraint_expr IS NULL_P
1003 { $$ = lappend( $1, makeString( "IS NULL")); }
1004 | constraint_expr NOTNULL
1005 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1006 | constraint_expr IS NOT NULL_P
1007 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1008 | constraint_expr IS TRUE_P
1009 { $$ = lappend( $1, makeString( "IS TRUE")); }
1010 | constraint_expr IS FALSE_P
1011 { $$ = lappend( $1, makeString( "IS FALSE")); }
1012 | constraint_expr IS NOT TRUE_P
1013 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1014 | constraint_expr IS NOT FALSE_P
1015 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1018 key_match: MATCH FULL { $$ = NULL; }
1019 | MATCH PARTIAL { $$ = NULL; }
1020 | /*EMPTY*/ { $$ = NULL; }
1023 key_actions: key_action key_action { $$ = NIL; }
1024 | key_action { $$ = NIL; }
1025 | /*EMPTY*/ { $$ = NIL; }
1028 key_action: ON DELETE key_reference { $$ = NIL; }
1029 | ON UPDATE key_reference { $$ = NIL; }
1032 key_reference: NO ACTION { $$ = NULL; }
1033 | CASCADE { $$ = NULL; }
1034 | SET DEFAULT { $$ = NULL; }
1035 | SET NULL_P { $$ = NULL; }
1038 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1039 | /*EMPTY*/ { $$ = NIL; }
1043 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1044 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1046 OptArchiveType: ARCHIVE '=' NONE { }
1050 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1052 SelectStmt *n = (SelectStmt *)$6;
1054 mapTargetColumns($4, n->targetList);
1060 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1061 | /*EMPTY*/ { $$ = NULL; }
1064 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1065 | CreateAsElement { $$ = lcons($1, NIL); }
1068 CreateAsElement: ColId
1070 ColumnDef *n = makeNode(ColumnDef);
1074 n->is_not_null = FALSE;
1075 n->constraints = NULL;
1081 /*****************************************************************************
1084 * CREATE SEQUENCE seqname
1086 *****************************************************************************/
1088 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1090 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1098 OptSeqList OptSeqElem
1099 { $$ = lappend($1, $2); }
1103 OptSeqElem: IDENT NumConst
1105 $$ = makeNode(DefElem);
1107 $$->arg = (Node *)$2;
1111 $$ = makeNode(DefElem);
1113 $$->arg = (Node *)NULL;
1117 /*****************************************************************************
1120 * CREATE PROCEDURAL LANGUAGE ...
1121 * DROP PROCEDURAL LANGUAGE ...
1123 *****************************************************************************/
1125 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1126 HANDLER def_name LANCOMPILER Sconst
1128 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1137 PLangTrusted: TRUSTED { $$ = TRUE; }
1140 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1142 DropPLangStmt *n = makeNode(DropPLangStmt);
1148 /*****************************************************************************
1151 * CREATE TRIGGER ...
1154 *****************************************************************************/
1156 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1157 relation_name TriggerForSpec EXECUTE PROCEDURE
1158 name '(' TriggerFuncArgs ')'
1160 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1167 memcpy (n->actions, $5, 4);
1172 TriggerActionTime: BEFORE { $$ = TRUE; }
1173 | AFTER { $$ = FALSE; }
1176 TriggerEvents: TriggerOneEvent
1178 char *e = palloc (4);
1179 e[0] = $1; e[1] = 0; $$ = e;
1181 | TriggerOneEvent OR TriggerOneEvent
1183 char *e = palloc (4);
1184 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1186 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1188 char *e = palloc (4);
1189 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1194 TriggerOneEvent: INSERT { $$ = 'i'; }
1195 | DELETE { $$ = 'd'; }
1196 | UPDATE { $$ = 'u'; }
1199 TriggerForSpec: FOR name name
1201 if ( strcmp ($2, "each") != 0 )
1202 elog(ERROR,"parser: syntax error near %s",$2);
1203 if ( strcmp ($3, "row") == 0 )
1205 else if ( strcmp ($3, "statement") == 0 )
1208 elog(ERROR,"parser: syntax error near %s",$3);
1212 TriggerFuncArgs: TriggerFuncArg
1213 { $$ = lcons($1, NIL); }
1214 | TriggerFuncArgs ',' TriggerFuncArg
1215 { $$ = lappend($1, $3); }
1220 TriggerFuncArg: ICONST
1222 char *s = (char *) palloc (256);
1223 sprintf (s, "%d", $1);
1228 char *s = (char *) palloc (256);
1229 sprintf (s, "%g", $1);
1232 | Sconst { $$ = $1; }
1233 | IDENT { $$ = $1; }
1236 DropTrigStmt: DROP TRIGGER name ON relation_name
1238 DropTrigStmt *n = makeNode(DropTrigStmt);
1246 /*****************************************************************************
1249 * define (type,operator,aggregate)
1251 *****************************************************************************/
1253 DefineStmt: CREATE def_type def_rest
1260 def_rest: def_name definition
1262 $$ = makeNode(DefineStmt);
1264 $$->definition = $2;
1268 def_type: OPERATOR { $$ = OPERATOR; }
1269 | TYPE_P { $$ = TYPE_P; }
1270 | AGGREGATE { $$ = AGGREGATE; }
1273 def_name: PROCEDURE { $$ = "procedure"; }
1274 | JOIN { $$ = "join"; }
1275 | ColId { $$ = $1; }
1276 | MathOp { $$ = $1; }
1280 definition: '(' def_list ')' { $$ = $2; }
1283 def_list: def_elem { $$ = lcons($1, NIL); }
1284 | def_list ',' def_elem { $$ = lappend($1, $3); }
1287 def_elem: def_name '=' def_arg
1289 $$ = makeNode(DefElem);
1291 $$->arg = (Node *)$3;
1295 $$ = makeNode(DefElem);
1297 $$->arg = (Node *)NULL;
1299 | DEFAULT '=' def_arg
1301 $$ = makeNode(DefElem);
1302 $$->defname = "default";
1303 $$->arg = (Node *)$3;
1307 def_arg: ColId { $$ = (Node *)makeString($1); }
1308 | all_Op { $$ = (Node *)makeString($1); }
1309 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1310 | Sconst { $$ = (Node *)makeString($1); }
1313 TypeName *n = makeNode(TypeName);
1316 n->arrayBounds = NULL;
1319 | DOUBLE { $$ = (Node *)makeString("double"); }
1323 /*****************************************************************************
1326 * destroy <relname1> [, <relname2> .. <relnameN> ]
1328 *****************************************************************************/
1330 DestroyStmt: DROP TABLE relation_name_list
1332 DestroyStmt *n = makeNode(DestroyStmt);
1334 n->sequence = FALSE;
1337 | DROP SEQUENCE relation_name_list
1339 DestroyStmt *n = makeNode(DestroyStmt);
1347 /*****************************************************************************
1350 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1352 *****************************************************************************/
1354 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1356 FetchStmt *n = makeNode(FetchStmt);
1363 | MOVE opt_direction fetch_how_many opt_portal_name
1365 FetchStmt *n = makeNode(FetchStmt);
1374 opt_direction: FORWARD { $$ = FORWARD; }
1375 | BACKWARD { $$ = BACKWARD; }
1376 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1379 fetch_how_many: Iconst
1381 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1382 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1383 | /*EMPTY*/ { $$ = 1; /*default*/ }
1386 opt_portal_name: IN name { $$ = $2; }
1387 | /*EMPTY*/ { $$ = NULL; }
1391 /*****************************************************************************
1394 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1396 *****************************************************************************/
1398 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1400 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1404 privileges: ALL PRIVILEGES
1406 $$ = aclmakepriv("rwaR",0);
1410 $$ = aclmakepriv("rwaR",0);
1412 | operation_commalist
1418 operation_commalist: operation
1420 $$ = aclmakepriv("",$1);
1422 | operation_commalist ',' operation
1424 $$ = aclmakepriv($1,$3);
1430 $$ = ACL_MODE_RD_CHR;
1434 $$ = ACL_MODE_AP_CHR;
1438 $$ = ACL_MODE_WR_CHR;
1442 $$ = ACL_MODE_WR_CHR;
1446 $$ = ACL_MODE_RU_CHR;
1452 $$ = aclmakeuser("A","");
1456 $$ = aclmakeuser("G",$2);
1460 $$ = aclmakeuser("U",$1);
1464 opt_with_grant: WITH GRANT OPTION
1466 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1472 /*****************************************************************************
1475 * REVOKE [privileges] ON [relation_name] FROM [user]
1477 *****************************************************************************/
1479 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1481 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1486 /*****************************************************************************
1489 * create index <indexname> on <relname>
1490 * using <access> "(" (<col> with <op>)+ ")" [with
1493 * [where <qual>] is not supported anymore
1494 *****************************************************************************/
1496 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1497 access_method_clause '(' index_params ')' opt_with
1499 /* should check that access_method is valid,
1500 etc ... but doesn't */
1501 IndexStmt *n = makeNode(IndexStmt);
1505 n->accessMethod = $7;
1506 n->indexParams = $9;
1507 n->withClause = $11;
1508 n->whereClause = NULL;
1513 index_opt_unique: UNIQUE { $$ = TRUE; }
1514 | /*EMPTY*/ { $$ = FALSE; }
1517 access_method_clause: USING access_method { $$ = $2; }
1518 | /*EMPTY*/ { $$ = "btree"; }
1521 index_params: index_list { $$ = $1; }
1522 | func_index { $$ = lcons($1,NIL); }
1525 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1526 | index_elem { $$ = lcons($1, NIL); }
1529 func_index: name '(' name_list ')' opt_type opt_class
1531 $$ = makeNode(IndexElem);
1539 index_elem: attr_name opt_type opt_class
1541 $$ = makeNode(IndexElem);
1549 opt_type: ':' Typename { $$ = $2; }
1550 | FOR Typename { $$ = $2; }
1551 | /*EMPTY*/ { $$ = NULL; }
1554 /* opt_class "WITH class" conflicts with preceeding opt_type
1555 * for Typename of "TIMESTAMP WITH TIME ZONE"
1556 * So, remove "WITH class" from the syntax. OK??
1557 * - thomas 1997-10-12
1558 * | WITH class { $$ = $2; }
1560 opt_class: class { $$ = $1; }
1561 | USING class { $$ = $2; }
1562 | /*EMPTY*/ { $$ = NULL; }
1566 /*****************************************************************************
1569 * extend index <indexname> [where <qual>]
1571 *****************************************************************************/
1573 ExtendStmt: EXTEND INDEX index_name where_clause
1575 ExtendStmt *n = makeNode(ExtendStmt);
1577 n->whereClause = $4;
1583 /*****************************************************************************
1586 * execute recipe <recipeName>
1588 *****************************************************************************/
1590 RecipeStmt: EXECUTE RECIPE recipe_name
1593 if (!IsTransactionBlock())
1594 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1596 n = makeNode(RecipeStmt);
1603 /*****************************************************************************
1606 * define function <fname>
1607 * (language = <lang>, returntype = <typename>
1608 * [, arch_pct = <percentage | pre-defined>]
1609 * [, disk_pct = <percentage | pre-defined>]
1610 * [, byte_pct = <percentage | pre-defined>]
1611 * [, perbyte_cpu = <int | pre-defined>]
1612 * [, percall_cpu = <int | pre-defined>]
1614 * [arg is (<type-1> { , <type-n>})]
1615 * as <filename or code in language as appropriate>
1617 *****************************************************************************/
1619 ProcedureStmt: CREATE FUNCTION def_name def_args
1620 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1622 ProcedureStmt *n = makeNode(ProcedureStmt);
1625 n->returnType = (Node *)$6;
1632 opt_with: WITH definition { $$ = $2; }
1633 | /*EMPTY*/ { $$ = NIL; }
1636 def_args: '(' def_name_list ')' { $$ = $2; }
1637 | '(' ')' { $$ = NIL; }
1640 def_name_list: name_list;
1642 /*****************************************************************************
1646 * remove function <funcname>
1647 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1648 * remove aggregate <aggname>
1649 * (REMOVE AGGREGATE "aggname" "aggtype")
1650 * remove operator <opname>
1651 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1652 * remove type <typename>
1653 * (REMOVE TYPE "typename")
1654 * remove rule <rulename>
1655 * (REMOVE RULE "rulename")
1657 *****************************************************************************/
1659 RemoveStmt: DROP remove_type name
1661 RemoveStmt *n = makeNode(RemoveStmt);
1668 remove_type: TYPE_P { $$ = TYPE_P; }
1669 | INDEX { $$ = INDEX; }
1670 | RULE { $$ = RULE; }
1671 | VIEW { $$ = VIEW; }
1674 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1676 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1683 aggr_argtype: name { $$ = $1; }
1684 | '*' { $$ = NULL; }
1687 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1689 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1696 func_argtypes: name_list { $$ = $1; }
1697 | /*EMPTY*/ { $$ = NIL; }
1700 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1702 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1709 all_Op: Op | MathOp;
1711 MathOp: '+' { $$ = "+"; }
1722 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1725 { $$ = makeList(makeString($1), makeString($3), -1); }
1726 | NONE ',' name /* left unary */
1727 { $$ = makeList(NULL, makeString($3), -1); }
1728 | name ',' NONE /* right unary */
1729 { $$ = makeList(makeString($1), NULL, -1); }
1733 /*****************************************************************************
1736 * rename <attrname1> in <relname> [*] to <attrname2>
1737 * rename <relname1> to <relname2>
1739 *****************************************************************************/
1741 RenameStmt: ALTER TABLE relation_name opt_inh_star
1742 RENAME opt_column opt_name TO name
1744 RenameStmt *n = makeNode(RenameStmt);
1753 opt_name: name { $$ = $1; }
1754 | /*EMPTY*/ { $$ = NULL; }
1757 opt_column: COLUMN { $$ = COLUMN; }
1758 | /*EMPTY*/ { $$ = 0; }
1762 /*****************************************************************************
1764 * QUERY: Define Rewrite Rule , Define Tuple Rule
1765 * Define Rule <old rules >
1767 * only rewrite rule is supported -- ay 9/94
1769 *****************************************************************************/
1771 RuleStmt: CREATE RULE name AS
1772 { QueryIsRule=TRUE; }
1773 ON event TO event_object where_clause
1774 DO opt_instead OptStmtList
1776 RuleStmt *n = makeNode(RuleStmt);
1780 n->whereClause = $10;
1787 OptStmtList: NOTHING { $$ = NIL; }
1788 | OptimizableStmt { $$ = lcons($1, NIL); }
1789 | '[' OptStmtBlock ']' { $$ = $2; }
1792 OptStmtBlock: OptStmtMulti
1795 { $$ = lcons($1, NIL); }
1798 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1799 { $$ = lappend($1, $2); }
1800 | OptStmtMulti OptimizableStmt
1801 { $$ = lappend($1, $2); }
1802 | OptimizableStmt ';'
1803 { $$ = lcons($1, NIL); }
1806 event_object: relation_name '.' attr_name
1808 $$ = makeNode(Attr);
1811 $$->attrs = lcons(makeString($3), NIL);
1812 $$->indirection = NIL;
1816 $$ = makeNode(Attr);
1820 $$->indirection = NIL;
1824 /* change me to select, update, etc. some day */
1825 event: SELECT { $$ = CMD_SELECT; }
1826 | UPDATE { $$ = CMD_UPDATE; }
1827 | DELETE { $$ = CMD_DELETE; }
1828 | INSERT { $$ = CMD_INSERT; }
1831 opt_instead: INSTEAD { $$ = TRUE; }
1832 | /*EMPTY*/ { $$ = FALSE; }
1836 /*****************************************************************************
1839 * NOTIFY <relation_name> can appear both in rule bodies and
1840 * as a query-level command
1842 *****************************************************************************/
1844 NotifyStmt: NOTIFY relation_name
1846 NotifyStmt *n = makeNode(NotifyStmt);
1852 ListenStmt: LISTEN relation_name
1854 ListenStmt *n = makeNode(ListenStmt);
1861 /*****************************************************************************
1872 *****************************************************************************/
1874 TransactionStmt: ABORT_TRANS TRANSACTION
1876 TransactionStmt *n = makeNode(TransactionStmt);
1877 n->command = ABORT_TRANS;
1880 | BEGIN_TRANS TRANSACTION
1882 TransactionStmt *n = makeNode(TransactionStmt);
1883 n->command = BEGIN_TRANS;
1888 TransactionStmt *n = makeNode(TransactionStmt);
1889 n->command = BEGIN_TRANS;
1894 TransactionStmt *n = makeNode(TransactionStmt);
1895 n->command = END_TRANS;
1898 | END_TRANS TRANSACTION
1900 TransactionStmt *n = makeNode(TransactionStmt);
1901 n->command = END_TRANS;
1906 TransactionStmt *n = makeNode(TransactionStmt);
1907 n->command = ABORT_TRANS;
1913 TransactionStmt *n = makeNode(TransactionStmt);
1914 n->command = ABORT_TRANS;
1919 TransactionStmt *n = makeNode(TransactionStmt);
1920 n->command = BEGIN_TRANS;
1925 TransactionStmt *n = makeNode(TransactionStmt);
1926 n->command = END_TRANS;
1932 TransactionStmt *n = makeNode(TransactionStmt);
1933 n->command = END_TRANS;
1938 TransactionStmt *n = makeNode(TransactionStmt);
1939 n->command = ABORT_TRANS;
1945 /*****************************************************************************
1948 * define view <viewname> '('target-list ')' [where <quals> ]
1950 *****************************************************************************/
1952 ViewStmt: CREATE VIEW name AS SelectStmt
1954 ViewStmt *n = makeNode(ViewStmt);
1956 n->query = (Query *)$5;
1957 if (((SelectStmt *)n->query)->sortClause != NULL)
1958 elog(ERROR,"Order by and Distinct on views is not implemented.");
1959 if (((SelectStmt *)n->query)->unionClause != NULL)
1960 elog(ERROR,"Views on unions not implemented.");
1966 /*****************************************************************************
1971 *****************************************************************************/
1973 LoadStmt: LOAD file_name
1975 LoadStmt *n = makeNode(LoadStmt);
1982 /*****************************************************************************
1987 *****************************************************************************/
1989 CreatedbStmt: CREATE DATABASE database_name opt_database
1991 CreatedbStmt *n = makeNode(CreatedbStmt);
1998 opt_database: WITH LOCATION '=' location { $$ = $4; }
1999 | /*EMPTY*/ { $$ = NULL; }
2002 location: Sconst { $$ = $1; }
2003 | DEFAULT { $$ = NULL; }
2004 | /*EMPTY*/ { $$ = NULL; }
2007 /*****************************************************************************
2012 *****************************************************************************/
2014 DestroydbStmt: DROP DATABASE database_name
2016 DestroydbStmt *n = makeNode(DestroydbStmt);
2023 /*****************************************************************************
2026 * cluster <index_name> on <relation_name>
2028 *****************************************************************************/
2030 ClusterStmt: CLUSTER index_name ON relation_name
2032 ClusterStmt *n = makeNode(ClusterStmt);
2040 /*****************************************************************************
2045 *****************************************************************************/
2047 VacuumStmt: VACUUM opt_verbose opt_analyze
2049 VacuumStmt *n = makeNode(VacuumStmt);
2056 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2058 VacuumStmt *n = makeNode(VacuumStmt);
2063 if ( $5 != NIL && !$4 )
2064 elog(ERROR,"parser: syntax error at or near \"(\"");
2069 opt_verbose: VERBOSE { $$ = TRUE; }
2070 | /*EMPTY*/ { $$ = FALSE; }
2073 opt_analyze: ANALYZE { $$ = TRUE; }
2074 | /*EMPTY*/ { $$ = FALSE; }
2077 opt_va_list: '(' va_list ')'
2084 { $$=lcons($1,NIL); }
2086 { $$=lappend($1,$3); }
2090 /*****************************************************************************
2095 *****************************************************************************/
2097 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2099 ExplainStmt *n = makeNode(ExplainStmt);
2101 n->query = (Query*)$3;
2107 /*****************************************************************************
2109 * Optimizable Stmts: *
2111 * one of the five queries processed by the planner *
2113 * [ultimately] produces query-trees as specified *
2114 * in the query-spec document in ~postgres/ref *
2116 *****************************************************************************/
2118 OptimizableStmt: SelectStmt
2123 | DeleteStmt /* by default all are $$=$1 */
2127 /*****************************************************************************
2132 *****************************************************************************/
2134 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2142 insert_rest: VALUES '(' res_target_list2 ')'
2144 $$ = makeNode(InsertStmt);
2146 $$->targetList = $3;
2147 $$->fromClause = NIL;
2148 $$->whereClause = NULL;
2149 $$->groupClause = NIL;
2150 $$->havingClause = NULL;
2151 $$->unionClause = NIL;
2153 | SELECT opt_unique res_target_list2
2154 from_clause where_clause
2155 group_clause having_clause
2158 $$ = makeNode(InsertStmt);
2160 $$->targetList = $3;
2161 $$->fromClause = $4;
2162 $$->whereClause = $5;
2163 $$->groupClause = $6;
2164 $$->havingClause = $7;
2165 $$->unionClause = $8;
2169 opt_column_list: '(' columnList ')' { $$ = $2; }
2170 | /*EMPTY*/ { $$ = NIL; }
2174 columnList ',' columnElem
2175 { $$ = lappend($1, $3); }
2177 { $$ = lcons($1, NIL); }
2180 columnElem: ColId opt_indirection
2182 Ident *id = makeNode(Ident);
2184 id->indirection = $2;
2190 /*****************************************************************************
2195 *****************************************************************************/
2197 DeleteStmt: DELETE FROM relation_name
2200 DeleteStmt *n = makeNode(DeleteStmt);
2202 n->whereClause = $4;
2208 * Total hack to just lock a table inside a transaction.
2209 * Is it worth making this a separate command, with
2210 * its own node type and file. I don't think so. bjm 1998/1/22
2212 LockStmt: LOCK_P relation_name
2214 DeleteStmt *n = makeNode(DeleteStmt);
2215 A_Const *c = makeNode(A_Const);
2217 c->val.type = T_String;
2218 c->val.val.str = "f";
2219 c->typename = makeNode(TypeName);
2220 c->typename->name = xlateSqlType("bool");
2223 n->whereClause = (Node *)c;
2229 /*****************************************************************************
2232 * UpdateStmt (UPDATE)
2234 *****************************************************************************/
2236 UpdateStmt: UPDATE relation_name
2241 UpdateStmt *n = makeNode(UpdateStmt);
2245 n->whereClause = $6;
2251 /*****************************************************************************
2256 *****************************************************************************/
2257 CursorStmt: DECLARE name opt_binary CURSOR FOR
2258 SELECT opt_unique res_target_list2
2259 from_clause where_clause
2260 group_clause having_clause
2261 union_clause sort_clause
2263 SelectStmt *n = makeNode(SelectStmt);
2265 /* from PORTAL name */
2267 * 15 august 1991 -- since 3.0 postgres does locking
2268 * right, we discovered that portals were violating
2269 * locking protocol. portal locks cannot span xacts.
2270 * as a short-term fix, we installed the check here.
2273 if (!IsTransactionBlock())
2274 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2281 n->whereClause = $10;
2282 n->groupClause = $11;
2283 n->havingClause = $12;
2284 n->unionClause = $13;
2285 n->sortClause = $14;
2291 /*****************************************************************************
2296 *****************************************************************************/
2298 SelectStmt: SELECT opt_unique res_target_list2
2299 result from_clause where_clause
2300 group_clause having_clause
2301 union_clause sort_clause
2303 SelectStmt *n = makeNode(SelectStmt);
2308 n->whereClause = $6;
2309 n->groupClause = $7;
2310 n->havingClause = $8;
2311 n->unionClause = $9;
2312 n->sortClause = $10;
2317 union_clause: UNION opt_union select_list
2319 SelectStmt *n = (SelectStmt *)lfirst($3);
2327 select_list: select_list UNION opt_union SubSelect
2329 SelectStmt *n = (SelectStmt *)$4;
2331 $$ = lappend($1, $4);
2334 { $$ = lcons($1, NIL); }
2337 SubSelect: SELECT opt_unique res_target_list2
2338 from_clause where_clause
2339 group_clause having_clause
2341 SelectStmt *n = makeNode(SelectStmt);
2343 n->unionall = FALSE;
2346 n->whereClause = $5;
2347 n->groupClause = $6;
2348 n->havingClause = $7;
2353 result: INTO TABLE relation_name
2359 opt_union: ALL { $$ = TRUE; }
2360 | /*EMPTY*/ { $$ = FALSE; }
2363 opt_unique: DISTINCT { $$ = "*"; }
2364 | DISTINCT ON ColId { $$ = $3; }
2365 | ALL { $$ = NULL; }
2366 | /*EMPTY*/ { $$ = NULL; }
2369 sort_clause: ORDER BY sortby_list { $$ = $3; }
2370 | /*EMPTY*/ { $$ = NIL; }
2373 sortby_list: sortby { $$ = lcons($1, NIL); }
2374 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2377 sortby: ColId OptUseOp
2379 $$ = makeNode(SortGroupBy);
2385 | ColId '.' ColId OptUseOp
2387 $$ = makeNode(SortGroupBy);
2395 $$ = makeNode(SortGroupBy);
2403 OptUseOp: USING Op { $$ = $2; }
2404 | USING '<' { $$ = "<"; }
2405 | USING '>' { $$ = ">"; }
2407 | DESC { $$ = ">"; }
2408 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2412 * jimmy bell-style recursive queries aren't supported in the
2415 * ...however, recursive addattr and rename supported. make special
2418 opt_inh_star: '*' { $$ = TRUE; }
2419 | /*EMPTY*/ { $$ = FALSE; }
2422 relation_name_list: name_list;
2425 { $$ = lcons(makeString($1),NIL); }
2426 | name_list ',' name
2427 { $$ = lappend($1,makeString($3)); }
2430 group_clause: GROUP BY groupby_list { $$ = $3; }
2431 | /*EMPTY*/ { $$ = NIL; }
2434 groupby_list: groupby { $$ = lcons($1, NIL); }
2435 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2440 $$ = makeNode(SortGroupBy);
2448 $$ = makeNode(SortGroupBy);
2456 $$ = makeNode(SortGroupBy);
2464 having_clause: HAVING a_expr
2466 elog(NOTICE, "HAVING not yet supported; ignore clause");
2469 | /*EMPTY*/ { $$ = NULL; }
2473 /*****************************************************************************
2475 * clauses common to all Optimizable Stmts:
2479 *****************************************************************************/
2481 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2484 elog(ERROR,"JOIN not yet implemented");
2486 | FROM from_list { $$ = $2; }
2487 | /*EMPTY*/ { $$ = NIL; }
2490 from_list: from_list ',' from_val
2491 { $$ = lappend($1, $3); }
2492 | from_val CROSS JOIN from_val
2493 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2495 { $$ = lcons($1, NIL); }
2498 from_val: relation_expr AS ColLabel
2500 $$ = makeNode(RangeVar);
2504 | relation_expr ColId
2506 $$ = makeNode(RangeVar);
2512 $$ = makeNode(RangeVar);
2518 join_expr: NATURAL join_expr { $$ = NULL; }
2520 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2522 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2524 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2526 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2528 { elog(ERROR,"INNER JOIN not yet implemented"); }
2530 { elog(ERROR,"UNION JOIN not yet implemented"); }
2532 { elog(ERROR,"INNER JOIN not yet implemented"); }
2535 join_outer: OUTER_P { $$ = NULL; }
2536 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2539 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2540 | USING '(' join_list ')' { $$ = NULL; }
2541 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2544 join_list: join_using { $$ = lcons($1, NIL); }
2545 | join_list ',' join_using { $$ = lappend($1, $3); }
2550 $$ = makeNode(SortGroupBy);
2558 $$ = makeNode(SortGroupBy);
2566 $$ = makeNode(SortGroupBy);
2574 where_clause: WHERE a_expr { $$ = $2; }
2575 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2578 relation_expr: relation_name
2580 /* normal relations */
2581 $$ = makeNode(RelExpr);
2585 | relation_name '*' %prec '='
2587 /* inheritance query */
2588 $$ = makeNode(RelExpr);
2593 opt_array_bounds: '[' ']' nest_array_bounds
2594 { $$ = lcons(makeInteger(-1), $3); }
2595 | '[' Iconst ']' nest_array_bounds
2596 { $$ = lcons(makeInteger($2), $4); }
2601 nest_array_bounds: '[' ']' nest_array_bounds
2602 { $$ = lcons(makeInteger(-1), $3); }
2603 | '[' Iconst ']' nest_array_bounds
2604 { $$ = lcons(makeInteger($2), $4); }
2610 /*****************************************************************************
2613 * SQL92 introduces a large amount of type-specific syntax.
2614 * Define individual clauses to handle these cases, and use
2615 * the generic case to handle regular type-extensible Postgres syntax.
2616 * - thomas 1997-10-10
2618 *****************************************************************************/
2620 Typename: Array opt_array_bounds
2623 $$->arrayBounds = $2;
2625 /* Is this the name of a complex type? If so, implement
2628 if (!strcmp(saved_relname, $$->name))
2629 /* This attr is the same type as the relation
2630 * being defined. The classic example: create
2631 * emp(name=text,mgr=emp)
2634 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2635 /* (Eventually add in here that the set can only
2636 * contain one element.)
2657 $$ = makeNode(TypeName);
2658 $$->name = xlateSqlType($1);
2662 generic: Id { $$ = $1; }
2663 | TYPE_P { $$ = xlateSqlType("type"); }
2664 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2667 /* SQL92 numeric data types
2668 * Check FLOAT() precision limits assuming IEEE floating types.
2669 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2670 * by checking parameters and making sure they match what is possible with INTEGER.
2671 * - thomas 1997-09-18
2673 Numeric: FLOAT opt_float
2675 $$ = makeNode(TypeName);
2676 $$->name = xlateSqlType($2);
2678 | DECIMAL opt_decimal
2680 $$ = makeNode(TypeName);
2681 $$->name = xlateSqlType("integer");
2683 | NUMERIC opt_numeric
2685 $$ = makeNode(TypeName);
2686 $$->name = xlateSqlType("integer");
2690 opt_float: '(' Iconst ')'
2693 elog(ERROR,"precision for FLOAT must be at least 1");
2695 $$ = xlateSqlType("float4");
2697 $$ = xlateSqlType("float8");
2699 elog(ERROR,"precision for FLOAT must be less than 16");
2703 $$ = xlateSqlType("float8");
2707 opt_numeric: '(' Iconst ',' Iconst ')'
2710 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2712 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2717 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2725 opt_decimal: '(' Iconst ',' Iconst ')'
2728 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2730 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2736 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2745 /* SQL92 character data types
2746 * The following implements CHAR() and VARCHAR().
2747 * We do it here instead of the 'Generic' production
2748 * because we don't want to allow arrays of VARCHAR().
2749 * I haven't thought about whether that will work or not.
2752 Character: character '(' Iconst ')'
2754 $$ = makeNode(TypeName);
2755 if (!strcasecmp($1, "char"))
2756 $$->name = xlateSqlType("bpchar");
2757 else if (!strcasecmp($1, "varchar"))
2758 $$->name = xlateSqlType("varchar");
2760 yyerror("parse error");
2762 elog(ERROR,"length for '%s' type must be at least 1",$1);
2764 /* we can store a char() of length up to the size
2765 * of a page (8KB) - page headers and friends but
2766 * just to be safe here... - ay 6/95
2767 * XXX note this hardcoded limit - thomas 1997-07-13
2769 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2771 /* we actually implement this sort of like a varlen, so
2772 * the first 4 bytes is the length. (the difference
2773 * between this and "text" is that we blank-pad and
2774 * truncate where necessary
2776 $$->typmod = VARHDRSZ + $3;
2780 $$ = makeNode(TypeName);
2781 $$->name = xlateSqlType($1);
2785 character: CHARACTER opt_varying opt_charset opt_collate
2788 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2789 if ($2) type = xlateSqlType("varchar");
2790 else type = xlateSqlType("char");
2793 c = palloc(strlen("var") + strlen($3) + 1);
2796 type = xlateSqlType(c);
2798 type = xlateSqlType($3);
2802 elog(ERROR,"COLLATE %s not yet implemented",$4);
2805 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2806 | VARCHAR { $$ = xlateSqlType("varchar"); }
2807 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2808 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2811 opt_varying: VARYING { $$ = TRUE; }
2812 | /*EMPTY*/ { $$ = FALSE; }
2815 opt_charset: CHARACTER SET ColId { $$ = $3; }
2816 | /*EMPTY*/ { $$ = NULL; }
2819 opt_collate: COLLATE ColId { $$ = $2; }
2820 | /*EMPTY*/ { $$ = NULL; }
2825 $$ = makeNode(TypeName);
2826 $$->name = xlateSqlType($1);
2828 | TIMESTAMP opt_timezone
2830 $$ = makeNode(TypeName);
2831 $$->name = xlateSqlType("timestamp");
2836 $$ = makeNode(TypeName);
2837 $$->name = xlateSqlType("time");
2839 | INTERVAL opt_interval
2841 $$ = makeNode(TypeName);
2842 $$->name = xlateSqlType("interval");
2846 datetime: YEAR_P { $$ = "year"; }
2847 | MONTH_P { $$ = "month"; }
2848 | DAY_P { $$ = "day"; }
2849 | HOUR_P { $$ = "hour"; }
2850 | MINUTE_P { $$ = "minute"; }
2851 | SECOND_P { $$ = "second"; }
2854 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2855 | /*EMPTY*/ { $$ = FALSE; }
2858 opt_interval: datetime { $$ = lcons($1, NIL); }
2859 | YEAR_P TO MONTH_P { $$ = NIL; }
2860 | DAY_P TO HOUR_P { $$ = NIL; }
2861 | DAY_P TO MINUTE_P { $$ = NIL; }
2862 | DAY_P TO SECOND_P { $$ = NIL; }
2863 | HOUR_P TO MINUTE_P { $$ = NIL; }
2864 | HOUR_P TO SECOND_P { $$ = NIL; }
2865 | /*EMPTY*/ { $$ = NIL; }
2869 /*****************************************************************************
2871 * expression grammar, still needs some cleanup
2873 *****************************************************************************/
2875 a_expr_or_null: a_expr
2879 A_Const *n = makeNode(A_Const);
2880 n->val.type = T_Null;
2885 /* Expressions using row descriptors
2886 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2887 * with singleton expressions.
2889 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2891 SubLink *n = makeNode(SubLink);
2893 n->oper = lcons("=",NIL);
2895 n->subLinkType = ANY_SUBLINK;
2899 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
2901 SubLink *n = makeNode(SubLink);
2903 n->oper = lcons("<>",NIL);
2905 n->subLinkType = ALL_SUBLINK;
2909 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
2911 SubLink *n = makeNode(SubLink);
2913 n->oper = lcons($4,NIL);
2915 n->subLinkType = ANY_SUBLINK;
2919 | '(' row_descriptor ')' '+' ANY '(' SubSelect ')'
2921 SubLink *n = makeNode(SubLink);
2923 n->oper = lcons("+",NIL);
2925 n->subLinkType = ANY_SUBLINK;
2929 | '(' row_descriptor ')' '-' ANY '(' SubSelect ')'
2931 SubLink *n = makeNode(SubLink);
2933 n->oper = lcons("-",NIL);
2935 n->subLinkType = ANY_SUBLINK;
2939 | '(' row_descriptor ')' '/' ANY '(' SubSelect ')'
2941 SubLink *n = makeNode(SubLink);
2943 n->oper = lcons("/",NIL);
2945 n->subLinkType = ANY_SUBLINK;
2949 | '(' row_descriptor ')' '*' ANY '(' SubSelect ')'
2951 SubLink *n = makeNode(SubLink);
2953 n->oper = lcons("*",NIL);
2955 n->subLinkType = ANY_SUBLINK;
2959 | '(' row_descriptor ')' '<' ANY '(' SubSelect ')'
2961 SubLink *n = makeNode(SubLink);
2963 n->oper = lcons("<",NIL);
2965 n->subLinkType = ANY_SUBLINK;
2969 | '(' row_descriptor ')' '>' ANY '(' SubSelect ')'
2971 SubLink *n = makeNode(SubLink);
2973 n->oper = lcons(">",NIL);
2975 n->subLinkType = ANY_SUBLINK;
2979 | '(' row_descriptor ')' '=' ANY '(' SubSelect ')'
2981 SubLink *n = makeNode(SubLink);
2983 n->oper = lcons("=",NIL);
2985 n->subLinkType = ANY_SUBLINK;
2989 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
2991 SubLink *n = makeNode(SubLink);
2993 n->oper = lcons($4,NIL);
2995 n->subLinkType = ALL_SUBLINK;
2999 | '(' row_descriptor ')' '+' ALL '(' SubSelect ')'
3001 SubLink *n = makeNode(SubLink);
3003 n->oper = lcons("+",NIL);
3005 n->subLinkType = ALL_SUBLINK;
3009 | '(' row_descriptor ')' '-' ALL '(' SubSelect ')'
3011 SubLink *n = makeNode(SubLink);
3013 n->oper = lcons("-",NIL);
3015 n->subLinkType = ALL_SUBLINK;
3019 | '(' row_descriptor ')' '/' ALL '(' SubSelect ')'
3021 SubLink *n = makeNode(SubLink);
3023 n->oper = lcons("/",NIL);
3025 n->subLinkType = ALL_SUBLINK;
3029 | '(' row_descriptor ')' '*' ALL '(' SubSelect ')'
3031 SubLink *n = makeNode(SubLink);
3033 n->oper = lcons("*",NIL);
3035 n->subLinkType = ALL_SUBLINK;
3039 | '(' row_descriptor ')' '<' ALL '(' SubSelect ')'
3041 SubLink *n = makeNode(SubLink);
3043 n->oper = lcons("<",NIL);
3045 n->subLinkType = ALL_SUBLINK;
3049 | '(' row_descriptor ')' '>' ALL '(' SubSelect ')'
3051 SubLink *n = makeNode(SubLink);
3053 n->oper = lcons(">",NIL);
3055 n->subLinkType = ALL_SUBLINK;
3059 | '(' row_descriptor ')' '=' ALL '(' SubSelect ')'
3061 SubLink *n = makeNode(SubLink);
3063 n->oper = lcons("=",NIL);
3065 n->subLinkType = ALL_SUBLINK;
3069 | '(' row_descriptor ')' Op '(' SubSelect ')'
3071 SubLink *n = makeNode(SubLink);
3073 n->oper = lcons($4, NIL);
3074 if (strcmp($4,"<>") == 0)
3078 n->subLinkType = EXPR_SUBLINK;
3082 | '(' row_descriptor ')' '+' '(' SubSelect ')'
3084 SubLink *n = makeNode(SubLink);
3086 n->oper = lcons("+", NIL);
3088 n->subLinkType = EXPR_SUBLINK;
3092 | '(' row_descriptor ')' '-' '(' SubSelect ')'
3094 SubLink *n = makeNode(SubLink);
3096 n->oper = lcons("-", NIL);
3098 n->subLinkType = EXPR_SUBLINK;
3102 | '(' row_descriptor ')' '/' '(' SubSelect ')'
3104 SubLink *n = makeNode(SubLink);
3106 n->oper = lcons("/", NIL);
3108 n->subLinkType = EXPR_SUBLINK;
3112 | '(' row_descriptor ')' '*' '(' SubSelect ')'
3114 SubLink *n = makeNode(SubLink);
3116 n->oper = lcons("*", NIL);
3118 n->subLinkType = EXPR_SUBLINK;
3122 | '(' row_descriptor ')' '<' '(' SubSelect ')'
3124 SubLink *n = makeNode(SubLink);
3126 n->oper = lcons("<", NIL);
3128 n->subLinkType = EXPR_SUBLINK;
3132 | '(' row_descriptor ')' '>' '(' SubSelect ')'
3134 SubLink *n = makeNode(SubLink);
3136 n->oper = lcons(">", NIL);
3138 n->subLinkType = EXPR_SUBLINK;
3142 | '(' row_descriptor ')' '=' '(' SubSelect ')'
3144 SubLink *n = makeNode(SubLink);
3146 n->oper = lcons("=", NIL);
3148 n->subLinkType = EXPR_SUBLINK;
3152 | '(' row_descriptor ')' Op '(' row_descriptor ')'
3154 $$ = makeRowExpr($4, $2, $6);
3156 | '(' row_descriptor ')' '+' '(' row_descriptor ')'
3158 $$ = makeRowExpr("+", $2, $6);
3160 | '(' row_descriptor ')' '-' '(' row_descriptor ')'
3162 $$ = makeRowExpr("-", $2, $6);
3164 | '(' row_descriptor ')' '/' '(' row_descriptor ')'
3166 $$ = makeRowExpr("/", $2, $6);
3168 | '(' row_descriptor ')' '*' '(' row_descriptor ')'
3170 $$ = makeRowExpr("*", $2, $6);
3172 | '(' row_descriptor ')' '<' '(' row_descriptor ')'
3174 $$ = makeRowExpr("<", $2, $6);
3176 | '(' row_descriptor ')' '>' '(' row_descriptor ')'
3178 $$ = makeRowExpr(">", $2, $6);
3180 | '(' row_descriptor ')' '=' '(' row_descriptor ')'
3182 $$ = makeRowExpr("=", $2, $6);
3186 row_descriptor: row_list ',' a_expr
3188 $$ = lappend($1, $3);
3192 row_list: row_list ',' a_expr
3194 $$ = lappend($1, $3);
3198 $$ = lcons($1, NIL);
3203 * This is the heart of the expression syntax.
3204 * Note that the BETWEEN clause looks similar to a boolean expression
3205 * and so we must define b_expr which is almost the same as a_expr
3206 * but without the boolean expressions.
3207 * All operations are allowed in a BETWEEN clause if surrounded by parens.
3210 a_expr: attr opt_indirection
3212 $1->indirection = $2;
3221 /* could be a column name or a relation_name */
3222 Ident *n = makeNode(Ident);
3224 n->indirection = NULL;
3227 | '-' a_expr %prec UMINUS
3228 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3230 { $$ = makeA_Expr(OP, "+", $1, $3); }
3232 { $$ = makeA_Expr(OP, "-", $1, $3); }
3234 { $$ = makeA_Expr(OP, "/", $1, $3); }
3236 { $$ = makeA_Expr(OP, "*", $1, $3); }
3238 { $$ = makeA_Expr(OP, "<", $1, $3); }
3240 { $$ = makeA_Expr(OP, ">", $1, $3); }
3242 { $$ = makeA_Expr(OP, "=", $1, $3); }
3244 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3246 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3248 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3249 | a_expr TYPECAST Typename
3252 /* AexprConst can be either A_Const or ParamNo */
3253 if (nodeTag($1) == T_A_Const) {
3254 ((A_Const *)$1)->typename = $3;
3255 } else if (nodeTag($1) == T_Param) {
3256 ((ParamNo *)$1)->typename = $3;
3257 /* otherwise, try to transform to a function call */
3259 FuncCall *n = makeNode(FuncCall);
3260 n->funcname = $3->name;
3261 n->args = lcons($1,NIL);
3265 | CAST a_expr AS Typename
3268 /* AexprConst can be either A_Const or ParamNo */
3269 if (nodeTag($2) == T_A_Const) {
3270 ((A_Const *)$2)->typename = $4;
3271 } else if (nodeTag($2) == T_Param) {
3272 ((ParamNo *)$2)->typename = $4;
3273 /* otherwise, try to transform to a function call */
3275 FuncCall *n = makeNode(FuncCall);
3276 n->funcname = $4->name;
3277 n->args = lcons($2,NIL);
3281 | '(' a_expr_or_null ')'
3284 { $$ = makeIndexable($2,$1,$3); }
3285 | a_expr LIKE a_expr
3286 { $$ = makeIndexable("~~", $1, $3); }
3287 | a_expr NOT LIKE a_expr
3288 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3290 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3292 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3295 /* cheap hack for aggregate (eg. count) */
3296 FuncCall *n = makeNode(FuncCall);
3297 A_Const *star = makeNode(A_Const);
3299 star->val.type = T_String;
3300 star->val.val.str = "";
3302 n->args = lcons(star, NIL);
3307 FuncCall *n = makeNode(FuncCall);
3312 | name '(' expr_list ')'
3314 FuncCall *n = makeNode(FuncCall);
3321 A_Const *n = makeNode(A_Const);
3322 TypeName *t = makeNode(TypeName);
3324 n->val.type = T_String;
3325 n->val.val.str = "now";
3328 t->name = xlateSqlType("date");
3335 A_Const *n = makeNode(A_Const);
3336 TypeName *t = makeNode(TypeName);
3338 n->val.type = T_String;
3339 n->val.val.str = "now";
3342 t->name = xlateSqlType("time");
3347 | CURRENT_TIME '(' Iconst ')'
3349 FuncCall *n = makeNode(FuncCall);
3350 A_Const *s = makeNode(A_Const);
3351 TypeName *t = makeNode(TypeName);
3353 n->funcname = xlateSqlType("time");
3354 n->args = lcons(s, NIL);
3356 s->val.type = T_String;
3357 s->val.val.str = "now";
3360 t->name = xlateSqlType("time");
3364 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3370 A_Const *n = makeNode(A_Const);
3371 TypeName *t = makeNode(TypeName);
3373 n->val.type = T_String;
3374 n->val.val.str = "now";
3377 t->name = xlateSqlType("timestamp");
3382 | CURRENT_TIMESTAMP '(' Iconst ')'
3384 FuncCall *n = makeNode(FuncCall);
3385 A_Const *s = makeNode(A_Const);
3386 TypeName *t = makeNode(TypeName);
3388 n->funcname = xlateSqlType("timestamp");
3389 n->args = lcons(s, NIL);
3391 s->val.type = T_String;
3392 s->val.val.str = "now";
3395 t->name = xlateSqlType("timestamp");
3399 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3405 FuncCall *n = makeNode(FuncCall);
3406 n->funcname = "getpgusername";
3410 | EXISTS '(' SubSelect ')'
3412 SubLink *n = makeNode(SubLink);
3416 n->subLinkType = EXISTS_SUBLINK;
3420 | EXTRACT '(' extract_list ')'
3422 FuncCall *n = makeNode(FuncCall);
3423 n->funcname = "date_part";
3427 | POSITION '(' position_list ')'
3429 FuncCall *n = makeNode(FuncCall);
3430 n->funcname = "strpos";
3434 | SUBSTRING '(' substr_list ')'
3436 FuncCall *n = makeNode(FuncCall);
3437 n->funcname = "substr";
3441 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3442 | TRIM '(' BOTH trim_list ')'
3444 FuncCall *n = makeNode(FuncCall);
3445 n->funcname = "btrim";
3449 | TRIM '(' LEADING trim_list ')'
3451 FuncCall *n = makeNode(FuncCall);
3452 n->funcname = "ltrim";
3456 | TRIM '(' TRAILING trim_list ')'
3458 FuncCall *n = makeNode(FuncCall);
3459 n->funcname = "rtrim";
3463 | TRIM '(' trim_list ')'
3465 FuncCall *n = makeNode(FuncCall);
3466 n->funcname = "btrim";
3471 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3473 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3475 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3476 | a_expr IS NOT NULL_P
3477 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3478 /* IS TRUE, IS FALSE, etc used to be function calls
3479 * but let's make them expressions to allow the optimizer
3480 * a chance to eliminate them if a_expr is a constant string.
3481 * - thomas 1997-12-22
3485 A_Const *n = makeNode(A_Const);
3486 n->val.type = T_String;
3487 n->val.val.str = "t";
3488 n->typename = makeNode(TypeName);
3489 n->typename->name = xlateSqlType("bool");
3490 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3492 | a_expr IS NOT FALSE_P
3494 A_Const *n = makeNode(A_Const);
3495 n->val.type = T_String;
3496 n->val.val.str = "t";
3497 n->typename = makeNode(TypeName);
3498 n->typename->name = xlateSqlType("bool");
3499 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3503 A_Const *n = makeNode(A_Const);
3504 n->val.type = T_String;
3505 n->val.val.str = "f";
3506 n->typename = makeNode(TypeName);
3507 n->typename->name = xlateSqlType("bool");
3508 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3510 | a_expr IS NOT TRUE_P
3512 A_Const *n = makeNode(A_Const);
3513 n->val.type = T_String;
3514 n->val.val.str = "f";
3515 n->typename = makeNode(TypeName);
3516 n->typename->name = xlateSqlType("bool");
3517 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3519 | a_expr BETWEEN b_expr AND b_expr
3521 $$ = makeA_Expr(AND, NULL,
3522 makeA_Expr(OP, ">=", $1, $3),
3523 makeA_Expr(OP, "<=", $1, $5));
3525 | a_expr NOT BETWEEN b_expr AND b_expr
3527 $$ = makeA_Expr(OR, NULL,
3528 makeA_Expr(OP, "<", $1, $4),
3529 makeA_Expr(OP, ">", $1, $6));
3531 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3533 saved_In_Expr = lnext(saved_In_Expr);
3534 if (nodeTag($5) == T_SubLink)
3536 SubLink *n = (SubLink *)$5;
3537 n->lefthand = lcons($1, NIL);
3538 n->oper = lcons("=",NIL);
3540 n->subLinkType = ANY_SUBLINK;
3545 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
3547 saved_In_Expr = lnext(saved_In_Expr);
3548 if (nodeTag($6) == T_SubLink)
3550 SubLink *n = (SubLink *)$6;
3551 n->lefthand = lcons($1, NIL);
3552 n->oper = lcons("<>",NIL);
3554 n->subLinkType = ALL_SUBLINK;
3559 | a_expr Op ANY '(' SubSelect ')'
3561 SubLink *n = makeNode(SubLink);
3562 n->lefthand = lcons($1,NIL);
3563 n->oper = lcons($2,NIL);
3565 n->subLinkType = ANY_SUBLINK;
3569 | a_expr '+' ANY '(' SubSelect ')'
3571 SubLink *n = makeNode(SubLink);
3572 n->lefthand = lcons($1,NIL);
3573 n->oper = lcons("+",NIL);
3575 n->subLinkType = ANY_SUBLINK;
3579 | a_expr '-' ANY '(' SubSelect ')'
3581 SubLink *n = makeNode(SubLink);
3582 n->lefthand = lcons($1,NIL);
3583 n->oper = lcons("-",NIL);
3585 n->subLinkType = ANY_SUBLINK;
3589 | a_expr '/' ANY '(' SubSelect ')'
3591 SubLink *n = makeNode(SubLink);
3592 n->lefthand = lcons($1,NIL);
3593 n->oper = lcons("/",NIL);
3595 n->subLinkType = ANY_SUBLINK;
3599 | a_expr '*' ANY '(' SubSelect ')'
3601 SubLink *n = makeNode(SubLink);
3602 n->lefthand = lcons($1,NIL);
3603 n->oper = lcons("*",NIL);
3605 n->subLinkType = ANY_SUBLINK;
3609 | a_expr '<' ANY '(' SubSelect ')'
3611 SubLink *n = makeNode(SubLink);
3612 n->lefthand = lcons($1,NIL);
3613 n->oper = lcons("<",NIL);
3615 n->subLinkType = ANY_SUBLINK;
3619 | a_expr '>' ANY '(' SubSelect ')'
3621 SubLink *n = makeNode(SubLink);
3622 n->lefthand = lcons($1,NIL);
3623 n->oper = lcons(">",NIL);
3625 n->subLinkType = ANY_SUBLINK;
3629 | a_expr '=' ANY '(' SubSelect ')'
3631 SubLink *n = makeNode(SubLink);
3632 n->lefthand = lcons($1,NIL);
3633 n->oper = lcons("=",NIL);
3635 n->subLinkType = ANY_SUBLINK;
3639 | a_expr Op ALL '(' SubSelect ')'
3641 SubLink *n = makeNode(SubLink);
3642 n->lefthand = lcons($1, NULL);
3643 n->oper = lcons($2,NIL);
3645 n->subLinkType = ALL_SUBLINK;
3649 | a_expr '+' ALL '(' SubSelect ')'
3651 SubLink *n = makeNode(SubLink);
3652 n->lefthand = lcons($1, NULL);
3653 n->oper = lcons("+",NIL);
3655 n->subLinkType = ALL_SUBLINK;
3659 | a_expr '-' ALL '(' SubSelect ')'
3661 SubLink *n = makeNode(SubLink);
3662 n->lefthand = lcons($1, NULL);
3663 n->oper = lcons("-",NIL);
3665 n->subLinkType = ALL_SUBLINK;
3669 | a_expr '/' ALL '(' SubSelect ')'
3671 SubLink *n = makeNode(SubLink);
3672 n->lefthand = lcons($1, NULL);
3673 n->oper = lcons("/",NIL);
3675 n->subLinkType = ALL_SUBLINK;
3679 | a_expr '*' ALL '(' SubSelect ')'
3681 SubLink *n = makeNode(SubLink);
3682 n->lefthand = lcons($1, NULL);
3683 n->oper = lcons("*",NIL);
3685 n->subLinkType = ALL_SUBLINK;
3689 | a_expr '<' ALL '(' SubSelect ')'
3691 SubLink *n = makeNode(SubLink);
3692 n->lefthand = lcons($1, NULL);
3693 n->oper = lcons("<",NIL);
3695 n->subLinkType = ALL_SUBLINK;
3699 | a_expr '>' ALL '(' SubSelect ')'
3701 SubLink *n = makeNode(SubLink);
3702 n->lefthand = lcons($1, NULL);
3703 n->oper = lcons(">",NIL);
3705 n->subLinkType = ALL_SUBLINK;
3709 | a_expr '=' ALL '(' SubSelect ')'
3711 SubLink *n = makeNode(SubLink);
3712 n->lefthand = lcons($1, NULL);
3713 n->oper = lcons("=",NIL);
3715 n->subLinkType = ALL_SUBLINK;
3719 | a_expr Op '(' SubSelect ')'
3721 SubLink *n = makeNode(SubLink);
3722 n->lefthand = lcons($1, NULL);
3723 n->oper = lcons($2,NIL);
3725 n->subLinkType = ALL_SUBLINK;
3729 | a_expr '+' '(' SubSelect ')'
3731 SubLink *n = makeNode(SubLink);
3732 n->lefthand = lcons($1, NULL);
3733 n->oper = lcons("+",NIL);
3735 n->subLinkType = ALL_SUBLINK;
3739 | a_expr '-' '(' SubSelect ')'
3741 SubLink *n = makeNode(SubLink);
3742 n->lefthand = lcons($1, NULL);
3743 n->oper = lcons("-",NIL);
3745 n->subLinkType = ALL_SUBLINK;
3749 | a_expr '/' '(' SubSelect ')'
3751 SubLink *n = makeNode(SubLink);
3752 n->lefthand = lcons($1, NULL);
3753 n->oper = lcons("/",NIL);
3755 n->subLinkType = ALL_SUBLINK;
3759 | a_expr '*' '(' SubSelect ')'
3761 SubLink *n = makeNode(SubLink);
3762 n->lefthand = lcons($1, NULL);
3763 n->oper = lcons("*",NIL);
3765 n->subLinkType = ALL_SUBLINK;
3769 | a_expr '<' '(' SubSelect ')'
3771 SubLink *n = makeNode(SubLink);
3772 n->lefthand = lcons($1, NULL);
3773 n->oper = lcons("<",NIL);
3775 n->subLinkType = ALL_SUBLINK;
3779 | a_expr '>' '(' SubSelect ')'
3781 SubLink *n = makeNode(SubLink);
3782 n->lefthand = lcons($1, NULL);
3783 n->oper = lcons(">",NIL);
3785 n->subLinkType = ALL_SUBLINK;
3789 | a_expr '=' '(' SubSelect ')'
3791 SubLink *n = makeNode(SubLink);
3792 n->lefthand = lcons($1, NULL);
3793 n->oper = lcons("=",NIL);
3795 n->subLinkType = ALL_SUBLINK;
3800 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3802 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3804 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3808 * b_expr is a subset of the complete expression syntax
3809 * defined by a_expr. b_expr is used in BETWEEN clauses
3810 * to eliminate parser ambiguities stemming from the AND keyword.
3813 b_expr: attr opt_indirection
3815 $1->indirection = $2;
3822 /* could be a column name or a relation_name */
3823 Ident *n = makeNode(Ident);
3825 n->indirection = NULL;
3828 | '-' b_expr %prec UMINUS
3829 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3831 { $$ = makeA_Expr(OP, "+", $1, $3); }
3833 { $$ = makeA_Expr(OP, "-", $1, $3); }
3835 { $$ = makeA_Expr(OP, "/", $1, $3); }
3837 { $$ = makeA_Expr(OP, "*", $1, $3); }
3839 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3841 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3843 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3844 | b_expr TYPECAST Typename
3847 /* AexprConst can be either A_Const or ParamNo */
3848 if (nodeTag($1) == T_A_Const) {
3849 ((A_Const *)$1)->typename = $3;
3850 } else if (nodeTag($1) == T_Param) {
3851 ((ParamNo *)$1)->typename = $3;
3852 /* otherwise, try to transform to a function call */
3854 FuncCall *n = makeNode(FuncCall);
3855 n->funcname = $3->name;
3856 n->args = lcons($1,NIL);
3860 | CAST b_expr AS Typename
3863 /* AexprConst can be either A_Const or ParamNo */
3864 if (nodeTag($2) == T_A_Const) {
3865 ((A_Const *)$2)->typename = $4;
3866 } else if (nodeTag($2) == T_Param) {
3867 ((ParamNo *)$2)->typename = $4;
3868 /* otherwise, try to transform to a function call */
3870 FuncCall *n = makeNode(FuncCall);
3871 n->funcname = $4->name;
3872 n->args = lcons($2,NIL);
3879 { $$ = makeIndexable($2,$1,$3); }
3881 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3883 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3886 FuncCall *n = makeNode(FuncCall);
3891 | name '(' expr_list ')'
3893 FuncCall *n = makeNode(FuncCall);
3900 A_Const *n = makeNode(A_Const);
3901 TypeName *t = makeNode(TypeName);
3903 n->val.type = T_String;
3904 n->val.val.str = "now";
3907 t->name = xlateSqlType("date");
3914 A_Const *n = makeNode(A_Const);
3915 TypeName *t = makeNode(TypeName);
3917 n->val.type = T_String;
3918 n->val.val.str = "now";
3921 t->name = xlateSqlType("time");
3926 | CURRENT_TIME '(' Iconst ')'
3928 FuncCall *n = makeNode(FuncCall);
3929 A_Const *s = makeNode(A_Const);
3930 TypeName *t = makeNode(TypeName);
3932 n->funcname = xlateSqlType("time");
3933 n->args = lcons(s, NIL);
3935 s->val.type = T_String;
3936 s->val.val.str = "now";
3939 t->name = xlateSqlType("time");
3943 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3949 A_Const *n = makeNode(A_Const);
3950 TypeName *t = makeNode(TypeName);
3952 n->val.type = T_String;
3953 n->val.val.str = "now";
3956 t->name = xlateSqlType("timestamp");
3961 | CURRENT_TIMESTAMP '(' Iconst ')'
3963 FuncCall *n = makeNode(FuncCall);
3964 A_Const *s = makeNode(A_Const);
3965 TypeName *t = makeNode(TypeName);
3967 n->funcname = xlateSqlType("timestamp");
3968 n->args = lcons(s, NIL);
3970 s->val.type = T_String;
3971 s->val.val.str = "now";
3974 t->name = xlateSqlType("timestamp");
3978 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3984 FuncCall *n = makeNode(FuncCall);
3985 n->funcname = "getpgusername";
3989 | POSITION '(' position_list ')'
3991 FuncCall *n = makeNode(FuncCall);
3992 n->funcname = "strpos";
3996 | SUBSTRING '(' substr_list ')'
3998 FuncCall *n = makeNode(FuncCall);
3999 n->funcname = "substr";
4003 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4004 | TRIM '(' BOTH trim_list ')'
4006 FuncCall *n = makeNode(FuncCall);
4007 n->funcname = "btrim";
4011 | TRIM '(' LEADING trim_list ')'
4013 FuncCall *n = makeNode(FuncCall);
4014 n->funcname = "ltrim";
4018 | TRIM '(' TRAILING trim_list ')'
4020 FuncCall *n = makeNode(FuncCall);
4021 n->funcname = "rtrim";
4025 | TRIM '(' trim_list ')'
4027 FuncCall *n = makeNode(FuncCall);
4028 n->funcname = "btrim";
4034 opt_indirection: '[' a_expr ']' opt_indirection
4036 A_Indices *ai = makeNode(A_Indices);
4041 | '[' a_expr ':' a_expr ']' opt_indirection
4043 A_Indices *ai = makeNode(A_Indices);
4052 expr_list: a_expr_or_null
4053 { $$ = lcons($1, NIL); }
4054 | expr_list ',' a_expr_or_null
4055 { $$ = lappend($1, $3); }
4056 | expr_list USING a_expr
4057 { $$ = lappend($1, $3); }
4060 extract_list: datetime FROM a_expr
4062 A_Const *n = makeNode(A_Const);
4063 n->val.type = T_String;
4064 n->val.val.str = $1;
4065 $$ = lappend(lcons((Node *)n,NIL), $3);
4071 position_list: position_expr IN position_expr
4072 { $$ = makeList($3, $1, -1); }
4077 position_expr: attr opt_indirection
4079 $1->indirection = $2;
4084 | '-' position_expr %prec UMINUS
4085 { $$ = makeA_Expr(OP, "-", NULL, $2); }
4086 | position_expr '+' position_expr
4087 { $$ = makeA_Expr(OP, "+", $1, $3); }
4088 | position_expr '-' position_expr
4089 { $$ = makeA_Expr(OP, "-", $1, $3); }
4090 | position_expr '/' position_expr
4091 { $$ = makeA_Expr(OP, "/", $1, $3); }
4092 | position_expr '*' position_expr
4093 { $$ = makeA_Expr(OP, "*", $1, $3); }
4095 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4096 | position_expr TYPECAST Typename
4099 /* AexprConst can be either A_Const or ParamNo */
4100 if (nodeTag($1) == T_A_Const) {
4101 ((A_Const *)$1)->typename = $3;
4102 } else if (nodeTag($1) == T_Param) {
4103 ((ParamNo *)$1)->typename = $3;
4104 /* otherwise, try to transform to a function call */
4106 FuncCall *n = makeNode(FuncCall);
4107 n->funcname = $3->name;
4108 n->args = lcons($1,NIL);
4112 | CAST position_expr AS Typename
4115 /* AexprConst can be either A_Const or ParamNo */
4116 if (nodeTag($2) == T_A_Const) {
4117 ((A_Const *)$2)->typename = $4;
4118 } else if (nodeTag($2) == T_Param) {
4119 ((ParamNo *)$2)->typename = $4;
4120 /* otherwise, try to transform to a function call */
4122 FuncCall *n = makeNode(FuncCall);
4123 n->funcname = $4->name;
4124 n->args = lcons($2,NIL);
4128 | '(' position_expr ')'
4130 | position_expr Op position_expr
4131 { $$ = makeA_Expr(OP, $2, $1, $3); }
4133 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4135 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4138 /* could be a column name or a relation_name */
4139 Ident *n = makeNode(Ident);
4141 n->indirection = NULL;
4146 FuncCall *n = makeNode(FuncCall);
4151 | name '(' expr_list ')'
4153 FuncCall *n = makeNode(FuncCall);
4158 | POSITION '(' position_list ')'
4160 FuncCall *n = makeNode(FuncCall);
4161 n->funcname = "strpos";
4165 | SUBSTRING '(' substr_list ')'
4167 FuncCall *n = makeNode(FuncCall);
4168 n->funcname = "substr";
4172 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4173 | TRIM '(' BOTH trim_list ')'
4175 FuncCall *n = makeNode(FuncCall);
4176 n->funcname = "btrim";
4180 | TRIM '(' LEADING trim_list ')'
4182 FuncCall *n = makeNode(FuncCall);
4183 n->funcname = "ltrim";
4187 | TRIM '(' TRAILING trim_list ')'
4189 FuncCall *n = makeNode(FuncCall);
4190 n->funcname = "rtrim";
4194 | TRIM '(' trim_list ')'
4196 FuncCall *n = makeNode(FuncCall);
4197 n->funcname = "btrim";
4203 substr_list: expr_list substr_from substr_for
4205 $$ = nconc(nconc($1,$2),$3);
4211 substr_from: FROM expr_list
4215 A_Const *n = makeNode(A_Const);
4216 n->val.type = T_Integer;
4217 n->val.val.ival = 1;
4218 $$ = lcons((Node *)n,NIL);
4222 substr_for: FOR expr_list
4228 trim_list: a_expr FROM expr_list
4229 { $$ = lappend($3, $1); }
4238 SubLink *n = makeNode(SubLink);
4246 in_expr_nodes: AexprConst
4247 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4248 | in_expr_nodes ',' AexprConst
4249 { $$ = makeA_Expr(OR, NULL, $1,
4250 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4254 not_in_expr: SubSelect
4256 SubLink *n = makeNode(SubLink);
4264 not_in_expr_nodes: AexprConst
4265 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4266 | not_in_expr_nodes ',' AexprConst
4267 { $$ = makeA_Expr(AND, NULL, $1,
4268 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4272 attr: relation_name '.' attrs
4274 $$ = makeNode(Attr);
4278 $$->indirection = NULL;
4282 $$ = makeNode(Attr);
4286 $$->indirection = NULL;
4291 { $$ = lcons(makeString($1), NIL); }
4292 | attrs '.' attr_name
4293 { $$ = lappend($1, makeString($3)); }
4295 { $$ = lappend($1, makeString("*")); }
4299 /*****************************************************************************
4303 *****************************************************************************/
4305 res_target_list: res_target_list ',' res_target_el
4306 { $$ = lappend($1,$3); }
4308 { $$ = lcons($1, NIL); }
4311 ResTarget *rt = makeNode(ResTarget);
4312 Attr *att = makeNode(Attr);
4314 att->paramNo = NULL;
4316 att->indirection = NIL;
4318 rt->indirection = NULL;
4319 rt->val = (Node *)att;
4320 $$ = lcons(rt, NIL);
4324 res_target_el: ColId opt_indirection '=' a_expr_or_null
4326 $$ = makeNode(ResTarget);
4328 $$->indirection = $2;
4329 $$->val = (Node *)$4;
4331 | attr opt_indirection
4333 $$ = makeNode(ResTarget);
4335 $$->indirection = $2;
4336 $$->val = (Node *)$1;
4338 | relation_name '.' '*'
4340 Attr *att = makeNode(Attr);
4342 att->paramNo = NULL;
4343 att->attrs = lcons(makeString("*"), NIL);
4344 att->indirection = NIL;
4345 $$ = makeNode(ResTarget);
4347 $$->indirection = NULL;
4348 $$->val = (Node *)att;
4353 ** target list for select.
4354 ** should get rid of the other but is still needed by the defunct select into
4355 ** and update (uses a subset)
4357 res_target_list2: res_target_list2 ',' res_target_el2
4358 { $$ = lappend($1, $3); }
4360 { $$ = lcons($1, NIL); }
4363 /* AS is not optional because shift/red conflict with unary ops */
4364 res_target_el2: a_expr_or_null AS ColLabel
4366 $$ = makeNode(ResTarget);
4368 $$->indirection = NULL;
4369 $$->val = (Node *)$1;
4373 $$ = makeNode(ResTarget);
4375 $$->indirection = NULL;
4376 $$->val = (Node *)$1;
4378 | relation_name '.' '*'
4380 Attr *att = makeNode(Attr);
4382 att->paramNo = NULL;
4383 att->attrs = lcons(makeString("*"), NIL);
4384 att->indirection = NIL;
4385 $$ = makeNode(ResTarget);
4387 $$->indirection = NULL;
4388 $$->val = (Node *)att;
4392 Attr *att = makeNode(Attr);
4394 att->paramNo = NULL;
4396 att->indirection = NIL;
4397 $$ = makeNode(ResTarget);
4399 $$->indirection = NULL;
4400 $$->val = (Node *)att;
4404 opt_id: ColId { $$ = $1; }
4405 | /* EMPTY */ { $$ = NULL; }
4408 relation_name: SpecialRuleRelation
4411 StrNCpy(saved_relname, $1, NAMEDATALEN);
4415 /* disallow refs to variable system tables */
4416 if (strcmp(LogRelationName, $1) == 0
4417 || strcmp(VariableRelationName, $1) == 0)
4418 elog(ERROR,"%s cannot be accessed by users",$1);
4421 StrNCpy(saved_relname, $1, NAMEDATALEN);
4425 database_name: ColId { $$ = $1; };
4426 access_method: Id { $$ = $1; };
4427 attr_name: ColId { $$ = $1; };
4428 class: Id { $$ = $1; };
4429 index_name: ColId { $$ = $1; };
4432 * Include date/time keywords as SQL92 extension.
4433 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4435 name: ColId { $$ = $1; };
4437 file_name: Sconst { $$ = $1; };
4438 recipe_name: Id { $$ = $1; };
4441 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4445 A_Const *n = makeNode(A_Const);
4446 n->val.type = T_Integer;
4447 n->val.val.ival = $1;
4452 A_Const *n = makeNode(A_Const);
4453 n->val.type = T_Float;
4454 n->val.val.dval = $1;
4459 A_Const *n = makeNode(A_Const);
4460 n->val.type = T_String;
4461 n->val.val.str = $1;
4466 A_Const *n = makeNode(A_Const);
4468 n->val.type = T_String;
4469 n->val.val.str = $2;
4473 { $$ = (Node *)$1; }
4476 A_Const *n = makeNode(A_Const);
4477 n->val.type = T_String;
4478 n->val.val.str = "t";
4479 n->typename = makeNode(TypeName);
4480 n->typename->name = xlateSqlType("bool");
4485 A_Const *n = makeNode(A_Const);
4486 n->val.type = T_String;
4487 n->val.val.str = "f";
4488 n->typename = makeNode(TypeName);
4489 n->typename->name = xlateSqlType("bool");
4496 $$ = makeNode(ParamNo);
4501 NumConst: Iconst { $$ = makeInteger($1); }
4502 | FCONST { $$ = makeFloat($1); }
4505 Iconst: ICONST { $$ = $1; };
4506 Sconst: SCONST { $$ = $1; };
4508 /* Column and type identifier
4509 * Does not include explicit datetime types
4510 * since these must be decoupled in Typename syntax.
4511 * Use ColId for most identifiers. - thomas 1997-10-21
4513 Id: IDENT { $$ = $1; };
4515 /* Column identifier
4516 * Include date/time keywords as SQL92 extension.
4517 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4518 * Add other keywords. Note that as the syntax expands,
4519 * some of these keywords will have to be removed from this
4520 * list due to shift/reduce conflicts in yacc. If so, move
4521 * down to the ColLabel entity. - thomas 1997-11-06
4523 ColId: Id { $$ = $1; }
4524 | datetime { $$ = $1; }
4525 | ACTION { $$ = "action"; }
4526 | DATABASE { $$ = "database"; }
4527 | DELIMITERS { $$ = "delimiters"; }
4528 | FUNCTION { $$ = "function"; }
4529 | INDEX { $$ = "index"; }
4530 | KEY { $$ = "key"; }
4531 | LANGUAGE { $$ = "language"; }
4532 | LOCATION { $$ = "location"; }
4533 | MATCH { $$ = "match"; }
4534 | OPERATOR { $$ = "operator"; }
4535 | OPTION { $$ = "option"; }
4536 | PRIVILEGES { $$ = "privileges"; }
4537 | RECIPE { $$ = "recipe"; }
4538 | TIME { $$ = "time"; }
4539 | TRIGGER { $$ = "trigger"; }
4540 | TYPE_P { $$ = "type"; }
4541 | VERSION { $$ = "version"; }
4542 | ZONE { $$ = "zone"; }
4546 * Allowed labels in "AS" clauses.
4547 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4548 * compatibility. Cannot allow this for column names since the
4549 * syntax would not distinguish between the constant value and
4550 * a column name. - thomas 1997-10-24
4551 * Add other keywords to this list. Note that they appear here
4552 * rather than in ColId if there was a shift/reduce conflict
4553 * when used as a full identifier. - thomas 1997-11-06
4555 ColLabel: ColId { $$ = $1; }
4556 | ARCHIVE { $$ = "archive"; }
4557 | CLUSTER { $$ = "cluster"; }
4558 | CONSTRAINT { $$ = "constraint"; }
4559 | CROSS { $$ = "cross"; }
4560 | FOREIGN { $$ = "foreign"; }
4561 | GROUP { $$ = "group"; }
4562 | LOAD { $$ = "load"; }
4563 | ORDER { $$ = "order"; }
4564 | POSITION { $$ = "position"; }
4565 | PRECISION { $$ = "precision"; }
4566 | TABLE { $$ = "table"; }
4567 | TRANSACTION { $$ = "transaction"; }
4568 | TRUE_P { $$ = "true"; }
4569 | FALSE_P { $$ = "false"; }
4572 SpecialRuleRelation: CURRENT
4577 elog(ERROR,"CURRENT used in non-rule query");
4584 elog(ERROR,"NEW used in non-rule query");
4591 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
4593 A_Expr *a = makeNode(A_Expr);
4602 * Generate separate operator nodes for a single row descriptor expression.
4603 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
4606 makeRowExpr(char *opr, List *largs, List *rargs)
4611 if (length(largs) != length(rargs))
4612 elog(ERROR,"Unequal number of entries in row expression");
4614 if (lnext(largs) != NIL)
4615 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
4617 larg = lfirst(largs);
4618 rarg = lfirst(rargs);
4620 if ((strcmp(opr, "=") == 0)
4621 || (strcmp(opr, "<") == 0)
4622 || (strcmp(opr, "<=") == 0)
4623 || (strcmp(opr, ">") == 0)
4624 || (strcmp(opr, ">=") == 0))
4627 expr = makeA_Expr(OP, opr, larg, rarg);
4629 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4631 else if (strcmp(opr, "<>") == 0)
4634 expr = makeA_Expr(OP, opr, larg, rarg);
4636 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4640 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
4644 while ((largs != NIL) && (rargs != NIL))
4646 larg = lfirst(largs);
4647 rarg = lfirst(rargs);
4650 expr = makeA_Expr(OP, opr, larg, rarg);
4652 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4654 largs = lnext(largs);
4655 rargs = lnext(rargs);
4664 mapTargetColumns(List *src, List *dst)
4669 if (length(src) != length(dst))
4670 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
4672 while ((src != NIL) && (dst != NIL))
4674 s = (ColumnDef *)lfirst(src);
4675 d = (ResTarget *)lfirst(dst);
4677 d->name = s->colname;
4684 } /* mapTargetColumns() */
4686 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
4688 Node *result = NULL;
4690 /* we do this so indexes can be used */
4691 if (strcmp(opname,"~") == 0 ||
4692 strcmp(opname,"~*") == 0)
4694 if (nodeTag(rexpr) == T_A_Const &&
4695 ((A_Const *)rexpr)->val.type == T_String &&
4696 ((A_Const *)rexpr)->val.val.str[0] == '^')
4698 A_Const *n = (A_Const *)rexpr;
4699 char *match_least = palloc(strlen(n->val.val.str)+2);
4700 char *match_most = palloc(strlen(n->val.val.str)+2);
4701 int pos, match_pos=0;
4703 /* skip leading ^ */
4704 for (pos = 1; n->val.val.str[pos]; pos++)
4706 if (n->val.val.str[pos] == '.' ||
4707 n->val.val.str[pos] == '?' ||
4708 n->val.val.str[pos] == '*' ||
4709 n->val.val.str[pos] == '[' ||
4710 n->val.val.str[pos] == '$' ||
4711 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4713 if (n->val.val.str[pos] == '\\')
4715 match_least[match_pos] = n->val.val.str[pos];
4716 match_most[match_pos++] = n->val.val.str[pos];
4721 A_Const *least = makeNode(A_Const);
4722 A_Const *most = makeNode(A_Const);
4724 /* make strings to be used in index use */
4725 match_least[match_pos] = '\0';
4726 match_most[match_pos] = '\377';
4727 match_most[match_pos+1] = '\0';
4728 least->val.type = T_String;
4729 least->val.val.str = match_least;
4730 most->val.type = T_String;
4731 most->val.val.str = match_most;
4732 result = makeA_Expr(AND, NULL,
4733 makeA_Expr(OP, "~", lexpr, rexpr),
4734 makeA_Expr(AND, NULL,
4735 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4736 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4740 else if (strcmp(opname,"~~") == 0)
4742 if (nodeTag(rexpr) == T_A_Const &&
4743 ((A_Const *)rexpr)->val.type == T_String)
4745 A_Const *n = (A_Const *)rexpr;
4746 char *match_least = palloc(strlen(n->val.val.str)+2);
4747 char *match_most = palloc(strlen(n->val.val.str)+2);
4748 int pos, match_pos=0;
4750 for (pos = 0; n->val.val.str[pos]; pos++)
4752 if ((n->val.val.str[pos] == '%' &&
4753 n->val.val.str[pos+1] != '%') ||
4754 (n->val.val.str[pos] == '_' &&
4755 n->val.val.str[pos+1] != '_'))
4757 if (n->val.val.str[pos] == '%' ||
4758 n->val.val.str[pos] == '_' ||
4759 n->val.val.str[pos] == '\\')
4761 match_least[match_pos] = n->val.val.str[pos];
4762 match_most[match_pos++] = n->val.val.str[pos];
4767 A_Const *least = makeNode(A_Const);
4768 A_Const *most = makeNode(A_Const);
4770 /* make strings to be used in index use */
4771 match_least[match_pos] = '\0';
4772 match_most[match_pos] = '\377';
4773 match_most[match_pos+1] = '\0';
4774 least->val.type = T_String;
4775 least->val.val.str = match_least;
4776 most->val.type = T_String;
4777 most->val.val.str = match_most;
4778 result = makeA_Expr(AND, NULL,
4779 makeA_Expr(OP, "~~", lexpr, rexpr),
4780 makeA_Expr(AND, NULL,
4781 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4782 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4788 result = makeA_Expr(OP, opname, lexpr, rexpr);
4790 } /* makeIndexable() */
4794 * Convert alternate type names to internal Postgres types.
4795 * Do not convert "float", since that is handled elsewhere
4796 * for FLOAT(p) syntax.
4799 xlateSqlType(char *name)
4801 if (!strcasecmp(name,"int")
4802 || !strcasecmp(name,"integer"))
4804 else if (!strcasecmp(name, "smallint"))
4806 else if (!strcasecmp(name, "real"))
4808 else if (!strcasecmp(name, "interval"))
4810 else if (!strcasecmp(name, "boolean"))
4814 } /* xlateSqlName() */
4817 void parser_init(Oid *typev, int nargs)
4819 QueryIsRule = FALSE;
4820 saved_relname[0]= '\0';
4821 saved_In_Expr = NULL;
4823 param_type_init(typev, nargs);
4827 /* FlattenStringList()
4828 * Traverse list of string nodes and convert to a single string.
4829 * Used for reconstructing string form of complex expressions.
4831 * Allocate at least one byte for terminator.
4834 FlattenStringList(List *list)
4842 nlist = length(list);
4845 v = (Value *)lfirst(l);
4852 s = (char*) palloc(len+1);
4857 v = (Value *)lfirst(l);
4861 if (l != NIL) strcat(s," ");
4866 printf( "flattened string is \"%s\"\n", s);
4870 } /* FlattenStringList() */
4873 /* makeConstantList()
4874 * Convert constant value node into string node.
4877 makeConstantList( A_Const *n)
4879 char *defval = NULL;
4880 if (nodeTag(n) != T_A_Const) {
4881 elog(ERROR,"Cannot handle non-constant parameter");
4883 } else if (n->val.type == T_Float) {
4884 defval = (char*) palloc(20+1);
4885 sprintf( defval, "%g", n->val.val.dval);
4887 } else if (n->val.type == T_Integer) {
4888 defval = (char*) palloc(20+1);
4889 sprintf( defval, "%ld", n->val.val.ival);
4891 } else if (n->val.type == T_String) {
4892 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
4893 strcpy( defval, "'");
4894 strcat( defval, ((A_Const *) n)->val.val.str);
4895 strcat( defval, "'");
4898 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
4902 printf( "AexprConst argument is \"%s\"\n", defval);
4905 return( lcons( makeString(defval), NIL));
4906 } /* makeConstantList() */
4910 * Check input string for non-lowercase/non-numeric characters.
4911 * Returns either input string or input surrounded by double quotes.
4918 for (cp = rawid; *cp != '\0'; cp++)
4919 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
4922 cp = palloc(strlen(rawid)+1);
4931 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
4940 * keep enough information around fill out the type of param nodes
4941 * used in postquel functions
4944 param_type_init(Oid *typev, int nargs)
4946 pfunc_num_args = nargs;
4947 param_type_info = typev;
4950 Oid param_type(int t)
4952 if ((t > pfunc_num_args) || (t == 0))
4954 return param_type_info[t - 1];