4 /*-------------------------------------------------------------------------
7 * POSTGRES SQL YACC rules/actions
9 * Copyright (c) 1994, Regents of the University of California
13 * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 1.95 1998/01/20 05:04:07 momjian Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlType(char *);
65 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
66 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
67 void mapTargetColumns(List *source, List *target);
68 static List *makeConstantList( A_Const *node);
69 static char *FlattenStringList(List *list);
70 static char *fmtId(char *rawid);
71 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
72 static void param_type_init(Oid *typev, int nargs);
74 Oid param_type(int t); /* used in parse_expr.c */
76 /* old versions of flex define this as a macro */
90 bool* pboolean; /* for pg_user privileges */
100 SortGroupBy *sortgroupby;
115 AddAttrStmt, ClosePortalStmt,
116 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
117 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
118 CreatePLangStmt, DropPLangStmt,
119 IndexStmt, ListenStmt, OptimizableStmt,
120 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
121 RemoveFuncStmt, RemoveStmt,
122 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
123 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
124 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
125 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
126 CreateUserStmt, AlterUserStmt, DropUserStmt
130 %type <str> opt_database, location
132 %type <pboolean> user_createdb_clause, user_createuser_clause
133 %type <str> user_passwd_clause
134 %type <str> user_valid_clause
135 %type <list> user_group_list, user_group_clause
137 %type <str> join_expr, join_outer, join_spec
138 %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
140 %type <str> TriggerEvents, TriggerFuncArg
142 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
143 database_name, access_method_clause, access_method, attr_name,
144 class, index_name, name, file_name, recipe_name, aggr_argtype
146 %type <str> opt_id, opt_portal_name,
147 all_Op, MathOp, opt_name, opt_unique,
148 result, OptUseOp, opt_class, SpecialRuleRelation
150 %type <str> privileges, operation_commalist, grantee
151 %type <chr> operation, TriggerOneEvent
153 %type <list> stmtblock, stmtmulti,
154 relation_name_list, OptTableElementList,
155 OptInherit, definition,
156 opt_with, def_args, def_name_list, func_argtypes,
157 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
158 opt_column_list, columnList, opt_va_list, va_list,
159 sort_clause, sortby_list, index_params, index_list, name_list,
160 from_clause, from_list, opt_array_bounds, nest_array_bounds,
161 expr_list, attrs, res_target_list, res_target_list2,
162 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
164 %type <list> union_clause, select_list
165 %type <list> join_list
168 %type <boolean> opt_union
170 %type <node> position_expr
171 %type <list> extract_list, position_list
172 %type <list> substr_list, substr_from, substr_for, trim_list
173 %type <list> opt_interval
175 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
176 index_opt_unique, opt_verbose, opt_analyze
178 %type <ival> copy_dirn, def_type, opt_direction, remove_type,
181 %type <ival> fetch_how_many
183 %type <list> OptSeqList
184 %type <defelt> OptSeqElem
186 %type <dstmt> def_rest
187 %type <astmt> insert_rest
189 %type <node> OptTableElement, ConstraintElem
190 %type <node> columnDef, alter_clause
191 %type <defelt> def_elem
192 %type <node> def_arg, columnElem, where_clause,
193 a_expr, a_expr_or_null, AexprConst,
194 in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
196 %type <list> row_descriptor, row_list
197 %type <node> row_expr
198 %type <list> OptCreateAs, CreateAsList
199 %type <node> CreateAsElement
200 %type <value> NumConst
201 %type <attr> event_object, attr
202 %type <sortgroupby> groupby
203 %type <sortgroupby> sortby
204 %type <ielem> index_elem, func_index
205 %type <range> from_val
206 %type <relexp> relation_expr
207 %type <target> res_target_el, res_target_el2
208 %type <paramno> ParamNo
210 %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
211 %type <str> generic, character, datetime
212 %type <str> opt_charset, opt_collate
213 %type <str> opt_float, opt_numeric, opt_decimal
214 %type <boolean> opt_varying, opt_timezone
218 %type <str> Id, var_value, zone_value
219 %type <str> ColId, ColLabel
221 %type <node> TableConstraint
222 %type <list> constraint_list, constraint_expr
223 %type <list> default_list, default_expr
224 %type <list> ColQualList, ColQualifier
225 %type <node> ColConstraint, ColConstraintElem
226 %type <list> key_actions, key_action
227 %type <str> key_match, key_reference
230 * If you make any token changes, remember to:
231 * - use "yacc -d" and update parse.h
232 * - update the keyword table in parser/keywords.c
235 /* Reserved word tokens
236 * SQL92 syntax has many type-specific constructs.
237 * So, go ahead and make these types reserved words,
238 * and call-out the syntax explicitly.
239 * This gets annoying when trying to also retain Postgres' nice
240 * type-extensible features, but we don't really have a choice.
241 * - thomas 1997-10-11
244 /* Keywords (in SQL92 reserved words) */
245 %token ACTION, ADD, ALL, ALTER, AND, ANY AS, ASC,
246 BEGIN_TRANS, BETWEEN, BOTH, BY,
247 CASCADE, CAST, CHAR, CHARACTER, CHECK, CLOSE, COLLATE, COLUMN, COMMIT,
248 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME,
249 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
250 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
251 END_TRANS, EXECUTE, EXISTS, EXTRACT,
252 FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
253 GRANT, GROUP, HAVING, HOUR_P,
254 IN, INNER_P, INSERT, INTERVAL, INTO, IS,
255 JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
256 MATCH, MINUTE_P, MONTH_P,
257 NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
258 ON, OPTION, OR, ORDER, OUTER_P,
259 PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
260 REFERENCES, REVOKE, RIGHT, ROLLBACK,
261 SECOND_P, SELECT, SET, SUBSTRING,
262 TABLE, TIME, TIMESTAMP, TO, TRAILING, TRANSACTION, TRIM,
263 UNION, UNIQUE, UPDATE, USING,
264 VALUES, VARCHAR, VARYING, VERBOSE, VERSION, VIEW,
265 WHERE, WITH, WORK, YEAR_P, ZONE
267 /* Keywords (in SQL3 reserved words) */
268 %token FALSE_P, TRIGGER, TRUE_P
270 /* Keywords (in SQL92 non-reserved words) */
273 /* Keywords for Postgres support (not in SQL92 reserved words) */
274 %token ABORT_TRANS, ACL, AFTER, AGGREGATE, ANALYZE,
275 APPEND, BACKWARD, BEFORE, BINARY, CHANGE, CLUSTER, COPY,
276 DATABASE, DELIMITERS, DO, EXPLAIN, EXTEND,
277 FORWARD, FUNCTION, HANDLER,
278 INDEX, INHERITS, INSTEAD, ISNULL,
279 LANCOMPILER, LISTEN, LOAD, LOCATION, MERGE, MOVE,
280 NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
281 RECIPE, RENAME, REPLACE, RESET, RETURNS, RULE,
282 SEQUENCE, SETOF, SHOW, STDIN, STDOUT, TRUSTED,
283 VACUUM, VERBOSE, VERSION
285 /* Keywords (obsolete; retain temporarily for parser - thomas 1997-12-04) */
289 * Tokens for pg_passwd support. The CREATEDB and CREATEUSER tokens should go away
290 * when some sort of pg_privileges relation is introduced.
294 %token USER, PASSWORD, CREATEDB, NOCREATEDB, CREATEUSER, NOCREATEUSER, VALID, UNTIL
296 /* Special keywords, not in the query language - see the "lex" file */
297 %token <str> IDENT, SCONST, Op
298 %token <ival> ICONST, PARAM
301 /* these are not real. they are here so that they get generated as #define's*/
313 %nonassoc Op /* multi-character ops and user-defined operators */
319 %left '|' /* this is the relation union op, not logical or */
320 /* Unary Operators */
322 %left ';' /* end of statement or natural log */
334 { parsetree = lcons($1,NIL); }
337 stmtmulti: stmtmulti stmt ';'
338 { $$ = lappend($1, $2); }
340 { $$ = lappend($1, $2); }
342 { $$ = lcons($1,NIL); }
388 /*****************************************************************************
390 * Create a new Postgres DBMS user
393 *****************************************************************************/
395 CreateUserStmt: CREATE USER Id user_passwd_clause user_createdb_clause
396 user_createuser_clause user_group_clause user_valid_clause
398 CreateUserStmt *n = makeNode(CreateUserStmt);
409 /*****************************************************************************
411 * Alter a postresql DBMS user
414 *****************************************************************************/
416 AlterUserStmt: ALTER USER Id user_passwd_clause user_createdb_clause
417 user_createuser_clause user_group_clause user_valid_clause
419 AlterUserStmt *n = makeNode(AlterUserStmt);
430 /*****************************************************************************
432 * Drop a postresql DBMS user
435 *****************************************************************************/
437 DropUserStmt: DROP USER Id
439 DropUserStmt *n = makeNode(DropUserStmt);
445 user_passwd_clause: WITH PASSWORD Id { $$ = $3; }
446 | /*EMPTY*/ { $$ = NULL; }
449 user_createdb_clause: CREATEDB
452 $$ = (b = (bool*)palloc(sizeof(bool)));
458 $$ = (b = (bool*)palloc(sizeof(bool)));
461 | /*EMPTY*/ { $$ = NULL; }
464 user_createuser_clause: CREATEUSER
467 $$ = (b = (bool*)palloc(sizeof(bool)));
473 $$ = (b = (bool*)palloc(sizeof(bool)));
476 | /*EMPTY*/ { $$ = NULL; }
479 user_group_list: user_group_list ',' Id
481 $$ = lcons((void*)makeString($3), $1);
485 $$ = lcons((void*)makeString($1), NIL);
489 user_group_clause: IN GROUP user_group_list { $$ = $3; }
490 | /*EMPTY*/ { $$ = NULL; }
493 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
494 | /*EMPTY*/ { $$ = NULL; }
497 /*****************************************************************************
499 * Set PG internal variable
500 * SET name TO 'var_value'
501 * Include SQL92 syntax (thomas 1997-10-22):
502 * SET TIME ZONE 'var_value'
504 *****************************************************************************/
506 VariableSetStmt: SET ColId TO var_value
508 VariableSetStmt *n = makeNode(VariableSetStmt);
513 | SET ColId '=' var_value
515 VariableSetStmt *n = makeNode(VariableSetStmt);
520 | SET TIME ZONE zone_value
522 VariableSetStmt *n = makeNode(VariableSetStmt);
523 n->name = "timezone";
529 var_value: Sconst { $$ = $1; }
530 | DEFAULT { $$ = NULL; }
533 zone_value: Sconst { $$ = $1; }
534 | DEFAULT { $$ = NULL; }
535 | LOCAL { $$ = "default"; }
538 VariableShowStmt: SHOW ColId
540 VariableShowStmt *n = makeNode(VariableShowStmt);
546 VariableShowStmt *n = makeNode(VariableShowStmt);
547 n->name = "timezone";
552 VariableResetStmt: RESET ColId
554 VariableResetStmt *n = makeNode(VariableResetStmt);
560 VariableResetStmt *n = makeNode(VariableResetStmt);
561 n->name = "timezone";
567 /*****************************************************************************
570 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
572 *****************************************************************************/
574 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
576 AddAttrStmt *n = makeNode(AddAttrStmt);
584 alter_clause: ADD opt_column columnDef
588 | ADD '(' OptTableElementList ')'
590 Node *lp = lfirst($3);
593 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
596 | DROP opt_column ColId
597 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
598 | ALTER opt_column ColId SET DEFAULT default_expr
599 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
600 | ALTER opt_column ColId DROP DEFAULT
601 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
603 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
607 /*****************************************************************************
612 *****************************************************************************/
614 ClosePortalStmt: CLOSE opt_id
616 ClosePortalStmt *n = makeNode(ClosePortalStmt);
623 /*****************************************************************************
626 * COPY [BINARY] <relname> FROM/TO
627 * [USING DELIMITERS <delimiter>]
629 *****************************************************************************/
631 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
633 CopyStmt *n = makeNode(CopyStmt);
651 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
652 * used depends on the direction. (It really doesn't make sense to copy from
653 * stdout. We silently correct the "typo". - AY 9/94
655 copy_file_name: Sconst { $$ = $1; }
656 | STDIN { $$ = NULL; }
657 | STDOUT { $$ = NULL; }
660 opt_binary: BINARY { $$ = TRUE; }
661 | /*EMPTY*/ { $$ = FALSE; }
664 opt_with_copy: WITH OIDS { $$ = TRUE; }
665 | /*EMPTY*/ { $$ = FALSE; }
669 * the default copy delimiter is tab but the user can configure it
671 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
672 | /*EMPTY*/ { $$ = "\t"; }
676 /*****************************************************************************
681 *****************************************************************************/
683 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
684 OptInherit OptArchiveType
686 CreateStmt *n = makeNode(CreateStmt);
690 n->constraints = NIL;
695 OptTableElementList: OptTableElementList ',' OptTableElement
696 { $$ = lappend($1, $3); }
697 | OptTableElement { $$ = lcons($1, NIL); }
698 | /*EMPTY*/ { $$ = NULL; }
701 OptTableElement: columnDef { $$ = $1; }
702 | TableConstraint { $$ = $1; }
705 columnDef: ColId Typename ColQualifier
707 ColumnDef *n = makeNode(ColumnDef);
711 n->is_not_null = FALSE;
717 ColQualifier: ColQualList { $$ = $1; }
718 | /*EMPTY*/ { $$ = NULL; }
721 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
722 | ColConstraint { $$ = lcons($1, NIL); }
726 CONSTRAINT name ColConstraintElem
728 Constraint *n = (Constraint *)$3;
736 ColConstraintElem: CHECK '(' constraint_expr ')'
738 Constraint *n = makeNode(Constraint);
739 n->contype = CONSTR_CHECK;
741 n->def = FlattenStringList($3);
745 | DEFAULT default_expr
747 Constraint *n = makeNode(Constraint);
748 n->contype = CONSTR_DEFAULT;
750 n->def = FlattenStringList($2);
756 Constraint *n = makeNode(Constraint);
757 n->contype = CONSTR_NOTNULL;
765 Constraint *n = makeNode(Constraint);
766 n->contype = CONSTR_UNIQUE;
774 Constraint *n = makeNode(Constraint);
775 n->contype = CONSTR_PRIMARY;
781 | REFERENCES ColId opt_column_list key_match key_actions
783 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
788 default_list: default_list ',' default_expr
790 $$ = lappend($1,makeString(","));
799 default_expr: AexprConst
800 { $$ = makeConstantList((A_Const *) $1); }
802 { $$ = lcons( makeString("NULL"), NIL); }
803 | '-' default_expr %prec UMINUS
804 { $$ = lcons( makeString( "-"), $2); }
805 | default_expr '+' default_expr
806 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
807 | default_expr '-' default_expr
808 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
809 | default_expr '/' default_expr
810 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
811 | default_expr '*' default_expr
812 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
813 | default_expr '=' default_expr
814 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
815 | default_expr '<' default_expr
816 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
817 | default_expr '>' default_expr
818 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
820 { $$ = lcons( makeString( ":"), $2); }
822 { $$ = lcons( makeString( ";"), $2); }
824 { $$ = lcons( makeString( "|"), $2); }
825 | default_expr TYPECAST Typename
827 $3->name = fmtId($3->name);
828 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
830 | CAST default_expr AS Typename
832 $4->name = fmtId($4->name);
833 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
835 | '(' default_expr ')'
836 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
839 $$ = makeList( makeString($1), makeString("("), -1);
840 $$ = lappend( $$, makeString(")"));
842 | name '(' default_list ')'
844 $$ = makeList( makeString($1), makeString("("), -1);
846 $$ = lappend( $$, makeString(")"));
848 | default_expr Op default_expr
850 if (!strcmp("<=", $2) || !strcmp(">=", $2))
851 elog(ERROR,"boolean expressions not supported in DEFAULT");
852 $$ = nconc( $1, lcons( makeString( $2), $3));
855 { $$ = lcons( makeString( $1), $2); }
857 { $$ = lappend( $1, makeString( $2)); }
858 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
860 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
862 { $$ = lcons( makeString( "'now'::time"), NIL); }
863 | CURRENT_TIME '(' Iconst ')'
866 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
867 $$ = lcons( makeString( "'now'::time"), NIL);
870 { $$ = lcons( makeString( "now()"), NIL); }
871 | CURRENT_TIMESTAMP '(' Iconst ')'
874 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
875 $$ = lcons( makeString( "now()"), NIL);
878 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
881 /* ConstraintElem specifies constraint syntax which is not embedded into
882 * a column definition. ColConstraintElem specifies the embedded form.
883 * - thomas 1997-12-03
885 TableConstraint: CONSTRAINT name ConstraintElem
887 Constraint *n = (Constraint *)$3;
895 ConstraintElem: CHECK '(' constraint_expr ')'
897 Constraint *n = makeNode(Constraint);
898 n->contype = CONSTR_CHECK;
900 n->def = FlattenStringList($3);
903 | UNIQUE '(' columnList ')'
905 Constraint *n = makeNode(Constraint);
906 n->contype = CONSTR_UNIQUE;
912 | PRIMARY KEY '(' columnList ')'
914 Constraint *n = makeNode(Constraint);
915 n->contype = CONSTR_PRIMARY;
921 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
922 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented"); }
925 constraint_list: constraint_list ',' constraint_expr
927 $$ = lappend($1,makeString(","));
936 constraint_expr: AexprConst
937 { $$ = makeConstantList((A_Const *) $1); }
939 { $$ = lcons( makeString("NULL"), NIL); }
942 $$ = lcons( makeString(fmtId($1)), NIL);
944 | '-' constraint_expr %prec UMINUS
945 { $$ = lcons( makeString( "-"), $2); }
946 | constraint_expr '+' constraint_expr
947 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
948 | constraint_expr '-' constraint_expr
949 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
950 | constraint_expr '/' constraint_expr
951 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
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
961 { $$ = lcons( makeString( ":"), $2); }
962 | ';' constraint_expr
963 { $$ = lcons( makeString( ";"), $2); }
964 | '|' constraint_expr
965 { $$ = lcons( makeString( "|"), $2); }
966 | constraint_expr TYPECAST Typename
968 $3->name = fmtId($3->name);
969 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
971 | CAST constraint_expr AS Typename
973 $4->name = fmtId($4->name);
974 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
976 | '(' constraint_expr ')'
977 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
980 $$ = makeList( makeString($1), makeString("("), -1);
981 $$ = lappend( $$, makeString(")"));
983 | name '(' constraint_list ')'
985 $$ = makeList( makeString($1), makeString("("), -1);
987 $$ = lappend( $$, makeString(")"));
989 | constraint_expr Op constraint_expr
990 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
991 | constraint_expr AND constraint_expr
992 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
993 | constraint_expr OR constraint_expr
994 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
995 | NOT constraint_expr
996 { $$ = lcons( makeString( "NOT"), $2); }
998 { $$ = lcons( makeString( $1), $2); }
1000 { $$ = lappend( $1, makeString( $2)); }
1001 | constraint_expr ISNULL
1002 { $$ = lappend( $1, makeString( "IS NULL")); }
1003 | constraint_expr IS NULL_P
1004 { $$ = lappend( $1, makeString( "IS NULL")); }
1005 | constraint_expr NOTNULL
1006 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1007 | constraint_expr IS NOT NULL_P
1008 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1009 | constraint_expr IS TRUE_P
1010 { $$ = lappend( $1, makeString( "IS TRUE")); }
1011 | constraint_expr IS FALSE_P
1012 { $$ = lappend( $1, makeString( "IS FALSE")); }
1013 | constraint_expr IS NOT TRUE_P
1014 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1015 | constraint_expr IS NOT FALSE_P
1016 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1019 key_match: MATCH FULL { $$ = NULL; }
1020 | MATCH PARTIAL { $$ = NULL; }
1021 | /*EMPTY*/ { $$ = NULL; }
1024 key_actions: key_action key_action { $$ = NIL; }
1025 | key_action { $$ = NIL; }
1026 | /*EMPTY*/ { $$ = NIL; }
1029 key_action: ON DELETE key_reference { $$ = NIL; }
1030 | ON UPDATE key_reference { $$ = NIL; }
1033 key_reference: NO ACTION { $$ = NULL; }
1034 | CASCADE { $$ = NULL; }
1035 | SET DEFAULT { $$ = NULL; }
1036 | SET NULL_P { $$ = NULL; }
1039 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1040 | /*EMPTY*/ { $$ = NIL; }
1044 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1045 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1047 OptArchiveType: ARCHIVE '=' NONE { }
1051 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1053 SelectStmt *n = (SelectStmt *)$6;
1055 mapTargetColumns($4, n->targetList);
1061 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1062 | /*EMPTY*/ { $$ = NULL; }
1065 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1066 | CreateAsElement { $$ = lcons($1, NIL); }
1069 CreateAsElement: ColId
1071 ColumnDef *n = makeNode(ColumnDef);
1075 n->is_not_null = FALSE;
1076 n->constraints = NULL;
1082 /*****************************************************************************
1085 * CREATE SEQUENCE seqname
1087 *****************************************************************************/
1089 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1091 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1099 OptSeqList OptSeqElem
1100 { $$ = lappend($1, $2); }
1104 OptSeqElem: IDENT NumConst
1106 $$ = makeNode(DefElem);
1108 $$->arg = (Node *)$2;
1112 $$ = makeNode(DefElem);
1114 $$->arg = (Node *)NULL;
1118 /*****************************************************************************
1121 * CREATE PROCEDURAL LANGUAGE ...
1122 * DROP PROCEDURAL LANGUAGE ...
1124 *****************************************************************************/
1126 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1127 HANDLER def_name LANCOMPILER Sconst
1129 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1138 PLangTrusted: TRUSTED { $$ = TRUE; }
1141 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1143 DropPLangStmt *n = makeNode(DropPLangStmt);
1149 /*****************************************************************************
1152 * CREATE TRIGGER ...
1155 *****************************************************************************/
1157 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1158 relation_name TriggerForSpec EXECUTE PROCEDURE
1159 name '(' TriggerFuncArgs ')'
1161 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1168 memcpy (n->actions, $5, 4);
1173 TriggerActionTime: BEFORE { $$ = TRUE; }
1174 | AFTER { $$ = FALSE; }
1177 TriggerEvents: TriggerOneEvent
1179 char *e = palloc (4);
1180 e[0] = $1; e[1] = 0; $$ = e;
1182 | TriggerOneEvent OR TriggerOneEvent
1184 char *e = palloc (4);
1185 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1187 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1189 char *e = palloc (4);
1190 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1195 TriggerOneEvent: INSERT { $$ = 'i'; }
1196 | DELETE { $$ = 'd'; }
1197 | UPDATE { $$ = 'u'; }
1200 TriggerForSpec: FOR name name
1202 if ( strcmp ($2, "each") != 0 )
1203 elog(ERROR,"parser: syntax error near %s",$2);
1204 if ( strcmp ($3, "row") == 0 )
1206 else if ( strcmp ($3, "statement") == 0 )
1209 elog(ERROR,"parser: syntax error near %s",$3);
1213 TriggerFuncArgs: TriggerFuncArg
1214 { $$ = lcons($1, NIL); }
1215 | TriggerFuncArgs ',' TriggerFuncArg
1216 { $$ = lappend($1, $3); }
1221 TriggerFuncArg: ICONST
1223 char *s = (char *) palloc (256);
1224 sprintf (s, "%d", $1);
1229 char *s = (char *) palloc (256);
1230 sprintf (s, "%g", $1);
1233 | Sconst { $$ = $1; }
1234 | IDENT { $$ = $1; }
1237 DropTrigStmt: DROP TRIGGER name ON relation_name
1239 DropTrigStmt *n = makeNode(DropTrigStmt);
1247 /*****************************************************************************
1250 * define (type,operator,aggregate)
1252 *****************************************************************************/
1254 DefineStmt: CREATE def_type def_rest
1261 def_rest: def_name definition
1263 $$ = makeNode(DefineStmt);
1265 $$->definition = $2;
1269 def_type: OPERATOR { $$ = OPERATOR; }
1270 | TYPE_P { $$ = TYPE_P; }
1271 | AGGREGATE { $$ = AGGREGATE; }
1274 def_name: PROCEDURE { $$ = "procedure"; }
1275 | JOIN { $$ = "join"; }
1276 | ColId { $$ = $1; }
1277 | MathOp { $$ = $1; }
1281 definition: '(' def_list ')' { $$ = $2; }
1284 def_list: def_elem { $$ = lcons($1, NIL); }
1285 | def_list ',' def_elem { $$ = lappend($1, $3); }
1288 def_elem: def_name '=' def_arg
1290 $$ = makeNode(DefElem);
1292 $$->arg = (Node *)$3;
1296 $$ = makeNode(DefElem);
1298 $$->arg = (Node *)NULL;
1300 | DEFAULT '=' def_arg
1302 $$ = makeNode(DefElem);
1303 $$->defname = "default";
1304 $$->arg = (Node *)$3;
1308 def_arg: ColId { $$ = (Node *)makeString($1); }
1309 | all_Op { $$ = (Node *)makeString($1); }
1310 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1311 | Sconst { $$ = (Node *)makeString($1); }
1314 TypeName *n = makeNode(TypeName);
1317 n->arrayBounds = NULL;
1320 | DOUBLE { $$ = (Node *)makeString("double"); }
1324 /*****************************************************************************
1327 * destroy <relname1> [, <relname2> .. <relnameN> ]
1329 *****************************************************************************/
1331 DestroyStmt: DROP TABLE relation_name_list
1333 DestroyStmt *n = makeNode(DestroyStmt);
1335 n->sequence = FALSE;
1338 | DROP SEQUENCE relation_name_list
1340 DestroyStmt *n = makeNode(DestroyStmt);
1348 /*****************************************************************************
1351 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1353 *****************************************************************************/
1355 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1357 FetchStmt *n = makeNode(FetchStmt);
1364 | MOVE opt_direction fetch_how_many opt_portal_name
1366 FetchStmt *n = makeNode(FetchStmt);
1375 opt_direction: FORWARD { $$ = FORWARD; }
1376 | BACKWARD { $$ = BACKWARD; }
1377 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1380 fetch_how_many: Iconst
1382 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1383 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1384 | /*EMPTY*/ { $$ = 1; /*default*/ }
1387 opt_portal_name: IN name { $$ = $2; }
1388 | /*EMPTY*/ { $$ = NULL; }
1392 /*****************************************************************************
1395 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1397 *****************************************************************************/
1399 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1401 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1407 privileges: ALL PRIVILEGES
1409 $$ = aclmakepriv("rwaR",0);
1413 $$ = aclmakepriv("rwaR",0);
1415 | operation_commalist
1421 operation_commalist: operation
1423 $$ = aclmakepriv("",$1);
1425 | operation_commalist ',' operation
1427 $$ = aclmakepriv($1,$3);
1434 $$ = ACL_MODE_RD_CHR;
1438 $$ = ACL_MODE_AP_CHR;
1442 $$ = ACL_MODE_WR_CHR;
1446 $$ = ACL_MODE_WR_CHR;
1450 $$ = ACL_MODE_RU_CHR;
1456 $$ = aclmakeuser("A","");
1460 $$ = aclmakeuser("G",$2);
1464 $$ = aclmakeuser("U",$1);
1468 opt_with_grant: WITH GRANT OPTION
1470 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1476 /*****************************************************************************
1479 * REVOKE [privileges] ON [relation_name] FROM [user]
1481 *****************************************************************************/
1483 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1485 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1492 /*****************************************************************************
1495 * create index <indexname> on <relname>
1496 * using <access> "(" (<col> with <op>)+ ")" [with
1499 * [where <qual>] is not supported anymore
1500 *****************************************************************************/
1502 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1503 access_method_clause '(' index_params ')' opt_with
1505 /* should check that access_method is valid,
1506 etc ... but doesn't */
1507 IndexStmt *n = makeNode(IndexStmt);
1511 n->accessMethod = $7;
1512 n->indexParams = $9;
1513 n->withClause = $11;
1514 n->whereClause = NULL;
1519 index_opt_unique: UNIQUE { $$ = TRUE; }
1520 | /*EMPTY*/ { $$ = FALSE; }
1523 access_method_clause: USING access_method { $$ = $2; }
1524 | /*EMPTY*/ { $$ = "btree"; }
1527 index_params: index_list { $$ = $1; }
1528 | func_index { $$ = lcons($1,NIL); }
1531 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1532 | index_elem { $$ = lcons($1, NIL); }
1535 func_index: name '(' name_list ')' opt_type opt_class
1537 $$ = makeNode(IndexElem);
1545 index_elem: attr_name opt_type opt_class
1547 $$ = makeNode(IndexElem);
1555 opt_type: ':' Typename { $$ = $2; }
1556 | FOR Typename { $$ = $2; }
1557 | /*EMPTY*/ { $$ = NULL; }
1560 /* opt_class "WITH class" conflicts with preceeding opt_type
1561 * for Typename of "TIMESTAMP WITH TIME ZONE"
1562 * So, remove "WITH class" from the syntax. OK??
1563 * - thomas 1997-10-12
1564 * | WITH class { $$ = $2; }
1566 opt_class: class { $$ = $1; }
1567 | USING class { $$ = $2; }
1568 | /*EMPTY*/ { $$ = NULL; }
1572 /*****************************************************************************
1575 * extend index <indexname> [where <qual>]
1577 *****************************************************************************/
1579 ExtendStmt: EXTEND INDEX index_name where_clause
1581 ExtendStmt *n = makeNode(ExtendStmt);
1583 n->whereClause = $4;
1589 /*****************************************************************************
1592 * execute recipe <recipeName>
1594 *****************************************************************************/
1596 RecipeStmt: EXECUTE RECIPE recipe_name
1599 if (!IsTransactionBlock())
1600 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1602 n = makeNode(RecipeStmt);
1609 /*****************************************************************************
1612 * define function <fname>
1613 * (language = <lang>, returntype = <typename>
1614 * [, arch_pct = <percentage | pre-defined>]
1615 * [, disk_pct = <percentage | pre-defined>]
1616 * [, byte_pct = <percentage | pre-defined>]
1617 * [, perbyte_cpu = <int | pre-defined>]
1618 * [, percall_cpu = <int | pre-defined>]
1620 * [arg is (<type-1> { , <type-n>})]
1621 * as <filename or code in language as appropriate>
1623 *****************************************************************************/
1625 ProcedureStmt: CREATE FUNCTION def_name def_args
1626 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1628 ProcedureStmt *n = makeNode(ProcedureStmt);
1631 n->returnType = (Node *)$6;
1638 opt_with: WITH definition { $$ = $2; }
1639 | /*EMPTY*/ { $$ = NIL; }
1642 def_args: '(' def_name_list ')' { $$ = $2; }
1643 | '(' ')' { $$ = NIL; }
1646 def_name_list: name_list;
1648 /*****************************************************************************
1652 * remove function <funcname>
1653 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1654 * remove aggregate <aggname>
1655 * (REMOVE AGGREGATE "aggname" "aggtype")
1656 * remove operator <opname>
1657 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1658 * remove type <typename>
1659 * (REMOVE TYPE "typename")
1660 * remove rule <rulename>
1661 * (REMOVE RULE "rulename")
1663 *****************************************************************************/
1665 RemoveStmt: DROP remove_type name
1667 RemoveStmt *n = makeNode(RemoveStmt);
1674 remove_type: TYPE_P { $$ = TYPE_P; }
1675 | INDEX { $$ = INDEX; }
1676 | RULE { $$ = RULE; }
1677 | VIEW { $$ = VIEW; }
1680 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1682 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1689 aggr_argtype: name { $$ = $1; }
1690 | '*' { $$ = NULL; }
1693 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1695 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1702 func_argtypes: name_list { $$ = $1; }
1703 | /*EMPTY*/ { $$ = NIL; }
1706 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1708 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1715 all_Op: Op | MathOp;
1717 MathOp: '+' { $$ = "+"; }
1728 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1731 { $$ = makeList(makeString($1), makeString($3), -1); }
1732 | NONE ',' name /* left unary */
1733 { $$ = makeList(NULL, makeString($3), -1); }
1734 | name ',' NONE /* right unary */
1735 { $$ = makeList(makeString($1), NULL, -1); }
1739 /*****************************************************************************
1742 * rename <attrname1> in <relname> [*] to <attrname2>
1743 * rename <relname1> to <relname2>
1745 *****************************************************************************/
1747 RenameStmt: ALTER TABLE relation_name opt_inh_star
1748 RENAME opt_column opt_name TO name
1750 RenameStmt *n = makeNode(RenameStmt);
1759 opt_name: name { $$ = $1; }
1760 | /*EMPTY*/ { $$ = NULL; }
1763 opt_column: COLUMN { $$ = COLUMN; }
1764 | /*EMPTY*/ { $$ = 0; }
1768 /*****************************************************************************
1770 * QUERY: Define Rewrite Rule , Define Tuple Rule
1771 * Define Rule <old rules >
1773 * only rewrite rule is supported -- ay 9/94
1775 *****************************************************************************/
1777 RuleStmt: CREATE RULE name AS
1778 { QueryIsRule=TRUE; }
1779 ON event TO event_object where_clause
1780 DO opt_instead OptStmtList
1782 RuleStmt *n = makeNode(RuleStmt);
1786 n->whereClause = $10;
1793 OptStmtList: NOTHING { $$ = NIL; }
1794 | OptimizableStmt { $$ = lcons($1, NIL); }
1795 | '[' OptStmtBlock ']' { $$ = $2; }
1798 OptStmtBlock: OptStmtMulti
1801 { $$ = lcons($1, NIL); }
1804 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1805 { $$ = lappend($1, $2); }
1806 | OptStmtMulti OptimizableStmt
1807 { $$ = lappend($1, $2); }
1808 | OptimizableStmt ';'
1809 { $$ = lcons($1, NIL); }
1812 event_object: relation_name '.' attr_name
1814 $$ = makeNode(Attr);
1817 $$->attrs = lcons(makeString($3), NIL);
1818 $$->indirection = NIL;
1822 $$ = makeNode(Attr);
1826 $$->indirection = NIL;
1830 /* change me to select, update, etc. some day */
1831 event: SELECT { $$ = CMD_SELECT; }
1832 | UPDATE { $$ = CMD_UPDATE; }
1833 | DELETE { $$ = CMD_DELETE; }
1834 | INSERT { $$ = CMD_INSERT; }
1837 opt_instead: INSTEAD { $$ = TRUE; }
1838 | /*EMPTY*/ { $$ = FALSE; }
1842 /*****************************************************************************
1845 * NOTIFY <relation_name> can appear both in rule bodies and
1846 * as a query-level command
1848 *****************************************************************************/
1850 NotifyStmt: NOTIFY relation_name
1852 NotifyStmt *n = makeNode(NotifyStmt);
1858 ListenStmt: LISTEN relation_name
1860 ListenStmt *n = makeNode(ListenStmt);
1867 /*****************************************************************************
1878 *****************************************************************************/
1880 TransactionStmt: ABORT_TRANS TRANSACTION
1882 TransactionStmt *n = makeNode(TransactionStmt);
1883 n->command = ABORT_TRANS;
1886 | BEGIN_TRANS TRANSACTION
1888 TransactionStmt *n = makeNode(TransactionStmt);
1889 n->command = BEGIN_TRANS;
1894 TransactionStmt *n = makeNode(TransactionStmt);
1895 n->command = BEGIN_TRANS;
1900 TransactionStmt *n = makeNode(TransactionStmt);
1901 n->command = END_TRANS;
1904 | END_TRANS TRANSACTION
1906 TransactionStmt *n = makeNode(TransactionStmt);
1907 n->command = END_TRANS;
1912 TransactionStmt *n = makeNode(TransactionStmt);
1913 n->command = ABORT_TRANS;
1919 TransactionStmt *n = makeNode(TransactionStmt);
1920 n->command = ABORT_TRANS;
1925 TransactionStmt *n = makeNode(TransactionStmt);
1926 n->command = BEGIN_TRANS;
1931 TransactionStmt *n = makeNode(TransactionStmt);
1932 n->command = END_TRANS;
1938 TransactionStmt *n = makeNode(TransactionStmt);
1939 n->command = END_TRANS;
1944 TransactionStmt *n = makeNode(TransactionStmt);
1945 n->command = ABORT_TRANS;
1951 /*****************************************************************************
1954 * define view <viewname> '('target-list ')' [where <quals> ]
1956 *****************************************************************************/
1958 ViewStmt: CREATE VIEW name AS SelectStmt
1960 ViewStmt *n = makeNode(ViewStmt);
1962 n->query = (Query *)$5;
1963 if (((SelectStmt *)n->query)->sortClause != NULL)
1964 elog(ERROR,"Order by and Distinct on views is not implemented.");
1965 if (((SelectStmt *)n->query)->unionClause != NULL)
1966 elog(ERROR,"Views on unions not implemented.");
1972 /*****************************************************************************
1977 *****************************************************************************/
1979 LoadStmt: LOAD file_name
1981 LoadStmt *n = makeNode(LoadStmt);
1988 /*****************************************************************************
1993 *****************************************************************************/
1995 CreatedbStmt: CREATE DATABASE database_name opt_database
1997 CreatedbStmt *n = makeNode(CreatedbStmt);
2004 opt_database: WITH LOCATION '=' location { $$ = $4; }
2005 | /*EMPTY*/ { $$ = NULL; }
2008 location: Sconst { $$ = $1; }
2009 | DEFAULT { $$ = NULL; }
2010 | /*EMPTY*/ { $$ = NULL; }
2013 /*****************************************************************************
2018 *****************************************************************************/
2020 DestroydbStmt: DROP DATABASE database_name
2022 DestroydbStmt *n = makeNode(DestroydbStmt);
2029 /*****************************************************************************
2032 * cluster <index_name> on <relation_name>
2034 *****************************************************************************/
2036 ClusterStmt: CLUSTER index_name ON relation_name
2038 ClusterStmt *n = makeNode(ClusterStmt);
2046 /*****************************************************************************
2051 *****************************************************************************/
2053 VacuumStmt: VACUUM opt_verbose opt_analyze
2055 VacuumStmt *n = makeNode(VacuumStmt);
2062 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2064 VacuumStmt *n = makeNode(VacuumStmt);
2069 if ( $5 != NIL && !$4 )
2070 elog(ERROR,"parser: syntax error at or near \"(\"");
2075 opt_verbose: VERBOSE { $$ = TRUE; }
2076 | /*EMPTY*/ { $$ = FALSE; }
2079 opt_analyze: ANALYZE { $$ = TRUE; }
2080 | /*EMPTY*/ { $$ = FALSE; }
2083 opt_va_list: '(' va_list ')'
2090 { $$=lcons($1,NIL); }
2092 { $$=lappend($1,$3); }
2096 /*****************************************************************************
2101 *****************************************************************************/
2103 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2105 ExplainStmt *n = makeNode(ExplainStmt);
2107 n->query = (Query*)$3;
2113 /*****************************************************************************
2115 * Optimizable Stmts: *
2117 * one of the five queries processed by the planner *
2119 * [ultimately] produces query-trees as specified *
2120 * in the query-spec document in ~postgres/ref *
2122 *****************************************************************************/
2124 OptimizableStmt: SelectStmt
2129 | DeleteStmt /* by default all are $$=$1 */
2133 /*****************************************************************************
2138 *****************************************************************************/
2140 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2148 insert_rest: VALUES '(' res_target_list2 ')'
2150 $$ = makeNode(InsertStmt);
2152 $$->targetList = $3;
2153 $$->fromClause = NIL;
2154 $$->whereClause = NULL;
2155 $$->groupClause = NIL;
2156 $$->havingClause = NULL;
2157 $$->unionClause = NIL;
2159 | SELECT opt_unique res_target_list2
2160 from_clause where_clause
2161 group_clause having_clause
2164 $$ = makeNode(InsertStmt);
2166 $$->targetList = $3;
2167 $$->fromClause = $4;
2168 $$->whereClause = $5;
2169 $$->groupClause = $6;
2170 $$->havingClause = $7;
2171 $$->unionClause = $8;
2175 opt_column_list: '(' columnList ')' { $$ = $2; }
2176 | /*EMPTY*/ { $$ = NIL; }
2180 columnList ',' columnElem
2181 { $$ = lappend($1, $3); }
2183 { $$ = lcons($1, NIL); }
2186 columnElem: ColId opt_indirection
2188 Ident *id = makeNode(Ident);
2190 id->indirection = $2;
2196 /*****************************************************************************
2201 *****************************************************************************/
2203 DeleteStmt: DELETE FROM relation_name
2206 DeleteStmt *n = makeNode(DeleteStmt);
2208 n->whereClause = $4;
2214 /*****************************************************************************
2217 * UpdateStmt (UPDATE)
2219 *****************************************************************************/
2221 UpdateStmt: UPDATE relation_name
2226 UpdateStmt *n = makeNode(UpdateStmt);
2230 n->whereClause = $6;
2236 /*****************************************************************************
2241 *****************************************************************************/
2242 CursorStmt: DECLARE name opt_binary CURSOR FOR
2243 SELECT opt_unique res_target_list2
2244 from_clause where_clause
2245 group_clause having_clause
2246 union_clause sort_clause
2248 SelectStmt *n = makeNode(SelectStmt);
2250 /* from PORTAL name */
2252 * 15 august 1991 -- since 3.0 postgres does locking
2253 * right, we discovered that portals were violating
2254 * locking protocol. portal locks cannot span xacts.
2255 * as a short-term fix, we installed the check here.
2258 if (!IsTransactionBlock())
2259 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2266 n->whereClause = $10;
2267 n->groupClause = $11;
2268 n->havingClause = $12;
2269 n->unionClause = $13;
2270 n->sortClause = $14;
2276 /*****************************************************************************
2281 *****************************************************************************/
2283 SelectStmt: SELECT opt_unique res_target_list2
2284 result from_clause where_clause
2285 group_clause having_clause
2286 union_clause sort_clause
2288 SelectStmt *n = makeNode(SelectStmt);
2293 n->whereClause = $6;
2294 n->groupClause = $7;
2295 n->havingClause = $8;
2296 n->unionClause = $9;
2297 n->sortClause = $10;
2302 union_clause: UNION opt_union select_list
2304 SelectStmt *n = (SelectStmt *)lfirst($3);
2312 select_list: select_list UNION opt_union SubSelect
2314 SelectStmt *n = (SelectStmt *)$4;
2316 $$ = lappend($1, $4);
2319 { $$ = lcons($1, NIL); }
2322 SubSelect: SELECT opt_unique res_target_list2
2323 from_clause where_clause
2324 group_clause having_clause
2326 SelectStmt *n = makeNode(SelectStmt);
2328 n->unionall = FALSE;
2331 n->whereClause = $5;
2332 n->groupClause = $6;
2333 n->havingClause = $7;
2338 result: INTO TABLE relation_name
2344 opt_union: ALL { $$ = TRUE; }
2345 | /*EMPTY*/ { $$ = FALSE; }
2348 opt_unique: DISTINCT { $$ = "*"; }
2349 | DISTINCT ON ColId { $$ = $3; }
2350 | ALL { $$ = NULL; }
2351 | /*EMPTY*/ { $$ = NULL; }
2354 sort_clause: ORDER BY sortby_list { $$ = $3; }
2355 | /*EMPTY*/ { $$ = NIL; }
2358 sortby_list: sortby { $$ = lcons($1, NIL); }
2359 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2362 sortby: ColId OptUseOp
2364 $$ = makeNode(SortGroupBy);
2370 | ColId '.' ColId OptUseOp
2372 $$ = makeNode(SortGroupBy);
2380 $$ = makeNode(SortGroupBy);
2388 OptUseOp: USING Op { $$ = $2; }
2389 | USING '<' { $$ = "<"; }
2390 | USING '>' { $$ = ">"; }
2392 | DESC { $$ = ">"; }
2393 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2397 * jimmy bell-style recursive queries aren't supported in the
2400 * ...however, recursive addattr and rename supported. make special
2403 opt_inh_star: '*' { $$ = TRUE; }
2404 | /*EMPTY*/ { $$ = FALSE; }
2407 relation_name_list: name_list;
2410 { $$ = lcons(makeString($1),NIL); }
2411 | name_list ',' name
2412 { $$ = lappend($1,makeString($3)); }
2415 group_clause: GROUP BY groupby_list { $$ = $3; }
2416 | /*EMPTY*/ { $$ = NIL; }
2419 groupby_list: groupby { $$ = lcons($1, NIL); }
2420 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2425 $$ = makeNode(SortGroupBy);
2433 $$ = makeNode(SortGroupBy);
2441 $$ = makeNode(SortGroupBy);
2449 having_clause: HAVING a_expr
2451 elog(NOTICE, "HAVING not yet supported; ignore clause");
2454 | /*EMPTY*/ { $$ = NULL; }
2458 /*****************************************************************************
2460 * clauses common to all Optimizable Stmts:
2464 *****************************************************************************/
2466 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2469 elog(ERROR,"JOIN not yet implemented");
2471 | FROM from_list { $$ = $2; }
2472 | /*EMPTY*/ { $$ = NIL; }
2475 from_list: from_list ',' from_val
2476 { $$ = lappend($1, $3); }
2477 | from_val CROSS JOIN from_val
2478 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2480 { $$ = lcons($1, NIL); }
2483 from_val: relation_expr AS ColLabel
2485 $$ = makeNode(RangeVar);
2489 | relation_expr ColId
2491 $$ = makeNode(RangeVar);
2497 $$ = makeNode(RangeVar);
2503 join_expr: NATURAL join_expr { $$ = NULL; }
2505 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2507 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2509 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2511 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2513 { elog(ERROR,"INNER JOIN not yet implemented"); }
2515 { elog(ERROR,"UNION JOIN not yet implemented"); }
2517 { elog(ERROR,"INNER JOIN not yet implemented"); }
2520 join_outer: OUTER_P { $$ = NULL; }
2521 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2524 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2525 | USING '(' join_list ')' { $$ = NULL; }
2526 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2529 join_list: join_using { $$ = lcons($1, NIL); }
2530 | join_list ',' join_using { $$ = lappend($1, $3); }
2535 $$ = makeNode(SortGroupBy);
2543 $$ = makeNode(SortGroupBy);
2551 $$ = makeNode(SortGroupBy);
2559 where_clause: WHERE a_expr { $$ = $2; }
2560 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2563 relation_expr: relation_name
2565 /* normal relations */
2566 $$ = makeNode(RelExpr);
2570 | relation_name '*' %prec '='
2572 /* inheritance query */
2573 $$ = makeNode(RelExpr);
2578 opt_array_bounds: '[' ']' nest_array_bounds
2579 { $$ = lcons(makeInteger(-1), $3); }
2580 | '[' Iconst ']' nest_array_bounds
2581 { $$ = lcons(makeInteger($2), $4); }
2586 nest_array_bounds: '[' ']' nest_array_bounds
2587 { $$ = lcons(makeInteger(-1), $3); }
2588 | '[' Iconst ']' nest_array_bounds
2589 { $$ = lcons(makeInteger($2), $4); }
2595 /*****************************************************************************
2598 * SQL92 introduces a large amount of type-specific syntax.
2599 * Define individual clauses to handle these cases, and use
2600 * the generic case to handle regular type-extensible Postgres syntax.
2601 * - thomas 1997-10-10
2603 *****************************************************************************/
2605 Typename: Array opt_array_bounds
2608 $$->arrayBounds = $2;
2610 /* Is this the name of a complex type? If so, implement
2613 if (!strcmp(saved_relname, $$->name))
2614 /* This attr is the same type as the relation
2615 * being defined. The classic example: create
2616 * emp(name=text,mgr=emp)
2619 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2620 /* (Eventually add in here that the set can only
2621 * contain one element.)
2642 $$ = makeNode(TypeName);
2643 $$->name = xlateSqlType($1);
2647 generic: Id { $$ = $1; }
2648 | TYPE_P { $$ = xlateSqlType("type"); }
2649 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2652 /* SQL92 numeric data types
2653 * Check FLOAT() precision limits assuming IEEE floating types.
2654 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2655 * by checking parameters and making sure they match what is possible with INTEGER.
2656 * - thomas 1997-09-18
2658 Numeric: FLOAT opt_float
2660 $$ = makeNode(TypeName);
2661 $$->name = xlateSqlType($2);
2663 | DECIMAL opt_decimal
2665 $$ = makeNode(TypeName);
2666 $$->name = xlateSqlType("integer");
2668 | NUMERIC opt_numeric
2670 $$ = makeNode(TypeName);
2671 $$->name = xlateSqlType("integer");
2675 opt_float: '(' Iconst ')'
2678 elog(ERROR,"precision for FLOAT must be at least 1");
2680 $$ = xlateSqlType("float4");
2682 $$ = xlateSqlType("float8");
2684 elog(ERROR,"precision for FLOAT must be less than 16");
2688 $$ = xlateSqlType("float8");
2692 opt_numeric: '(' Iconst ',' Iconst ')'
2695 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2697 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2702 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2710 opt_decimal: '(' Iconst ',' Iconst ')'
2713 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2715 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2721 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2730 /* SQL92 character data types
2731 * The following implements CHAR() and VARCHAR().
2732 * We do it here instead of the 'Generic' production
2733 * because we don't want to allow arrays of VARCHAR().
2734 * I haven't thought about whether that will work or not.
2737 Character: character '(' Iconst ')'
2739 $$ = makeNode(TypeName);
2740 if (!strcasecmp($1, "char"))
2741 $$->name = xlateSqlType("bpchar");
2742 else if (!strcasecmp($1, "varchar"))
2743 $$->name = xlateSqlType("varchar");
2745 yyerror("parse error");
2747 elog(ERROR,"length for '%s' type must be at least 1",$1);
2749 /* we can store a char() of length up to the size
2750 * of a page (8KB) - page headers and friends but
2751 * just to be safe here... - ay 6/95
2752 * XXX note this hardcoded limit - thomas 1997-07-13
2754 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2756 /* we actually implement this sort of like a varlen, so
2757 * the first 4 bytes is the length. (the difference
2758 * between this and "text" is that we blank-pad and
2759 * truncate where necessary
2761 $$->typmod = VARHDRSZ + $3;
2765 $$ = makeNode(TypeName);
2766 $$->name = xlateSqlType($1);
2770 character: CHARACTER opt_varying opt_charset opt_collate
2773 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2774 if ($2) type = xlateSqlType("varchar");
2775 else type = xlateSqlType("char");
2778 c = palloc(strlen("var") + strlen($3) + 1);
2781 type = xlateSqlType(c);
2783 type = xlateSqlType($3);
2787 elog(ERROR,"COLLATE %s not yet implemented",$4);
2790 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2791 | VARCHAR { $$ = xlateSqlType("varchar"); }
2792 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2793 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2796 opt_varying: VARYING { $$ = TRUE; }
2797 | /*EMPTY*/ { $$ = FALSE; }
2800 opt_charset: CHARACTER SET ColId { $$ = $3; }
2801 | /*EMPTY*/ { $$ = NULL; }
2804 opt_collate: COLLATE ColId { $$ = $2; }
2805 | /*EMPTY*/ { $$ = NULL; }
2810 $$ = makeNode(TypeName);
2811 $$->name = xlateSqlType($1);
2813 | TIMESTAMP opt_timezone
2815 $$ = makeNode(TypeName);
2816 $$->name = xlateSqlType("timestamp");
2821 $$ = makeNode(TypeName);
2822 $$->name = xlateSqlType("time");
2824 | INTERVAL opt_interval
2826 $$ = makeNode(TypeName);
2827 $$->name = xlateSqlType("interval");
2831 datetime: YEAR_P { $$ = "year"; }
2832 | MONTH_P { $$ = "month"; }
2833 | DAY_P { $$ = "day"; }
2834 | HOUR_P { $$ = "hour"; }
2835 | MINUTE_P { $$ = "minute"; }
2836 | SECOND_P { $$ = "second"; }
2839 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2840 | /*EMPTY*/ { $$ = FALSE; }
2843 opt_interval: datetime { $$ = lcons($1, NIL); }
2844 | YEAR_P TO MONTH_P { $$ = NIL; }
2845 | DAY_P TO HOUR_P { $$ = NIL; }
2846 | DAY_P TO MINUTE_P { $$ = NIL; }
2847 | DAY_P TO SECOND_P { $$ = NIL; }
2848 | HOUR_P TO MINUTE_P { $$ = NIL; }
2849 | HOUR_P TO SECOND_P { $$ = NIL; }
2850 | /*EMPTY*/ { $$ = NIL; }
2854 /*****************************************************************************
2856 * expression grammar, still needs some cleanup
2858 *****************************************************************************/
2860 a_expr_or_null: a_expr
2864 A_Const *n = makeNode(A_Const);
2865 n->val.type = T_Null;
2870 /* Expressions using row descriptors
2871 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2872 * with singleton expressions.
2874 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2876 SubLink *n = makeNode(SubLink);
2878 n->oper = lcons("=",NIL);
2880 n->subLinkType = ANY_SUBLINK;
2884 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
2886 SubLink *n = makeNode(SubLink);
2888 n->oper = lcons("<>",NIL);
2890 n->subLinkType = ALL_SUBLINK;
2894 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
2896 SubLink *n = makeNode(SubLink);
2898 n->oper = lcons($4,NIL);
2900 n->subLinkType = ANY_SUBLINK;
2904 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
2906 SubLink *n = makeNode(SubLink);
2908 n->oper = lcons($4,NIL);
2910 n->subLinkType = ALL_SUBLINK;
2914 | '(' row_descriptor ')' Op '(' SubSelect ')'
2916 SubLink *n = makeNode(SubLink);
2918 n->oper = lcons($4, NIL);
2919 if (strcmp($4,"<>") == 0)
2923 n->subLinkType = EXPR_SUBLINK;
2927 | '(' row_descriptor ')' Op '(' row_descriptor ')'
2929 $$ = makeRowExpr($4, $2, $6);
2933 row_descriptor: row_list ',' a_expr
2935 $$ = lappend($1, $3);
2939 row_list: row_list ',' a_expr
2941 $$ = lappend($1, $3);
2945 $$ = lcons($1, NIL);
2949 a_expr: attr opt_indirection
2951 $1->indirection = $2;
2958 | '-' a_expr %prec UMINUS
2959 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2961 { $$ = makeA_Expr(OP, "+", $1, $3); }
2963 { $$ = makeA_Expr(OP, "-", $1, $3); }
2965 { $$ = makeA_Expr(OP, "/", $1, $3); }
2967 { $$ = makeA_Expr(OP, "*", $1, $3); }
2969 { $$ = makeA_Expr(OP, "<", $1, $3); }
2971 { $$ = makeA_Expr(OP, ">", $1, $3); }
2973 { $$ = makeA_Expr(OP, "=", $1, $3); }
2975 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2977 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2979 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2980 | a_expr TYPECAST Typename
2983 /* AexprConst can be either A_Const or ParamNo */
2984 if (nodeTag($1) == T_A_Const) {
2985 ((A_Const *)$1)->typename = $3;
2986 } else if (nodeTag($1) == T_Param) {
2987 ((ParamNo *)$1)->typename = $3;
2988 /* otherwise, try to transform to a function call */
2990 FuncCall *n = makeNode(FuncCall);
2991 n->funcname = $3->name;
2992 n->args = lcons($1,NIL);
2996 | CAST a_expr AS Typename
2999 /* AexprConst can be either A_Const or ParamNo */
3000 if (nodeTag($2) == T_A_Const) {
3001 ((A_Const *)$2)->typename = $4;
3002 } else if (nodeTag($2) == T_Param) {
3003 ((ParamNo *)$2)->typename = $4;
3004 /* otherwise, try to transform to a function call */
3006 FuncCall *n = makeNode(FuncCall);
3007 n->funcname = $4->name;
3008 n->args = lcons($2,NIL);
3012 | '(' a_expr_or_null ')'
3015 { $$ = makeIndexable($2,$1,$3); }
3016 | a_expr LIKE a_expr
3017 { $$ = makeIndexable("~~", $1, $3); }
3018 | a_expr NOT LIKE a_expr
3019 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3021 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3023 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3026 /* could be a column name or a relation_name */
3027 Ident *n = makeNode(Ident);
3029 n->indirection = NULL;
3034 /* cheap hack for aggregate (eg. count) */
3035 FuncCall *n = makeNode(FuncCall);
3036 A_Const *star = makeNode(A_Const);
3038 star->val.type = T_String;
3039 star->val.val.str = "";
3041 n->args = lcons(star, NIL);
3046 FuncCall *n = makeNode(FuncCall);
3051 | name '(' expr_list ')'
3053 FuncCall *n = makeNode(FuncCall);
3060 A_Const *n = makeNode(A_Const);
3061 TypeName *t = makeNode(TypeName);
3063 n->val.type = T_String;
3064 n->val.val.str = "now";
3067 t->name = xlateSqlType("date");
3074 A_Const *n = makeNode(A_Const);
3075 TypeName *t = makeNode(TypeName);
3077 n->val.type = T_String;
3078 n->val.val.str = "now";
3081 t->name = xlateSqlType("time");
3086 | CURRENT_TIME '(' Iconst ')'
3088 FuncCall *n = makeNode(FuncCall);
3089 A_Const *s = makeNode(A_Const);
3090 TypeName *t = makeNode(TypeName);
3092 n->funcname = xlateSqlType("time");
3093 n->args = lcons(s, NIL);
3095 s->val.type = T_String;
3096 s->val.val.str = "now";
3099 t->name = xlateSqlType("time");
3103 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3109 A_Const *n = makeNode(A_Const);
3110 TypeName *t = makeNode(TypeName);
3112 n->val.type = T_String;
3113 n->val.val.str = "now";
3116 t->name = xlateSqlType("timestamp");
3121 | CURRENT_TIMESTAMP '(' Iconst ')'
3123 FuncCall *n = makeNode(FuncCall);
3124 A_Const *s = makeNode(A_Const);
3125 TypeName *t = makeNode(TypeName);
3127 n->funcname = xlateSqlType("timestamp");
3128 n->args = lcons(s, NIL);
3130 s->val.type = T_String;
3131 s->val.val.str = "now";
3134 t->name = xlateSqlType("timestamp");
3138 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3144 FuncCall *n = makeNode(FuncCall);
3145 n->funcname = "getpgusername";
3149 | EXISTS '(' SubSelect ')'
3151 SubLink *n = makeNode(SubLink);
3155 n->subLinkType = EXISTS_SUBLINK;
3159 | EXTRACT '(' extract_list ')'
3161 FuncCall *n = makeNode(FuncCall);
3162 n->funcname = "date_part";
3166 | POSITION '(' position_list ')'
3168 FuncCall *n = makeNode(FuncCall);
3169 n->funcname = "strpos";
3173 | SUBSTRING '(' substr_list ')'
3175 FuncCall *n = makeNode(FuncCall);
3176 n->funcname = "substr";
3180 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3181 | TRIM '(' BOTH trim_list ')'
3183 FuncCall *n = makeNode(FuncCall);
3184 n->funcname = "btrim";
3188 | TRIM '(' LEADING trim_list ')'
3190 FuncCall *n = makeNode(FuncCall);
3191 n->funcname = "ltrim";
3195 | TRIM '(' TRAILING trim_list ')'
3197 FuncCall *n = makeNode(FuncCall);
3198 n->funcname = "rtrim";
3202 | TRIM '(' trim_list ')'
3204 FuncCall *n = makeNode(FuncCall);
3205 n->funcname = "btrim";
3210 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3212 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3214 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3215 | a_expr IS NOT NULL_P
3216 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3217 /* IS TRUE, IS FALSE, etc used to be function calls
3218 * but let's make them expressions to allow the optimizer
3219 * a chance to eliminate them if a_expr is a constant string.
3220 * - thomas 1997-12-22
3224 A_Const *n = makeNode(A_Const);
3225 n->val.type = T_String;
3226 n->val.val.str = "t";
3227 n->typename = makeNode(TypeName);
3228 n->typename->name = xlateSqlType("bool");
3229 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3231 | a_expr IS NOT FALSE_P
3233 A_Const *n = makeNode(A_Const);
3234 n->val.type = T_String;
3235 n->val.val.str = "t";
3236 n->typename = makeNode(TypeName);
3237 n->typename->name = xlateSqlType("bool");
3238 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3242 A_Const *n = makeNode(A_Const);
3243 n->val.type = T_String;
3244 n->val.val.str = "f";
3245 n->typename = makeNode(TypeName);
3246 n->typename->name = xlateSqlType("bool");
3247 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3249 | a_expr IS NOT TRUE_P
3251 A_Const *n = makeNode(A_Const);
3252 n->val.type = T_String;
3253 n->val.val.str = "f";
3254 n->typename = makeNode(TypeName);
3255 n->typename->name = xlateSqlType("bool");
3256 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3258 | a_expr BETWEEN AexprConst AND AexprConst
3260 $$ = makeA_Expr(AND, NULL,
3261 makeA_Expr(OP, ">=", $1, $3),
3262 makeA_Expr(OP, "<=", $1, $5));
3264 | a_expr NOT BETWEEN AexprConst AND AexprConst
3266 $$ = makeA_Expr(OR, NULL,
3267 makeA_Expr(OP, "<", $1, $4),
3268 makeA_Expr(OP, ">", $1, $6));
3270 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')' { saved_In_Expr = lnext(saved_In_Expr); }
3272 if (nodeTag($5) == T_SubLink)
3274 SubLink *n = (SubLink *)$5;
3275 n->lefthand = lcons($1, NIL);
3276 n->oper = lcons("=",NIL);
3278 n->subLinkType = ANY_SUBLINK;
3283 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')' { saved_In_Expr = lnext(saved_In_Expr); }
3285 if (nodeTag($6) == T_SubLink)
3287 SubLink *n = (SubLink *)$6;
3288 n->lefthand = lcons($1, NIL);
3289 n->oper = lcons("<>",NIL);
3291 n->subLinkType = ALL_SUBLINK;
3296 | a_expr Op ANY '(' SubSelect ')'
3298 SubLink *n = makeNode(SubLink);
3299 n->lefthand = lcons($1,NIL);
3300 n->oper = lcons($2,NIL);
3302 n->subLinkType = ANY_SUBLINK;
3306 | a_expr Op ALL '(' SubSelect ')'
3308 SubLink *n = makeNode(SubLink);
3309 n->lefthand = lcons($1, NULL);
3310 n->oper = lcons($2,NIL);
3312 n->subLinkType = ALL_SUBLINK;
3317 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3319 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3321 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3324 opt_indirection: '[' a_expr ']' opt_indirection
3326 A_Indices *ai = makeNode(A_Indices);
3331 | '[' a_expr ':' a_expr ']' opt_indirection
3333 A_Indices *ai = makeNode(A_Indices);
3342 expr_list: a_expr_or_null
3343 { $$ = lcons($1, NIL); }
3344 | expr_list ',' a_expr_or_null
3345 { $$ = lappend($1, $3); }
3346 | expr_list USING a_expr
3347 { $$ = lappend($1, $3); }
3350 extract_list: datetime FROM a_expr
3352 A_Const *n = makeNode(A_Const);
3353 n->val.type = T_String;
3354 n->val.val.str = $1;
3355 $$ = lappend(lcons((Node *)n,NIL), $3);
3361 position_list: position_expr IN position_expr
3362 { $$ = makeList($3, $1, -1); }
3367 position_expr: attr opt_indirection
3369 $1->indirection = $2;
3374 | '-' position_expr %prec UMINUS
3375 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3376 | position_expr '+' position_expr
3377 { $$ = makeA_Expr(OP, "+", $1, $3); }
3378 | position_expr '-' position_expr
3379 { $$ = makeA_Expr(OP, "-", $1, $3); }
3380 | position_expr '/' position_expr
3381 { $$ = makeA_Expr(OP, "/", $1, $3); }
3382 | position_expr '*' position_expr
3383 { $$ = makeA_Expr(OP, "*", $1, $3); }
3385 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3386 | position_expr TYPECAST Typename
3389 /* AexprConst can be either A_Const or ParamNo */
3390 if (nodeTag($1) == T_A_Const) {
3391 ((A_Const *)$1)->typename = $3;
3392 } else if (nodeTag($1) == T_Param) {
3393 ((ParamNo *)$1)->typename = $3;
3394 /* otherwise, try to transform to a function call */
3396 FuncCall *n = makeNode(FuncCall);
3397 n->funcname = $3->name;
3398 n->args = lcons($1,NIL);
3402 | CAST position_expr AS Typename
3405 /* AexprConst can be either A_Const or ParamNo */
3406 if (nodeTag($2) == T_A_Const) {
3407 ((A_Const *)$2)->typename = $4;
3408 } else if (nodeTag($2) == T_Param) {
3409 ((ParamNo *)$2)->typename = $4;
3410 /* otherwise, try to transform to a function call */
3412 FuncCall *n = makeNode(FuncCall);
3413 n->funcname = $4->name;
3414 n->args = lcons($2,NIL);
3418 | '(' position_expr ')'
3420 | position_expr Op position_expr
3421 { $$ = makeA_Expr(OP, $2, $1, $3); }
3423 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3425 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3428 /* could be a column name or a relation_name */
3429 Ident *n = makeNode(Ident);
3431 n->indirection = NULL;
3436 FuncCall *n = makeNode(FuncCall);
3441 | name '(' expr_list ')'
3443 FuncCall *n = makeNode(FuncCall);
3448 | POSITION '(' position_list ')'
3450 FuncCall *n = makeNode(FuncCall);
3451 n->funcname = "strpos";
3455 | SUBSTRING '(' substr_list ')'
3457 FuncCall *n = makeNode(FuncCall);
3458 n->funcname = "substr";
3462 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3463 | TRIM '(' BOTH trim_list ')'
3465 FuncCall *n = makeNode(FuncCall);
3466 n->funcname = "btrim";
3470 | TRIM '(' LEADING trim_list ')'
3472 FuncCall *n = makeNode(FuncCall);
3473 n->funcname = "ltrim";
3477 | TRIM '(' TRAILING trim_list ')'
3479 FuncCall *n = makeNode(FuncCall);
3480 n->funcname = "rtrim";
3484 | TRIM '(' trim_list ')'
3486 FuncCall *n = makeNode(FuncCall);
3487 n->funcname = "btrim";
3493 substr_list: expr_list substr_from substr_for
3495 $$ = nconc(nconc($1,$2),$3);
3501 substr_from: FROM expr_list
3505 A_Const *n = makeNode(A_Const);
3506 n->val.type = T_Integer;
3507 n->val.val.ival = 1;
3508 $$ = lcons((Node *)n,NIL);
3512 substr_for: FOR expr_list
3518 trim_list: a_expr FROM expr_list
3519 { $$ = lappend($3, $1); }
3528 SubLink *n = makeNode(SubLink);
3536 in_expr_nodes: AexprConst
3537 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
3538 | in_expr_nodes ',' AexprConst
3539 { $$ = makeA_Expr(OR, NULL, $1,
3540 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
3544 not_in_expr: SubSelect
3546 SubLink *n = makeNode(SubLink);
3554 not_in_expr_nodes: AexprConst
3555 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
3556 | not_in_expr_nodes ',' AexprConst
3557 { $$ = makeA_Expr(AND, NULL, $1,
3558 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
3562 attr: relation_name '.' attrs
3564 $$ = makeNode(Attr);
3568 $$->indirection = NULL;
3572 $$ = makeNode(Attr);
3576 $$->indirection = NULL;
3581 { $$ = lcons(makeString($1), NIL); }
3582 | attrs '.' attr_name
3583 { $$ = lappend($1, makeString($3)); }
3585 { $$ = lappend($1, makeString("*")); }
3589 /*****************************************************************************
3593 *****************************************************************************/
3595 res_target_list: res_target_list ',' res_target_el
3596 { $$ = lappend($1,$3); }
3598 { $$ = lcons($1, NIL); }
3601 ResTarget *rt = makeNode(ResTarget);
3602 Attr *att = makeNode(Attr);
3604 att->paramNo = NULL;
3606 att->indirection = NIL;
3608 rt->indirection = NULL;
3609 rt->val = (Node *)att;
3610 $$ = lcons(rt, NIL);
3614 res_target_el: ColId opt_indirection '=' a_expr_or_null
3616 $$ = makeNode(ResTarget);
3618 $$->indirection = $2;
3619 $$->val = (Node *)$4;
3621 | attr opt_indirection
3623 $$ = makeNode(ResTarget);
3625 $$->indirection = $2;
3626 $$->val = (Node *)$1;
3628 | relation_name '.' '*'
3630 Attr *att = makeNode(Attr);
3632 att->paramNo = NULL;
3633 att->attrs = lcons(makeString("*"), NIL);
3634 att->indirection = NIL;
3635 $$ = makeNode(ResTarget);
3637 $$->indirection = NULL;
3638 $$->val = (Node *)att;
3643 ** target list for select.
3644 ** should get rid of the other but is still needed by the defunct select into
3645 ** and update (uses a subset)
3647 res_target_list2: res_target_list2 ',' res_target_el2
3648 { $$ = lappend($1, $3); }
3650 { $$ = lcons($1, NIL); }
3653 /* AS is not optional because shift/red conflict with unary ops */
3654 res_target_el2: a_expr_or_null AS ColLabel
3656 $$ = makeNode(ResTarget);
3658 $$->indirection = NULL;
3659 $$->val = (Node *)$1;
3663 $$ = makeNode(ResTarget);
3665 $$->indirection = NULL;
3666 $$->val = (Node *)$1;
3668 | relation_name '.' '*'
3670 Attr *att = makeNode(Attr);
3672 att->paramNo = NULL;
3673 att->attrs = lcons(makeString("*"), NIL);
3674 att->indirection = NIL;
3675 $$ = makeNode(ResTarget);
3677 $$->indirection = NULL;
3678 $$->val = (Node *)att;
3682 Attr *att = makeNode(Attr);
3684 att->paramNo = NULL;
3686 att->indirection = NIL;
3687 $$ = makeNode(ResTarget);
3689 $$->indirection = NULL;
3690 $$->val = (Node *)att;
3694 opt_id: ColId { $$ = $1; }
3695 | /* EMPTY */ { $$ = NULL; }
3698 relation_name: SpecialRuleRelation
3701 StrNCpy(saved_relname, $1, NAMEDATALEN);
3705 /* disallow refs to variable system tables */
3706 if (strcmp(LogRelationName, $1) == 0
3707 || strcmp(VariableRelationName, $1) == 0)
3708 elog(ERROR,"%s cannot be accessed by users",$1);
3711 StrNCpy(saved_relname, $1, NAMEDATALEN);
3715 database_name: ColId { $$ = $1; };
3716 access_method: Id { $$ = $1; };
3717 attr_name: ColId { $$ = $1; };
3718 class: Id { $$ = $1; };
3719 index_name: ColId { $$ = $1; };
3722 * Include date/time keywords as SQL92 extension.
3723 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3725 name: ColId { $$ = $1; };
3727 file_name: Sconst { $$ = $1; };
3728 recipe_name: Id { $$ = $1; };
3731 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
3735 A_Const *n = makeNode(A_Const);
3736 n->val.type = T_Integer;
3737 n->val.val.ival = $1;
3742 A_Const *n = makeNode(A_Const);
3743 n->val.type = T_Float;
3744 n->val.val.dval = $1;
3749 A_Const *n = makeNode(A_Const);
3750 n->val.type = T_String;
3751 n->val.val.str = $1;
3756 A_Const *n = makeNode(A_Const);
3758 n->val.type = T_String;
3759 n->val.val.str = $2;
3763 { $$ = (Node *)$1; }
3766 A_Const *n = makeNode(A_Const);
3767 n->val.type = T_String;
3768 n->val.val.str = "t";
3769 n->typename = makeNode(TypeName);
3770 n->typename->name = xlateSqlType("bool");
3775 A_Const *n = makeNode(A_Const);
3776 n->val.type = T_String;
3777 n->val.val.str = "f";
3778 n->typename = makeNode(TypeName);
3779 n->typename->name = xlateSqlType("bool");
3786 $$ = makeNode(ParamNo);
3791 NumConst: Iconst { $$ = makeInteger($1); }
3792 | FCONST { $$ = makeFloat($1); }
3795 Iconst: ICONST { $$ = $1; };
3796 Sconst: SCONST { $$ = $1; };
3798 /* Column and type identifier
3799 * Does not include explicit datetime types
3800 * since these must be decoupled in Typename syntax.
3801 * Use ColId for most identifiers. - thomas 1997-10-21
3803 Id: IDENT { $$ = $1; };
3805 /* Column identifier
3806 * Include date/time keywords as SQL92 extension.
3807 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3808 * Add other keywords. Note that as the syntax expands,
3809 * some of these keywords will have to be removed from this
3810 * list due to shift/reduce conflicts in yacc. If so, move
3811 * down to the ColLabel entity. - thomas 1997-11-06
3813 ColId: Id { $$ = $1; }
3814 | datetime { $$ = $1; }
3815 | ACTION { $$ = "action"; }
3816 | DATABASE { $$ = "database"; }
3817 | DELIMITERS { $$ = "delimiters"; }
3818 | FUNCTION { $$ = "function"; }
3819 | INDEX { $$ = "index"; }
3820 | KEY { $$ = "key"; }
3821 | LANGUAGE { $$ = "language"; }
3822 | LOCATION { $$ = "location"; }
3823 | MATCH { $$ = "match"; }
3824 | OPERATOR { $$ = "operator"; }
3825 | OPTION { $$ = "option"; }
3826 | PRIVILEGES { $$ = "privileges"; }
3827 | RECIPE { $$ = "recipe"; }
3828 | TIME { $$ = "time"; }
3829 | TRIGGER { $$ = "trigger"; }
3830 | TYPE_P { $$ = "type"; }
3831 | VERSION { $$ = "version"; }
3832 | ZONE { $$ = "zone"; }
3836 * Allowed labels in "AS" clauses.
3837 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
3838 * compatibility. Cannot allow this for column names since the
3839 * syntax would not distinguish between the constant value and
3840 * a column name. - thomas 1997-10-24
3841 * Add other keywords to this list. Note that they appear here
3842 * rather than in ColId if there was a shift/reduce conflict
3843 * when used as a full identifier. - thomas 1997-11-06
3845 ColLabel: ColId { $$ = $1; }
3846 | ARCHIVE { $$ = "archive"; }
3847 | CLUSTER { $$ = "cluster"; }
3848 | CONSTRAINT { $$ = "constraint"; }
3849 | CROSS { $$ = "cross"; }
3850 | FOREIGN { $$ = "foreign"; }
3851 | GROUP { $$ = "group"; }
3852 | LOAD { $$ = "load"; }
3853 | ORDER { $$ = "order"; }
3854 | POSITION { $$ = "position"; }
3855 | PRECISION { $$ = "precision"; }
3856 | TABLE { $$ = "table"; }
3857 | TRANSACTION { $$ = "transaction"; }
3858 | TRUE_P { $$ = "true"; }
3859 | FALSE_P { $$ = "false"; }
3862 SpecialRuleRelation: CURRENT
3867 elog(ERROR,"CURRENT used in non-rule query");
3874 elog(ERROR,"NEW used in non-rule query");
3881 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
3883 A_Expr *a = makeNode(A_Expr);
3892 * Generate separate operator nodes for a single row descriptor expression.
3893 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
3896 makeRowExpr(char *opr, List *largs, List *rargs)
3901 if (length(largs) != length(rargs))
3902 elog(ERROR,"Unequal number of entries in row expression");
3904 if (lnext(largs) != NIL)
3905 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
3907 larg = lfirst(largs);
3908 rarg = lfirst(rargs);
3910 if ((strcmp(opr, "=") == 0)
3911 || (strcmp(opr, "<") == 0)
3912 || (strcmp(opr, "<=") == 0)
3913 || (strcmp(opr, ">") == 0)
3914 || (strcmp(opr, ">=") == 0))
3917 expr = makeA_Expr(OP, opr, larg, rarg);
3919 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3921 else if (strcmp(opr, "<>") == 0)
3924 expr = makeA_Expr(OP, opr, larg, rarg);
3926 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3930 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
3934 while ((largs != NIL) && (rargs != NIL))
3936 larg = lfirst(largs);
3937 rarg = lfirst(rargs);
3940 expr = makeA_Expr(OP, opr, larg, rarg);
3942 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3944 largs = lnext(largs);
3945 rargs = lnext(rargs);
3954 mapTargetColumns(List *src, List *dst)
3959 if (length(src) != length(dst))
3960 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
3962 while ((src != NIL) && (dst != NIL))
3964 s = (ColumnDef *)lfirst(src);
3965 d = (ResTarget *)lfirst(dst);
3967 d->name = s->colname;
3974 } /* mapTargetColumns() */
3976 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
3978 Node *result = NULL;
3980 /* we do this so indexes can be used */
3981 if (strcmp(opname,"~") == 0 ||
3982 strcmp(opname,"~*") == 0)
3984 if (nodeTag(rexpr) == T_A_Const &&
3985 ((A_Const *)rexpr)->val.type == T_String &&
3986 ((A_Const *)rexpr)->val.val.str[0] == '^')
3988 A_Const *n = (A_Const *)rexpr;
3989 char *match_least = palloc(strlen(n->val.val.str)+2);
3990 char *match_most = palloc(strlen(n->val.val.str)+2);
3991 int pos, match_pos=0;
3993 /* skip leading ^ */
3994 for (pos = 1; n->val.val.str[pos]; pos++)
3996 if (n->val.val.str[pos] == '.' ||
3997 n->val.val.str[pos] == '?' ||
3998 n->val.val.str[pos] == '*' ||
3999 n->val.val.str[pos] == '[' ||
4000 n->val.val.str[pos] == '$' ||
4001 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4003 if (n->val.val.str[pos] == '\\')
4005 match_least[match_pos] = n->val.val.str[pos];
4006 match_most[match_pos++] = n->val.val.str[pos];
4011 A_Const *least = makeNode(A_Const);
4012 A_Const *most = makeNode(A_Const);
4014 /* make strings to be used in index use */
4015 match_least[match_pos] = '\0';
4016 match_most[match_pos] = '\377';
4017 match_most[match_pos+1] = '\0';
4018 least->val.type = T_String;
4019 least->val.val.str = match_least;
4020 most->val.type = T_String;
4021 most->val.val.str = match_most;
4022 result = makeA_Expr(AND, NULL,
4023 makeA_Expr(OP, "~", lexpr, rexpr),
4024 makeA_Expr(AND, NULL,
4025 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4026 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4030 else if (strcmp(opname,"~~") == 0)
4032 if (nodeTag(rexpr) == T_A_Const &&
4033 ((A_Const *)rexpr)->val.type == T_String)
4035 A_Const *n = (A_Const *)rexpr;
4036 char *match_least = palloc(strlen(n->val.val.str)+2);
4037 char *match_most = palloc(strlen(n->val.val.str)+2);
4038 int pos, match_pos=0;
4040 for (pos = 0; n->val.val.str[pos]; pos++)
4042 if ((n->val.val.str[pos] == '%' &&
4043 n->val.val.str[pos+1] != '%') ||
4044 (n->val.val.str[pos] == '_' &&
4045 n->val.val.str[pos+1] != '_'))
4047 if (n->val.val.str[pos] == '%' ||
4048 n->val.val.str[pos] == '_' ||
4049 n->val.val.str[pos] == '\\')
4051 match_least[match_pos] = n->val.val.str[pos];
4052 match_most[match_pos++] = n->val.val.str[pos];
4057 A_Const *least = makeNode(A_Const);
4058 A_Const *most = makeNode(A_Const);
4060 /* make strings to be used in index use */
4061 match_least[match_pos] = '\0';
4062 match_most[match_pos] = '\377';
4063 match_most[match_pos+1] = '\0';
4064 least->val.type = T_String;
4065 least->val.val.str = match_least;
4066 most->val.type = T_String;
4067 most->val.val.str = match_most;
4068 result = makeA_Expr(AND, NULL,
4069 makeA_Expr(OP, "~~", lexpr, rexpr),
4070 makeA_Expr(AND, NULL,
4071 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4072 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4078 result = makeA_Expr(OP, opname, lexpr, rexpr);
4080 } /* makeIndexable() */
4084 * Convert alternate type names to internal Postgres types.
4085 * Do not convert "float", since that is handled elsewhere
4086 * for FLOAT(p) syntax.
4089 xlateSqlType(char *name)
4091 if (!strcasecmp(name,"int")
4092 || !strcasecmp(name,"integer"))
4094 else if (!strcasecmp(name, "smallint"))
4096 else if (!strcasecmp(name, "real"))
4098 else if (!strcasecmp(name, "interval"))
4100 else if (!strcasecmp(name, "boolean"))
4104 } /* xlateSqlName() */
4107 void parser_init(Oid *typev, int nargs)
4109 QueryIsRule = FALSE;
4110 saved_relname[0]= '\0';
4111 saved_In_Expr = NULL;
4113 param_type_init(typev, nargs);
4117 /* FlattenStringList()
4118 * Traverse list of string nodes and convert to a single string.
4119 * Used for reconstructing string form of complex expressions.
4121 * Allocate at least one byte for terminator.
4124 FlattenStringList(List *list)
4132 nlist = length(list);
4135 v = (Value *)lfirst(l);
4142 s = (char*) palloc(len+1);
4147 v = (Value *)lfirst(l);
4151 if (l != NIL) strcat(s," ");
4156 printf( "flattened string is \"%s\"\n", s);
4160 } /* FlattenStringList() */
4163 /* makeConstantList()
4164 * Convert constant value node into string node.
4167 makeConstantList( A_Const *n)
4169 char *defval = NULL;
4170 if (nodeTag(n) != T_A_Const) {
4171 elog(ERROR,"Cannot handle non-constant parameter");
4173 } else if (n->val.type == T_Float) {
4174 defval = (char*) palloc(20+1);
4175 sprintf( defval, "%g", n->val.val.dval);
4177 } else if (n->val.type == T_Integer) {
4178 defval = (char*) palloc(20+1);
4179 sprintf( defval, "%ld", n->val.val.ival);
4181 } else if (n->val.type == T_String) {
4182 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
4183 strcpy( defval, "'");
4184 strcat( defval, ((A_Const *) n)->val.val.str);
4185 strcat( defval, "'");
4188 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
4192 printf( "AexprConst argument is \"%s\"\n", defval);
4195 return( lcons( makeString(defval), NIL));
4196 } /* makeConstantList() */
4200 * Check input string for non-lowercase/non-numeric characters.
4201 * Returns either input string or input surrounded by double quotes.
4208 for (cp = rawid; *cp != '\0'; cp++)
4209 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
4212 cp = palloc(strlen(rawid)+1);
4221 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
4230 * keep enough information around fill out the type of param nodes
4231 * used in postquel functions
4234 param_type_init(Oid *typev, int nargs)
4236 pfunc_num_args = nargs;
4237 param_type_info = typev;
4240 Oid param_type(int t)
4242 if ((t > pfunc_num_args) || (t == 0))
4244 return param_type_info[t - 1];