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.97 1998/01/25 04:08:54 scrappy Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
23 * SQL92-specific syntax is separated from plain SQL/Postgres syntax
24 * to help isolate the non-extensible portions of the parser.
26 * if you use list, make sure the datum is a node so that the printing
30 * sometimes we assign constants to makeStrings. Make sure we don't free
33 *-------------------------------------------------------------------------
39 #include "nodes/parsenodes.h"
40 #include "nodes/print.h"
41 #include "parser/gramparse.h"
42 #include "parser/parse_type.h"
43 #include "utils/acl.h"
44 #include "utils/palloc.h"
45 #include "catalog/catname.h"
46 #include "utils/elog.h"
47 #include "access/xact.h"
49 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
50 static bool QueryIsRule = FALSE;
51 static List *saved_In_Expr = NIL;
52 static Oid *param_type_info;
53 static int pfunc_num_args;
54 extern List *parsetree;
58 * If you need access to certain yacc-generated variables and find that
59 * they're static by default, uncomment the next line. (this is not a
62 /*#define __YYSCLASS*/
64 static char *xlateSqlType(char *);
65 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
66 static Node *makeRowExpr(char *opr, List *largs, List *rargs);
67 void mapTargetColumns(List *source, List *target);
68 static List *makeConstantList( A_Const *node);
69 static char *FlattenStringList(List *list);
70 static char *fmtId(char *rawid);
71 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
72 static void param_type_init(Oid *typev, int nargs);
74 Oid param_type(int t); /* used in parse_expr.c */
76 /* old versions of flex define this as a macro */
90 bool* pboolean; /* for pg_user privileges */
100 SortGroupBy *sortgroupby;
115 AddAttrStmt, ClosePortalStmt,
116 CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
117 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
118 CreatePLangStmt, DropPLangStmt,
119 IndexStmt, ListenStmt, LockStmt, OptimizableStmt,
120 ProcedureStmt, RecipeStmt, RemoveAggrStmt, RemoveOperStmt,
121 RemoveFuncStmt, RemoveStmt,
122 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
123 CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
124 UpdateStmt, InsertStmt, SelectStmt, NotifyStmt, DeleteStmt, ClusterStmt,
125 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
126 CreateUserStmt, AlterUserStmt, DropUserStmt
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, LOCK_P, 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); }
389 /*****************************************************************************
391 * Create a new Postgres DBMS user
394 *****************************************************************************/
396 CreateUserStmt: CREATE USER Id user_passwd_clause user_createdb_clause
397 user_createuser_clause user_group_clause user_valid_clause
399 CreateUserStmt *n = makeNode(CreateUserStmt);
410 /*****************************************************************************
412 * Alter a postresql DBMS user
415 *****************************************************************************/
417 AlterUserStmt: ALTER USER Id user_passwd_clause user_createdb_clause
418 user_createuser_clause user_group_clause user_valid_clause
420 AlterUserStmt *n = makeNode(AlterUserStmt);
431 /*****************************************************************************
433 * Drop a postresql DBMS user
436 *****************************************************************************/
438 DropUserStmt: DROP USER Id
440 DropUserStmt *n = makeNode(DropUserStmt);
446 user_passwd_clause: WITH PASSWORD Id { $$ = $3; }
447 | /*EMPTY*/ { $$ = NULL; }
450 user_createdb_clause: CREATEDB
453 $$ = (b = (bool*)palloc(sizeof(bool)));
459 $$ = (b = (bool*)palloc(sizeof(bool)));
462 | /*EMPTY*/ { $$ = NULL; }
465 user_createuser_clause: CREATEUSER
468 $$ = (b = (bool*)palloc(sizeof(bool)));
474 $$ = (b = (bool*)palloc(sizeof(bool)));
477 | /*EMPTY*/ { $$ = NULL; }
480 user_group_list: user_group_list ',' Id
482 $$ = lcons((void*)makeString($3), $1);
486 $$ = lcons((void*)makeString($1), NIL);
490 user_group_clause: IN GROUP user_group_list { $$ = $3; }
491 | /*EMPTY*/ { $$ = NULL; }
494 user_valid_clause: VALID UNTIL SCONST { $$ = $3; }
495 | /*EMPTY*/ { $$ = NULL; }
498 /*****************************************************************************
500 * Set PG internal variable
501 * SET name TO 'var_value'
502 * Include SQL92 syntax (thomas 1997-10-22):
503 * SET TIME ZONE 'var_value'
505 *****************************************************************************/
507 VariableSetStmt: SET ColId TO var_value
509 VariableSetStmt *n = makeNode(VariableSetStmt);
514 | SET ColId '=' var_value
516 VariableSetStmt *n = makeNode(VariableSetStmt);
521 | SET TIME ZONE zone_value
523 VariableSetStmt *n = makeNode(VariableSetStmt);
524 n->name = "timezone";
530 var_value: Sconst { $$ = $1; }
531 | DEFAULT { $$ = NULL; }
534 zone_value: Sconst { $$ = $1; }
535 | DEFAULT { $$ = NULL; }
536 | LOCAL { $$ = "default"; }
539 VariableShowStmt: SHOW ColId
541 VariableShowStmt *n = makeNode(VariableShowStmt);
547 VariableShowStmt *n = makeNode(VariableShowStmt);
548 n->name = "timezone";
553 VariableResetStmt: RESET ColId
555 VariableResetStmt *n = makeNode(VariableResetStmt);
561 VariableResetStmt *n = makeNode(VariableResetStmt);
562 n->name = "timezone";
568 /*****************************************************************************
571 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
573 *****************************************************************************/
575 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
577 AddAttrStmt *n = makeNode(AddAttrStmt);
585 alter_clause: ADD opt_column columnDef
589 | ADD '(' OptTableElementList ')'
591 Node *lp = lfirst($3);
594 elog(ERROR,"ALTER TABLE/ADD() allows one column only");
597 | DROP opt_column ColId
598 { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
599 | ALTER opt_column ColId SET DEFAULT default_expr
600 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
601 | ALTER opt_column ColId DROP DEFAULT
602 { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
604 { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
608 /*****************************************************************************
613 *****************************************************************************/
615 ClosePortalStmt: CLOSE opt_id
617 ClosePortalStmt *n = makeNode(ClosePortalStmt);
624 /*****************************************************************************
627 * COPY [BINARY] <relname> FROM/TO
628 * [USING DELIMITERS <delimiter>]
630 *****************************************************************************/
632 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
634 CopyStmt *n = makeNode(CopyStmt);
652 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
653 * used depends on the direction. (It really doesn't make sense to copy from
654 * stdout. We silently correct the "typo". - AY 9/94
656 copy_file_name: Sconst { $$ = $1; }
657 | STDIN { $$ = NULL; }
658 | STDOUT { $$ = NULL; }
661 opt_binary: BINARY { $$ = TRUE; }
662 | /*EMPTY*/ { $$ = FALSE; }
665 opt_with_copy: WITH OIDS { $$ = TRUE; }
666 | /*EMPTY*/ { $$ = FALSE; }
670 * the default copy delimiter is tab but the user can configure it
672 copy_delimiter: USING DELIMITERS Sconst { $$ = $3; }
673 | /*EMPTY*/ { $$ = "\t"; }
677 /*****************************************************************************
682 *****************************************************************************/
684 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
685 OptInherit OptArchiveType
687 CreateStmt *n = makeNode(CreateStmt);
691 n->constraints = NIL;
696 OptTableElementList: OptTableElementList ',' OptTableElement
697 { $$ = lappend($1, $3); }
698 | OptTableElement { $$ = lcons($1, NIL); }
699 | /*EMPTY*/ { $$ = NULL; }
702 OptTableElement: columnDef { $$ = $1; }
703 | TableConstraint { $$ = $1; }
706 columnDef: ColId Typename ColQualifier
708 ColumnDef *n = makeNode(ColumnDef);
712 n->is_not_null = FALSE;
718 ColQualifier: ColQualList { $$ = $1; }
719 | /*EMPTY*/ { $$ = NULL; }
722 ColQualList: ColQualList ColConstraint { $$ = lappend($1,$2); }
723 | ColConstraint { $$ = lcons($1, NIL); }
727 CONSTRAINT name ColConstraintElem
729 Constraint *n = (Constraint *)$3;
737 ColConstraintElem: CHECK '(' constraint_expr ')'
739 Constraint *n = makeNode(Constraint);
740 n->contype = CONSTR_CHECK;
742 n->def = FlattenStringList($3);
746 | DEFAULT default_expr
748 Constraint *n = makeNode(Constraint);
749 n->contype = CONSTR_DEFAULT;
751 n->def = FlattenStringList($2);
757 Constraint *n = makeNode(Constraint);
758 n->contype = CONSTR_NOTNULL;
766 Constraint *n = makeNode(Constraint);
767 n->contype = CONSTR_UNIQUE;
775 Constraint *n = makeNode(Constraint);
776 n->contype = CONSTR_PRIMARY;
782 | REFERENCES ColId opt_column_list key_match key_actions
784 elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
789 default_list: default_list ',' default_expr
791 $$ = lappend($1,makeString(","));
800 default_expr: AexprConst
801 { $$ = makeConstantList((A_Const *) $1); }
803 { $$ = lcons( makeString("NULL"), NIL); }
804 | '-' default_expr %prec UMINUS
805 { $$ = lcons( makeString( "-"), $2); }
806 | default_expr '+' default_expr
807 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
808 | default_expr '-' default_expr
809 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
810 | default_expr '/' default_expr
811 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
812 | default_expr '*' default_expr
813 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
814 | default_expr '=' default_expr
815 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
816 | default_expr '<' default_expr
817 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
818 | default_expr '>' default_expr
819 { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
821 { $$ = lcons( makeString( ":"), $2); }
823 { $$ = lcons( makeString( ";"), $2); }
825 { $$ = lcons( makeString( "|"), $2); }
826 | default_expr TYPECAST Typename
828 $3->name = fmtId($3->name);
829 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
831 | CAST default_expr AS Typename
833 $4->name = fmtId($4->name);
834 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
836 | '(' default_expr ')'
837 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
840 $$ = makeList( makeString($1), makeString("("), -1);
841 $$ = lappend( $$, makeString(")"));
843 | name '(' default_list ')'
845 $$ = makeList( makeString($1), makeString("("), -1);
847 $$ = lappend( $$, makeString(")"));
849 | default_expr Op default_expr
851 if (!strcmp("<=", $2) || !strcmp(">=", $2))
852 elog(ERROR,"boolean expressions not supported in DEFAULT");
853 $$ = nconc( $1, lcons( makeString( $2), $3));
856 { $$ = lcons( makeString( $1), $2); }
858 { $$ = lappend( $1, makeString( $2)); }
859 /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
861 { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
863 { $$ = lcons( makeString( "'now'::time"), NIL); }
864 | CURRENT_TIME '(' Iconst ')'
867 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
868 $$ = lcons( makeString( "'now'::time"), NIL);
871 { $$ = lcons( makeString( "now()"), NIL); }
872 | CURRENT_TIMESTAMP '(' Iconst ')'
875 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
876 $$ = lcons( makeString( "now()"), NIL);
879 { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
882 /* ConstraintElem specifies constraint syntax which is not embedded into
883 * a column definition. ColConstraintElem specifies the embedded form.
884 * - thomas 1997-12-03
886 TableConstraint: CONSTRAINT name ConstraintElem
888 Constraint *n = (Constraint *)$3;
896 ConstraintElem: CHECK '(' constraint_expr ')'
898 Constraint *n = makeNode(Constraint);
899 n->contype = CONSTR_CHECK;
901 n->def = FlattenStringList($3);
904 | UNIQUE '(' columnList ')'
906 Constraint *n = makeNode(Constraint);
907 n->contype = CONSTR_UNIQUE;
913 | PRIMARY KEY '(' columnList ')'
915 Constraint *n = makeNode(Constraint);
916 n->contype = CONSTR_PRIMARY;
922 | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
923 { elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented"); }
926 constraint_list: constraint_list ',' constraint_expr
928 $$ = lappend($1,makeString(","));
937 constraint_expr: AexprConst
938 { $$ = makeConstantList((A_Const *) $1); }
940 { $$ = lcons( makeString("NULL"), NIL); }
943 $$ = lcons( makeString(fmtId($1)), NIL);
945 | '-' constraint_expr %prec UMINUS
946 { $$ = lcons( makeString( "-"), $2); }
947 | constraint_expr '+' constraint_expr
948 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
949 | constraint_expr '-' constraint_expr
950 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
951 | constraint_expr '/' constraint_expr
952 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
953 | constraint_expr '*' constraint_expr
954 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
955 | constraint_expr '=' constraint_expr
956 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
957 | constraint_expr '<' constraint_expr
958 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
959 | constraint_expr '>' constraint_expr
960 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
961 | ':' constraint_expr
962 { $$ = lcons( makeString( ":"), $2); }
963 | ';' constraint_expr
964 { $$ = lcons( makeString( ";"), $2); }
965 | '|' constraint_expr
966 { $$ = lcons( makeString( "|"), $2); }
967 | constraint_expr TYPECAST Typename
969 $3->name = fmtId($3->name);
970 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
972 | CAST constraint_expr AS Typename
974 $4->name = fmtId($4->name);
975 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
977 | '(' constraint_expr ')'
978 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
981 $$ = makeList( makeString($1), makeString("("), -1);
982 $$ = lappend( $$, makeString(")"));
984 | name '(' constraint_list ')'
986 $$ = makeList( makeString($1), makeString("("), -1);
988 $$ = lappend( $$, makeString(")"));
990 | constraint_expr Op constraint_expr
991 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
992 | constraint_expr AND constraint_expr
993 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
994 | constraint_expr OR constraint_expr
995 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
996 | NOT constraint_expr
997 { $$ = lcons( makeString( "NOT"), $2); }
999 { $$ = lcons( makeString( $1), $2); }
1000 | constraint_expr Op
1001 { $$ = lappend( $1, makeString( $2)); }
1002 | constraint_expr ISNULL
1003 { $$ = lappend( $1, makeString( "IS NULL")); }
1004 | constraint_expr IS NULL_P
1005 { $$ = lappend( $1, makeString( "IS NULL")); }
1006 | constraint_expr NOTNULL
1007 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1008 | constraint_expr IS NOT NULL_P
1009 { $$ = lappend( $1, makeString( "IS NOT NULL")); }
1010 | constraint_expr IS TRUE_P
1011 { $$ = lappend( $1, makeString( "IS TRUE")); }
1012 | constraint_expr IS FALSE_P
1013 { $$ = lappend( $1, makeString( "IS FALSE")); }
1014 | constraint_expr IS NOT TRUE_P
1015 { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
1016 | constraint_expr IS NOT FALSE_P
1017 { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
1020 key_match: MATCH FULL { $$ = NULL; }
1021 | MATCH PARTIAL { $$ = NULL; }
1022 | /*EMPTY*/ { $$ = NULL; }
1025 key_actions: key_action key_action { $$ = NIL; }
1026 | key_action { $$ = NIL; }
1027 | /*EMPTY*/ { $$ = NIL; }
1030 key_action: ON DELETE key_reference { $$ = NIL; }
1031 | ON UPDATE key_reference { $$ = NIL; }
1034 key_reference: NO ACTION { $$ = NULL; }
1035 | CASCADE { $$ = NULL; }
1036 | SET DEFAULT { $$ = NULL; }
1037 | SET NULL_P { $$ = NULL; }
1040 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
1041 | /*EMPTY*/ { $$ = NIL; }
1045 * "ARCHIVE" keyword was removed in 6.3, but we keep it for now
1046 * so people can upgrade with old pg_dump scripts. - momjian 1997-11-20(?)
1048 OptArchiveType: ARCHIVE '=' NONE { }
1052 CreateAsStmt: CREATE TABLE relation_name OptCreateAs AS SubSelect
1054 SelectStmt *n = (SelectStmt *)$6;
1056 mapTargetColumns($4, n->targetList);
1062 OptCreateAs: '(' CreateAsList ')' { $$ = $2; }
1063 | /*EMPTY*/ { $$ = NULL; }
1066 CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
1067 | CreateAsElement { $$ = lcons($1, NIL); }
1070 CreateAsElement: ColId
1072 ColumnDef *n = makeNode(ColumnDef);
1076 n->is_not_null = FALSE;
1077 n->constraints = NULL;
1083 /*****************************************************************************
1086 * CREATE SEQUENCE seqname
1088 *****************************************************************************/
1090 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
1092 CreateSeqStmt *n = makeNode(CreateSeqStmt);
1100 OptSeqList OptSeqElem
1101 { $$ = lappend($1, $2); }
1105 OptSeqElem: IDENT NumConst
1107 $$ = makeNode(DefElem);
1109 $$->arg = (Node *)$2;
1113 $$ = makeNode(DefElem);
1115 $$->arg = (Node *)NULL;
1119 /*****************************************************************************
1122 * CREATE PROCEDURAL LANGUAGE ...
1123 * DROP PROCEDURAL LANGUAGE ...
1125 *****************************************************************************/
1127 CreatePLangStmt: CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst
1128 HANDLER def_name LANCOMPILER Sconst
1130 CreatePLangStmt *n = makeNode(CreatePLangStmt);
1139 PLangTrusted: TRUSTED { $$ = TRUE; }
1142 DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
1144 DropPLangStmt *n = makeNode(DropPLangStmt);
1150 /*****************************************************************************
1153 * CREATE TRIGGER ...
1156 *****************************************************************************/
1158 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1159 relation_name TriggerForSpec EXECUTE PROCEDURE
1160 name '(' TriggerFuncArgs ')'
1162 CreateTrigStmt *n = makeNode(CreateTrigStmt);
1169 memcpy (n->actions, $5, 4);
1174 TriggerActionTime: BEFORE { $$ = TRUE; }
1175 | AFTER { $$ = FALSE; }
1178 TriggerEvents: TriggerOneEvent
1180 char *e = palloc (4);
1181 e[0] = $1; e[1] = 0; $$ = e;
1183 | TriggerOneEvent OR TriggerOneEvent
1185 char *e = palloc (4);
1186 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
1188 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1190 char *e = palloc (4);
1191 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
1196 TriggerOneEvent: INSERT { $$ = 'i'; }
1197 | DELETE { $$ = 'd'; }
1198 | UPDATE { $$ = 'u'; }
1201 TriggerForSpec: FOR name name
1203 if ( strcmp ($2, "each") != 0 )
1204 elog(ERROR,"parser: syntax error near %s",$2);
1205 if ( strcmp ($3, "row") == 0 )
1207 else if ( strcmp ($3, "statement") == 0 )
1210 elog(ERROR,"parser: syntax error near %s",$3);
1214 TriggerFuncArgs: TriggerFuncArg
1215 { $$ = lcons($1, NIL); }
1216 | TriggerFuncArgs ',' TriggerFuncArg
1217 { $$ = lappend($1, $3); }
1222 TriggerFuncArg: ICONST
1224 char *s = (char *) palloc (256);
1225 sprintf (s, "%d", $1);
1230 char *s = (char *) palloc (256);
1231 sprintf (s, "%g", $1);
1234 | Sconst { $$ = $1; }
1235 | IDENT { $$ = $1; }
1238 DropTrigStmt: DROP TRIGGER name ON relation_name
1240 DropTrigStmt *n = makeNode(DropTrigStmt);
1248 /*****************************************************************************
1251 * define (type,operator,aggregate)
1253 *****************************************************************************/
1255 DefineStmt: CREATE def_type def_rest
1262 def_rest: def_name definition
1264 $$ = makeNode(DefineStmt);
1266 $$->definition = $2;
1270 def_type: OPERATOR { $$ = OPERATOR; }
1271 | TYPE_P { $$ = TYPE_P; }
1272 | AGGREGATE { $$ = AGGREGATE; }
1275 def_name: PROCEDURE { $$ = "procedure"; }
1276 | JOIN { $$ = "join"; }
1277 | ColId { $$ = $1; }
1278 | MathOp { $$ = $1; }
1282 definition: '(' def_list ')' { $$ = $2; }
1285 def_list: def_elem { $$ = lcons($1, NIL); }
1286 | def_list ',' def_elem { $$ = lappend($1, $3); }
1289 def_elem: def_name '=' def_arg
1291 $$ = makeNode(DefElem);
1293 $$->arg = (Node *)$3;
1297 $$ = makeNode(DefElem);
1299 $$->arg = (Node *)NULL;
1301 | DEFAULT '=' def_arg
1303 $$ = makeNode(DefElem);
1304 $$->defname = "default";
1305 $$->arg = (Node *)$3;
1309 def_arg: ColId { $$ = (Node *)makeString($1); }
1310 | all_Op { $$ = (Node *)makeString($1); }
1311 | NumConst { $$ = (Node *)$1; /* already a Value */ }
1312 | Sconst { $$ = (Node *)makeString($1); }
1315 TypeName *n = makeNode(TypeName);
1318 n->arrayBounds = NULL;
1321 | DOUBLE { $$ = (Node *)makeString("double"); }
1325 /*****************************************************************************
1328 * destroy <relname1> [, <relname2> .. <relnameN> ]
1330 *****************************************************************************/
1332 DestroyStmt: DROP TABLE relation_name_list
1334 DestroyStmt *n = makeNode(DestroyStmt);
1336 n->sequence = FALSE;
1339 | DROP SEQUENCE relation_name_list
1341 DestroyStmt *n = makeNode(DestroyStmt);
1349 /*****************************************************************************
1352 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
1354 *****************************************************************************/
1356 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1358 FetchStmt *n = makeNode(FetchStmt);
1365 | MOVE opt_direction fetch_how_many opt_portal_name
1367 FetchStmt *n = makeNode(FetchStmt);
1376 opt_direction: FORWARD { $$ = FORWARD; }
1377 | BACKWARD { $$ = BACKWARD; }
1378 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1381 fetch_how_many: Iconst
1383 if ($1 <= 0) elog(ERROR,"Please specify nonnegative count for fetch"); }
1384 | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
1385 | /*EMPTY*/ { $$ = 1; /*default*/ }
1388 opt_portal_name: IN name { $$ = $2; }
1389 | /*EMPTY*/ { $$ = NULL; }
1393 /*****************************************************************************
1396 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1398 *****************************************************************************/
1400 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1402 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1406 privileges: ALL PRIVILEGES
1408 $$ = aclmakepriv("rwaR",0);
1412 $$ = aclmakepriv("rwaR",0);
1414 | operation_commalist
1420 operation_commalist: operation
1422 $$ = aclmakepriv("",$1);
1424 | operation_commalist ',' operation
1426 $$ = aclmakepriv($1,$3);
1432 $$ = ACL_MODE_RD_CHR;
1436 $$ = ACL_MODE_AP_CHR;
1440 $$ = ACL_MODE_WR_CHR;
1444 $$ = ACL_MODE_WR_CHR;
1448 $$ = ACL_MODE_RU_CHR;
1454 $$ = aclmakeuser("A","");
1458 $$ = aclmakeuser("G",$2);
1462 $$ = aclmakeuser("U",$1);
1466 opt_with_grant: WITH GRANT OPTION
1468 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1474 /*****************************************************************************
1477 * REVOKE [privileges] ON [relation_name] FROM [user]
1479 *****************************************************************************/
1481 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1483 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1488 /*****************************************************************************
1491 * create index <indexname> on <relname>
1492 * using <access> "(" (<col> with <op>)+ ")" [with
1495 * [where <qual>] is not supported anymore
1496 *****************************************************************************/
1498 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1499 access_method_clause '(' index_params ')' opt_with
1501 /* should check that access_method is valid,
1502 etc ... but doesn't */
1503 IndexStmt *n = makeNode(IndexStmt);
1507 n->accessMethod = $7;
1508 n->indexParams = $9;
1509 n->withClause = $11;
1510 n->whereClause = NULL;
1515 index_opt_unique: UNIQUE { $$ = TRUE; }
1516 | /*EMPTY*/ { $$ = FALSE; }
1519 access_method_clause: USING access_method { $$ = $2; }
1520 | /*EMPTY*/ { $$ = "btree"; }
1523 index_params: index_list { $$ = $1; }
1524 | func_index { $$ = lcons($1,NIL); }
1527 index_list: index_list ',' index_elem { $$ = lappend($1, $3); }
1528 | index_elem { $$ = lcons($1, NIL); }
1531 func_index: name '(' name_list ')' opt_type opt_class
1533 $$ = makeNode(IndexElem);
1541 index_elem: attr_name opt_type opt_class
1543 $$ = makeNode(IndexElem);
1551 opt_type: ':' Typename { $$ = $2; }
1552 | FOR Typename { $$ = $2; }
1553 | /*EMPTY*/ { $$ = NULL; }
1556 /* opt_class "WITH class" conflicts with preceeding opt_type
1557 * for Typename of "TIMESTAMP WITH TIME ZONE"
1558 * So, remove "WITH class" from the syntax. OK??
1559 * - thomas 1997-10-12
1560 * | WITH class { $$ = $2; }
1562 opt_class: class { $$ = $1; }
1563 | USING class { $$ = $2; }
1564 | /*EMPTY*/ { $$ = NULL; }
1568 /*****************************************************************************
1571 * extend index <indexname> [where <qual>]
1573 *****************************************************************************/
1575 ExtendStmt: EXTEND INDEX index_name where_clause
1577 ExtendStmt *n = makeNode(ExtendStmt);
1579 n->whereClause = $4;
1585 /*****************************************************************************
1588 * execute recipe <recipeName>
1590 *****************************************************************************/
1592 RecipeStmt: EXECUTE RECIPE recipe_name
1595 if (!IsTransactionBlock())
1596 elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
1598 n = makeNode(RecipeStmt);
1605 /*****************************************************************************
1608 * define function <fname>
1609 * (language = <lang>, returntype = <typename>
1610 * [, arch_pct = <percentage | pre-defined>]
1611 * [, disk_pct = <percentage | pre-defined>]
1612 * [, byte_pct = <percentage | pre-defined>]
1613 * [, perbyte_cpu = <int | pre-defined>]
1614 * [, percall_cpu = <int | pre-defined>]
1616 * [arg is (<type-1> { , <type-n>})]
1617 * as <filename or code in language as appropriate>
1619 *****************************************************************************/
1621 ProcedureStmt: CREATE FUNCTION def_name def_args
1622 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1624 ProcedureStmt *n = makeNode(ProcedureStmt);
1627 n->returnType = (Node *)$6;
1634 opt_with: WITH definition { $$ = $2; }
1635 | /*EMPTY*/ { $$ = NIL; }
1638 def_args: '(' def_name_list ')' { $$ = $2; }
1639 | '(' ')' { $$ = NIL; }
1642 def_name_list: name_list;
1644 /*****************************************************************************
1648 * remove function <funcname>
1649 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1650 * remove aggregate <aggname>
1651 * (REMOVE AGGREGATE "aggname" "aggtype")
1652 * remove operator <opname>
1653 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1654 * remove type <typename>
1655 * (REMOVE TYPE "typename")
1656 * remove rule <rulename>
1657 * (REMOVE RULE "rulename")
1659 *****************************************************************************/
1661 RemoveStmt: DROP remove_type name
1663 RemoveStmt *n = makeNode(RemoveStmt);
1670 remove_type: TYPE_P { $$ = TYPE_P; }
1671 | INDEX { $$ = INDEX; }
1672 | RULE { $$ = RULE; }
1673 | VIEW { $$ = VIEW; }
1676 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1678 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1685 aggr_argtype: name { $$ = $1; }
1686 | '*' { $$ = NULL; }
1689 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1691 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1698 func_argtypes: name_list { $$ = $1; }
1699 | /*EMPTY*/ { $$ = NIL; }
1702 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1704 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1711 all_Op: Op | MathOp;
1713 MathOp: '+' { $$ = "+"; }
1724 elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
1727 { $$ = makeList(makeString($1), makeString($3), -1); }
1728 | NONE ',' name /* left unary */
1729 { $$ = makeList(NULL, makeString($3), -1); }
1730 | name ',' NONE /* right unary */
1731 { $$ = makeList(makeString($1), NULL, -1); }
1735 /*****************************************************************************
1738 * rename <attrname1> in <relname> [*] to <attrname2>
1739 * rename <relname1> to <relname2>
1741 *****************************************************************************/
1743 RenameStmt: ALTER TABLE relation_name opt_inh_star
1744 RENAME opt_column opt_name TO name
1746 RenameStmt *n = makeNode(RenameStmt);
1755 opt_name: name { $$ = $1; }
1756 | /*EMPTY*/ { $$ = NULL; }
1759 opt_column: COLUMN { $$ = COLUMN; }
1760 | /*EMPTY*/ { $$ = 0; }
1764 /*****************************************************************************
1766 * QUERY: Define Rewrite Rule , Define Tuple Rule
1767 * Define Rule <old rules >
1769 * only rewrite rule is supported -- ay 9/94
1771 *****************************************************************************/
1773 RuleStmt: CREATE RULE name AS
1774 { QueryIsRule=TRUE; }
1775 ON event TO event_object where_clause
1776 DO opt_instead OptStmtList
1778 RuleStmt *n = makeNode(RuleStmt);
1782 n->whereClause = $10;
1789 OptStmtList: NOTHING { $$ = NIL; }
1790 | OptimizableStmt { $$ = lcons($1, NIL); }
1791 | '[' OptStmtBlock ']' { $$ = $2; }
1794 OptStmtBlock: OptStmtMulti
1797 { $$ = lcons($1, NIL); }
1800 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1801 { $$ = lappend($1, $2); }
1802 | OptStmtMulti OptimizableStmt
1803 { $$ = lappend($1, $2); }
1804 | OptimizableStmt ';'
1805 { $$ = lcons($1, NIL); }
1808 event_object: relation_name '.' attr_name
1810 $$ = makeNode(Attr);
1813 $$->attrs = lcons(makeString($3), NIL);
1814 $$->indirection = NIL;
1818 $$ = makeNode(Attr);
1822 $$->indirection = NIL;
1826 /* change me to select, update, etc. some day */
1827 event: SELECT { $$ = CMD_SELECT; }
1828 | UPDATE { $$ = CMD_UPDATE; }
1829 | DELETE { $$ = CMD_DELETE; }
1830 | INSERT { $$ = CMD_INSERT; }
1833 opt_instead: INSTEAD { $$ = TRUE; }
1834 | /*EMPTY*/ { $$ = FALSE; }
1838 /*****************************************************************************
1841 * NOTIFY <relation_name> can appear both in rule bodies and
1842 * as a query-level command
1844 *****************************************************************************/
1846 NotifyStmt: NOTIFY relation_name
1848 NotifyStmt *n = makeNode(NotifyStmt);
1854 ListenStmt: LISTEN relation_name
1856 ListenStmt *n = makeNode(ListenStmt);
1863 /*****************************************************************************
1874 *****************************************************************************/
1876 TransactionStmt: ABORT_TRANS TRANSACTION
1878 TransactionStmt *n = makeNode(TransactionStmt);
1879 n->command = ABORT_TRANS;
1882 | BEGIN_TRANS TRANSACTION
1884 TransactionStmt *n = makeNode(TransactionStmt);
1885 n->command = BEGIN_TRANS;
1890 TransactionStmt *n = makeNode(TransactionStmt);
1891 n->command = BEGIN_TRANS;
1896 TransactionStmt *n = makeNode(TransactionStmt);
1897 n->command = END_TRANS;
1900 | END_TRANS TRANSACTION
1902 TransactionStmt *n = makeNode(TransactionStmt);
1903 n->command = END_TRANS;
1908 TransactionStmt *n = makeNode(TransactionStmt);
1909 n->command = ABORT_TRANS;
1915 TransactionStmt *n = makeNode(TransactionStmt);
1916 n->command = ABORT_TRANS;
1921 TransactionStmt *n = makeNode(TransactionStmt);
1922 n->command = BEGIN_TRANS;
1927 TransactionStmt *n = makeNode(TransactionStmt);
1928 n->command = END_TRANS;
1934 TransactionStmt *n = makeNode(TransactionStmt);
1935 n->command = END_TRANS;
1940 TransactionStmt *n = makeNode(TransactionStmt);
1941 n->command = ABORT_TRANS;
1947 /*****************************************************************************
1950 * define view <viewname> '('target-list ')' [where <quals> ]
1952 *****************************************************************************/
1954 ViewStmt: CREATE VIEW name AS SelectStmt
1956 ViewStmt *n = makeNode(ViewStmt);
1958 n->query = (Query *)$5;
1959 if (((SelectStmt *)n->query)->sortClause != NULL)
1960 elog(ERROR,"Order by and Distinct on views is not implemented.");
1961 if (((SelectStmt *)n->query)->unionClause != NULL)
1962 elog(ERROR,"Views on unions not implemented.");
1968 /*****************************************************************************
1973 *****************************************************************************/
1975 LoadStmt: LOAD file_name
1977 LoadStmt *n = makeNode(LoadStmt);
1984 /*****************************************************************************
1989 *****************************************************************************/
1991 CreatedbStmt: CREATE DATABASE database_name opt_database
1993 CreatedbStmt *n = makeNode(CreatedbStmt);
2000 opt_database: WITH LOCATION '=' location { $$ = $4; }
2001 | /*EMPTY*/ { $$ = NULL; }
2004 location: Sconst { $$ = $1; }
2005 | DEFAULT { $$ = NULL; }
2006 | /*EMPTY*/ { $$ = NULL; }
2009 /*****************************************************************************
2014 *****************************************************************************/
2016 DestroydbStmt: DROP DATABASE database_name
2018 DestroydbStmt *n = makeNode(DestroydbStmt);
2025 /*****************************************************************************
2028 * cluster <index_name> on <relation_name>
2030 *****************************************************************************/
2032 ClusterStmt: CLUSTER index_name ON relation_name
2034 ClusterStmt *n = makeNode(ClusterStmt);
2042 /*****************************************************************************
2047 *****************************************************************************/
2049 VacuumStmt: VACUUM opt_verbose opt_analyze
2051 VacuumStmt *n = makeNode(VacuumStmt);
2058 | VACUUM opt_verbose opt_analyze relation_name opt_va_list
2060 VacuumStmt *n = makeNode(VacuumStmt);
2065 if ( $5 != NIL && !$4 )
2066 elog(ERROR,"parser: syntax error at or near \"(\"");
2071 opt_verbose: VERBOSE { $$ = TRUE; }
2072 | /*EMPTY*/ { $$ = FALSE; }
2075 opt_analyze: ANALYZE { $$ = TRUE; }
2076 | /*EMPTY*/ { $$ = FALSE; }
2079 opt_va_list: '(' va_list ')'
2086 { $$=lcons($1,NIL); }
2088 { $$=lappend($1,$3); }
2092 /*****************************************************************************
2097 *****************************************************************************/
2099 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
2101 ExplainStmt *n = makeNode(ExplainStmt);
2103 n->query = (Query*)$3;
2109 /*****************************************************************************
2111 * Optimizable Stmts: *
2113 * one of the five queries processed by the planner *
2115 * [ultimately] produces query-trees as specified *
2116 * in the query-spec document in ~postgres/ref *
2118 *****************************************************************************/
2120 OptimizableStmt: SelectStmt
2125 | DeleteStmt /* by default all are $$=$1 */
2129 /*****************************************************************************
2134 *****************************************************************************/
2136 InsertStmt: INSERT INTO relation_name opt_column_list insert_rest
2144 insert_rest: VALUES '(' res_target_list2 ')'
2146 $$ = makeNode(InsertStmt);
2148 $$->targetList = $3;
2149 $$->fromClause = NIL;
2150 $$->whereClause = NULL;
2151 $$->groupClause = NIL;
2152 $$->havingClause = NULL;
2153 $$->unionClause = NIL;
2155 | SELECT opt_unique res_target_list2
2156 from_clause where_clause
2157 group_clause having_clause
2160 $$ = makeNode(InsertStmt);
2162 $$->targetList = $3;
2163 $$->fromClause = $4;
2164 $$->whereClause = $5;
2165 $$->groupClause = $6;
2166 $$->havingClause = $7;
2167 $$->unionClause = $8;
2171 opt_column_list: '(' columnList ')' { $$ = $2; }
2172 | /*EMPTY*/ { $$ = NIL; }
2176 columnList ',' columnElem
2177 { $$ = lappend($1, $3); }
2179 { $$ = lcons($1, NIL); }
2182 columnElem: ColId opt_indirection
2184 Ident *id = makeNode(Ident);
2186 id->indirection = $2;
2192 /*****************************************************************************
2197 *****************************************************************************/
2199 DeleteStmt: DELETE FROM relation_name
2202 DeleteStmt *n = makeNode(DeleteStmt);
2204 n->whereClause = $4;
2210 * Total hack to just lock a table inside a transaction.
2211 * Is it worth making this a separate command, with
2212 * its own node type and file. I don't think so. bjm 1998/1/22
2214 LockStmt: LOCK_P relation_name
2216 DeleteStmt *n = makeNode(DeleteStmt);
2217 A_Const *c = makeNode(A_Const);
2219 c->val.type = T_String;
2220 c->val.val.str = "f";
2221 c->typename = makeNode(TypeName);
2222 c->typename->name = xlateSqlType("bool");
2231 /*****************************************************************************
2234 * UpdateStmt (UPDATE)
2236 *****************************************************************************/
2238 UpdateStmt: UPDATE relation_name
2243 UpdateStmt *n = makeNode(UpdateStmt);
2247 n->whereClause = $6;
2253 /*****************************************************************************
2258 *****************************************************************************/
2259 CursorStmt: DECLARE name opt_binary CURSOR FOR
2260 SELECT opt_unique res_target_list2
2261 from_clause where_clause
2262 group_clause having_clause
2263 union_clause sort_clause
2265 SelectStmt *n = makeNode(SelectStmt);
2267 /* from PORTAL name */
2269 * 15 august 1991 -- since 3.0 postgres does locking
2270 * right, we discovered that portals were violating
2271 * locking protocol. portal locks cannot span xacts.
2272 * as a short-term fix, we installed the check here.
2275 if (!IsTransactionBlock())
2276 elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
2283 n->whereClause = $10;
2284 n->groupClause = $11;
2285 n->havingClause = $12;
2286 n->unionClause = $13;
2287 n->sortClause = $14;
2293 /*****************************************************************************
2298 *****************************************************************************/
2300 SelectStmt: SELECT opt_unique res_target_list2
2301 result from_clause where_clause
2302 group_clause having_clause
2303 union_clause sort_clause
2305 SelectStmt *n = makeNode(SelectStmt);
2310 n->whereClause = $6;
2311 n->groupClause = $7;
2312 n->havingClause = $8;
2313 n->unionClause = $9;
2314 n->sortClause = $10;
2319 union_clause: UNION opt_union select_list
2321 SelectStmt *n = (SelectStmt *)lfirst($3);
2329 select_list: select_list UNION opt_union SubSelect
2331 SelectStmt *n = (SelectStmt *)$4;
2333 $$ = lappend($1, $4);
2336 { $$ = lcons($1, NIL); }
2339 SubSelect: SELECT opt_unique res_target_list2
2340 from_clause where_clause
2341 group_clause having_clause
2343 SelectStmt *n = makeNode(SelectStmt);
2345 n->unionall = FALSE;
2348 n->whereClause = $5;
2349 n->groupClause = $6;
2350 n->havingClause = $7;
2355 result: INTO TABLE relation_name
2361 opt_union: ALL { $$ = TRUE; }
2362 | /*EMPTY*/ { $$ = FALSE; }
2365 opt_unique: DISTINCT { $$ = "*"; }
2366 | DISTINCT ON ColId { $$ = $3; }
2367 | ALL { $$ = NULL; }
2368 | /*EMPTY*/ { $$ = NULL; }
2371 sort_clause: ORDER BY sortby_list { $$ = $3; }
2372 | /*EMPTY*/ { $$ = NIL; }
2375 sortby_list: sortby { $$ = lcons($1, NIL); }
2376 | sortby_list ',' sortby { $$ = lappend($1, $3); }
2379 sortby: ColId OptUseOp
2381 $$ = makeNode(SortGroupBy);
2387 | ColId '.' ColId OptUseOp
2389 $$ = makeNode(SortGroupBy);
2397 $$ = makeNode(SortGroupBy);
2405 OptUseOp: USING Op { $$ = $2; }
2406 | USING '<' { $$ = "<"; }
2407 | USING '>' { $$ = ">"; }
2409 | DESC { $$ = ">"; }
2410 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2414 * jimmy bell-style recursive queries aren't supported in the
2417 * ...however, recursive addattr and rename supported. make special
2420 opt_inh_star: '*' { $$ = TRUE; }
2421 | /*EMPTY*/ { $$ = FALSE; }
2424 relation_name_list: name_list;
2427 { $$ = lcons(makeString($1),NIL); }
2428 | name_list ',' name
2429 { $$ = lappend($1,makeString($3)); }
2432 group_clause: GROUP BY groupby_list { $$ = $3; }
2433 | /*EMPTY*/ { $$ = NIL; }
2436 groupby_list: groupby { $$ = lcons($1, NIL); }
2437 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2442 $$ = makeNode(SortGroupBy);
2450 $$ = makeNode(SortGroupBy);
2458 $$ = makeNode(SortGroupBy);
2466 having_clause: HAVING a_expr
2468 elog(NOTICE, "HAVING not yet supported; ignore clause");
2471 | /*EMPTY*/ { $$ = NULL; }
2475 /*****************************************************************************
2477 * clauses common to all Optimizable Stmts:
2481 *****************************************************************************/
2483 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2486 elog(ERROR,"JOIN not yet implemented");
2488 | FROM from_list { $$ = $2; }
2489 | /*EMPTY*/ { $$ = NIL; }
2492 from_list: from_list ',' from_val
2493 { $$ = lappend($1, $3); }
2494 | from_val CROSS JOIN from_val
2495 { elog(ERROR,"CROSS JOIN not yet implemented"); }
2497 { $$ = lcons($1, NIL); }
2500 from_val: relation_expr AS ColLabel
2502 $$ = makeNode(RangeVar);
2506 | relation_expr ColId
2508 $$ = makeNode(RangeVar);
2514 $$ = makeNode(RangeVar);
2520 join_expr: NATURAL join_expr { $$ = NULL; }
2522 { elog(ERROR,"FULL OUTER JOIN not yet implemented"); }
2524 { elog(ERROR,"LEFT OUTER JOIN not yet implemented"); }
2526 { elog(ERROR,"RIGHT OUTER JOIN not yet implemented"); }
2528 { elog(ERROR,"OUTER JOIN not yet implemented"); }
2530 { elog(ERROR,"INNER JOIN not yet implemented"); }
2532 { elog(ERROR,"UNION JOIN not yet implemented"); }
2534 { elog(ERROR,"INNER JOIN not yet implemented"); }
2537 join_outer: OUTER_P { $$ = NULL; }
2538 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2541 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2542 | USING '(' join_list ')' { $$ = NULL; }
2543 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2546 join_list: join_using { $$ = lcons($1, NIL); }
2547 | join_list ',' join_using { $$ = lappend($1, $3); }
2552 $$ = makeNode(SortGroupBy);
2560 $$ = makeNode(SortGroupBy);
2568 $$ = makeNode(SortGroupBy);
2576 where_clause: WHERE a_expr { $$ = $2; }
2577 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2580 relation_expr: relation_name
2582 /* normal relations */
2583 $$ = makeNode(RelExpr);
2587 | relation_name '*' %prec '='
2589 /* inheritance query */
2590 $$ = makeNode(RelExpr);
2595 opt_array_bounds: '[' ']' nest_array_bounds
2596 { $$ = lcons(makeInteger(-1), $3); }
2597 | '[' Iconst ']' nest_array_bounds
2598 { $$ = lcons(makeInteger($2), $4); }
2603 nest_array_bounds: '[' ']' nest_array_bounds
2604 { $$ = lcons(makeInteger(-1), $3); }
2605 | '[' Iconst ']' nest_array_bounds
2606 { $$ = lcons(makeInteger($2), $4); }
2612 /*****************************************************************************
2615 * SQL92 introduces a large amount of type-specific syntax.
2616 * Define individual clauses to handle these cases, and use
2617 * the generic case to handle regular type-extensible Postgres syntax.
2618 * - thomas 1997-10-10
2620 *****************************************************************************/
2622 Typename: Array opt_array_bounds
2625 $$->arrayBounds = $2;
2627 /* Is this the name of a complex type? If so, implement
2630 if (!strcmp(saved_relname, $$->name))
2631 /* This attr is the same type as the relation
2632 * being defined. The classic example: create
2633 * emp(name=text,mgr=emp)
2636 else if (typeTypeRelid(typenameType($$->name)) != InvalidOid)
2637 /* (Eventually add in here that the set can only
2638 * contain one element.)
2659 $$ = makeNode(TypeName);
2660 $$->name = xlateSqlType($1);
2664 generic: Id { $$ = $1; }
2665 | TYPE_P { $$ = xlateSqlType("type"); }
2666 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2669 /* SQL92 numeric data types
2670 * Check FLOAT() precision limits assuming IEEE floating types.
2671 * Provide rudimentary DECIMAL() and NUMERIC() implementations
2672 * by checking parameters and making sure they match what is possible with INTEGER.
2673 * - thomas 1997-09-18
2675 Numeric: FLOAT opt_float
2677 $$ = makeNode(TypeName);
2678 $$->name = xlateSqlType($2);
2680 | DECIMAL opt_decimal
2682 $$ = makeNode(TypeName);
2683 $$->name = xlateSqlType("integer");
2685 | NUMERIC opt_numeric
2687 $$ = makeNode(TypeName);
2688 $$->name = xlateSqlType("integer");
2692 opt_float: '(' Iconst ')'
2695 elog(ERROR,"precision for FLOAT must be at least 1");
2697 $$ = xlateSqlType("float4");
2699 $$ = xlateSqlType("float8");
2701 elog(ERROR,"precision for FLOAT must be less than 16");
2705 $$ = xlateSqlType("float8");
2709 opt_numeric: '(' Iconst ',' Iconst ')'
2712 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2714 elog(ERROR,"NUMERIC scale %d must be zero",$4);
2719 elog(ERROR,"NUMERIC precision %d must be 9",$2);
2727 opt_decimal: '(' Iconst ',' Iconst ')'
2730 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2732 elog(ERROR,"DECIMAL scale %d must be zero",$4);
2738 elog(ERROR,"DECIMAL precision %d exceeds implementation limit of 9",$2);
2747 /* SQL92 character data types
2748 * The following implements CHAR() and VARCHAR().
2749 * We do it here instead of the 'Generic' production
2750 * because we don't want to allow arrays of VARCHAR().
2751 * I haven't thought about whether that will work or not.
2754 Character: character '(' Iconst ')'
2756 $$ = makeNode(TypeName);
2757 if (!strcasecmp($1, "char"))
2758 $$->name = xlateSqlType("bpchar");
2759 else if (!strcasecmp($1, "varchar"))
2760 $$->name = xlateSqlType("varchar");
2762 yyerror("parse error");
2764 elog(ERROR,"length for '%s' type must be at least 1",$1);
2766 /* we can store a char() of length up to the size
2767 * of a page (8KB) - page headers and friends but
2768 * just to be safe here... - ay 6/95
2769 * XXX note this hardcoded limit - thomas 1997-07-13
2771 elog(ERROR,"length for type '%s' cannot exceed 4096",$1);
2773 /* we actually implement this sort of like a varlen, so
2774 * the first 4 bytes is the length. (the difference
2775 * between this and "text" is that we blank-pad and
2776 * truncate where necessary
2778 $$->typmod = VARHDRSZ + $3;
2782 $$ = makeNode(TypeName);
2783 $$->name = xlateSqlType($1);
2787 character: CHARACTER opt_varying opt_charset opt_collate
2790 if (($3 == NULL) || (strcasecmp($3, "sql_text") == 0)) {
2791 if ($2) type = xlateSqlType("varchar");
2792 else type = xlateSqlType("char");
2795 c = palloc(strlen("var") + strlen($3) + 1);
2798 type = xlateSqlType(c);
2800 type = xlateSqlType($3);
2804 elog(ERROR,"COLLATE %s not yet implemented",$4);
2807 | CHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2808 | VARCHAR { $$ = xlateSqlType("varchar"); }
2809 | NATIONAL CHARACTER opt_varying { $$ = xlateSqlType($3? "varchar": "char"); }
2810 | NCHAR opt_varying { $$ = xlateSqlType($2? "varchar": "char"); }
2813 opt_varying: VARYING { $$ = TRUE; }
2814 | /*EMPTY*/ { $$ = FALSE; }
2817 opt_charset: CHARACTER SET ColId { $$ = $3; }
2818 | /*EMPTY*/ { $$ = NULL; }
2821 opt_collate: COLLATE ColId { $$ = $2; }
2822 | /*EMPTY*/ { $$ = NULL; }
2827 $$ = makeNode(TypeName);
2828 $$->name = xlateSqlType($1);
2830 | TIMESTAMP opt_timezone
2832 $$ = makeNode(TypeName);
2833 $$->name = xlateSqlType("timestamp");
2838 $$ = makeNode(TypeName);
2839 $$->name = xlateSqlType("time");
2841 | INTERVAL opt_interval
2843 $$ = makeNode(TypeName);
2844 $$->name = xlateSqlType("interval");
2848 datetime: YEAR_P { $$ = "year"; }
2849 | MONTH_P { $$ = "month"; }
2850 | DAY_P { $$ = "day"; }
2851 | HOUR_P { $$ = "hour"; }
2852 | MINUTE_P { $$ = "minute"; }
2853 | SECOND_P { $$ = "second"; }
2856 opt_timezone: WITH TIME ZONE { $$ = TRUE; }
2857 | /*EMPTY*/ { $$ = FALSE; }
2860 opt_interval: datetime { $$ = lcons($1, NIL); }
2861 | YEAR_P TO MONTH_P { $$ = NIL; }
2862 | DAY_P TO HOUR_P { $$ = NIL; }
2863 | DAY_P TO MINUTE_P { $$ = NIL; }
2864 | DAY_P TO SECOND_P { $$ = NIL; }
2865 | HOUR_P TO MINUTE_P { $$ = NIL; }
2866 | HOUR_P TO SECOND_P { $$ = NIL; }
2867 | /*EMPTY*/ { $$ = NIL; }
2871 /*****************************************************************************
2873 * expression grammar, still needs some cleanup
2875 *****************************************************************************/
2877 a_expr_or_null: a_expr
2881 A_Const *n = makeNode(A_Const);
2882 n->val.type = T_Null;
2887 /* Expressions using row descriptors
2888 * Define row_descriptor to allow yacc to break the reduce/reduce conflict
2889 * with singleton expressions.
2891 row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
2893 SubLink *n = makeNode(SubLink);
2895 n->oper = lcons("=",NIL);
2897 n->subLinkType = ANY_SUBLINK;
2901 | '(' row_descriptor ')' NOT IN '(' SubSelect ')'
2903 SubLink *n = makeNode(SubLink);
2905 n->oper = lcons("<>",NIL);
2907 n->subLinkType = ALL_SUBLINK;
2911 | '(' row_descriptor ')' Op ANY '(' SubSelect ')'
2913 SubLink *n = makeNode(SubLink);
2915 n->oper = lcons($4,NIL);
2917 n->subLinkType = ANY_SUBLINK;
2921 | '(' row_descriptor ')' Op ALL '(' SubSelect ')'
2923 SubLink *n = makeNode(SubLink);
2925 n->oper = lcons($4,NIL);
2927 n->subLinkType = ALL_SUBLINK;
2931 | '(' row_descriptor ')' Op '(' SubSelect ')'
2933 SubLink *n = makeNode(SubLink);
2935 n->oper = lcons($4, NIL);
2936 if (strcmp($4,"<>") == 0)
2940 n->subLinkType = EXPR_SUBLINK;
2944 | '(' row_descriptor ')' Op '(' row_descriptor ')'
2946 $$ = makeRowExpr($4, $2, $6);
2950 row_descriptor: row_list ',' a_expr
2952 $$ = lappend($1, $3);
2956 row_list: row_list ',' a_expr
2958 $$ = lappend($1, $3);
2962 $$ = lcons($1, NIL);
2966 a_expr: attr opt_indirection
2968 $1->indirection = $2;
2975 | '-' a_expr %prec UMINUS
2976 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2978 { $$ = makeA_Expr(OP, "+", $1, $3); }
2980 { $$ = makeA_Expr(OP, "-", $1, $3); }
2982 { $$ = makeA_Expr(OP, "/", $1, $3); }
2984 { $$ = makeA_Expr(OP, "*", $1, $3); }
2986 { $$ = makeA_Expr(OP, "<", $1, $3); }
2988 { $$ = makeA_Expr(OP, ">", $1, $3); }
2990 { $$ = makeA_Expr(OP, "=", $1, $3); }
2992 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2994 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2996 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2997 | a_expr TYPECAST Typename
3000 /* AexprConst can be either A_Const or ParamNo */
3001 if (nodeTag($1) == T_A_Const) {
3002 ((A_Const *)$1)->typename = $3;
3003 } else if (nodeTag($1) == T_Param) {
3004 ((ParamNo *)$1)->typename = $3;
3005 /* otherwise, try to transform to a function call */
3007 FuncCall *n = makeNode(FuncCall);
3008 n->funcname = $3->name;
3009 n->args = lcons($1,NIL);
3013 | CAST a_expr AS Typename
3016 /* AexprConst can be either A_Const or ParamNo */
3017 if (nodeTag($2) == T_A_Const) {
3018 ((A_Const *)$2)->typename = $4;
3019 } else if (nodeTag($2) == T_Param) {
3020 ((ParamNo *)$2)->typename = $4;
3021 /* otherwise, try to transform to a function call */
3023 FuncCall *n = makeNode(FuncCall);
3024 n->funcname = $4->name;
3025 n->args = lcons($2,NIL);
3029 | '(' a_expr_or_null ')'
3032 { $$ = makeIndexable($2,$1,$3); }
3033 | a_expr LIKE a_expr
3034 { $$ = makeIndexable("~~", $1, $3); }
3035 | a_expr NOT LIKE a_expr
3036 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
3038 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3040 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3043 /* could be a column name or a relation_name */
3044 Ident *n = makeNode(Ident);
3046 n->indirection = NULL;
3051 /* cheap hack for aggregate (eg. count) */
3052 FuncCall *n = makeNode(FuncCall);
3053 A_Const *star = makeNode(A_Const);
3055 star->val.type = T_String;
3056 star->val.val.str = "";
3058 n->args = lcons(star, NIL);
3063 FuncCall *n = makeNode(FuncCall);
3068 | name '(' expr_list ')'
3070 FuncCall *n = makeNode(FuncCall);
3077 A_Const *n = makeNode(A_Const);
3078 TypeName *t = makeNode(TypeName);
3080 n->val.type = T_String;
3081 n->val.val.str = "now";
3084 t->name = xlateSqlType("date");
3091 A_Const *n = makeNode(A_Const);
3092 TypeName *t = makeNode(TypeName);
3094 n->val.type = T_String;
3095 n->val.val.str = "now";
3098 t->name = xlateSqlType("time");
3103 | CURRENT_TIME '(' Iconst ')'
3105 FuncCall *n = makeNode(FuncCall);
3106 A_Const *s = makeNode(A_Const);
3107 TypeName *t = makeNode(TypeName);
3109 n->funcname = xlateSqlType("time");
3110 n->args = lcons(s, NIL);
3112 s->val.type = T_String;
3113 s->val.val.str = "now";
3116 t->name = xlateSqlType("time");
3120 elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
3126 A_Const *n = makeNode(A_Const);
3127 TypeName *t = makeNode(TypeName);
3129 n->val.type = T_String;
3130 n->val.val.str = "now";
3133 t->name = xlateSqlType("timestamp");
3138 | CURRENT_TIMESTAMP '(' Iconst ')'
3140 FuncCall *n = makeNode(FuncCall);
3141 A_Const *s = makeNode(A_Const);
3142 TypeName *t = makeNode(TypeName);
3144 n->funcname = xlateSqlType("timestamp");
3145 n->args = lcons(s, NIL);
3147 s->val.type = T_String;
3148 s->val.val.str = "now";
3151 t->name = xlateSqlType("timestamp");
3155 elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
3161 FuncCall *n = makeNode(FuncCall);
3162 n->funcname = "getpgusername";
3166 | EXISTS '(' SubSelect ')'
3168 SubLink *n = makeNode(SubLink);
3172 n->subLinkType = EXISTS_SUBLINK;
3176 | EXTRACT '(' extract_list ')'
3178 FuncCall *n = makeNode(FuncCall);
3179 n->funcname = "date_part";
3183 | POSITION '(' position_list ')'
3185 FuncCall *n = makeNode(FuncCall);
3186 n->funcname = "strpos";
3190 | SUBSTRING '(' substr_list ')'
3192 FuncCall *n = makeNode(FuncCall);
3193 n->funcname = "substr";
3197 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3198 | TRIM '(' BOTH trim_list ')'
3200 FuncCall *n = makeNode(FuncCall);
3201 n->funcname = "btrim";
3205 | TRIM '(' LEADING trim_list ')'
3207 FuncCall *n = makeNode(FuncCall);
3208 n->funcname = "ltrim";
3212 | TRIM '(' TRAILING trim_list ')'
3214 FuncCall *n = makeNode(FuncCall);
3215 n->funcname = "rtrim";
3219 | TRIM '(' trim_list ')'
3221 FuncCall *n = makeNode(FuncCall);
3222 n->funcname = "btrim";
3227 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3229 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
3231 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3232 | a_expr IS NOT NULL_P
3233 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
3234 /* IS TRUE, IS FALSE, etc used to be function calls
3235 * but let's make them expressions to allow the optimizer
3236 * a chance to eliminate them if a_expr is a constant string.
3237 * - thomas 1997-12-22
3241 A_Const *n = makeNode(A_Const);
3242 n->val.type = T_String;
3243 n->val.val.str = "t";
3244 n->typename = makeNode(TypeName);
3245 n->typename->name = xlateSqlType("bool");
3246 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3248 | a_expr IS NOT FALSE_P
3250 A_Const *n = makeNode(A_Const);
3251 n->val.type = T_String;
3252 n->val.val.str = "t";
3253 n->typename = makeNode(TypeName);
3254 n->typename->name = xlateSqlType("bool");
3255 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3259 A_Const *n = makeNode(A_Const);
3260 n->val.type = T_String;
3261 n->val.val.str = "f";
3262 n->typename = makeNode(TypeName);
3263 n->typename->name = xlateSqlType("bool");
3264 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3266 | a_expr IS NOT TRUE_P
3268 A_Const *n = makeNode(A_Const);
3269 n->val.type = T_String;
3270 n->val.val.str = "f";
3271 n->typename = makeNode(TypeName);
3272 n->typename->name = xlateSqlType("bool");
3273 $$ = makeA_Expr(OP, "=", $1,(Node *)n);
3275 | a_expr BETWEEN AexprConst AND AexprConst
3277 $$ = makeA_Expr(AND, NULL,
3278 makeA_Expr(OP, ">=", $1, $3),
3279 makeA_Expr(OP, "<=", $1, $5));
3281 | a_expr NOT BETWEEN AexprConst AND AexprConst
3283 $$ = makeA_Expr(OR, NULL,
3284 makeA_Expr(OP, "<", $1, $4),
3285 makeA_Expr(OP, ">", $1, $6));
3287 | a_expr IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' in_expr ')' { saved_In_Expr = lnext(saved_In_Expr); }
3289 if (nodeTag($5) == T_SubLink)
3291 SubLink *n = (SubLink *)$5;
3292 n->lefthand = lcons($1, NIL);
3293 n->oper = lcons("=",NIL);
3295 n->subLinkType = ANY_SUBLINK;
3300 | a_expr NOT IN { saved_In_Expr = lcons($1,saved_In_Expr); } '(' not_in_expr ')' { saved_In_Expr = lnext(saved_In_Expr); }
3302 if (nodeTag($6) == T_SubLink)
3304 SubLink *n = (SubLink *)$6;
3305 n->lefthand = lcons($1, NIL);
3306 n->oper = lcons("<>",NIL);
3308 n->subLinkType = ALL_SUBLINK;
3313 | a_expr Op ANY '(' SubSelect ')'
3315 SubLink *n = makeNode(SubLink);
3316 n->lefthand = lcons($1,NIL);
3317 n->oper = lcons($2,NIL);
3319 n->subLinkType = ANY_SUBLINK;
3323 | a_expr Op ALL '(' SubSelect ')'
3325 SubLink *n = makeNode(SubLink);
3326 n->lefthand = lcons($1, NULL);
3327 n->oper = lcons($2,NIL);
3329 n->subLinkType = ALL_SUBLINK;
3334 { $$ = makeA_Expr(AND, NULL, $1, $3); }
3336 { $$ = makeA_Expr(OR, NULL, $1, $3); }
3338 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
3341 opt_indirection: '[' a_expr ']' opt_indirection
3343 A_Indices *ai = makeNode(A_Indices);
3348 | '[' a_expr ':' a_expr ']' opt_indirection
3350 A_Indices *ai = makeNode(A_Indices);
3359 expr_list: a_expr_or_null
3360 { $$ = lcons($1, NIL); }
3361 | expr_list ',' a_expr_or_null
3362 { $$ = lappend($1, $3); }
3363 | expr_list USING a_expr
3364 { $$ = lappend($1, $3); }
3367 extract_list: datetime FROM a_expr
3369 A_Const *n = makeNode(A_Const);
3370 n->val.type = T_String;
3371 n->val.val.str = $1;
3372 $$ = lappend(lcons((Node *)n,NIL), $3);
3378 position_list: position_expr IN position_expr
3379 { $$ = makeList($3, $1, -1); }
3384 position_expr: attr opt_indirection
3386 $1->indirection = $2;
3391 | '-' position_expr %prec UMINUS
3392 { $$ = makeA_Expr(OP, "-", NULL, $2); }
3393 | position_expr '+' position_expr
3394 { $$ = makeA_Expr(OP, "+", $1, $3); }
3395 | position_expr '-' position_expr
3396 { $$ = makeA_Expr(OP, "-", $1, $3); }
3397 | position_expr '/' position_expr
3398 { $$ = makeA_Expr(OP, "/", $1, $3); }
3399 | position_expr '*' position_expr
3400 { $$ = makeA_Expr(OP, "*", $1, $3); }
3402 { $$ = makeA_Expr(OP, "|", NULL, $2); }
3403 | position_expr TYPECAST Typename
3406 /* AexprConst can be either A_Const or ParamNo */
3407 if (nodeTag($1) == T_A_Const) {
3408 ((A_Const *)$1)->typename = $3;
3409 } else if (nodeTag($1) == T_Param) {
3410 ((ParamNo *)$1)->typename = $3;
3411 /* otherwise, try to transform to a function call */
3413 FuncCall *n = makeNode(FuncCall);
3414 n->funcname = $3->name;
3415 n->args = lcons($1,NIL);
3419 | CAST position_expr AS Typename
3422 /* AexprConst can be either A_Const or ParamNo */
3423 if (nodeTag($2) == T_A_Const) {
3424 ((A_Const *)$2)->typename = $4;
3425 } else if (nodeTag($2) == T_Param) {
3426 ((ParamNo *)$2)->typename = $4;
3427 /* otherwise, try to transform to a function call */
3429 FuncCall *n = makeNode(FuncCall);
3430 n->funcname = $4->name;
3431 n->args = lcons($2,NIL);
3435 | '(' position_expr ')'
3437 | position_expr Op position_expr
3438 { $$ = makeA_Expr(OP, $2, $1, $3); }
3440 { $$ = makeA_Expr(OP, $1, NULL, $2); }
3442 { $$ = makeA_Expr(OP, $2, $1, NULL); }
3445 /* could be a column name or a relation_name */
3446 Ident *n = makeNode(Ident);
3448 n->indirection = NULL;
3453 FuncCall *n = makeNode(FuncCall);
3458 | name '(' expr_list ')'
3460 FuncCall *n = makeNode(FuncCall);
3465 | POSITION '(' position_list ')'
3467 FuncCall *n = makeNode(FuncCall);
3468 n->funcname = "strpos";
3472 | SUBSTRING '(' substr_list ')'
3474 FuncCall *n = makeNode(FuncCall);
3475 n->funcname = "substr";
3479 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
3480 | TRIM '(' BOTH trim_list ')'
3482 FuncCall *n = makeNode(FuncCall);
3483 n->funcname = "btrim";
3487 | TRIM '(' LEADING trim_list ')'
3489 FuncCall *n = makeNode(FuncCall);
3490 n->funcname = "ltrim";
3494 | TRIM '(' TRAILING trim_list ')'
3496 FuncCall *n = makeNode(FuncCall);
3497 n->funcname = "rtrim";
3501 | TRIM '(' trim_list ')'
3503 FuncCall *n = makeNode(FuncCall);
3504 n->funcname = "btrim";
3510 substr_list: expr_list substr_from substr_for
3512 $$ = nconc(nconc($1,$2),$3);
3518 substr_from: FROM expr_list
3522 A_Const *n = makeNode(A_Const);
3523 n->val.type = T_Integer;
3524 n->val.val.ival = 1;
3525 $$ = lcons((Node *)n,NIL);
3529 substr_for: FOR expr_list
3535 trim_list: a_expr FROM expr_list
3536 { $$ = lappend($3, $1); }
3545 SubLink *n = makeNode(SubLink);
3553 in_expr_nodes: AexprConst
3554 { $$ = makeA_Expr(OP, "=", lfirst(saved_In_Expr), $1); }
3555 | in_expr_nodes ',' AexprConst
3556 { $$ = makeA_Expr(OR, NULL, $1,
3557 makeA_Expr(OP, "=", lfirst(saved_In_Expr), $3));
3561 not_in_expr: SubSelect
3563 SubLink *n = makeNode(SubLink);
3571 not_in_expr_nodes: AexprConst
3572 { $$ = makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $1); }
3573 | not_in_expr_nodes ',' AexprConst
3574 { $$ = makeA_Expr(AND, NULL, $1,
3575 makeA_Expr(OP, "<>", lfirst(saved_In_Expr), $3));
3579 attr: relation_name '.' attrs
3581 $$ = makeNode(Attr);
3585 $$->indirection = NULL;
3589 $$ = makeNode(Attr);
3593 $$->indirection = NULL;
3598 { $$ = lcons(makeString($1), NIL); }
3599 | attrs '.' attr_name
3600 { $$ = lappend($1, makeString($3)); }
3602 { $$ = lappend($1, makeString("*")); }
3606 /*****************************************************************************
3610 *****************************************************************************/
3612 res_target_list: res_target_list ',' res_target_el
3613 { $$ = lappend($1,$3); }
3615 { $$ = lcons($1, NIL); }
3618 ResTarget *rt = makeNode(ResTarget);
3619 Attr *att = makeNode(Attr);
3621 att->paramNo = NULL;
3623 att->indirection = NIL;
3625 rt->indirection = NULL;
3626 rt->val = (Node *)att;
3627 $$ = lcons(rt, NIL);
3631 res_target_el: ColId opt_indirection '=' a_expr_or_null
3633 $$ = makeNode(ResTarget);
3635 $$->indirection = $2;
3636 $$->val = (Node *)$4;
3638 | attr opt_indirection
3640 $$ = makeNode(ResTarget);
3642 $$->indirection = $2;
3643 $$->val = (Node *)$1;
3645 | relation_name '.' '*'
3647 Attr *att = makeNode(Attr);
3649 att->paramNo = NULL;
3650 att->attrs = lcons(makeString("*"), NIL);
3651 att->indirection = NIL;
3652 $$ = makeNode(ResTarget);
3654 $$->indirection = NULL;
3655 $$->val = (Node *)att;
3660 ** target list for select.
3661 ** should get rid of the other but is still needed by the defunct select into
3662 ** and update (uses a subset)
3664 res_target_list2: res_target_list2 ',' res_target_el2
3665 { $$ = lappend($1, $3); }
3667 { $$ = lcons($1, NIL); }
3670 /* AS is not optional because shift/red conflict with unary ops */
3671 res_target_el2: a_expr_or_null AS ColLabel
3673 $$ = makeNode(ResTarget);
3675 $$->indirection = NULL;
3676 $$->val = (Node *)$1;
3680 $$ = makeNode(ResTarget);
3682 $$->indirection = NULL;
3683 $$->val = (Node *)$1;
3685 | relation_name '.' '*'
3687 Attr *att = makeNode(Attr);
3689 att->paramNo = NULL;
3690 att->attrs = lcons(makeString("*"), NIL);
3691 att->indirection = NIL;
3692 $$ = makeNode(ResTarget);
3694 $$->indirection = NULL;
3695 $$->val = (Node *)att;
3699 Attr *att = makeNode(Attr);
3701 att->paramNo = NULL;
3703 att->indirection = NIL;
3704 $$ = makeNode(ResTarget);
3706 $$->indirection = NULL;
3707 $$->val = (Node *)att;
3711 opt_id: ColId { $$ = $1; }
3712 | /* EMPTY */ { $$ = NULL; }
3715 relation_name: SpecialRuleRelation
3718 StrNCpy(saved_relname, $1, NAMEDATALEN);
3722 /* disallow refs to variable system tables */
3723 if (strcmp(LogRelationName, $1) == 0
3724 || strcmp(VariableRelationName, $1) == 0)
3725 elog(ERROR,"%s cannot be accessed by users",$1);
3728 StrNCpy(saved_relname, $1, NAMEDATALEN);
3732 database_name: ColId { $$ = $1; };
3733 access_method: Id { $$ = $1; };
3734 attr_name: ColId { $$ = $1; };
3735 class: Id { $$ = $1; };
3736 index_name: ColId { $$ = $1; };
3739 * Include date/time keywords as SQL92 extension.
3740 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3742 name: ColId { $$ = $1; };
3744 file_name: Sconst { $$ = $1; };
3745 recipe_name: Id { $$ = $1; };
3748 * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
3752 A_Const *n = makeNode(A_Const);
3753 n->val.type = T_Integer;
3754 n->val.val.ival = $1;
3759 A_Const *n = makeNode(A_Const);
3760 n->val.type = T_Float;
3761 n->val.val.dval = $1;
3766 A_Const *n = makeNode(A_Const);
3767 n->val.type = T_String;
3768 n->val.val.str = $1;
3773 A_Const *n = makeNode(A_Const);
3775 n->val.type = T_String;
3776 n->val.val.str = $2;
3780 { $$ = (Node *)$1; }
3783 A_Const *n = makeNode(A_Const);
3784 n->val.type = T_String;
3785 n->val.val.str = "t";
3786 n->typename = makeNode(TypeName);
3787 n->typename->name = xlateSqlType("bool");
3792 A_Const *n = makeNode(A_Const);
3793 n->val.type = T_String;
3794 n->val.val.str = "f";
3795 n->typename = makeNode(TypeName);
3796 n->typename->name = xlateSqlType("bool");
3803 $$ = makeNode(ParamNo);
3808 NumConst: Iconst { $$ = makeInteger($1); }
3809 | FCONST { $$ = makeFloat($1); }
3812 Iconst: ICONST { $$ = $1; };
3813 Sconst: SCONST { $$ = $1; };
3815 /* Column and type identifier
3816 * Does not include explicit datetime types
3817 * since these must be decoupled in Typename syntax.
3818 * Use ColId for most identifiers. - thomas 1997-10-21
3820 Id: IDENT { $$ = $1; };
3822 /* Column identifier
3823 * Include date/time keywords as SQL92 extension.
3824 * Include TYPE as a SQL92 unreserved keyword. - thomas 1997-10-05
3825 * Add other keywords. Note that as the syntax expands,
3826 * some of these keywords will have to be removed from this
3827 * list due to shift/reduce conflicts in yacc. If so, move
3828 * down to the ColLabel entity. - thomas 1997-11-06
3830 ColId: Id { $$ = $1; }
3831 | datetime { $$ = $1; }
3832 | ACTION { $$ = "action"; }
3833 | DATABASE { $$ = "database"; }
3834 | DELIMITERS { $$ = "delimiters"; }
3835 | FUNCTION { $$ = "function"; }
3836 | INDEX { $$ = "index"; }
3837 | KEY { $$ = "key"; }
3838 | LANGUAGE { $$ = "language"; }
3839 | LOCATION { $$ = "location"; }
3840 | MATCH { $$ = "match"; }
3841 | OPERATOR { $$ = "operator"; }
3842 | OPTION { $$ = "option"; }
3843 | PRIVILEGES { $$ = "privileges"; }
3844 | RECIPE { $$ = "recipe"; }
3845 | TIME { $$ = "time"; }
3846 | TRIGGER { $$ = "trigger"; }
3847 | TYPE_P { $$ = "type"; }
3848 | VERSION { $$ = "version"; }
3849 | ZONE { $$ = "zone"; }
3853 * Allowed labels in "AS" clauses.
3854 * Include TRUE/FALSE SQL3 reserved words for Postgres backward
3855 * compatibility. Cannot allow this for column names since the
3856 * syntax would not distinguish between the constant value and
3857 * a column name. - thomas 1997-10-24
3858 * Add other keywords to this list. Note that they appear here
3859 * rather than in ColId if there was a shift/reduce conflict
3860 * when used as a full identifier. - thomas 1997-11-06
3862 ColLabel: ColId { $$ = $1; }
3863 | ARCHIVE { $$ = "archive"; }
3864 | CLUSTER { $$ = "cluster"; }
3865 | CONSTRAINT { $$ = "constraint"; }
3866 | CROSS { $$ = "cross"; }
3867 | FOREIGN { $$ = "foreign"; }
3868 | GROUP { $$ = "group"; }
3869 | LOAD { $$ = "load"; }
3870 | ORDER { $$ = "order"; }
3871 | POSITION { $$ = "position"; }
3872 | PRECISION { $$ = "precision"; }
3873 | TABLE { $$ = "table"; }
3874 | TRANSACTION { $$ = "transaction"; }
3875 | TRUE_P { $$ = "true"; }
3876 | FALSE_P { $$ = "false"; }
3879 SpecialRuleRelation: CURRENT
3884 elog(ERROR,"CURRENT used in non-rule query");
3891 elog(ERROR,"NEW used in non-rule query");
3898 makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
3900 A_Expr *a = makeNode(A_Expr);
3909 * Generate separate operator nodes for a single row descriptor expression.
3910 * Perhaps this should go deeper in the parser someday... - thomas 1997-12-22
3913 makeRowExpr(char *opr, List *largs, List *rargs)
3918 if (length(largs) != length(rargs))
3919 elog(ERROR,"Unequal number of entries in row expression");
3921 if (lnext(largs) != NIL)
3922 expr = makeRowExpr(opr,lnext(largs),lnext(rargs));
3924 larg = lfirst(largs);
3925 rarg = lfirst(rargs);
3927 if ((strcmp(opr, "=") == 0)
3928 || (strcmp(opr, "<") == 0)
3929 || (strcmp(opr, "<=") == 0)
3930 || (strcmp(opr, ">") == 0)
3931 || (strcmp(opr, ">=") == 0))
3934 expr = makeA_Expr(OP, opr, larg, rarg);
3936 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3938 else if (strcmp(opr, "<>") == 0)
3941 expr = makeA_Expr(OP, opr, larg, rarg);
3943 expr = makeA_Expr(OR, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3947 elog(ERROR,"Operator '%s' not implemented for row expressions",opr);
3951 while ((largs != NIL) && (rargs != NIL))
3953 larg = lfirst(largs);
3954 rarg = lfirst(rargs);
3957 expr = makeA_Expr(OP, opr, larg, rarg);
3959 expr = makeA_Expr(AND, NULL, expr, makeA_Expr(OP, opr, larg, rarg));
3961 largs = lnext(largs);
3962 rargs = lnext(rargs);
3971 mapTargetColumns(List *src, List *dst)
3976 if (length(src) != length(dst))
3977 elog(ERROR,"CREATE TABLE/AS SELECT has mismatched column count");
3979 while ((src != NIL) && (dst != NIL))
3981 s = (ColumnDef *)lfirst(src);
3982 d = (ResTarget *)lfirst(dst);
3984 d->name = s->colname;
3991 } /* mapTargetColumns() */
3993 static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr)
3995 Node *result = NULL;
3997 /* we do this so indexes can be used */
3998 if (strcmp(opname,"~") == 0 ||
3999 strcmp(opname,"~*") == 0)
4001 if (nodeTag(rexpr) == T_A_Const &&
4002 ((A_Const *)rexpr)->val.type == T_String &&
4003 ((A_Const *)rexpr)->val.val.str[0] == '^')
4005 A_Const *n = (A_Const *)rexpr;
4006 char *match_least = palloc(strlen(n->val.val.str)+2);
4007 char *match_most = palloc(strlen(n->val.val.str)+2);
4008 int pos, match_pos=0;
4010 /* skip leading ^ */
4011 for (pos = 1; n->val.val.str[pos]; pos++)
4013 if (n->val.val.str[pos] == '.' ||
4014 n->val.val.str[pos] == '?' ||
4015 n->val.val.str[pos] == '*' ||
4016 n->val.val.str[pos] == '[' ||
4017 n->val.val.str[pos] == '$' ||
4018 (strcmp(opname,"~*") == 0 && isalpha(n->val.val.str[pos])))
4020 if (n->val.val.str[pos] == '\\')
4022 match_least[match_pos] = n->val.val.str[pos];
4023 match_most[match_pos++] = n->val.val.str[pos];
4028 A_Const *least = makeNode(A_Const);
4029 A_Const *most = makeNode(A_Const);
4031 /* make strings to be used in index use */
4032 match_least[match_pos] = '\0';
4033 match_most[match_pos] = '\377';
4034 match_most[match_pos+1] = '\0';
4035 least->val.type = T_String;
4036 least->val.val.str = match_least;
4037 most->val.type = T_String;
4038 most->val.val.str = match_most;
4039 result = makeA_Expr(AND, NULL,
4040 makeA_Expr(OP, "~", lexpr, rexpr),
4041 makeA_Expr(AND, NULL,
4042 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4043 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4047 else if (strcmp(opname,"~~") == 0)
4049 if (nodeTag(rexpr) == T_A_Const &&
4050 ((A_Const *)rexpr)->val.type == T_String)
4052 A_Const *n = (A_Const *)rexpr;
4053 char *match_least = palloc(strlen(n->val.val.str)+2);
4054 char *match_most = palloc(strlen(n->val.val.str)+2);
4055 int pos, match_pos=0;
4057 for (pos = 0; n->val.val.str[pos]; pos++)
4059 if ((n->val.val.str[pos] == '%' &&
4060 n->val.val.str[pos+1] != '%') ||
4061 (n->val.val.str[pos] == '_' &&
4062 n->val.val.str[pos+1] != '_'))
4064 if (n->val.val.str[pos] == '%' ||
4065 n->val.val.str[pos] == '_' ||
4066 n->val.val.str[pos] == '\\')
4068 match_least[match_pos] = n->val.val.str[pos];
4069 match_most[match_pos++] = n->val.val.str[pos];
4074 A_Const *least = makeNode(A_Const);
4075 A_Const *most = makeNode(A_Const);
4077 /* make strings to be used in index use */
4078 match_least[match_pos] = '\0';
4079 match_most[match_pos] = '\377';
4080 match_most[match_pos+1] = '\0';
4081 least->val.type = T_String;
4082 least->val.val.str = match_least;
4083 most->val.type = T_String;
4084 most->val.val.str = match_most;
4085 result = makeA_Expr(AND, NULL,
4086 makeA_Expr(OP, "~~", lexpr, rexpr),
4087 makeA_Expr(AND, NULL,
4088 makeA_Expr(OP, ">=", lexpr, (Node *)least),
4089 makeA_Expr(OP, "<=", lexpr, (Node *)most)));
4095 result = makeA_Expr(OP, opname, lexpr, rexpr);
4097 } /* makeIndexable() */
4101 * Convert alternate type names to internal Postgres types.
4102 * Do not convert "float", since that is handled elsewhere
4103 * for FLOAT(p) syntax.
4106 xlateSqlType(char *name)
4108 if (!strcasecmp(name,"int")
4109 || !strcasecmp(name,"integer"))
4111 else if (!strcasecmp(name, "smallint"))
4113 else if (!strcasecmp(name, "real"))
4115 else if (!strcasecmp(name, "interval"))
4117 else if (!strcasecmp(name, "boolean"))
4121 } /* xlateSqlName() */
4124 void parser_init(Oid *typev, int nargs)
4126 QueryIsRule = FALSE;
4127 saved_relname[0]= '\0';
4128 saved_In_Expr = NULL;
4130 param_type_init(typev, nargs);
4134 /* FlattenStringList()
4135 * Traverse list of string nodes and convert to a single string.
4136 * Used for reconstructing string form of complex expressions.
4138 * Allocate at least one byte for terminator.
4141 FlattenStringList(List *list)
4149 nlist = length(list);
4152 v = (Value *)lfirst(l);
4159 s = (char*) palloc(len+1);
4164 v = (Value *)lfirst(l);
4168 if (l != NIL) strcat(s," ");
4173 printf( "flattened string is \"%s\"\n", s);
4177 } /* FlattenStringList() */
4180 /* makeConstantList()
4181 * Convert constant value node into string node.
4184 makeConstantList( A_Const *n)
4186 char *defval = NULL;
4187 if (nodeTag(n) != T_A_Const) {
4188 elog(ERROR,"Cannot handle non-constant parameter");
4190 } else if (n->val.type == T_Float) {
4191 defval = (char*) palloc(20+1);
4192 sprintf( defval, "%g", n->val.val.dval);
4194 } else if (n->val.type == T_Integer) {
4195 defval = (char*) palloc(20+1);
4196 sprintf( defval, "%ld", n->val.val.ival);
4198 } else if (n->val.type == T_String) {
4199 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
4200 strcpy( defval, "'");
4201 strcat( defval, ((A_Const *) n)->val.val.str);
4202 strcat( defval, "'");
4205 elog(ERROR,"Internal error in makeConstantList(): cannot encode node");
4209 printf( "AexprConst argument is \"%s\"\n", defval);
4212 return( lcons( makeString(defval), NIL));
4213 } /* makeConstantList() */
4217 * Check input string for non-lowercase/non-numeric characters.
4218 * Returns either input string or input surrounded by double quotes.
4225 for (cp = rawid; *cp != '\0'; cp++)
4226 if (! (islower(*cp) || isdigit(*cp) || (*cp == '_'))) break;
4229 cp = palloc(strlen(rawid)+1);
4238 printf("fmtId- %sconvert %s to %s\n", ((cp == rawid)? "do not ": ""), rawid, cp);
4247 * keep enough information around fill out the type of param nodes
4248 * used in postquel functions
4251 param_type_init(Oid *typev, int nargs)
4253 pfunc_num_args = nargs;
4254 param_type_info = typev;
4257 Oid param_type(int t)
4259 if ((t > pfunc_num_args) || (t == 0))
4261 return param_type_info[t - 1];