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 2.6 1998/03/07 06:04:59 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 *xlateSqlFunc(char *);
65 static char *xlateSqlType(char *);
66 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
67 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
68 void mapTargetColumns(List *source, List *target);
69 static List *makeConstantList( A_Const *node);
70 static char *FlattenStringList(List *list);
71 static char *fmtId(char *rawid);
72 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
73 static void param_type_init(Oid *typev, int nargs);
75 Oid param_type(int t); /* used in parse_expr.c */
77 /* old versions of flex define this as a macro */
91 bool* pboolean; /* for pg_shadow privileges */
101 SortGroupBy *sortgroupby;
116 AddAttrStmt, ClosePortalStmt,
117 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
118 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
119 CreatePLangStmt, DropPLangStmt,
120 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
121 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
122 RemoveFuncStmt, RemoveStmt,
123 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
124 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
125 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
126 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
127 CreateUserStmt, AlterUserStmt, DropUserStmt
129 %type <str> opt_database, location
131 %type <pboolean> user_createdb_clause, user_createuser_clause
132 %type <str> user_passwd_clause
133 %type <str> user_valid_clause
134 %type <list> user_group_list, user_group_clause
136 %type <str> join_expr, join_outer, join_spec
137 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
139 %type <str> TriggerEvents, TriggerFuncArg
141 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
142 database_name, access_method_clause, access_method, attr_name,
143 class, index_name, name, func_name, file_name, recipe_name, aggr_argtype
145 %type <str> opt_id, opt_portal_name,
146 all_Op, MathOp, opt_name, opt_unique,
147 result, OptUseOp, opt_class, SpecialRuleRelation
149 %type <str> privileges, operation_commalist, grantee
150 %type <chr> operation, TriggerOneEvent
152 %type <list> stmtblock, stmtmulti,
153 relation_name_list, OptTableElementList,
154 OptInherit, definition,
155 opt_with, func_args, func_args_list,
156 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
157 opt_column_list, columnList, opt_va_list, va_list,
158 sort_clause, sortby_list, index_params, index_list, name_list,
159 from_clause, from_list, opt_array_bounds, nest_array_bounds,
160 expr_list, attrs, res_target_list, res_target_list2,
161 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
163 %type <node> func_return
164 %type <boolean> set_opt
166 %type <boolean> TriggerForOpt, TriggerForType
168 %type <list> union_clause, select_list
169 %type <list> join_list
172 %type <boolean> opt_union
174 %type <node> position_expr
175 %type <list> extract_list, position_list
176 %type <list> substr_list, substr_from, substr_for, trim_list
177 %type <list> opt_interval
179 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
180 index_opt_unique, opt_verbose, opt_analyze
182 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
185 %type <ival> fetch_how_many
187 %type <list> OptSeqList
188 %type <defelt> OptSeqElem
190 %type <dstmt> def_rest
191 %type <astmt> insert_rest
193 %type <node> OptTableElement, ConstraintElem
194 %type <node> columnDef, alter_clause
195 %type <defelt> def_elem
196 %type <node> def_arg, columnElem, where_clause,
197 a_expr, a_expr_or_null, b_expr, AexprConst,
198 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
200 %type <list> row_descriptor, row_list
201 %type <node> row_expr
202 %type <list> OptCreateAs, CreateAsList
203 %type <node> CreateAsElement
204 %type <value> NumConst
205 %type <attr> event_object, attr
206 %type <sortgroupby> groupby
207 %type <sortgroupby> sortby
208 %type <ielem> index_elem, func_index
209 %type <range> from_val
210 %type <relexp> relation_expr
211 %type <target> res_target_el, res_target_el2
212 %type <paramno> ParamNo
214 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
215 %type <str> generic, numeric, character, datetime
216 %type <str> opt_charset, opt_collate
217 %type <str> opt_float, opt_numeric, opt_decimal
218 %type <boolean> opt_varying, opt_timezone
222 %type <str> UserId, var_value, zone_value
223 %type <str> ColId, ColLabel
226 %type <node> TableConstraint
227 %type <list> constraint_list, constraint_expr
228 %type <list> default_list, default_expr
229 %type <list> ColQualList, ColQualifier
230 %type <node> ColConstraint, ColConstraintElem
231 %type <list> key_actions, key_action
232 %type <str> key_match, key_reference
235 * If you make any token changes, remember to:
236 * - use "yacc -d" and update parse.h
237 * - update the keyword table in parser/keywords.c
240 /* Reserved word tokens
241 * SQL92 syntax has many type-specific constructs.
242 * So, go ahead and make these types reserved words,
243 * and call-out the syntax explicitly.
244 * This gets annoying when trying to also retain Postgres' nice
245 * type-extensible features, but we don't really have a choice.
246 * - thomas 1997-10-11
249 /* Keywords (in SQL92 reserved words) */
250 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
251 BEGIN_TRANS, BETWEEN, BOTH, BY,
252 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
253 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
254 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
255 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
256 END_TRANS, EXECUTE, EXISTS, EXTRACT,
257 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
258 GRANT, GROUP, HAVING, HOUR_P,
259 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
260 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
261 MATCH, MINUTE_P, MONTH_P,
262 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
263 ON, OPTION, OR, ORDER, OUTER_P,
264 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
265 REFERENCES, REVOKE, RIGHT, ROLLBACK,
266 SECOND_P, SELECT, SET, SUBSTRING,
267 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
268 UNION, UNIQUE, UPDATE, USING,
269 VALUES, VARCHAR, VARYING, VIEW,
270 WHERE, WITH, WORK, YEAR_P, ZONE
272 /* Keywords (in SQL3 reserved words) */
273 %token FALSE_P, TRIGGER, TRUE_P
275 /* Keywords (in SQL92 non-reserved words) */
278 /* Keywords for Postgres support (not in SQL92 reserved words) */
279 %token ABORT_TRANS, AFTER, AGGREGATE, ANALYZE,
280 BACKWARD, BEFORE, BINARY, CLUSTER, COPY,
281 DATABASE, DELIMITERS, DO, EACH, EXPLAIN, EXTEND,
282 FORWARD, FUNCTION, HANDLER,
283 INDEX, INHERITS, INSTEAD, ISNULL,
284 LANCOMPILER, LISTEN, LOAD, LOCK_P, LOCATION, MOVE,
285 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
286 RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
287 SEQUENCE, SETOF, SHOW, STATEMENT, STDIN, STDOUT, TRUSTED,
288 VACUUM, VERBOSE, VERSION
290 /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-04) */
294 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
295 * when some sort of pg_privileges relation is introduced.
299 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
301 /* Special keywords, not in the query language - see the "lex" file */
302 %token <str> IDENT, SCONST, Op
303 %token <ival> ICONST, PARAM
306 /* these are not real. they are here so that they get generated as #define's*/
318 %nonassoc Op /* multi-character ops and user-defined operators */
324 %left '|' /* this is the relation union op, not logical or */
325 /* Unary Operators */
327 %left ';' /* end of statement or natural log */
339 { parsetree = lcons($1,NIL); }
342 stmtmulti: stmtmulti stmt ';'
343 { $$ = lappend($1, $2); }
345 { $$ = lappend($1, $2); }
347 { $$ = lcons($1,NIL); }
394 /*****************************************************************************
396 * Create a new Postgres DBMS user
399 *****************************************************************************/
401 CreateUserStmt: CREATE USER UserId user_passwd_clause user_createdb_clause
402 user_createuser_clause user_group_clause user_valid_clause
404 CreateUserStmt *n = makeNode(CreateUserStmt);
415 /*****************************************************************************
417 * Alter a postresql DBMS user
420 *****************************************************************************/
422 AlterUserStmt: ALTER USER UserId user_passwd_clause user_createdb_clause
423 user_createuser_clause user_group_clause user_valid_clause
425 AlterUserStmt *n = makeNode(AlterUserStmt);
436 /*****************************************************************************
438 * Drop a postresql DBMS user
441 *****************************************************************************/
443 DropUserStmt: DROP USER UserId
445 DropUserStmt *n = makeNode(DropUserStmt);
451 user_passwd_clause: WITH PASSWORD UserId { $$ = $3; }
452 | /*EMPTY*/ { $$ = NULL; }
455 user_createdb_clause: CREATEDB
458 $$ = (b = (bool*)palloc(sizeof(bool)));
464 $$ = (b = (bool*)palloc(sizeof(bool)));
467 | /*EMPTY*/ { $$ = NULL; }
470 user_createuser_clause: CREATEUSER
473 $$ = (b = (bool*)palloc(sizeof(bool)));
479 $$ = (b = (bool*)palloc(sizeof(bool)));
482 | /*EMPTY*/ { $$ = NULL; }
485 user_group_list: user_group_list ',' UserId
487 $$ = lcons((void*)makeString($3), $1);
491 $$ = lcons((void*)makeString($1), NIL);
495 user_group_clause: IN GROUP user_group_list { $$ = $3; }
496 | /*EMPTY*/ { $$ = NULL; }
499 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
500 | /*EMPTY*/ { $$ = NULL; }
503 /*****************************************************************************
505 * Set PG internal variable
506 * SET name TO 'var_value'
507 * Include SQL92 syntax (thomas 1997-10-22):
508 * SET TIME ZONE 'var_value'
510 *****************************************************************************/
512 VariableSetStmt: SET ColId TO var_value
514 VariableSetStmt *n = makeNode(VariableSetStmt);
519 | SET ColId '=' var_value
521 VariableSetStmt *n = makeNode(VariableSetStmt);
526 | SET TIME ZONE zone_value
528 VariableSetStmt *n = makeNode(VariableSetStmt);
529 n->name = "timezone";
535 var_value: Sconst { $$ = $1; }
536 | DEFAULT { $$ = NULL; }
539 zone_value: Sconst { $$ = $1; }
540 | DEFAULT { $$ = NULL; }
541 | LOCAL { $$ = "default"; }
544 VariableShowStmt: SHOW ColId
546 VariableShowStmt *n = makeNode(VariableShowStmt);
552 VariableShowStmt *n = makeNode(VariableShowStmt);
553 n->name = "timezone";
558 VariableResetStmt: RESET ColId
560 VariableResetStmt *n = makeNode(VariableResetStmt);
566 VariableResetStmt *n = makeNode(VariableResetStmt);
567 n->name = "timezone";
573 /*****************************************************************************
576 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
578 *****************************************************************************/
580 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
582 AddAttrStmt *n = makeNode(AddAttrStmt);
590 alter_clause: ADD opt_column columnDef
594 | ADD '(' OptTableElementList ')'
596 Node *lp = lfirst($3);
599 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
602 | DROP opt_column ColId
603 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
604 | ALTER opt_column ColId SET DEFAULT default_expr
605 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
606 | ALTER opt_column ColId DROP DEFAULT
607 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
609 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
613 /*****************************************************************************
618 *****************************************************************************/
620 ClosePortalStmt: CLOSE opt_id
622 ClosePortalStmt *n = makeNode(ClosePortalStmt);
629 /*****************************************************************************
632 * COPY [BINARY] <relname> FROM/TO
633 * [USING DELIMITERS <delimiter>]
635 *****************************************************************************/
637 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
639 CopyStmt *n = makeNode(CopyStmt);
657 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
658 * used depends on the direction. (It really doesn't make sense to copy from
659 * stdout. We silently correct the "typo". - AY 9/94
661 copy_file_name: Sconst { $$ = $1; }
662 | STDIN { $$ = NULL; }
663 | STDOUT { $$ = NULL; }
666 opt_binary: BINARY { $$ = TRUE; }
667 | /*EMPTY*/ { $$ = FALSE; }
670 opt_with_copy: WITH OIDS { $$ = TRUE; }
671 | /*EMPTY*/ { $$ = FALSE; }
675 * the default copy delimiter is tab but the user can configure it
677 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
678 | /*EMPTY*/ { $$ = "\t"; }
682 /*****************************************************************************
687 *****************************************************************************/
689 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
690 OptInherit OptArchiveType
692 CreateStmt *n = makeNode(CreateStmt);
696 n->constraints = NIL;
701 OptTableElementList: OptTableElementList ',' OptTableElement
702 { $$ = lappend($1, $3); }
703 | OptTableElement { $$ = lcons($1, NIL); }
704 | /*EMPTY*/ { $$ = NULL; }
707 OptTableElement: columnDef { $$ = $1; }
708 | TableConstraint { $$ = $1; }
711 columnDef: ColId Typename ColQualifier
713 ColumnDef *n = makeNode(ColumnDef);
717 n->is_not_null = FALSE;
723 ColQualifier: ColQualList { $$ = $1; }
724 | /*EMPTY*/ { $$ = NULL; }
727 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
728 | ColConstraint { $$ = lcons($1, NIL); }
732 CONSTRAINT name ColConstraintElem
734 Constraint *n = (Constraint *)$3;
742 ColConstraintElem: CHECK '(' constraint_expr ')'
744 Constraint *n = makeNode(Constraint);
745 n->contype = CONSTR_CHECK;
747 n->def = FlattenStringList($3);
751 | DEFAULT default_expr
753 Constraint *n = makeNode(Constraint);
754 n->contype = CONSTR_DEFAULT;
756 n->def = FlattenStringList($2);
762 Constraint *n = makeNode(Constraint);
763 n->contype = CONSTR_NOTNULL;
771 Constraint *n = makeNode(Constraint);
772 n->contype = CONSTR_UNIQUE;
780 Constraint *n = makeNode(Constraint);
781 n->contype = CONSTR_PRIMARY;
787 | REFERENCES ColId opt_column_list key_match key_actions
789 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
794 default_list: default_list ',' default_expr
796 $$ = lappend($1,makeString(","));
805 default_expr: AexprConst
806 { $$ = makeConstantList((A_Const *) $1); }
808 { $$ = lcons( makeString("NULL"), NIL); }
809 | '-' default_expr %prec UMINUS
810 { $$ = lcons( makeString( "-"), $2); }
811 | default_expr '+' default_expr
812 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
813 | default_expr '-' default_expr
814 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
815 | default_expr '/' default_expr
816 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
817 | default_expr '*' default_expr
818 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
819 | default_expr '=' default_expr
820 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
821 | default_expr '<' default_expr
822 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
823 | default_expr '>' default_expr
824 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
826 { $$ = lcons( makeString( ":"), $2); }
828 { $$ = lcons( makeString( ";"), $2); }
830 { $$ = lcons( makeString( "|"), $2); }
831 | default_expr TYPECAST Typename
833 $3->name = fmtId($3->name);
834 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
836 | CAST '(' default_expr AS Typename ')'
838 $5->name = fmtId($5->name);
839 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
841 | '(' default_expr ')'
842 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
845 $$ = makeList( makeString($1), makeString("("), -1);
846 $$ = lappend( $$, makeString(")"));
848 | func_name '(' default_list ')'
850 $$ = makeList( makeString($1), makeString("("), -1);
852 $$ = lappend( $$, makeString(")"));
854 | default_expr Op default_expr
856 if (!strcmp("<=", $2) || !strcmp(">=", $2))
857 elog(ERROR,"boolean expressions not supported in DEFAULT");
858 $$ = nconc( $1, lcons( makeString( $2), $3));
861 { $$ = lcons( makeString( $1), $2); }
863 { $$ = lappend( $1, makeString( $2)); }
864 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
866 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
868 { $$ = lcons( makeString( "'now'::time"), NIL); }
869 | CURRENT_TIME '(' Iconst ')'
872 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
873 $$ = lcons( makeString( "'now'::time"), NIL);
876 { $$ = lcons( makeString( "now()"), NIL); }
877 | CURRENT_TIMESTAMP '(' Iconst ')'
880 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
881 $$ = lcons( makeString( "now()"), NIL);
884 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
887 /* ConstraintElem specifies constraint syntax which is not embedded into
888 * a column definition. ColConstraintElem specifies the embedded form.
889 * - thomas 1997-12-03
891 TableConstraint: CONSTRAINT name ConstraintElem
893 Constraint *n = (Constraint *)$3;
901 ConstraintElem: CHECK '(' constraint_expr ')'
903 Constraint *n = makeNode(Constraint);
904 n->contype = CONSTR_CHECK;
906 n->def = FlattenStringList($3);
909 | UNIQUE '(' columnList ')'
911 Constraint *n = makeNode(Constraint);
912 n->contype = CONSTR_UNIQUE;
918 | PRIMARY KEY '(' columnList ')'
920 Constraint *n = makeNode(Constraint);
921 n->contype = CONSTR_PRIMARY;
927 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
928 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented"); }
931 constraint_list: constraint_list ',' constraint_expr
933 $$ = lappend($1,makeString(","));
942 constraint_expr: AexprConst
943 { $$ = makeConstantList((A_Const *) $1); }
945 { $$ = lcons( makeString("NULL"), NIL); }
948 $$ = lcons( makeString(fmtId($1)), NIL);
950 | '-' constraint_expr %prec UMINUS
951 { $$ = lcons( makeString( "-"), $2); }
952 | constraint_expr '+' constraint_expr
953 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
954 | constraint_expr '-' constraint_expr
955 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
956 | constraint_expr '/' constraint_expr
957 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
958 | constraint_expr '*' constraint_expr
959 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
960 | constraint_expr '=' constraint_expr
961 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
962 | constraint_expr '<' constraint_expr
963 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
964 | constraint_expr '>' constraint_expr
965 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
966 | ':' constraint_expr
967 { $$ = lcons( makeString( ":"), $2); }
968 | ';' constraint_expr
969 { $$ = lcons( makeString( ";"), $2); }
970 | '|' constraint_expr
971 { $$ = lcons( makeString( "|"), $2); }
972 | constraint_expr TYPECAST Typename
974 $3->name = fmtId($3->name);
975 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
977 | CAST '(' constraint_expr AS Typename ')'
979 $5->name = fmtId($5->name);
980 $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
982 | '(' constraint_expr ')'
983 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
986 $$ = makeList( makeString($1), makeString("("), -1);
987 $$ = lappend( $$, makeString(")"));
989 | func_name '(' constraint_list ')'
991 $$ = makeList( makeString($1), makeString("("), -1);
993 $$ = lappend( $$, makeString(")"));
995 | constraint_expr Op constraint_expr
996 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
997 | constraint_expr LIKE constraint_expr
998 { $$ = nconc( $1, lcons( makeString( "like"), $3)); }
999 | constraint_expr AND constraint_expr
1000 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
1001 | constraint_expr OR constraint_expr
1002 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
1003 | NOT constraint_expr
1004 { $$ = lcons( makeString( "NOT"), $2); }
1005 | Op constraint_expr
1006 { $$ = lcons( makeString( $1), $2); }
1007 | constraint_expr Op
1008 { $$ = lappend( $1, makeString( $2)); }
1009 | constraint_expr ISNULL
1010 { $$ = lappend( $1, makeString( "IS NULL")); }
1011 | constraint_expr IS NULL_P
1012 { $$ = lappend( $1, makeString( "IS NULL")); }
1013 | constraint_expr NOTNULL
1014 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1015 | constraint_expr IS NOT NULL_P
1016 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1017 | constraint_expr IS TRUE_P
1018 { $$ = lappend( $1, makeString( "IS TRUE")); }
1019 | constraint_expr IS FALSE_P
1020 { $$ = lappend( $1, makeString( "IS FALSE")); }
1021 | constraint_expr IS NOT TRUE_P
1022 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1023 | constraint_expr IS NOT FALSE_P
1024 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1027 key_match: MATCH FULL { $$ = NULL; }
1028 | MATCH PARTIAL { $$ = NULL; }
1029 | /*EMPTY*/ { $$ = NULL; }
1032 key_actions: key_action key_action { $$ = NIL; }
1033 | key_action { $$ = NIL; }
1034 | /*EMPTY*/ { $$ = NIL; }
1037 key_action: ON DELETE key_reference { $$ = NIL; }
1038 | ON UPDATE key_reference { $$ = NIL; }
1041 key_reference: NO ACTION { $$ = NULL; }
1042 | CASCADE { $$ = NULL; }
1043 | SET DEFAULT { $$ = NULL; }
1044 | SET NULL_P { $$ = NULL; }
1047 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1048 | /*EMPTY*/ { $$ = NIL; }
1052 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1053 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1055 OptArchiveType: ARCHIVE '=' NONE { }
1059 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1061 SelectStmt *n = (SelectStmt *)$6;
1063 mapTargetColumns($4, n->targetList);
1069 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1070 | /*EMPTY*/ { $$ = NULL; }
1073 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1074 | CreateAsElement { $$ = lcons($1, NIL); }
1077 CreateAsElement: ColId
1079 ColumnDef *n = makeNode(ColumnDef);
1083 n->is_not_null = FALSE;
1084 n->constraints = NULL;
1090 /*****************************************************************************
1093 * CREATE SEQUENCE seqname
1095 *****************************************************************************/
1097 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1099 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1107 OptSeqList OptSeqElem
1108 { $$ = lappend($1, $2); }
1112 OptSeqElem: IDENT NumConst
1114 $$ = makeNode(DefElem);
1116 $$->arg = (Node *)$2;
1120 $$ = makeNode(DefElem);
1122 $$->arg = (Node *)NULL;
1126 /*****************************************************************************
1129 * CREATE PROCEDURAL LANGUAGE ...
1130 * DROP PROCEDURAL LANGUAGE ...
1132 *****************************************************************************/
1134 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1135 HANDLER def_name LANCOMPILER Sconst
1137 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1146 PLangTrusted: TRUSTED { $$ = TRUE; }
1149 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1151 DropPLangStmt *n = makeNode(DropPLangStmt);
1157 /*****************************************************************************
1160 * CREATE TRIGGER ...
1163 *****************************************************************************/
1165 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1166 relation_name TriggerForSpec EXECUTE PROCEDURE
1167 name '(' TriggerFuncArgs ')'
1169 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1176 memcpy (n->actions, $5, 4);
1181 TriggerActionTime: BEFORE { $$ = TRUE; }
1182 | AFTER { $$ = FALSE; }
1185 TriggerEvents: TriggerOneEvent
1187 char *e = palloc (4);
1188 e[0] = $1; e[1] = 0; $$ = e;
1190 | TriggerOneEvent OR TriggerOneEvent
1192 char *e = palloc (4);
1193 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1195 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1197 char *e = palloc (4);
1198 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1203 TriggerOneEvent: INSERT { $$ = 'i'; }
1204 | DELETE { $$ = 'd'; }
1205 | UPDATE { $$ = 'u'; }
1208 TriggerForSpec: FOR TriggerForOpt TriggerForType
1214 TriggerForOpt: EACH { $$ = TRUE; }
1215 | /*EMPTY*/ { $$ = FALSE; }
1218 TriggerForType: ROW { $$ = TRUE; }
1219 | STATEMENT { $$ = FALSE; }
1222 TriggerFuncArgs: TriggerFuncArg
1223 { $$ = lcons($1, NIL); }
1224 | TriggerFuncArgs ',' TriggerFuncArg
1225 { $$ = lappend($1, $3); }
1230 TriggerFuncArg: ICONST
1232 char *s = (char *) palloc (256);
1233 sprintf (s, "%d", $1);
1238 char *s = (char *) palloc (256);
1239 sprintf (s, "%g", $1);
1242 | Sconst { $$ = $1; }
1243 | IDENT { $$ = $1; }
1246 DropTrigStmt: DROP TRIGGER name ON relation_name
1248 DropTrigStmt *n = makeNode(DropTrigStmt);
1256 /*****************************************************************************
1259 * define (type,operator,aggregate)
1261 *****************************************************************************/
1263 DefineStmt: CREATE def_type def_rest
1270 def_rest: def_name definition
1272 $$ = makeNode(DefineStmt);
1274 $$->definition = $2;
1278 def_type: OPERATOR { $$ = OPERATOR; }
1279 | TYPE_P { $$ = TYPE_P; }
1280 | AGGREGATE { $$ = AGGREGATE; }
1283 def_name: PROCEDURE { $$ = "procedure"; }
1284 | JOIN { $$ = "join"; }
1285 | ColId { $$ = $1; }
1286 | MathOp { $$ = $1; }
1290 definition: '(' def_list ')' { $$ = $2; }
1293 def_list: def_elem { $$ = lcons($1, NIL); }
1294 | def_list ',' def_elem { $$ = lappend($1, $3); }
1297 def_elem: def_name '=' def_arg
1299 $$ = makeNode(DefElem);
1301 $$->arg = (Node *)$3;
1305 $$ = makeNode(DefElem);
1307 $$->arg = (Node *)NULL;
1309 | DEFAULT '=' def_arg
1311 $$ = makeNode(DefElem);
1312 $$->defname = "default";
1313 $$->arg = (Node *)$3;
1317 def_arg: ColId { $$ = (Node *)makeString($1); }
1318 | all_Op { $$ = (Node *)makeString($1); }
1319 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1320 | Sconst { $$ = (Node *)makeString($1); }
1323 TypeName *n = makeNode(TypeName);
1326 n->arrayBounds = NULL;
1333 /*****************************************************************************
1336 * destroy <relname1> [, <relname2> .. <relnameN> ]
1338 *****************************************************************************/
1340 DestroyStmt: DROP TABLE relation_name_list
1342 DestroyStmt *n = makeNode(DestroyStmt);
1344 n->sequence = FALSE;
1347 | DROP SEQUENCE relation_name_list
1349 DestroyStmt *n = makeNode(DestroyStmt);
1357 /*****************************************************************************
1360 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1362 *****************************************************************************/
1364 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1366 FetchStmt *n = makeNode(FetchStmt);
1373 | MOVE opt_direction fetch_how_many opt_portal_name
1375 FetchStmt *n = makeNode(FetchStmt);
1384 opt_direction: FORWARD { $$ = FORWARD; }
1385 | BACKWARD { $$ = BACKWARD; }
1386 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1389 fetch_how_many: Iconst
1391 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1392 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1393 | /*EMPTY*/ { $$ = 1; /*default*/ }
1396 opt_portal_name: IN name { $$ = $2; }
1397 | /*EMPTY*/ { $$ = NULL; }
1401 /*****************************************************************************
1404 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1406 *****************************************************************************/
1408 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1410 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1414 privileges: ALL PRIVILEGES
1416 $$ = aclmakepriv("rwaR",0);
1420 $$ = aclmakepriv("rwaR",0);
1422 | operation_commalist
1428 operation_commalist: operation
1430 $$ = aclmakepriv("",$1);
1432 | operation_commalist ',' operation
1434 $$ = aclmakepriv($1,$3);
1440 $$ = ACL_MODE_RD_CHR;
1444 $$ = ACL_MODE_AP_CHR;
1448 $$ = ACL_MODE_WR_CHR;
1452 $$ = ACL_MODE_WR_CHR;
1456 $$ = ACL_MODE_RU_CHR;
1462 $$ = aclmakeuser("A","");
1466 $$ = aclmakeuser("G",$2);
1470 $$ = aclmakeuser("U",$1);
1474 opt_with_grant: WITH GRANT OPTION
1476 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1482 /*****************************************************************************
1485 * REVOKE [privileges] ON [relation_name] FROM [user]
1487 *****************************************************************************/
1489 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1491 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1496 /*****************************************************************************
1499 * create index <indexname> on <relname>
1500 * using <access> "(" (<col> with <op>)+ ")" [with
1503 * [where <qual>] is not supported anymore
1504 *****************************************************************************/
1506 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1507 access_method_clause '(' index_params ')' opt_with
1509 /* should check that access_method is valid,
1510 etc ... but doesn't */
1511 IndexStmt *n = makeNode(IndexStmt);
1515 n->accessMethod = $7;
1516 n->indexParams = $9;
1517 n->withClause = $11;
1518 n->whereClause = NULL;
1523 index_opt_unique: UNIQUE { $$ = TRUE; }
1524 | /*EMPTY*/ { $$ = FALSE; }
1527 access_method_clause: USING access_method { $$ = $2; }
1528 | /*EMPTY*/ { $$ = "btree"; }
1531 index_params: index_list { $$ = $1; }
1532 | func_index { $$ = lcons($1,NIL); }
1535 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1536 | index_elem { $$ = lcons($1, NIL); }
1539 func_index: func_name '(' name_list ')' opt_type opt_class
1541 $$ = makeNode(IndexElem);
1549 index_elem: attr_name opt_type opt_class
1551 $$ = makeNode(IndexElem);
1559 opt_type: ':' Typename { $$ = $2; }
1560 | FOR Typename { $$ = $2; }
1561 | /*EMPTY*/ { $$ = NULL; }
1564 /* opt_class "WITH class" conflicts with preceeding opt_type
1565 * for Typename of "TIMESTAMP WITH TIME ZONE"
1566 * So, remove "WITH class" from the syntax. OK??
1567 * - thomas 1997-10-12
1568 * | WITH class { $$ = $2; }
1570 opt_class: class { $$ = $1; }
1571 | USING class { $$ = $2; }
1572 | /*EMPTY*/ { $$ = NULL; }
1576 /*****************************************************************************
1579 * extend index <indexname> [where <qual>]
1581 *****************************************************************************/
1583 ExtendStmt: EXTEND INDEX index_name where_clause
1585 ExtendStmt *n = makeNode(ExtendStmt);
1587 n->whereClause = $4;
1593 /*****************************************************************************
1596 * execute recipe <recipeName>
1598 *****************************************************************************/
1600 RecipeStmt: EXECUTE RECIPE recipe_name
1603 if (!IsTransactionBlock())
1604 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1606 n = makeNode(RecipeStmt);
1613 /*****************************************************************************
1616 * define function <fname>
1617 * (language = <lang>, returntype = <typename>
1618 * [, arch_pct = <percentage | pre-defined>]
1619 * [, disk_pct = <percentage | pre-defined>]
1620 * [, byte_pct = <percentage | pre-defined>]
1621 * [, perbyte_cpu = <int | pre-defined>]
1622 * [, percall_cpu = <int | pre-defined>]
1624 * [arg is (<type-1> { , <type-n>})]
1625 * as <filename or code in language as appropriate>
1627 *****************************************************************************/
1629 ProcedureStmt: CREATE FUNCTION func_name func_args
1630 RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
1632 ProcedureStmt *n = makeNode(ProcedureStmt);
1642 opt_with: WITH definition { $$ = $2; }
1643 | /*EMPTY*/ { $$ = NIL; }
1646 func_args: '(' func_args_list ')' { $$ = $2; }
1647 | '(' ')' { $$ = NIL; }
1650 func_args_list: TypeId
1651 { $$ = lcons(makeString($1),NIL); }
1652 | func_args_list ',' TypeId
1653 { $$ = lappend($1,makeString($3)); }
1656 func_return: set_opt TypeId
1658 TypeName *n = makeNode(TypeName);
1661 n->arrayBounds = NULL;
1666 set_opt: SETOF { $$ = TRUE; }
1667 | /*EMPTY*/ { $$ = FALSE; }
1670 /*****************************************************************************
1674 * remove function <funcname>
1675 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1676 * remove aggregate <aggname>
1677 * (REMOVE AGGREGATE "aggname" "aggtype")
1678 * remove operator <opname>
1679 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1680 * remove type <typename>
1681 * (REMOVE TYPE "typename")
1682 * remove rule <rulename>
1683 * (REMOVE RULE "rulename")
1685 *****************************************************************************/
1687 RemoveStmt: DROP remove_type name
1689 RemoveStmt *n = makeNode(RemoveStmt);
1696 remove_type: TYPE_P { $$ = TYPE_P; }
1697 | INDEX { $$ = INDEX; }
1698 | RULE { $$ = RULE; }
1699 | VIEW { $$ = VIEW; }
1703 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1705 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1712 aggr_argtype: name { $$ = $1; }
1713 | '*' { $$ = NULL; }
1717 RemoveFuncStmt: DROP FUNCTION func_name func_args
1719 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1727 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1729 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1736 all_Op: Op | MathOp;
1738 MathOp: '+' { $$ = "+"; }
1749 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1752 { $$ = makeList(makeString($1), makeString($3), -1); }
1753 | NONE ',' name /* left unary */
1754 { $$ = makeList(NULL, makeString($3), -1); }
1755 | name ',' NONE /* right unary */
1756 { $$ = makeList(makeString($1), NULL, -1); }
1760 /*****************************************************************************
1763 * rename <attrname1> in <relname> [*] to <attrname2>
1764 * rename <relname1> to <relname2>
1766 *****************************************************************************/
1768 RenameStmt: ALTER TABLE relation_name opt_inh_star
1769 RENAME opt_column opt_name TO name
1771 RenameStmt *n = makeNode(RenameStmt);
1780 opt_name: name { $$ = $1; }
1781 | /*EMPTY*/ { $$ = NULL; }
1784 opt_column: COLUMN { $$ = COLUMN; }
1785 | /*EMPTY*/ { $$ = 0; }
1789 /*****************************************************************************
1791 * QUERY: Define Rewrite Rule , Define Tuple Rule
1792 * Define Rule <old rules >
1794 * only rewrite rule is supported -- ay 9/94
1796 *****************************************************************************/
1798 RuleStmt: CREATE RULE name AS
1799 { QueryIsRule=TRUE; }
1800 ON event TO event_object where_clause
1801 DO opt_instead OptStmtList
1803 RuleStmt *n = makeNode(RuleStmt);
1807 n->whereClause = $10;
1814 OptStmtList: NOTHING { $$ = NIL; }
1815 | OptimizableStmt { $$ = lcons($1, NIL); }
1816 | '[' OptStmtBlock ']' { $$ = $2; }
1819 OptStmtBlock: OptStmtMulti
1822 { $$ = lcons($1, NIL); }
1825 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1826 { $$ = lappend($1, $2); }
1827 | OptStmtMulti OptimizableStmt
1828 { $$ = lappend($1, $2); }
1829 | OptimizableStmt ';'
1830 { $$ = lcons($1, NIL); }
1833 event_object: relation_name '.' attr_name
1835 $$ = makeNode(Attr);
1838 $$->attrs = lcons(makeString($3), NIL);
1839 $$->indirection = NIL;
1843 $$ = makeNode(Attr);
1847 $$->indirection = NIL;
1851 /* change me to select, update, etc. some day */
1852 event: SELECT { $$ = CMD_SELECT; }
1853 | UPDATE { $$ = CMD_UPDATE; }
1854 | DELETE { $$ = CMD_DELETE; }
1855 | INSERT { $$ = CMD_INSERT; }
1858 opt_instead: INSTEAD { $$ = TRUE; }
1859 | /*EMPTY*/ { $$ = FALSE; }
1863 /*****************************************************************************
1866 * NOTIFY <relation_name> can appear both in rule bodies and
1867 * as a query-level command
1869 *****************************************************************************/
1871 NotifyStmt: NOTIFY relation_name
1873 NotifyStmt *n = makeNode(NotifyStmt);
1879 ListenStmt: LISTEN relation_name
1881 ListenStmt *n = makeNode(ListenStmt);
1888 /*****************************************************************************
1899 *****************************************************************************/
1901 TransactionStmt: ABORT_TRANS TRANSACTION
1903 TransactionStmt *n = makeNode(TransactionStmt);
1904 n->command = ABORT_TRANS;
1907 | BEGIN_TRANS TRANSACTION
1909 TransactionStmt *n = makeNode(TransactionStmt);
1910 n->command = BEGIN_TRANS;
1915 TransactionStmt *n = makeNode(TransactionStmt);
1916 n->command = BEGIN_TRANS;
1921 TransactionStmt *n = makeNode(TransactionStmt);
1922 n->command = END_TRANS;
1925 | END_TRANS TRANSACTION
1927 TransactionStmt *n = makeNode(TransactionStmt);
1928 n->command = END_TRANS;
1933 TransactionStmt *n = makeNode(TransactionStmt);
1934 n->command = ABORT_TRANS;
1940 TransactionStmt *n = makeNode(TransactionStmt);
1941 n->command = ABORT_TRANS;
1946 TransactionStmt *n = makeNode(TransactionStmt);
1947 n->command = BEGIN_TRANS;
1952 TransactionStmt *n = makeNode(TransactionStmt);
1953 n->command = END_TRANS;
1959 TransactionStmt *n = makeNode(TransactionStmt);
1960 n->command = END_TRANS;
1965 TransactionStmt *n = makeNode(TransactionStmt);
1966 n->command = ABORT_TRANS;
1972 /*****************************************************************************
1975 * define view <viewname> '('target-list ')' [where <quals> ]
1977 *****************************************************************************/
1979 ViewStmt: CREATE VIEW name AS SelectStmt
1981 ViewStmt *n = makeNode(ViewStmt);
1983 n->query = (Query *)$5;
1984 if (((SelectStmt *)n->query)->sortClause != NULL)
1985 elog(ERROR,"Order by and Distinct on views is not implemented.");
1986 if (((SelectStmt *)n->query)->unionClause != NULL)
1987 elog(ERROR,"Views on unions not implemented.");
1993 /*****************************************************************************
1998 *****************************************************************************/
2000 LoadStmt: LOAD file_name
2002 LoadStmt *n = makeNode(LoadStmt);
2009 /*****************************************************************************
2014 *****************************************************************************/
2016 CreatedbStmt: CREATE DATABASE database_name opt_database
2018 CreatedbStmt *n = makeNode(CreatedbStmt);
2025 opt_database: WITH LOCATION '=' location { $$ = $4; }
2026 | /*EMPTY*/ { $$ = NULL; }
2029 location: Sconst { $$ = $1; }
2030 | DEFAULT { $$ = NULL; }
2031 | /*EMPTY*/ { $$ = NULL; }
2034 /*****************************************************************************
2039 *****************************************************************************/
2041 DestroydbStmt: DROP DATABASE database_name
2043 DestroydbStmt *n = makeNode(DestroydbStmt);
2050 /*****************************************************************************
2053 * cluster <index_name> on <relation_name>
2055 *****************************************************************************/
2057 ClusterStmt: CLUSTER index_name ON relation_name
2059 ClusterStmt *n = makeNode(ClusterStmt);
2067 /*****************************************************************************
2072 *****************************************************************************/
2074 VacuumStmt: VACUUM opt_verbose opt_analyze
2076 VacuumStmt *n = makeNode(VacuumStmt);
2083 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2085 VacuumStmt *n = makeNode(VacuumStmt);
2090 if ( $5 != NIL && !$4 )
2091 elog(ERROR,"parser: syntax error at or near \"(\"");
2096 opt_verbose: VERBOSE { $$ = TRUE; }
2097 | /*EMPTY*/ { $$ = FALSE; }
2100 opt_analyze: ANALYZE { $$ = TRUE; }
2101 | /*EMPTY*/ { $$ = FALSE; }
2104 opt_va_list: '(' va_list ')'
2111 { $$=lcons($1,NIL); }
2113 { $$=lappend($1,$3); }
2117 /*****************************************************************************
2122 *****************************************************************************/
2124 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2126 ExplainStmt *n = makeNode(ExplainStmt);
2128 n->query = (Query*)$3;
2134 /*****************************************************************************
2136 * Optimizable Stmts: *
2138 * one of the five queries processed by the planner *
2140 * [ultimately] produces query-trees as specified *
2141 * in the query-spec document in ~postgres/ref *
2143 *****************************************************************************/
2145 OptimizableStmt: SelectStmt
2150 | DeleteStmt /* by default all are $$=$1 */
2154 /*****************************************************************************
2159 *****************************************************************************/
2161 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2169 insert_rest: VALUES '(' res_target_list2 ')'
2171 $$ = makeNode(InsertStmt);
2173 $$->targetList = $3;
2174 $$->fromClause = NIL;
2175 $$->whereClause = NULL;
2176 $$->groupClause = NIL;
2177 $$->havingClause = NULL;
2178 $$->unionClause = NIL;
2180 | SELECT opt_unique res_target_list2
2181 from_clause where_clause
2182 group_clause having_clause
2185 $$ = makeNode(InsertStmt);
2187 $$->targetList = $3;
2188 $$->fromClause = $4;
2189 $$->whereClause = $5;
2190 $$->groupClause = $6;
2191 $$->havingClause = $7;
2192 $$->unionClause = $8;
2196 opt_column_list: '(' columnList ')' { $$ = $2; }
2197 | /*EMPTY*/ { $$ = NIL; }
2201 columnList ',' columnElem
2202 { $$ = lappend($1, $3); }
2204 { $$ = lcons($1, NIL); }
2207 columnElem: ColId opt_indirection
2209 Ident *id = makeNode(Ident);
2211 id->indirection = $2;
2217 /*****************************************************************************
2222 *****************************************************************************/
2224 DeleteStmt: DELETE FROM relation_name
2227 DeleteStmt *n = makeNode(DeleteStmt);
2229 n->whereClause = $4;
2235 * Total hack to just lock a table inside a transaction.
2236 * Is it worth making this a separate command, with
2237 * its own node type and file. I don't think so. bjm 1998/1/22
2239 LockStmt: LOCK_P relation_name
2241 DeleteStmt *n = makeNode(DeleteStmt);
2242 A_Const *c = makeNode(A_Const);
2244 c->val.type = T_String;
2245 c->val.val.str = "f";
2246 c->typename = makeNode(TypeName);
2247 c->typename->name = xlateSqlType("bool");
2248 c->typename->typmod = -1;
2251 n->whereClause = (Node *)c;
2257 /*****************************************************************************
2260 * UpdateStmt (UPDATE)
2262 *****************************************************************************/
2264 UpdateStmt: UPDATE relation_name
2269 UpdateStmt *n = makeNode(UpdateStmt);
2273 n->whereClause = $6;
2279 /*****************************************************************************
2284 *****************************************************************************/
2285 CursorStmt: DECLARE name opt_binary CURSOR FOR
2286 SELECT opt_unique res_target_list2
2287 from_clause where_clause
2288 group_clause having_clause
2289 union_clause sort_clause
2291 SelectStmt *n = makeNode(SelectStmt);
2293 /* from PORTAL name */
2295 * 15 august 1991 -- since 3.0 postgres does locking
2296 * right, we discovered that portals were violating
2297 * locking protocol. portal locks cannot span xacts.
2298 * as a short-term fix, we installed the check here.
2301 if (!IsTransactionBlock())
2302 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2309 n->whereClause = $10;
2310 n->groupClause = $11;
2311 n->havingClause = $12;
2312 n->unionClause = $13;
2313 n->sortClause = $14;
2319 /*****************************************************************************
2324 *****************************************************************************/
2326 SelectStmt: SELECT opt_unique res_target_list2
2327 result from_clause where_clause
2328 group_clause having_clause
2329 union_clause sort_clause
2331 SelectStmt *n = makeNode(SelectStmt);
2336 n->whereClause = $6;
2337 n->groupClause = $7;
2338 n->havingClause = $8;
2339 n->unionClause = $9;
2340 n->sortClause = $10;
2345 union_clause: UNION opt_union select_list
2347 SelectStmt *n = (SelectStmt *)lfirst($3);
2355 select_list: select_list UNION opt_union SubSelect
2357 SelectStmt *n = (SelectStmt *)$4;
2359 $$ = lappend($1, $4);
2362 { $$ = lcons($1, NIL); }
2365 SubSelect: SELECT opt_unique res_target_list2
2366 from_clause where_clause
2367 group_clause having_clause
2369 SelectStmt *n = makeNode(SelectStmt);
2371 n->unionall = FALSE;
2374 n->whereClause = $5;
2375 n->groupClause = $6;
2376 n->havingClause = $7;
2381 result: INTO TABLE relation_name
2387 opt_union: ALL { $$ = TRUE; }
2388 | /*EMPTY*/ { $$ = FALSE; }
2391 opt_unique: DISTINCT { $$ = "*"; }
2392 | DISTINCT ON ColId { $$ = $3; }
2393 | ALL { $$ = NULL; }
2394 | /*EMPTY*/ { $$ = NULL; }
2397 sort_clause: ORDER BY sortby_list { $$ = $3; }
2398 | /*EMPTY*/ { $$ = NIL; }
2401 sortby_list: sortby { $$ = lcons($1, NIL); }
2402 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2405 sortby: ColId OptUseOp
2407 $$ = makeNode(SortGroupBy);
2413 | ColId '.' ColId OptUseOp
2415 $$ = makeNode(SortGroupBy);
2423 $$ = makeNode(SortGroupBy);
2431 OptUseOp: USING Op { $$ = $2; }
2432 | USING '<' { $$ = "<"; }
2433 | USING '>' { $$ = ">"; }
2435 | DESC { $$ = ">"; }
2436 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2440 * jimmy bell-style recursive queries aren't supported in the
2443 * ...however, recursive addattr and rename supported. make special
2446 opt_inh_star: '*' { $$ = TRUE; }
2447 | /*EMPTY*/ { $$ = FALSE; }
2450 relation_name_list: name_list;
2453 { $$ = lcons(makeString($1),NIL); }
2454 | name_list ',' name
2455 { $$ = lappend($1,makeString($3)); }
2458 group_clause: GROUP BY groupby_list { $$ = $3; }
2459 | /*EMPTY*/ { $$ = NIL; }
2462 groupby_list: groupby { $$ = lcons($1, NIL); }
2463 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2468 $$ = makeNode(SortGroupBy);
2476 $$ = makeNode(SortGroupBy);
2484 $$ = makeNode(SortGroupBy);
2492 having_clause: HAVING a_expr
2494 elog(NOTICE, "HAVING not yet supported; ignore clause");
2497 | /*EMPTY*/ { $$ = NULL; }
2501 /*****************************************************************************
2503 * clauses common to all Optimizable Stmts:
2507 *****************************************************************************/
2509 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2512 elog(ERROR,"JOIN not yet implemented");
2514 | FROM from_list { $$ = $2; }
2515 | /*EMPTY*/ { $$ = NIL; }
2518 from_list: from_list ',' from_val
2519 { $$ = lappend($1, $3); }
2520 | from_val CROSS JOIN from_val
2521 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2523 { $$ = lcons($1, NIL); }
2526 from_val: relation_expr AS ColLabel
2528 $$ = makeNode(RangeVar);
2532 | relation_expr ColId
2534 $$ = makeNode(RangeVar);
2540 $$ = makeNode(RangeVar);
2546 join_expr: NATURAL join_expr { $$ = NULL; }
2548 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2550 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2552 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2554 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2556 { elog(ERROR,"INNER JOIN not yet implemented"); }
2558 { elog(ERROR,"UNION JOIN not yet implemented"); }
2560 { elog(ERROR,"INNER JOIN not yet implemented"); }
2563 join_outer: OUTER_P { $$ = NULL; }
2564 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2567 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2568 | USING '(' join_list ')' { $$ = NULL; }
2569 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2572 join_list: join_using { $$ = lcons($1, NIL); }
2573 | join_list ',' join_using { $$ = lappend($1, $3); }
2578 $$ = makeNode(SortGroupBy);
2586 $$ = makeNode(SortGroupBy);
2594 $$ = makeNode(SortGroupBy);
2602 where_clause: WHERE a_expr { $$ = $2; }
2603 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2606 relation_expr: relation_name
2608 /* normal relations */
2609 $$ = makeNode(RelExpr);
2613 | relation_name '*' %prec '='
2615 /* inheritance query */
2616 $$ = makeNode(RelExpr);
2621 opt_array_bounds: '[' ']' nest_array_bounds
2622 { $$ = lcons(makeInteger(-1), $3); }
2623 | '[' Iconst ']' nest_array_bounds
2624 { $$ = lcons(makeInteger($2), $4); }
2629 nest_array_bounds: '[' ']' nest_array_bounds
2630 { $$ = lcons(makeInteger(-1), $3); }
2631 | '[' Iconst ']' nest_array_bounds
2632 { $$ = lcons(makeInteger($2), $4); }
2638 /*****************************************************************************
2641 * SQL92 introduces a large amount of type-specific syntax.
2642 * Define individual clauses to handle these cases, and use
2643 * the generic case to handle regular type-extensible Postgres syntax.
2644 * - thomas 1997-10-10
2646 *****************************************************************************/
2648 Typename: Array opt_array_bounds
2651 $$->arrayBounds = $2;
2653 /* Is this the name of a complex type? If so, implement
2656 if (!strcmp(saved_relname, $$->name))
2657 /* This attr is the same type as the relation
2658 * being defined. The classic example: create
2659 * emp(name=text,mgr=emp)
2662 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2663 /* (Eventually add in here that the set can only
2664 * contain one element.)
2685 $$ = makeNode(TypeName);
2686 $$->name = xlateSqlType($1);
2691 generic: IDENT { $$ = $1; }
2692 | TYPE_P { $$ = xlateSqlType("type"); }
2695 /* SQL92 numeric data types
2696 * Check FLOAT() precision limits assuming IEEE floating types.
2697 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2698 * by checking parameters and making sure they match what is possible with INTEGER.
2699 * - thomas 1997-09-18
2701 Numeric: FLOAT opt_float
2703 $$ = makeNode(TypeName);
2704 $$->name = xlateSqlType($2);
2709 $$ = makeNode(TypeName);
2710 $$->name = xlateSqlType("float");
2712 | DECIMAL opt_decimal
2714 $$ = makeNode(TypeName);
2715 $$->name = xlateSqlType("integer");
2718 | NUMERIC opt_numeric
2720 $$ = makeNode(TypeName);
2721 $$->name = xlateSqlType("integer");
2727 { $$ = xlateSqlType("float8"); }
2729 { $$ = xlateSqlType("float8"); }
2731 { $$ = xlateSqlType("decimal"); }
2733 { $$ = xlateSqlType("numeric"); }
2736 opt_float: '(' Iconst ')'
2739 elog(ERROR,"precision for FLOAT must be at least 1");
2741 $$ = xlateSqlType("float4");
2743 $$ = xlateSqlType("float8");
2745 elog(ERROR,"precision for FLOAT must be less than 16");
2749 $$ = xlateSqlType("float8");
2753 opt_numeric: '(' Iconst ',' Iconst ')'
2756 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2758 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2763 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2771 opt_decimal: '(' Iconst ',' Iconst ')'
2774 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2776 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2782 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2791 /* SQL92 character data types
2792 * The following implements CHAR() and VARCHAR().
2793 * We do it here instead of the 'Generic' production
2794 * because we don't want to allow arrays of VARCHAR().
2795 * I haven't thought about whether that will work or not.
2798 Character: character '(' Iconst ')'
2800 $$ = makeNode(TypeName);
2801 if (!strcasecmp($1, "char"))
2802 $$->name = xlateSqlType("bpchar");
2803 else if (!strcasecmp($1, "varchar"))
2804 $$->name = xlateSqlType("varchar");
2806 yyerror("parse error");
2808 elog(ERROR,"length for '%s' type must be at least 1",$1);
2810 /* we can store a char() of length up to the size
2811 * of a page (8KB) - page headers and friends but
2812 * just to be safe here... - ay 6/95
2813 * XXX note this hardcoded limit - thomas 1997-07-13
2815 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2817 /* we actually implement this sort of like a varlen, so
2818 * the first 4 bytes is the length. (the difference
2819 * between this and "text" is that we blank-pad and
2820 * truncate where necessary
2822 $$->typmod = VARHDRSZ + $3;
2826 $$ = makeNode(TypeName);
2827 $$->name = xlateSqlType($1);
2832 character: CHARACTER opt_varying opt_charset opt_collate
2835 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2836 if ($2) type = xlateSqlType("varchar");
2837 else type = xlateSqlType("char");
2840 c = palloc(strlen("var") + strlen($3) + 1);
2843 type = xlateSqlType(c);
2845 type = xlateSqlType($3);
2849 elog(ERROR,"COLLATE %s not yet implemented",$4);
2852 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2853 | VARCHAR { $$ = xlateSqlType("varchar"); }
2854 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2855 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2858 opt_varying: VARYING { $$ = TRUE; }
2859 | /*EMPTY*/ { $$ = FALSE; }
2862 opt_charset: CHARACTER SET ColId { $$ = $3; }
2863 | /*EMPTY*/ { $$ = NULL; }
2866 opt_collate: COLLATE ColId { $$ = $2; }
2867 | /*EMPTY*/ { $$ = NULL; }
2872 $$ = makeNode(TypeName);
2873 $$->name = xlateSqlType($1);
2876 | TIMESTAMP opt_timezone
2878 $$ = makeNode(TypeName);
2879 $$->name = xlateSqlType("timestamp");
2885 $$ = makeNode(TypeName);
2886 $$->name = xlateSqlType("time");
2889 | INTERVAL opt_interval
2891 $$ = makeNode(TypeName);
2892 $$->name = xlateSqlType("interval");
2897 datetime: YEAR_P { $$ = "year"; }
2898 | MONTH_P { $$ = "month"; }
2899 | DAY_P { $$ = "day"; }
2900 | HOUR_P { $$ = "hour"; }
2901 | MINUTE_P { $$ = "minute"; }
2902 | SECOND_P { $$ = "second"; }
2905 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2906 | /*EMPTY*/ { $$ = FALSE; }
2909 opt_interval: datetime { $$ = lcons($1, NIL); }
2910 | YEAR_P TO MONTH_P { $$ = NIL; }
2911 | DAY_P TO HOUR_P { $$ = NIL; }
2912 | DAY_P TO MINUTE_P { $$ = NIL; }
2913 | DAY_P TO SECOND_P { $$ = NIL; }
2914 | HOUR_P TO MINUTE_P { $$ = NIL; }
2915 | HOUR_P TO SECOND_P { $$ = NIL; }
2916 | /*EMPTY*/ { $$ = NIL; }
2920 /*****************************************************************************
2922 * expression grammar, still needs some cleanup
2924 *****************************************************************************/
2926 a_expr_or_null: a_expr
2930 A_Const *n = makeNode(A_Const);
2931 n->val.type = T_Null;
2936 /* Expressions using row descriptors
2937 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2938 * with singleton expressions.
2940 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2942 SubLink *n = makeNode(SubLink);
2944 n->oper = lcons("=",NIL);
2946 n->subLinkType = ANY_SUBLINK;
2950 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
2952 SubLink *n = makeNode(SubLink);
2954 n->oper = lcons("<>",NIL);
2956 n->subLinkType = ALL_SUBLINK;
2960 | '(' row_descriptor ')' Op '(' SubSelect ')'
2962 SubLink *n = makeNode(SubLink);
2964 n->oper = lcons($4, NIL);
2965 if (strcmp($4,"<>") == 0)
2969 n->subLinkType = EXPR_SUBLINK;
2973 | '(' row_descriptor ')' '+' '(' SubSelect ')'
2975 SubLink *n = makeNode(SubLink);
2977 n->oper = lcons("+", NIL);
2979 n->subLinkType = EXPR_SUBLINK;
2983 | '(' row_descriptor ')' '-' '(' SubSelect ')'
2985 SubLink *n = makeNode(SubLink);
2987 n->oper = lcons("-", NIL);
2989 n->subLinkType = EXPR_SUBLINK;
2993 | '(' row_descriptor ')' '/' '(' SubSelect ')'
2995 SubLink *n = makeNode(SubLink);
2997 n->oper = lcons("/", NIL);
2999 n->subLinkType = EXPR_SUBLINK;
3003 | '(' row_descriptor ')' '*' '(' SubSelect ')'
3005 SubLink *n = makeNode(SubLink);
3007 n->oper = lcons("*", NIL);
3009 n->subLinkType = EXPR_SUBLINK;
3013 | '(' row_descriptor ')' '<' '(' SubSelect ')'
3015 SubLink *n = makeNode(SubLink);
3017 n->oper = lcons("<", NIL);
3019 n->subLinkType = EXPR_SUBLINK;
3023 | '(' row_descriptor ')' '>' '(' SubSelect ')'
3025 SubLink *n = makeNode(SubLink);
3027 n->oper = lcons(">", NIL);
3029 n->subLinkType = EXPR_SUBLINK;
3033 | '(' row_descriptor ')' '=' '(' SubSelect ')'
3035 SubLink *n = makeNode(SubLink);
3037 n->oper = lcons("=", NIL);
3039 n->subLinkType = EXPR_SUBLINK;
3043 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
3045 SubLink *n = makeNode(SubLink);
3047 n->oper = lcons($4,NIL);
3048 if (strcmp($4,"<>") == 0)
3052 n->subLinkType = ANY_SUBLINK;
3056 | '(' row_descriptor ')' '+' ANY '(' SubSelect ')'
3058 SubLink *n = makeNode(SubLink);
3060 n->oper = lcons("+",NIL);
3062 n->subLinkType = ANY_SUBLINK;
3066 | '(' row_descriptor ')' '-' ANY '(' SubSelect ')'
3068 SubLink *n = makeNode(SubLink);
3070 n->oper = lcons("-",NIL);
3072 n->subLinkType = ANY_SUBLINK;
3076 | '(' row_descriptor ')' '/' ANY '(' SubSelect ')'
3078 SubLink *n = makeNode(SubLink);
3080 n->oper = lcons("/",NIL);
3082 n->subLinkType = ANY_SUBLINK;
3086 | '(' row_descriptor ')' '*' ANY '(' SubSelect ')'
3088 SubLink *n = makeNode(SubLink);
3090 n->oper = lcons("*",NIL);
3092 n->subLinkType = ANY_SUBLINK;
3096 | '(' row_descriptor ')' '<' ANY '(' SubSelect ')'
3098 SubLink *n = makeNode(SubLink);
3100 n->oper = lcons("<",NIL);
3102 n->subLinkType = ANY_SUBLINK;
3106 | '(' row_descriptor ')' '>' ANY '(' SubSelect ')'
3108 SubLink *n = makeNode(SubLink);
3110 n->oper = lcons(">",NIL);
3112 n->subLinkType = ANY_SUBLINK;
3116 | '(' row_descriptor ')' '=' ANY '(' SubSelect ')'
3118 SubLink *n = makeNode(SubLink);
3120 n->oper = lcons("=",NIL);
3122 n->subLinkType = ANY_SUBLINK;
3126 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
3128 SubLink *n = makeNode(SubLink);
3130 n->oper = lcons($4,NIL);
3131 if (strcmp($4,"<>") == 0)
3135 n->subLinkType = ALL_SUBLINK;
3139 | '(' row_descriptor ')' '+' ALL '(' SubSelect ')'
3141 SubLink *n = makeNode(SubLink);
3143 n->oper = lcons("+",NIL);
3145 n->subLinkType = ALL_SUBLINK;
3149 | '(' row_descriptor ')' '-' ALL '(' SubSelect ')'
3151 SubLink *n = makeNode(SubLink);
3153 n->oper = lcons("-",NIL);
3155 n->subLinkType = ALL_SUBLINK;
3159 | '(' row_descriptor ')' '/' ALL '(' SubSelect ')'
3161 SubLink *n = makeNode(SubLink);
3163 n->oper = lcons("/",NIL);
3165 n->subLinkType = ALL_SUBLINK;
3169 | '(' row_descriptor ')' '*' ALL '(' SubSelect ')'
3171 SubLink *n = makeNode(SubLink);
3173 n->oper = lcons("*",NIL);
3175 n->subLinkType = ALL_SUBLINK;
3179 | '(' row_descriptor ')' '<' ALL '(' SubSelect ')'
3181 SubLink *n = makeNode(SubLink);
3183 n->oper = lcons("<",NIL);
3185 n->subLinkType = ALL_SUBLINK;
3189 | '(' row_descriptor ')' '>' ALL '(' SubSelect ')'
3191 SubLink *n = makeNode(SubLink);
3193 n->oper = lcons(">",NIL);
3195 n->subLinkType = ALL_SUBLINK;
3199 | '(' row_descriptor ')' '=' ALL '(' SubSelect ')'
3201 SubLink *n = makeNode(SubLink);
3203 n->oper = lcons("=",NIL);
3205 n->subLinkType = ALL_SUBLINK;
3209 | '(' row_descriptor ')' Op '(' row_descriptor ')'
3211 $$ = makeRowExpr($4, $2, $6);
3213 | '(' row_descriptor ')' '+' '(' row_descriptor ')'
3215 $$ = makeRowExpr("+", $2, $6);
3217 | '(' row_descriptor ')' '-' '(' row_descriptor ')'
3219 $$ = makeRowExpr("-", $2, $6);
3221 | '(' row_descriptor ')' '/' '(' row_descriptor ')'
3223 $$ = makeRowExpr("/", $2, $6);
3225 | '(' row_descriptor ')' '*' '(' row_descriptor ')'
3227 $$ = makeRowExpr("*", $2, $6);
3229 | '(' row_descriptor ')' '<' '(' row_descriptor ')'
3231 $$ = makeRowExpr("<", $2, $6);
3233 | '(' row_descriptor ')' '>' '(' row_descriptor ')'
3235 $$ = makeRowExpr(">", $2, $6);
3237 | '(' row_descriptor ')' '=' '(' row_descriptor ')'
3239 $$ = makeRowExpr("=", $2, $6);
3243 row_descriptor: row_list ',' a_expr
3245 $$ = lappend($1, $3);
3249 row_list: row_list ',' a_expr
3251 $$ = lappend($1, $3);
3255 $$ = lcons($1, NIL);
3260 * This is the heart of the expression syntax.
3261 * Note that the BETWEEN clause looks similar to a boolean expression
3262 * and so we must define b_expr which is almost the same as a_expr
3263 * but without the boolean expressions.
3264 * All operations are allowed in a BETWEEN clause if surrounded by parens.
3267 a_expr: attr opt_indirection
3269 $1->indirection = $2;
3278 /* could be a column name or a relation_name */
3279 Ident *n = makeNode(Ident);
3281 n->indirection = NULL;
3284 | '-' a_expr %prec UMINUS
3285 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3287 { $$ = makeA_Expr(OP, "+", $1, $3); }
3289 { $$ = makeA_Expr(OP, "-", $1, $3); }
3291 { $$ = makeA_Expr(OP, "/", $1, $3); }
3293 { $$ = makeA_Expr(OP, "*", $1, $3); }
3295 { $$ = makeA_Expr(OP, "<", $1, $3); }
3297 { $$ = makeA_Expr(OP, ">", $1, $3); }
3299 { $$ = makeA_Expr(OP, "=", $1, $3); }
3301 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3303 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3305 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3306 | a_expr TYPECAST Typename
3309 /* AexprConst can be either A_Const or ParamNo */
3310 if (nodeTag($1) == T_A_Const) {
3311 ((A_Const *)$1)->typename = $3;
3312 } else if (nodeTag($1) == T_Param) {
3313 ((ParamNo *)$1)->typename = $3;
3314 /* otherwise, try to transform to a function call */
3316 FuncCall *n = makeNode(FuncCall);
3317 n->funcname = $3->name;
3318 n->args = lcons($1,NIL);
3322 | CAST '(' a_expr AS Typename ')'
3325 /* AexprConst can be either A_Const or ParamNo */
3326 if (nodeTag($3) == T_A_Const) {
3327 ((A_Const *)$3)->typename = $5;
3328 } else if (nodeTag($5) == T_Param) {
3329 ((ParamNo *)$3)->typename = $5;
3330 /* otherwise, try to transform to a function call */
3332 FuncCall *n = makeNode(FuncCall);
3333 n->funcname = $5->name;
3334 n->args = lcons($3,NIL);
3338 | '(' a_expr_or_null ')'
3341 { $$ = makeIndexable($2,$1,$3); }
3342 | a_expr LIKE a_expr
3343 { $$ = makeIndexable("~~", $1, $3); }
3344 | a_expr NOT LIKE a_expr
3345 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3347 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3349 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3350 | func_name '(' '*' ')'
3352 /* cheap hack for aggregate (eg. count) */
3353 FuncCall *n = makeNode(FuncCall);
3354 A_Const *star = makeNode(A_Const);
3356 star->val.type = T_String;
3357 star->val.val.str = "";
3359 n->args = lcons(star, NIL);
3364 FuncCall *n = makeNode(FuncCall);
3369 | func_name '(' expr_list ')'
3371 FuncCall *n = makeNode(FuncCall);
3378 A_Const *n = makeNode(A_Const);
3379 TypeName *t = makeNode(TypeName);
3381 n->val.type = T_String;
3382 n->val.val.str = "now";
3385 t->name = xlateSqlType("date");
3393 A_Const *n = makeNode(A_Const);
3394 TypeName *t = makeNode(TypeName);
3396 n->val.type = T_String;
3397 n->val.val.str = "now";
3400 t->name = xlateSqlType("time");
3406 | CURRENT_TIME '(' Iconst ')'
3408 FuncCall *n = makeNode(FuncCall);
3409 A_Const *s = makeNode(A_Const);
3410 TypeName *t = makeNode(TypeName);
3412 n->funcname = xlateSqlType("time");
3413 n->args = lcons(s, NIL);
3415 s->val.type = T_String;
3416 s->val.val.str = "now";
3419 t->name = xlateSqlType("time");
3424 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3430 A_Const *n = makeNode(A_Const);
3431 TypeName *t = makeNode(TypeName);
3433 n->val.type = T_String;
3434 n->val.val.str = "now";
3437 t->name = xlateSqlType("timestamp");
3443 | CURRENT_TIMESTAMP '(' Iconst ')'
3445 FuncCall *n = makeNode(FuncCall);
3446 A_Const *s = makeNode(A_Const);
3447 TypeName *t = makeNode(TypeName);
3449 n->funcname = xlateSqlType("timestamp");
3450 n->args = lcons(s, NIL);
3452 s->val.type = T_String;
3453 s->val.val.str = "now";
3456 t->name = xlateSqlType("timestamp");
3461 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3467 FuncCall *n = makeNode(FuncCall);
3468 n->funcname = "getpgusername";
3472 | EXISTS '(' SubSelect ')'
3474 SubLink *n = makeNode(SubLink);
3478 n->subLinkType = EXISTS_SUBLINK;
3482 | EXTRACT '(' extract_list ')'
3484 FuncCall *n = makeNode(FuncCall);
3485 n->funcname = "date_part";
3489 | POSITION '(' position_list ')'
3491 FuncCall *n = makeNode(FuncCall);
3492 n->funcname = "strpos";
3496 | SUBSTRING '(' substr_list ')'
3498 FuncCall *n = makeNode(FuncCall);
3499 n->funcname = "substr";
3503 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3504 | TRIM '(' BOTH trim_list ')'
3506 FuncCall *n = makeNode(FuncCall);
3507 n->funcname = "btrim";
3511 | TRIM '(' LEADING trim_list ')'
3513 FuncCall *n = makeNode(FuncCall);
3514 n->funcname = "ltrim";
3518 | TRIM '(' TRAILING trim_list ')'
3520 FuncCall *n = makeNode(FuncCall);
3521 n->funcname = "rtrim";
3525 | TRIM '(' trim_list ')'
3527 FuncCall *n = makeNode(FuncCall);
3528 n->funcname = "btrim";
3533 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3535 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3537 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3538 | a_expr IS NOT NULL_P
3539 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3540 /* IS TRUE, IS FALSE, etc used to be function calls
3541 * but let's make them expressions to allow the optimizer
3542 * a chance to eliminate them if a_expr is a constant string.
3543 * - thomas 1997-12-22
3547 A_Const *n = makeNode(A_Const);
3548 n->val.type = T_String;
3549 n->val.val.str = "t";
3550 n->typename = makeNode(TypeName);
3551 n->typename->name = xlateSqlType("bool");
3552 n->typename->typmod = -1;
3553 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3555 | a_expr IS NOT FALSE_P
3557 A_Const *n = makeNode(A_Const);
3558 n->val.type = T_String;
3559 n->val.val.str = "t";
3560 n->typename = makeNode(TypeName);
3561 n->typename->name = xlateSqlType("bool");
3562 n->typename->typmod = -1;
3563 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3567 A_Const *n = makeNode(A_Const);
3568 n->val.type = T_String;
3569 n->val.val.str = "f";
3570 n->typename = makeNode(TypeName);
3571 n->typename->name = xlateSqlType("bool");
3572 n->typename->typmod = -1;
3573 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3575 | a_expr IS NOT TRUE_P
3577 A_Const *n = makeNode(A_Const);
3578 n->val.type = T_String;
3579 n->val.val.str = "f";
3580 n->typename = makeNode(TypeName);
3581 n->typename->name = xlateSqlType("bool");
3582 n->typename->typmod = -1;
3583 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3585 | a_expr BETWEEN b_expr AND b_expr
3587 $$ = makeA_Expr(AND, NULL,
3588 makeA_Expr(OP, ">=", $1, $3),
3589 makeA_Expr(OP, "<=", $1, $5));
3591 | a_expr NOT BETWEEN b_expr AND b_expr
3593 $$ = makeA_Expr(OR, NULL,
3594 makeA_Expr(OP, "<", $1, $4),
3595 makeA_Expr(OP, ">", $1, $6));
3597 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')'
3599 saved_In_Expr = lnext(saved_In_Expr);
3600 if (nodeTag($5) == T_SubLink)
3602 SubLink *n = (SubLink *)$5;
3603 n->lefthand = lcons($1, NIL);
3604 n->oper = lcons("=",NIL);
3606 n->subLinkType = ANY_SUBLINK;
3611 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')'
3613 saved_In_Expr = lnext(saved_In_Expr);
3614 if (nodeTag($6) == T_SubLink)
3616 SubLink *n = (SubLink *)$6;
3617 n->lefthand = lcons($1, NIL);
3618 n->oper = lcons("<>",NIL);
3620 n->subLinkType = ALL_SUBLINK;
3625 | a_expr Op '(' SubSelect ')'
3627 SubLink *n = makeNode(SubLink);
3628 n->lefthand = lcons($1, NULL);
3629 n->oper = lcons($2,NIL);
3631 n->subLinkType = EXPR_SUBLINK;
3635 | a_expr '+' '(' SubSelect ')'
3637 SubLink *n = makeNode(SubLink);
3638 n->lefthand = lcons($1, NULL);
3639 n->oper = lcons("+",NIL);
3641 n->subLinkType = EXPR_SUBLINK;
3645 | a_expr '-' '(' SubSelect ')'
3647 SubLink *n = makeNode(SubLink);
3648 n->lefthand = lcons($1, NULL);
3649 n->oper = lcons("-",NIL);
3651 n->subLinkType = EXPR_SUBLINK;
3655 | a_expr '/' '(' SubSelect ')'
3657 SubLink *n = makeNode(SubLink);
3658 n->lefthand = lcons($1, NULL);
3659 n->oper = lcons("/",NIL);
3661 n->subLinkType = EXPR_SUBLINK;
3665 | a_expr '*' '(' SubSelect ')'
3667 SubLink *n = makeNode(SubLink);
3668 n->lefthand = lcons($1, NULL);
3669 n->oper = lcons("*",NIL);
3671 n->subLinkType = EXPR_SUBLINK;
3675 | a_expr '<' '(' SubSelect ')'
3677 SubLink *n = makeNode(SubLink);
3678 n->lefthand = lcons($1, NULL);
3679 n->oper = lcons("<",NIL);
3681 n->subLinkType = EXPR_SUBLINK;
3685 | a_expr '>' '(' SubSelect ')'
3687 SubLink *n = makeNode(SubLink);
3688 n->lefthand = lcons($1, NULL);
3689 n->oper = lcons(">",NIL);
3691 n->subLinkType = EXPR_SUBLINK;
3695 | a_expr '=' '(' SubSelect ')'
3697 SubLink *n = makeNode(SubLink);
3698 n->lefthand = lcons($1, NULL);
3699 n->oper = lcons("=",NIL);
3701 n->subLinkType = EXPR_SUBLINK;
3705 | a_expr Op ANY '(' SubSelect ')'
3707 SubLink *n = makeNode(SubLink);
3708 n->lefthand = lcons($1,NIL);
3709 n->oper = lcons($2,NIL);
3711 n->subLinkType = ANY_SUBLINK;
3715 | a_expr '+' ANY '(' SubSelect ')'
3717 SubLink *n = makeNode(SubLink);
3718 n->lefthand = lcons($1,NIL);
3719 n->oper = lcons("+",NIL);
3721 n->subLinkType = ANY_SUBLINK;
3725 | a_expr '-' ANY '(' SubSelect ')'
3727 SubLink *n = makeNode(SubLink);
3728 n->lefthand = lcons($1,NIL);
3729 n->oper = lcons("-",NIL);
3731 n->subLinkType = ANY_SUBLINK;
3735 | a_expr '/' ANY '(' SubSelect ')'
3737 SubLink *n = makeNode(SubLink);
3738 n->lefthand = lcons($1,NIL);
3739 n->oper = lcons("/",NIL);
3741 n->subLinkType = ANY_SUBLINK;
3745 | a_expr '*' ANY '(' SubSelect ')'
3747 SubLink *n = makeNode(SubLink);
3748 n->lefthand = lcons($1,NIL);
3749 n->oper = lcons("*",NIL);
3751 n->subLinkType = ANY_SUBLINK;
3755 | a_expr '<' ANY '(' SubSelect ')'
3757 SubLink *n = makeNode(SubLink);
3758 n->lefthand = lcons($1,NIL);
3759 n->oper = lcons("<",NIL);
3761 n->subLinkType = ANY_SUBLINK;
3765 | a_expr '>' ANY '(' SubSelect ')'
3767 SubLink *n = makeNode(SubLink);
3768 n->lefthand = lcons($1,NIL);
3769 n->oper = lcons(">",NIL);
3771 n->subLinkType = ANY_SUBLINK;
3775 | a_expr '=' ANY '(' SubSelect ')'
3777 SubLink *n = makeNode(SubLink);
3778 n->lefthand = lcons($1,NIL);
3779 n->oper = lcons("=",NIL);
3781 n->subLinkType = ANY_SUBLINK;
3785 | a_expr Op ALL '(' SubSelect ')'
3787 SubLink *n = makeNode(SubLink);
3788 n->lefthand = lcons($1, NULL);
3789 n->oper = lcons($2,NIL);
3791 n->subLinkType = ALL_SUBLINK;
3795 | a_expr '+' ALL '(' SubSelect ')'
3797 SubLink *n = makeNode(SubLink);
3798 n->lefthand = lcons($1, NULL);
3799 n->oper = lcons("+",NIL);
3801 n->subLinkType = ALL_SUBLINK;
3805 | a_expr '-' ALL '(' SubSelect ')'
3807 SubLink *n = makeNode(SubLink);
3808 n->lefthand = lcons($1, NULL);
3809 n->oper = lcons("-",NIL);
3811 n->subLinkType = ALL_SUBLINK;
3815 | a_expr '/' ALL '(' SubSelect ')'
3817 SubLink *n = makeNode(SubLink);
3818 n->lefthand = lcons($1, NULL);
3819 n->oper = lcons("/",NIL);
3821 n->subLinkType = ALL_SUBLINK;
3825 | a_expr '*' ALL '(' SubSelect ')'
3827 SubLink *n = makeNode(SubLink);
3828 n->lefthand = lcons($1, NULL);
3829 n->oper = lcons("*",NIL);
3831 n->subLinkType = ALL_SUBLINK;
3835 | a_expr '<' ALL '(' SubSelect ')'
3837 SubLink *n = makeNode(SubLink);
3838 n->lefthand = lcons($1, NULL);
3839 n->oper = lcons("<",NIL);
3841 n->subLinkType = ALL_SUBLINK;
3845 | a_expr '>' ALL '(' SubSelect ')'
3847 SubLink *n = makeNode(SubLink);
3848 n->lefthand = lcons($1, NULL);
3849 n->oper = lcons(">",NIL);
3851 n->subLinkType = ALL_SUBLINK;
3855 | a_expr '=' ALL '(' SubSelect ')'
3857 SubLink *n = makeNode(SubLink);
3858 n->lefthand = lcons($1, NULL);
3859 n->oper = lcons("=",NIL);
3861 n->subLinkType = ALL_SUBLINK;
3866 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3868 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3870 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3874 * b_expr is a subset of the complete expression syntax
3875 * defined by a_expr. b_expr is used in BETWEEN clauses
3876 * to eliminate parser ambiguities stemming from the AND keyword.
3879 b_expr: attr opt_indirection
3881 $1->indirection = $2;
3888 /* could be a column name or a relation_name */
3889 Ident *n = makeNode(Ident);
3891 n->indirection = NULL;
3894 | '-' b_expr %prec UMINUS
3895 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3897 { $$ = makeA_Expr(OP, "+", $1, $3); }
3899 { $$ = makeA_Expr(OP, "-", $1, $3); }
3901 { $$ = makeA_Expr(OP, "/", $1, $3); }
3903 { $$ = makeA_Expr(OP, "*", $1, $3); }
3905 { $$ = makeA_Expr(OP, ":", NULL, $2); }
3907 { $$ = makeA_Expr(OP, ";", NULL, $2); }
3909 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3910 | b_expr TYPECAST Typename
3913 /* AexprConst can be either A_Const or ParamNo */
3914 if (nodeTag($1) == T_A_Const) {
3915 ((A_Const *)$1)->typename = $3;
3916 } else if (nodeTag($1) == T_Param) {
3917 ((ParamNo *)$1)->typename = $3;
3918 /* otherwise, try to transform to a function call */
3920 FuncCall *n = makeNode(FuncCall);
3921 n->funcname = $3->name;
3922 n->args = lcons($1,NIL);
3926 | CAST '(' b_expr AS Typename ')'
3929 /* AexprConst can be either A_Const or ParamNo */
3930 if (nodeTag($3) == T_A_Const) {
3931 ((A_Const *)$3)->typename = $5;
3932 } else if (nodeTag($3) == T_Param) {
3933 ((ParamNo *)$3)->typename = $5;
3934 /* otherwise, try to transform to a function call */
3936 FuncCall *n = makeNode(FuncCall);
3937 n->funcname = $5->name;
3938 n->args = lcons($3,NIL);
3945 { $$ = makeIndexable($2,$1,$3); }
3947 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3949 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3952 FuncCall *n = makeNode(FuncCall);
3957 | func_name '(' expr_list ')'
3959 FuncCall *n = makeNode(FuncCall);
3966 A_Const *n = makeNode(A_Const);
3967 TypeName *t = makeNode(TypeName);
3969 n->val.type = T_String;
3970 n->val.val.str = "now";
3973 t->name = xlateSqlType("date");
3981 A_Const *n = makeNode(A_Const);
3982 TypeName *t = makeNode(TypeName);
3984 n->val.type = T_String;
3985 n->val.val.str = "now";
3988 t->name = xlateSqlType("time");
3994 | CURRENT_TIME '(' Iconst ')'
3996 FuncCall *n = makeNode(FuncCall);
3997 A_Const *s = makeNode(A_Const);
3998 TypeName *t = makeNode(TypeName);
4000 n->funcname = xlateSqlType("time");
4001 n->args = lcons(s, NIL);
4003 s->val.type = T_String;
4004 s->val.val.str = "now";
4007 t->name = xlateSqlType("time");
4012 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
4018 A_Const *n = makeNode(A_Const);
4019 TypeName *t = makeNode(TypeName);
4021 n->val.type = T_String;
4022 n->val.val.str = "now";
4025 t->name = xlateSqlType("timestamp");
4031 | CURRENT_TIMESTAMP '(' Iconst ')'
4033 FuncCall *n = makeNode(FuncCall);
4034 A_Const *s = makeNode(A_Const);
4035 TypeName *t = makeNode(TypeName);
4037 n->funcname = xlateSqlType("timestamp");
4038 n->args = lcons(s, NIL);
4040 s->val.type = T_String;
4041 s->val.val.str = "now";
4044 t->name = xlateSqlType("timestamp");
4049 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
4055 FuncCall *n = makeNode(FuncCall);
4056 n->funcname = "getpgusername";
4060 | POSITION '(' position_list ')'
4062 FuncCall *n = makeNode(FuncCall);
4063 n->funcname = "strpos";
4067 | SUBSTRING '(' substr_list ')'
4069 FuncCall *n = makeNode(FuncCall);
4070 n->funcname = "substr";
4074 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4075 | TRIM '(' BOTH trim_list ')'
4077 FuncCall *n = makeNode(FuncCall);
4078 n->funcname = "btrim";
4082 | TRIM '(' LEADING trim_list ')'
4084 FuncCall *n = makeNode(FuncCall);
4085 n->funcname = "ltrim";
4089 | TRIM '(' TRAILING trim_list ')'
4091 FuncCall *n = makeNode(FuncCall);
4092 n->funcname = "rtrim";
4096 | TRIM '(' trim_list ')'
4098 FuncCall *n = makeNode(FuncCall);
4099 n->funcname = "btrim";
4105 opt_indirection: '[' a_expr ']' opt_indirection
4107 A_Indices *ai = makeNode(A_Indices);
4112 | '[' a_expr ':' a_expr ']' opt_indirection
4114 A_Indices *ai = makeNode(A_Indices);
4123 expr_list: a_expr_or_null
4124 { $$ = lcons($1, NIL); }
4125 | expr_list ',' a_expr_or_null
4126 { $$ = lappend($1, $3); }
4127 | expr_list USING a_expr
4128 { $$ = lappend($1, $3); }
4131 extract_list: datetime FROM a_expr
4133 A_Const *n = makeNode(A_Const);
4134 n->val.type = T_String;
4135 n->val.val.str = $1;
4136 $$ = lappend(lcons((Node *)n,NIL), $3);
4142 position_list: position_expr IN position_expr
4143 { $$ = makeList($3, $1, -1); }
4148 position_expr: attr opt_indirection
4150 $1->indirection = $2;
4155 | '-' position_expr %prec UMINUS
4156 { $$ = makeA_Expr(OP, "-", NULL, $2); }
4157 | position_expr '+' position_expr
4158 { $$ = makeA_Expr(OP, "+", $1, $3); }
4159 | position_expr '-' position_expr
4160 { $$ = makeA_Expr(OP, "-", $1, $3); }
4161 | position_expr '/' position_expr
4162 { $$ = makeA_Expr(OP, "/", $1, $3); }
4163 | position_expr '*' position_expr
4164 { $$ = makeA_Expr(OP, "*", $1, $3); }
4166 { $$ = makeA_Expr(OP, "|", NULL, $2); }
4167 | position_expr TYPECAST Typename
4170 /* AexprConst can be either A_Const or ParamNo */
4171 if (nodeTag($1) == T_A_Const) {
4172 ((A_Const *)$1)->typename = $3;
4173 } else if (nodeTag($1) == T_Param) {
4174 ((ParamNo *)$1)->typename = $3;
4175 /* otherwise, try to transform to a function call */
4177 FuncCall *n = makeNode(FuncCall);
4178 n->funcname = $3->name;
4179 n->args = lcons($1,NIL);
4183 | CAST '(' position_expr AS Typename ')'
4186 /* AexprConst can be either A_Const or ParamNo */
4187 if (nodeTag($3) == T_A_Const) {
4188 ((A_Const *)$3)->typename = $5;
4189 } else if (nodeTag($3) == T_Param) {
4190 ((ParamNo *)$3)->typename = $5;
4191 /* otherwise, try to transform to a function call */
4193 FuncCall *n = makeNode(FuncCall);
4194 n->funcname = $5->name;
4195 n->args = lcons($3,NIL);
4199 | '(' position_expr ')'
4201 | position_expr Op position_expr
4202 { $$ = makeA_Expr(OP, $2, $1, $3); }
4204 { $$ = makeA_Expr(OP, $1, NULL, $2); }
4206 { $$ = makeA_Expr(OP, $2, $1, NULL); }
4209 /* could be a column name or a relation_name */
4210 Ident *n = makeNode(Ident);
4212 n->indirection = NULL;
4217 FuncCall *n = makeNode(FuncCall);
4222 | func_name '(' expr_list ')'
4224 FuncCall *n = makeNode(FuncCall);
4229 | POSITION '(' position_list ')'
4231 FuncCall *n = makeNode(FuncCall);
4232 n->funcname = "strpos";
4236 | SUBSTRING '(' substr_list ')'
4238 FuncCall *n = makeNode(FuncCall);
4239 n->funcname = "substr";
4243 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4244 | TRIM '(' BOTH trim_list ')'
4246 FuncCall *n = makeNode(FuncCall);
4247 n->funcname = "btrim";
4251 | TRIM '(' LEADING trim_list ')'
4253 FuncCall *n = makeNode(FuncCall);
4254 n->funcname = "ltrim";
4258 | TRIM '(' TRAILING trim_list ')'
4260 FuncCall *n = makeNode(FuncCall);
4261 n->funcname = "rtrim";
4265 | TRIM '(' trim_list ')'
4267 FuncCall *n = makeNode(FuncCall);
4268 n->funcname = "btrim";
4274 substr_list: expr_list substr_from substr_for
4276 $$ = nconc(nconc($1,$2),$3);
4282 substr_from: FROM expr_list
4286 A_Const *n = makeNode(A_Const);
4287 n->val.type = T_Integer;
4288 n->val.val.ival = 1;
4289 $$ = lcons((Node *)n,NIL);
4293 substr_for: FOR expr_list
4299 trim_list: a_expr FROM expr_list
4300 { $$ = lappend($3, $1); }
4309 SubLink *n = makeNode(SubLink);
4317 in_expr_nodes: AexprConst
4318 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
4319 | in_expr_nodes ',' AexprConst
4320 { $$ = makeA_Expr(OR, NULL, $1,
4321 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
4325 not_in_expr: SubSelect
4327 SubLink *n = makeNode(SubLink);
4335 not_in_expr_nodes: AexprConst
4336 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
4337 | not_in_expr_nodes ',' AexprConst
4338 { $$ = makeA_Expr(AND, NULL, $1,
4339 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
4343 attr: relation_name '.' attrs
4345 $$ = makeNode(Attr);
4349 $$->indirection = NULL;
4353 $$ = makeNode(Attr);
4357 $$->indirection = NULL;
4362 { $$ = lcons(makeString($1), NIL); }
4363 | attrs '.' attr_name
4364 { $$ = lappend($1, makeString($3)); }
4366 { $$ = lappend($1, makeString("*")); }
4370 /*****************************************************************************
4374 *****************************************************************************/
4376 res_target_list: res_target_list ',' res_target_el
4377 { $$ = lappend($1,$3); }
4379 { $$ = lcons($1, NIL); }
4382 ResTarget *rt = makeNode(ResTarget);
4383 Attr *att = makeNode(Attr);
4385 att->paramNo = NULL;
4387 att->indirection = NIL;
4389 rt->indirection = NULL;
4390 rt->val = (Node *)att;
4391 $$ = lcons(rt, NIL);
4395 res_target_el: ColId opt_indirection '=' a_expr_or_null
4397 $$ = makeNode(ResTarget);
4399 $$->indirection = $2;
4400 $$->val = (Node *)$4;
4402 | attr opt_indirection
4404 $$ = makeNode(ResTarget);
4406 $$->indirection = $2;
4407 $$->val = (Node *)$1;
4409 | relation_name '.' '*'
4411 Attr *att = makeNode(Attr);
4413 att->paramNo = NULL;
4414 att->attrs = lcons(makeString("*"), NIL);
4415 att->indirection = NIL;
4416 $$ = makeNode(ResTarget);
4418 $$->indirection = NULL;
4419 $$->val = (Node *)att;
4424 ** target list for select.
4425 ** should get rid of the other but is still needed by the defunct select into
4426 ** and update (uses a subset)
4428 res_target_list2: res_target_list2 ',' res_target_el2
4429 { $$ = lappend($1, $3); }
4431 { $$ = lcons($1, NIL); }
4434 /* AS is not optional because shift/red conflict with unary ops */
4435 res_target_el2: a_expr_or_null AS ColLabel
4437 $$ = makeNode(ResTarget);
4439 $$->indirection = NULL;
4440 $$->val = (Node *)$1;
4444 $$ = makeNode(ResTarget);
4446 $$->indirection = NULL;
4447 $$->val = (Node *)$1;
4449 | relation_name '.' '*'
4451 Attr *att = makeNode(Attr);
4453 att->paramNo = NULL;
4454 att->attrs = lcons(makeString("*"), NIL);
4455 att->indirection = NIL;
4456 $$ = makeNode(ResTarget);
4458 $$->indirection = NULL;
4459 $$->val = (Node *)att;
4463 Attr *att = makeNode(Attr);
4465 att->paramNo = NULL;
4467 att->indirection = NIL;
4468 $$ = makeNode(ResTarget);
4470 $$->indirection = NULL;
4471 $$->val = (Node *)att;
4475 opt_id: ColId { $$ = $1; }
4476 | /* EMPTY */ { $$ = NULL; }
4479 relation_name: SpecialRuleRelation
4482 StrNCpy(saved_relname, $1, NAMEDATALEN);
4486 /* disallow refs to variable system tables */
4487 if (strcmp(LogRelationName, $1) == 0
4488 || strcmp(VariableRelationName, $1) == 0)
4489 elog(ERROR,"%s cannot be accessed by users",$1);
4492 StrNCpy(saved_relname, $1, NAMEDATALEN);
4496 database_name: ColId { $$ = $1; };
4497 access_method: IDENT { $$ = $1; };
4498 attr_name: ColId { $$ = $1; };
4499 class: IDENT { $$ = $1; };
4500 index_name: ColId { $$ = $1; };
4503 * Include date/time keywords as SQL92 extension.
4504 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4506 name: ColId { $$ = $1; };
4507 func_name: ColId { $$ = xlateSqlFunc($1); };
4509 file_name: Sconst { $$ = $1; };
4510 recipe_name: IDENT { $$ = $1; };
4513 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4517 A_Const *n = makeNode(A_Const);
4518 n->val.type = T_Integer;
4519 n->val.val.ival = $1;
4524 A_Const *n = makeNode(A_Const);
4525 n->val.type = T_Float;
4526 n->val.val.dval = $1;
4531 A_Const *n = makeNode(A_Const);
4532 n->val.type = T_String;
4533 n->val.val.str = $1;
4538 A_Const *n = makeNode(A_Const);
4540 n->val.type = T_String;
4541 n->val.val.str = $2;
4545 { $$ = (Node *)$1; }
4548 A_Const *n = makeNode(A_Const);
4549 n->val.type = T_String;
4550 n->val.val.str = "t";
4551 n->typename = makeNode(TypeName);
4552 n->typename->name = xlateSqlType("bool");
4553 n->typename->typmod = -1;
4558 A_Const *n = makeNode(A_Const);
4559 n->val.type = T_String;
4560 n->val.val.str = "f";
4561 n->typename = makeNode(TypeName);
4562 n->typename->name = xlateSqlType("bool");
4563 n->typename->typmod = -1;
4570 $$ = makeNode(ParamNo);
4575 NumConst: Iconst { $$ = makeInteger($1); }
4576 | FCONST { $$ = makeFloat($1); }
4579 Iconst: ICONST { $$ = $1; };
4580 Sconst: SCONST { $$ = $1; };
4581 UserId: IDENT { $$ = $1; };
4583 /* Column and type identifier
4584 * Does not include explicit datetime types
4585 * since these must be decoupled in Typename syntax.
4586 * Use ColId for most identifiers. - thomas 1997-10-21
4589 { $$ = xlateSqlType($1); }
4591 { $$ = xlateSqlType($1); }
4593 { $$ = xlateSqlType($1); }
4595 /* Column identifier
4596 * Include date/time keywords as SQL92 extension.
4597 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
4598 * Add other keywords. Note that as the syntax expands,
4599 * some of these keywords will have to be removed from this
4600 * list due to shift/reduce conflicts in yacc. If so, move
4601 * down to the ColLabel entity. - thomas 1997-11-06
4603 ColId: IDENT { $$ = $1; }
4604 | datetime { $$ = $1; }
4605 | ACTION { $$ = "action"; }
4606 | DATABASE { $$ = "database"; }
4607 | DELIMITERS { $$ = "delimiters"; }
4608 | DOUBLE { $$ = "double"; }
4609 | EACH { $$ = "each"; }
4610 | FUNCTION { $$ = "function"; }
4611 | INDEX { $$ = "index"; }
4612 | KEY { $$ = "key"; }
4613 | LANGUAGE { $$ = "language"; }
4614 | LOCATION { $$ = "location"; }
4615 | MATCH { $$ = "match"; }
4616 | OPERATOR { $$ = "operator"; }
4617 | OPTION { $$ = "option"; }
4618 | PRIVILEGES { $$ = "privileges"; }
4619 | RECIPE { $$ = "recipe"; }
4620 | ROW { $$ = "row"; }
4621 | STATEMENT { $$ = "statement"; }
4622 | TIME { $$ = "time"; }
4623 | TRIGGER { $$ = "trigger"; }
4624 | TYPE_P { $$ = "type"; }
4625 | USER { $$ = "user"; }
4626 | VALID { $$ = "valid"; }
4627 | VERSION { $$ = "version"; }
4628 | ZONE { $$ = "zone"; }
4632 * Allowed labels in "AS" clauses.
4633 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
4634 * compatibility. Cannot allow this for column names since the
4635 * syntax would not distinguish between the constant value and
4636 * a column name. - thomas 1997-10-24
4637 * Add other keywords to this list. Note that they appear here
4638 * rather than in ColId if there was a shift/reduce conflict
4639 * when used as a full identifier. - thomas 1997-11-06
4641 ColLabel: ColId { $$ = $1; }
4642 | ARCHIVE { $$ = "archive"; }
4643 | CLUSTER { $$ = "cluster"; }
4644 | CONSTRAINT { $$ = "constraint"; }
4645 | CROSS { $$ = "cross"; }
4646 | FOREIGN { $$ = "foreign"; }
4647 | GROUP { $$ = "group"; }
4648 | LOAD { $$ = "load"; }
4649 | ORDER { $$ = "order"; }
4650 | POSITION { $$ = "position"; }
4651 | PRECISION { $$ = "precision"; }
4652 | TABLE { $$ = "table"; }
4653 | TRANSACTION { $$ = "transaction"; }
4654 | TRUE_P { $$ = "true"; }
4655 | FALSE_P { $$ = "false"; }
4658 SpecialRuleRelation: CURRENT
4663 elog(ERROR,"CURRENT used in non-rule query");
4670 elog(ERROR,"NEW used in non-rule query");
4677 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
4679 A_Expr *a = makeNode(A_Expr);
4688 * Generate separate operator nodes for a single row descriptor expression.
4689 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
4692 makeRowExpr(char *opr, List *largs, List *rargs)
4697 if (length(largs) != length(rargs))
4698 elog(ERROR,"Unequal number of entries in row expression");
4700 if (lnext(largs) != NIL)
4701 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
4703 larg = lfirst(largs);
4704 rarg = lfirst(rargs);
4706 if ((strcmp(opr, "=") == 0)
4707 || (strcmp(opr, "<") == 0)
4708 || (strcmp(opr, "<=") == 0)
4709 || (strcmp(opr, ">") == 0)
4710 || (strcmp(opr, ">=") == 0))
4713 expr = makeA_Expr(OP, opr, larg, rarg);
4715 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4717 else if (strcmp(opr, "<>") == 0)
4720 expr = makeA_Expr(OP, opr, larg, rarg);
4722 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4726 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
4730 while ((largs != NIL) && (rargs != NIL))
4732 larg = lfirst(largs);
4733 rarg = lfirst(rargs);
4736 expr = makeA_Expr(OP, opr, larg, rarg);
4738 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
4740 largs = lnext(largs);
4741 rargs = lnext(rargs);
4750 mapTargetColumns(List *src, List *dst)
4755 if (length(src) != length(dst))
4756 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
4758 while ((src != NIL) && (dst != NIL))
4760 s = (ColumnDef *)lfirst(src);
4761 d = (ResTarget *)lfirst(dst);
4763 d->name = s->colname;
4770 } /* mapTargetColumns() */
4772 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
4774 Node *result = NULL;
4776 /* we do this so indexes can be used */
4777 if (strcmp(opname,"~") == 0 ||
4778 strcmp(opname,"~*") == 0)
4780 if (nodeTag(rexpr) == T_A_Const &&
4781 ((A_Const *)rexpr)->val.type == T_String &&
4782 ((A_Const *)rexpr)->val.val.str[0] == '^')
4784 A_Const *n = (A_Const *)rexpr;
4785 char *match_least = palloc(strlen(n->val.val.str)+2);
4786 char *match_most = palloc(strlen(n->val.val.str)+2);
4787 int pos, match_pos=0;
4789 /* skip leading ^ */
4790 for (pos = 1; n->val.val.str[pos]; pos++)
4792 if (n->val.val.str[pos] == '.' ||
4793 n->val.val.str[pos] == '?' ||
4794 n->val.val.str[pos] == '*' ||
4795 n->val.val.str[pos] == '[' ||
4796 n->val.val.str[pos] == '$' ||
4797 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4799 if (n->val.val.str[pos] == '\\')
4801 match_least[match_pos] = n->val.val.str[pos];
4802 match_most[match_pos++] = n->val.val.str[pos];
4807 A_Const *least = makeNode(A_Const);
4808 A_Const *most = makeNode(A_Const);
4810 /* make strings to be used in index use */
4811 match_least[match_pos] = '\0';
4812 match_most[match_pos] = '\377';
4813 match_most[match_pos+1] = '\0';
4814 least->val.type = T_String;
4815 least->val.val.str = match_least;
4816 most->val.type = T_String;
4817 most->val.val.str = match_most;
4818 result = makeA_Expr(AND, NULL,
4819 makeA_Expr(OP, "~", lexpr, rexpr),
4820 makeA_Expr(AND, NULL,
4821 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4822 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4826 else if (strcmp(opname,"~~") == 0)
4828 if (nodeTag(rexpr) == T_A_Const &&
4829 ((A_Const *)rexpr)->val.type == T_String)
4831 A_Const *n = (A_Const *)rexpr;
4832 char *match_least = palloc(strlen(n->val.val.str)+2);
4833 char *match_most = palloc(strlen(n->val.val.str)+2);
4834 int pos, match_pos=0;
4836 for (pos = 0; n->val.val.str[pos]; pos++)
4838 if (n->val.val.str[pos] == '%' &&
4839 n->val.val.str[pos+1] != '%')
4841 if(n->val.val.str[pos] == '_')
4843 if (n->val.val.str[pos] == '\\' ||
4844 n->val.val.str[pos] == '%')
4846 if (n->val.val.str[pos] == '\0')
4848 match_least[match_pos] = n->val.val.str[pos];
4849 match_most[match_pos++] = n->val.val.str[pos];
4854 A_Const *least = makeNode(A_Const);
4855 A_Const *most = makeNode(A_Const);
4857 /* make strings to be used in index use */
4858 match_least[match_pos] = '\0';
4859 match_most[match_pos] = '\377';
4860 match_most[match_pos+1] = '\0';
4861 least->val.type = T_String;
4862 least->val.val.str = match_least;
4863 most->val.type = T_String;
4864 most->val.val.str = match_most;
4865 result = makeA_Expr(AND, NULL,
4866 makeA_Expr(OP, "~~", lexpr, rexpr),
4867 makeA_Expr(AND, NULL,
4868 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4869 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4875 result = makeA_Expr(OP, opname, lexpr, rexpr);
4877 } /* makeIndexable() */
4881 * Convert alternate type names to internal Postgres types.
4882 * Do not convert "float", since that is handled elsewhere
4883 * for FLOAT(p) syntax.
4886 xlateSqlFunc(char *name)
4888 if (!strcasecmp(name,"character_length")
4889 || !strcasecmp(name,"char_length"))
4893 } /* xlateSqlFunc() */
4896 * Convert alternate type names to internal Postgres types.
4899 xlateSqlType(char *name)
4901 if (!strcasecmp(name,"int")
4902 || !strcasecmp(name,"integer"))
4904 else if (!strcasecmp(name, "smallint"))
4906 else if (!strcasecmp(name, "real")
4907 || !strcasecmp(name, "float"))
4909 else if (!strcasecmp(name, "interval"))
4911 else if (!strcasecmp(name, "boolean"))
4915 } /* xlateSqlType() */
4918 void parser_init(Oid *typev, int nargs)
4920 QueryIsRule = FALSE;
4921 saved_relname[0]= '\0';
4922 saved_In_Expr = NULL;
4924 param_type_init(typev, nargs);
4928 /* FlattenStringList()
4929 * Traverse list of string nodes and convert to a single string.
4930 * Used for reconstructing string form of complex expressions.
4932 * Allocate at least one byte for terminator.
4935 FlattenStringList(List *list)
4943 nlist = length(list);
4946 v = (Value *)lfirst(l);
4953 s = (char*) palloc(len+1);
4958 v = (Value *)lfirst(l);
4962 if (l != NIL) strcat(s," ");
4967 printf( "flattened string is \"%s\"\n", s);
4971 } /* FlattenStringList() */
4974 /* makeConstantList()
4975 * Convert constant value node into string node.
4978 makeConstantList( A_Const *n)
4980 char *defval = NULL;
4981 if (nodeTag(n) != T_A_Const) {
4982 elog(ERROR,"Cannot handle non-constant parameter");
4984 } else if (n->val.type == T_Float) {
4985 defval = (char*) palloc(20+1);
4986 sprintf( defval, "%g", n->val.val.dval);
4988 } else if (n->val.type == T_Integer) {
4989 defval = (char*) palloc(20+1);
4990 sprintf( defval, "%ld", n->val.val.ival);
4992 } else if (n->val.type == T_String) {
4993 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
4994 strcpy( defval, "'");
4995 strcat( defval, ((A_Const *) n)->val.val.str);
4996 strcat( defval, "'");
4999 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
5003 printf( "AexprConst argument is \"%s\"\n", defval);
5006 return( lcons( makeString(defval), NIL));
5007 } /* makeConstantList() */
5011 * Check input string for non-lowercase/non-numeric characters.
5012 * Returns either input string or input surrounded by double quotes.
5019 for (cp = rawid; *cp != '\0'; cp++)
5020 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
5023 cp = palloc(strlen(rawid)+1);
5032 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
5041 * keep enough information around fill out the type of param nodes
5042 * used in postquel functions
5045 param_type_init(Oid *typev, int nargs)
5047 pfunc_num_args = nargs;
5048 param_type_info = typev;
5051 Oid param_type(int t)
5053 if ((t > pfunc_num_args) || (t == 0))
5055 return param_type_info[t - 1];