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.53 1997/09/29 05:58:12 vadim Exp $
16 * AUTHOR DATE MAJOR EVENT
17 * Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
18 * Andrew Yu Oct, 1994 lispy code conversion
21 * CAPITALS are used to represent terminal symbols.
22 * non-capitals are used to represent non-terminals.
24 * if you use list, make sure the datum is a node so that the printing
28 * sometimes we assign constants to makeStrings. Make sure we don't free
31 *-------------------------------------------------------------------------
37 #include "nodes/parsenodes.h"
38 #include "nodes/print.h"
39 #include "parser/gramparse.h"
40 #include "parser/catalog_utils.h"
41 #include "parser/parse_query.h"
42 #include "storage/smgr.h"
43 #include "utils/acl.h"
44 #include "catalog/catname.h"
45 #include "utils/elog.h"
46 #include "access/xact.h"
48 static char saved_relname[NAMEDATALEN]; /* need this for complex attributes */
49 static bool QueryIsRule = FALSE;
50 static Node *saved_In_Expr;
51 extern List *parsetree;
54 * If you need access to certain yacc-generated variables and find that
55 * they're static by default, uncomment the next line. (this is not a
58 /*#define __YYSCLASS*/
60 static char *xlateSqlType(char *);
61 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
62 static List *makeConstantList( A_Const *node);
63 static char *FlattenStringList(List *list);
65 /* old versions of flex define this as a macro */
86 ConstraintDef *constrdef;
90 SortGroupBy *sortgroupby;
107 AddAttrStmt, ClosePortalStmt,
108 CopyStmt, CreateStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
109 ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
110 IndexStmt, ListenStmt, OptimizableStmt,
111 ProcedureStmt, PurgeStmt,
112 RecipeStmt, RemoveAggrStmt, RemoveOperStmt, RemoveFuncStmt, RemoveStmt,
113 RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
114 CreatedbStmt, DestroydbStmt, VacuumStmt, RetrieveStmt, CursorStmt,
115 ReplaceStmt, AppendStmt, NotifyStmt, DeleteStmt, ClusterStmt,
116 ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt
118 %type <str> txname, char_type
119 %type <node> SubSelect
120 %type <str> join_expr, join_outer, join_spec
121 %type <boolean> TriggerActionTime, TriggerForSpec
123 %type <str> DateTime, TriggerEvents, TriggerFuncArg
125 %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
126 database_name, access_method_clause, access_method, attr_name,
127 class, index_name, name, file_name, recipe_name, aggr_argtype
129 %type <constrdef> ConstraintElem, ConstraintDef
131 %type <str> opt_id, opt_portal_name,
132 before_clause, after_clause, all_Op, MathOp, opt_name, opt_unique,
133 result, OptUseOp, opt_class, opt_range_start, opt_range_end,
136 %type <str> privileges, operation_commalist, grantee
137 %type <chr> operation, TriggerOneEvent
139 %type <list> stmtblock, stmtmulti,
140 relation_name_list, OptTableElementList, tableElementList,
141 OptInherit, OptConstraint, ConstraintList, definition,
142 opt_with, def_args, def_name_list, func_argtypes,
143 oper_argtypes, OptStmtList, OptStmtBlock, OptStmtMulti,
144 opt_column_list, columnList, opt_va_list, va_list,
145 sort_clause, sortby_list, index_params, index_list, name_list,
146 from_clause, from_list, opt_array_bounds, nest_array_bounds,
147 expr_list, attrs, res_target_list, res_target_list2,
148 def_list, opt_indirection, group_clause, groupby_list, TriggerFuncArgs
150 %type <list> union_clause, select_list
151 %type <list> join_list
152 %type <sortgroupby> join_using
154 %type <node> position_expr
155 %type <list> extract_list, position_list
156 %type <list> substr_list, substr_from, substr_for, trim_list
157 %type <list> interval_opts
159 %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_col, opt_with_copy,
160 index_opt_unique, opt_verbose, opt_analyze, opt_null
162 %type <ival> copy_dirn, archive_type, OptArchiveType, OptArchiveLocation,
163 def_type, opt_direction, remove_type, opt_column, event
165 %type <ival> OptLocation, fetch_how_many
167 %type <list> OptSeqList
168 %type <defelt> OptSeqElem
170 %type <dstmt> def_rest
171 %type <pstmt> purge_quals
172 %type <astmt> insert_rest
174 %type <typnam> Typename, typname, opt_type
175 %type <coldef> columnDef, alter_clause
176 %type <defelt> def_elem
177 %type <node> def_arg, columnElem, where_clause,
178 a_expr, a_expr_or_null, AexprConst,
179 in_expr_nodes, not_in_expr_nodes,
181 %type <value> NumConst
182 %type <attr> event_object, attr
183 %type <sortgroupby> groupby
184 %type <sortgroupby> sortby
185 %type <ielem> index_elem, func_index
186 %type <range> from_val
187 %type <relexp> relation_expr
188 %type <trange> time_range
189 %type <target> res_target_el, res_target_el2
190 %type <paramno> ParamNo
194 %type <str> Id, date, var_value, zone_value
197 %type <list> default_expr
198 %type <str> opt_default
199 %type <list> constraint_elem
202 * If you make any token changes, remember to:
203 * - use "yacc -d" and update parse.h
204 * - update the keyword table in parser/keywords.c
208 %token ABORT_TRANS, ACL, ADD, AFTER, AGGREGATE, ALL, ALTER, ANALYZE,
209 AND, APPEND, ARCHIVE, ARCH_STORE, AS, ASC,
210 BACKWARD, BEFORE, BEGIN_TRANS, BETWEEN, BINARY, BY,
211 CAST, CHANGE, CHECK, CLOSE, CLUSTER, COLUMN,
212 COMMIT, CONSTRAINT, COPY, CREATE, CROSS, CURRENT, CURSOR,
213 DATABASE, DECLARE, DEFAULT, DELETE, DELIMITERS, DESC,
214 DISTINCT, DO, DROP, END_TRANS, EXISTS, EXTEND,
215 FETCH, FOR, FORWARD, FROM, FULL, FUNCTION, GRANT, GROUP, HAVING, HEAVY,
216 IN, INDEX, INHERITS, INNERJOIN, INSERT, INSTEAD, INTO, IS, ISNULL,
217 JOIN, LANGUAGE, LEFT, LIGHT, LISTEN, LOAD, LOCAL, MERGE, MOVE,
218 NATURAL, NEW, NONE, NOT, NOTHING, NOTIFY, NOTNULL,
219 OIDS, ON, OPERATOR, OPTION, OR, ORDER, OUTERJOIN,
220 PNULL, PRIVILEGES, PROCEDURE, PUBLIC, PURGE, P_TYPE,
221 RENAME, REPLACE, RESET, RETRIEVE, RETURNS, REVOKE, RIGHT, ROLLBACK, RULE,
222 SELECT, SET, SETOF, SHOW, STDIN, STDOUT, STORE,
223 TABLE, TO, TRANSACTION, TRIGGER,
224 UNION, UNIQUE, UPDATE, USING, VACUUM, VALUES,
225 VERBOSE, VERSION, VIEW, WHERE, WITH, WORK
226 %token EXECUTE, RECIPE, EXPLAIN, LIKE, SEQUENCE
229 %token INTERVAL, TIME, ZONE
230 %token DAYINTERVAL, HOURINTERVAL, MINUTEINTERVAL, MONTHINTERVAL,
231 SECONDINTERVAL, YEARINTERVAL
232 %token BOTH, LEADING, TRAILING,
233 %token EXTRACT, POSITION, SUBSTRING, TRIM
234 %token DOUBLE, PRECISION, FLOAT
235 %token DECIMAL, NUMERIC
236 %token CHARACTER, VARYING
237 %token CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP
239 /* Special keywords, not in the query language - see the "lex" file */
240 %token <str> IDENT, SCONST, Op
241 %token <ival> ICONST, PARAM
244 /* these are not real. they are here so that they get generated as #define's*/
261 %left '|' /* this is the relation union op, not logical or */
262 %right ':' /* Unary Operators */
263 %left ';' /* end of statement or natural log */
276 { parsetree = lcons($1,NIL); }
279 stmtmulti: stmtmulti stmt ';'
280 { $$ = lappend($1, $2); }
282 { $$ = lappend($1, $2); }
284 { $$ = lcons($1,NIL); }
325 /*****************************************************************************
327 * Set PG internal variable
328 * SET name TO 'var_value'
330 *****************************************************************************/
332 VariableSetStmt: SET Id TO var_value
334 VariableSetStmt *n = makeNode(VariableSetStmt);
339 | SET Id '=' var_value
341 VariableSetStmt *n = makeNode(VariableSetStmt);
346 | SET TIME ZONE zone_value
348 VariableSetStmt *n = makeNode(VariableSetStmt);
349 n->name = "timezone";
355 var_value: Sconst { $$ = $1; }
358 zone_value: Sconst { $$ = $1; }
359 | LOCAL { $$ = NULL; }
362 VariableShowStmt: SHOW Id
364 VariableShowStmt *n = makeNode(VariableShowStmt);
370 VariableResetStmt: RESET Id
372 VariableResetStmt *n = makeNode(VariableResetStmt);
378 /*****************************************************************************
381 * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
383 *****************************************************************************/
385 AddAttrStmt: ALTER TABLE relation_name opt_inh_star alter_clause
387 AddAttrStmt *n = makeNode(AddAttrStmt);
395 alter_clause: ADD opt_column columnDef
399 | ADD '(' tableElementList ')'
401 ColumnDef *lp = lfirst($3);
404 elog(WARN,"ALTER TABLE/ADD() allows one column only",NULL);
406 printf( "list has %d elements\n", length($3));
411 { elog(WARN,"ALTER TABLE/DROP COLUMN not yet implemented",NULL); }
412 | ALTER opt_column Id SET opt_default
413 { elog(WARN,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented",NULL); }
414 | ALTER opt_column Id DROP DEFAULT
415 { elog(WARN,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented",NULL); }
417 { elog(WARN,"ALTER TABLE/ADD CONSTRAINT not yet implemented",NULL); }
420 /* Column definition might include WITH TIME ZONE, but only for the data types
421 * called out in SQL92 date/time definitions. So, check explicitly for "timestamp"
422 * and "time". - thomas 1997-07-14
424 columnDef: Id Typename opt_with_col opt_default opt_null
426 $$ = makeNode(ColumnDef);
429 $$->typename->timezone = $3;
431 $$->is_not_null = $5;
432 if ($$->typename->timezone
433 && (strcasecmp($$->typename->name, "timestamp")
434 && strcasecmp($$->typename->name, "time")))
435 elog(NOTICE,"%s does not use WITH TIME ZONE",$$->typename->name);
439 opt_default: DEFAULT default_expr
441 $$ = FlattenStringList($2);
443 | /*EMPTY*/ { $$ = NULL; }
446 default_expr: AexprConst
447 { $$ = makeConstantList((A_Const *) $1); }
449 { $$ = lcons( makeString("NULL"), NIL); }
450 | '-' default_expr %prec UMINUS
451 { $$ = lcons( makeString( "-"), $2); }
452 | default_expr '+' default_expr
453 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
454 | default_expr '-' default_expr
455 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
456 | default_expr '/' default_expr
457 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
458 | default_expr '*' default_expr
459 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
460 | default_expr '=' default_expr
461 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
462 | default_expr '<' default_expr
463 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
464 | default_expr '>' default_expr
465 { elog(WARN,"boolean expressions not supported in DEFAULT",NULL); }
467 { $$ = lcons( makeString( ":"), $2); }
469 { $$ = lcons( makeString( ";"), $2); }
471 { $$ = lcons( makeString( "|"), $2); }
472 | default_expr TYPECAST Typename
474 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
476 | CAST default_expr AS Typename
478 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
480 | '(' default_expr ')'
481 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
482 | name '(' default_expr ')'
484 $$ = makeList( makeString($1), makeString("("), -1);
486 $$ = lappend( $$, makeString(")"));
490 $$ = makeList( makeString($1), makeString("("), -1);
491 $$ = lappend( $$, makeString(")"));
493 | default_expr Op default_expr
495 if (!strcmp("<=", $2) || !strcmp(">=", $2))
496 elog(WARN,"boolean expressions not supported in DEFAULT",NULL);
497 $$ = nconc( $1, lcons( makeString( $2), $3));
500 { $$ = lcons( makeString( $1), $2); }
502 { $$ = lappend( $1, makeString( $2)); }
505 opt_null: NOT PNULL { $$ = TRUE; }
506 | NOTNULL { $$ = TRUE; }
507 | /* EMPTY */ { $$ = FALSE; }
510 opt_with_col: WITH TIME ZONE { $$ = TRUE; }
511 | /* EMPTY */ { $$ = FALSE; }
514 /*****************************************************************************
519 *****************************************************************************/
521 ClosePortalStmt: CLOSE opt_id
523 ClosePortalStmt *n = makeNode(ClosePortalStmt);
530 /*****************************************************************************
533 * COPY [BINARY] <relname> FROM/TO
534 * [USING DELIMITERS <delimiter>]
536 *****************************************************************************/
538 CopyStmt: COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
540 CopyStmt *n = makeNode(CopyStmt);
558 * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
559 * used depends on the direction. (It really doesn't make sense to copy from
560 * stdout. We silently correct the "typo". - AY 9/94
562 copy_file_name: Sconst { $$ = $1; }
563 | STDIN { $$ = NULL; }
564 | STDOUT { $$ = NULL; }
567 opt_binary: BINARY { $$ = TRUE; }
568 | /*EMPTY*/ { $$ = FALSE; }
571 opt_with_copy: WITH OIDS { $$ = TRUE; }
572 | /* EMPTY */ { $$ = FALSE; }
576 * the default copy delimiter is tab but the user can configure it
578 copy_delimiter: USING DELIMITERS Sconst { $$ = $3;}
579 | /* EMPTY */ { $$ = "\t"; }
583 /*****************************************************************************
588 *****************************************************************************/
590 CreateStmt: CREATE TABLE relation_name '(' OptTableElementList ')'
591 OptInherit OptConstraint OptArchiveType OptLocation
594 CreateStmt *n = makeNode(CreateStmt);
606 OptTableElementList: tableElementList { $$ = $1; }
607 | /* EMPTY */ { $$ = NULL; }
611 tableElementList ',' columnDef
612 { $$ = lappend($1, $3); }
614 { $$ = lcons($1, NIL); }
618 OptArchiveType: ARCHIVE '=' archive_type { $$ = $3; }
619 | /*EMPTY*/ { $$ = ARCH_NONE; }
622 archive_type: HEAVY { $$ = ARCH_HEAVY; }
623 | LIGHT { $$ = ARCH_LIGHT; }
624 | NONE { $$ = ARCH_NONE; }
627 OptLocation: STORE '=' Sconst
633 OptArchiveLocation: ARCH_STORE '=' Sconst
639 OptInherit: INHERITS '(' relation_name_list ')' { $$ = $3; }
640 | /*EMPTY*/ { $$ = NIL; }
643 OptConstraint: ConstraintList { $$ = $1; }
644 | /*EMPTY*/ { $$ = NULL; }
648 ConstraintList ',' ConstraintElem
649 { $$ = lappend($1, $3); }
651 { $$ = lcons($1, NIL); }
655 CONSTRAINT name ConstraintDef
660 | ConstraintDef { $$ = $1; }
663 ConstraintDef: CHECK constraint_elem
665 ConstraintDef *constr = palloc (sizeof(ConstraintDef));
667 printf("in ConstraintDef\n");
669 constr->type = CONSTR_CHECK;
671 constr->def = FlattenStringList($2);
673 printf("ConstraintDef: string is %s\n", (char *) constr->def);
679 constraint_elem: AexprConst
680 { $$ = makeConstantList((A_Const *) $1); }
682 { $$ = lcons( makeString("NULL"), NIL); }
686 printf( "Id is %s\n", $1);
688 $$ = lcons( makeString($1), NIL);
690 | '-' constraint_elem %prec UMINUS
691 { $$ = lcons( makeString( "-"), $2); }
692 | constraint_elem '+' constraint_elem
693 { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
694 | constraint_elem '-' constraint_elem
695 { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
696 | constraint_elem '/' constraint_elem
697 { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
698 | constraint_elem '*' constraint_elem
699 { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
700 | constraint_elem '=' constraint_elem
701 { $$ = nconc( $1, lcons( makeString( "="), $3)); }
702 | constraint_elem '<' constraint_elem
703 { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
704 | constraint_elem '>' constraint_elem
705 { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
706 | ':' constraint_elem
707 { $$ = lcons( makeString( ":"), $2); }
708 | ';' constraint_elem
709 { $$ = lcons( makeString( ";"), $2); }
710 | '|' constraint_elem
711 { $$ = lcons( makeString( "|"), $2); }
712 | constraint_elem TYPECAST Typename
714 $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
716 | CAST constraint_elem AS Typename
718 $$ = nconc( lcons( makeString( "CAST"), $2), makeList( makeString("AS"), $4, -1));
720 | '(' constraint_elem ')'
721 { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
722 | name '(' constraint_elem ')'
724 $$ = makeList( makeString($1), makeString("("), -1);
726 $$ = lappend( $$, makeString(")"));
728 | constraint_elem Op constraint_elem
729 { $$ = nconc( $1, lcons( makeString( $2), $3)); }
730 | constraint_elem AND constraint_elem
731 { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
732 | constraint_elem OR constraint_elem
733 { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
735 { $$ = lcons( makeString( $1), $2); }
737 { $$ = lappend( $1, makeString( $2)); }
741 /*****************************************************************************
744 * CREATE SEQUENCE seqname
746 *****************************************************************************/
748 CreateSeqStmt: CREATE SEQUENCE relation_name OptSeqList
750 CreateSeqStmt *n = makeNode(CreateSeqStmt);
758 OptSeqList OptSeqElem
759 { $$ = lappend($1, $2); }
763 OptSeqElem: IDENT NumConst
765 $$ = makeNode(DefElem);
767 $$->arg = (Node *)$2;
771 $$ = makeNode(DefElem);
773 $$->arg = (Node *)NULL;
778 /*****************************************************************************
784 *****************************************************************************/
786 CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON
787 relation_name TriggerForSpec EXECUTE PROCEDURE
788 name '(' TriggerFuncArgs ')'
790 CreateTrigStmt *n = makeNode(CreateTrigStmt);
797 memcpy (n->actions, $5, 4);
802 TriggerActionTime: BEFORE { $$ = TRUE; }
803 | AFTER { $$ = FALSE; }
806 TriggerEvents: TriggerOneEvent
808 char *e = palloc (4);
809 e[0] = $1; e[1] = 0; $$ = e;
811 | TriggerOneEvent OR TriggerOneEvent
813 char *e = palloc (4);
814 e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
816 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
818 char *e = palloc (4);
819 e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
824 TriggerOneEvent: INSERT { $$ = 'i'; }
825 | DELETE { $$ = 'd'; }
826 | UPDATE { $$ = 'u'; }
829 TriggerForSpec: FOR name name
831 if ( strcmp ($2, "each") != 0 )
832 elog(WARN,"parser: syntax error near %s",$2);
833 if ( strcmp ($3, "row") == 0 )
835 else if ( strcmp ($3, "statement") == 0 )
838 elog(WARN,"parser: syntax error near %s",$3);
842 TriggerFuncArgs: TriggerFuncArg
843 { $$ = lcons($1, NIL); }
844 | TriggerFuncArgs ',' TriggerFuncArg
845 { $$ = lappend($1, $3); }
846 | /* EMPTY */ { $$ = NIL; }
849 TriggerFuncArg: ICONST
851 char *s = (char *) palloc (256);
852 sprintf (s, "%d", $1);
857 char *s = (char *) palloc (256);
858 sprintf (s, "%g", $1);
861 | Sconst { $$ = $1; }
865 DropTrigStmt: DROP TRIGGER name ON relation_name
867 DropTrigStmt *n = makeNode(DropTrigStmt);
874 /*****************************************************************************
877 * define (type,operator,aggregate)
879 *****************************************************************************/
881 DefineStmt: CREATE def_type def_rest
888 def_rest: def_name definition
890 $$ = makeNode(DefineStmt);
893 printf("def_rest: defname is %s\n", $1);
899 def_type: OPERATOR { $$ = OPERATOR; }
903 printf("def_type: decoding P_TYPE\n");
907 | AGGREGATE { $$ = AGGREGATE; }
910 def_name: PROCEDURE { $$ = "procedure"; }
912 | MathOp { $$ = $1; }
916 definition: '(' def_list ')' { $$ = $2; }
919 def_list: def_elem { $$ = lcons($1, NIL); }
920 | def_list ',' def_elem { $$ = lappend($1, $3); }
923 def_elem: def_name '=' def_arg
926 printf("def_elem: decoding %s =\n", $1);
929 $$ = makeNode(DefElem);
931 $$->arg = (Node *)$3;
936 printf("def_elem: decoding %s\n", $1);
938 $$ = makeNode(DefElem);
940 $$->arg = (Node *)NULL;
942 | DEFAULT '=' def_arg
945 printf("def_elem: decoding DEFAULT =\n");
948 $$ = makeNode(DefElem);
949 $$->defname = "default";
950 $$->arg = (Node *)$3;
954 def_arg: Id { $$ = (Node *)makeString($1); }
955 | all_Op { $$ = (Node *)makeString($1); }
956 | NumConst { $$ = (Node *)$1; /* already a Value */ }
957 | Sconst { $$ = (Node *)makeString($1); }
960 TypeName *n = makeNode(TypeName);
963 n->arrayBounds = NULL;
966 | DOUBLE { $$ = (Node *)makeString("double"); }
970 /*****************************************************************************
973 * destroy <relname1> [, <relname2> .. <relnameN> ]
975 *****************************************************************************/
977 DestroyStmt: DROP TABLE relation_name_list
979 DestroyStmt *n = makeNode(DestroyStmt);
984 | DROP SEQUENCE relation_name_list
986 DestroyStmt *n = makeNode(DestroyStmt);
994 /*****************************************************************************
997 * fetch/move [forward | backward] [number | all ] [ in <portalname> ]
999 *****************************************************************************/
1001 FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
1003 FetchStmt *n = makeNode(FetchStmt);
1010 | MOVE opt_direction fetch_how_many opt_portal_name
1012 FetchStmt *n = makeNode(FetchStmt);
1021 opt_direction: FORWARD { $$ = FORWARD; }
1022 | BACKWARD { $$ = BACKWARD; }
1023 | /*EMPTY*/ { $$ = FORWARD; /* default */ }
1026 fetch_how_many: Iconst
1028 if ($1 <= 0) elog(WARN,"Please specify nonnegative count for fetch",NULL); }
1029 | ALL { $$ = 0; /* 0 means fetch all tuples*/}
1030 | /*EMPTY*/ { $$ = 1; /*default*/ }
1033 opt_portal_name: IN name { $$ = $2;}
1034 | /*EMPTY*/ { $$ = NULL; }
1037 /*****************************************************************************
1040 * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
1042 *****************************************************************************/
1044 GrantStmt: GRANT privileges ON relation_name_list TO grantee opt_with_grant
1046 $$ = (Node*)makeAclStmt($2,$4,$6,'+');
1052 privileges: ALL PRIVILEGES
1054 $$ = aclmakepriv("rwaR",0);
1058 $$ = aclmakepriv("rwaR",0);
1060 | operation_commalist
1066 operation_commalist: operation
1068 $$ = aclmakepriv("",$1);
1070 | operation_commalist ',' operation
1072 $$ = aclmakepriv($1,$3);
1079 $$ = ACL_MODE_RD_CHR;
1083 $$ = ACL_MODE_AP_CHR;
1087 $$ = ACL_MODE_WR_CHR;
1091 $$ = ACL_MODE_WR_CHR;
1095 $$ = ACL_MODE_RU_CHR;
1101 $$ = aclmakeuser("A","");
1105 $$ = aclmakeuser("G",$2);
1109 $$ = aclmakeuser("U",$1);
1113 opt_with_grant : /* empty */
1116 yyerror("WITH GRANT OPTION is not supported. Only relation owners can set privileges");
1120 /*****************************************************************************
1123 * REVOKE [privileges] ON [relation_name] FROM [user]
1125 *****************************************************************************/
1127 RevokeStmt: REVOKE privileges ON relation_name_list FROM grantee
1129 $$ = (Node*)makeAclStmt($2,$4,$6,'-');
1135 /*****************************************************************************
1138 * define [archive] index <indexname> on <relname>
1139 * using <access> "(" (<col> with <op>)+ ")" [with
1142 * [where <qual>] is not supported anymore
1143 *****************************************************************************/
1145 IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
1146 access_method_clause '(' index_params ')' opt_with
1148 /* should check that access_method is valid,
1149 etc ... but doesn't */
1150 IndexStmt *n = makeNode(IndexStmt);
1154 n->accessMethod = $7;
1155 n->indexParams = $9;
1156 n->withClause = $11;
1157 n->whereClause = NULL;
1162 access_method_clause: USING access_method { $$ = $2; }
1163 | /* empty -- 'btree' is default access method */
1167 index_opt_unique: UNIQUE { $$ = TRUE; }
1168 | /*empty*/ { $$ = FALSE; }
1171 /*****************************************************************************
1174 * extend index <indexname> [where <qual>]
1176 *****************************************************************************/
1178 ExtendStmt: EXTEND INDEX index_name where_clause
1180 ExtendStmt *n = makeNode(ExtendStmt);
1182 n->whereClause = $4;
1187 /*****************************************************************************
1190 * execute recipe <recipeName>
1192 *****************************************************************************/
1194 RecipeStmt: EXECUTE RECIPE recipe_name
1197 if (!IsTransactionBlock())
1198 elog(WARN,"EXECUTE RECIPE may only be used in begin/end transaction blocks",NULL);
1200 n = makeNode(RecipeStmt);
1207 /*****************************************************************************
1210 * define function <fname>
1211 * (language = <lang>, returntype = <typename>
1212 * [, arch_pct = <percentage | pre-defined>]
1213 * [, disk_pct = <percentage | pre-defined>]
1214 * [, byte_pct = <percentage | pre-defined>]
1215 * [, perbyte_cpu = <int | pre-defined>]
1216 * [, percall_cpu = <int | pre-defined>]
1218 * [arg is (<type-1> { , <type-n>})]
1219 * as <filename or code in language as appropriate>
1221 *****************************************************************************/
1223 ProcedureStmt: CREATE FUNCTION def_name def_args
1224 RETURNS def_arg opt_with AS Sconst LANGUAGE Sconst
1226 ProcedureStmt *n = makeNode(ProcedureStmt);
1229 n->returnType = (Node *)$6;
1236 opt_with: WITH definition { $$ = $2; }
1237 | /* EMPTY */ { $$ = NIL; }
1240 def_args: '(' def_name_list ')' { $$ = $2; }
1241 | '(' ')' { $$ = NIL; }
1244 def_name_list: name_list;
1247 /*****************************************************************************
1250 * purge <relname> [before <date>] [after <date>]
1252 * purge <relname> [after <date>] [before <date>]
1254 *****************************************************************************/
1256 PurgeStmt: PURGE relation_name purge_quals
1263 purge_quals: before_clause
1265 $$ = makeNode(PurgeStmt);
1266 $$->beforeDate = $1;
1267 $$->afterDate = NULL;
1271 $$ = makeNode(PurgeStmt);
1272 $$->beforeDate = NULL;
1275 | before_clause after_clause
1277 $$ = makeNode(PurgeStmt);
1278 $$->beforeDate = $1;
1281 | after_clause before_clause
1283 $$ = makeNode(PurgeStmt);
1284 $$->beforeDate = $2;
1289 $$ = makeNode(PurgeStmt);
1290 $$->beforeDate = NULL;
1291 $$->afterDate = NULL;
1295 before_clause: BEFORE date { $$ = $2; }
1296 after_clause: AFTER date { $$ = $2; }
1299 /*****************************************************************************
1303 * remove function <funcname>
1304 * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
1305 * remove aggregate <aggname>
1306 * (REMOVE AGGREGATE "aggname" "aggtype")
1307 * remove operator <opname>
1308 * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
1309 * remove type <typename>
1310 * (REMOVE TYPE "typename")
1311 * remove rule <rulename>
1312 * (REMOVE RULE "rulename")
1314 *****************************************************************************/
1316 RemoveStmt: DROP remove_type name
1318 RemoveStmt *n = makeNode(RemoveStmt);
1325 remove_type: Type { $$ = P_TYPE; }
1326 | INDEX { $$ = INDEX; }
1327 | RULE { $$ = RULE; }
1328 | VIEW { $$ = VIEW; }
1331 RemoveAggrStmt: DROP AGGREGATE name aggr_argtype
1333 RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
1340 aggr_argtype: name { $$ = $1; }
1341 | '*' { $$ = NULL; }
1344 RemoveFuncStmt: DROP FUNCTION name '(' func_argtypes ')'
1346 RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
1353 func_argtypes: name_list { $$ = $1; }
1354 | /*EMPTY*/ { $$ = NIL; }
1357 RemoveOperStmt: DROP OPERATOR all_Op '(' oper_argtypes ')'
1359 RemoveOperStmt *n = makeNode(RemoveOperStmt);
1366 all_Op: Op | MathOp;
1368 MathOp: '+' { $$ = "+"; }
1379 elog(WARN,"parser: argument type missing (use NONE for unary operators)",NULL);
1382 { $$ = makeList(makeString($1), makeString($3), -1); }
1383 | NONE ',' name /* left unary */
1384 { $$ = makeList(NULL, makeString($3), -1); }
1385 | name ',' NONE /* right unary */
1386 { $$ = makeList(makeString($1), NULL, -1); }
1389 /*****************************************************************************
1392 * rename <attrname1> in <relname> [*] to <attrname2>
1393 * rename <relname1> to <relname2>
1395 *****************************************************************************/
1397 RenameStmt: ALTER TABLE relation_name opt_inh_star
1398 RENAME opt_column opt_name TO name
1400 RenameStmt *n = makeNode(RenameStmt);
1409 opt_name: name { $$ = $1; }
1410 | /*EMPTY*/ { $$ = NULL; }
1413 opt_column: COLUMN { $$ = COLUMN; }
1414 | /*EMPTY*/ { $$ = 0; }
1418 /*****************************************************************************
1420 * QUERY: Define Rewrite Rule , Define Tuple Rule
1421 * Define Rule <old rules >
1423 * only rewrite rule is supported -- ay 9/94
1425 *****************************************************************************/
1427 RuleStmt: CREATE RULE name AS
1428 { QueryIsRule=TRUE; }
1429 ON event TO event_object where_clause
1430 DO opt_instead OptStmtList
1432 RuleStmt *n = makeNode(RuleStmt);
1436 n->whereClause = $10;
1443 OptStmtList: NOTHING { $$ = NIL; }
1444 | OptimizableStmt { $$ = lcons($1, NIL); }
1445 | '[' OptStmtBlock ']' { $$ = $2; }
1448 OptStmtBlock: OptStmtMulti
1451 { $$ = lcons($1, NIL); }
1454 OptStmtMulti: OptStmtMulti OptimizableStmt ';'
1455 { $$ = lappend($1, $2); }
1456 | OptStmtMulti OptimizableStmt
1457 { $$ = lappend($1, $2); }
1458 | OptimizableStmt ';'
1459 { $$ = lcons($1, NIL); }
1462 event_object: relation_name '.' attr_name
1464 $$ = makeNode(Attr);
1467 $$->attrs = lcons(makeString($3), NIL);
1468 $$->indirection = NIL;
1472 $$ = makeNode(Attr);
1476 $$->indirection = NIL;
1480 /* change me to select, update, etc. some day */
1481 event: SELECT { $$ = CMD_SELECT; }
1482 | UPDATE { $$ = CMD_UPDATE; }
1483 | DELETE { $$ = CMD_DELETE; }
1484 | INSERT { $$ = CMD_INSERT; }
1487 opt_instead: INSTEAD { $$ = TRUE; }
1488 | /* EMPTY */ { $$ = FALSE; }
1492 /*****************************************************************************
1495 * NOTIFY <relation_name> can appear both in rule bodies and
1496 * as a query-level command
1498 *****************************************************************************/
1500 NotifyStmt: NOTIFY relation_name
1502 NotifyStmt *n = makeNode(NotifyStmt);
1508 ListenStmt: LISTEN relation_name
1510 ListenStmt *n = makeNode(ListenStmt);
1517 /*****************************************************************************
1528 *****************************************************************************/
1530 TransactionStmt: ABORT_TRANS TRANSACTION
1532 TransactionStmt *n = makeNode(TransactionStmt);
1533 n->command = ABORT_TRANS;
1536 | BEGIN_TRANS TRANSACTION
1538 TransactionStmt *n = makeNode(TransactionStmt);
1539 n->command = BEGIN_TRANS;
1544 TransactionStmt *n = makeNode(TransactionStmt);
1545 n->command = BEGIN_TRANS;
1550 TransactionStmt *n = makeNode(TransactionStmt);
1551 n->command = END_TRANS;
1554 | END_TRANS TRANSACTION
1556 TransactionStmt *n = makeNode(TransactionStmt);
1557 n->command = END_TRANS;
1562 TransactionStmt *n = makeNode(TransactionStmt);
1563 n->command = ABORT_TRANS;
1569 TransactionStmt *n = makeNode(TransactionStmt);
1570 n->command = ABORT_TRANS;
1575 TransactionStmt *n = makeNode(TransactionStmt);
1576 n->command = BEGIN_TRANS;
1581 TransactionStmt *n = makeNode(TransactionStmt);
1582 n->command = END_TRANS;
1588 TransactionStmt *n = makeNode(TransactionStmt);
1589 n->command = END_TRANS;
1594 TransactionStmt *n = makeNode(TransactionStmt);
1595 n->command = ABORT_TRANS;
1601 /*****************************************************************************
1604 * define view <viewname> '('target-list ')' [where <quals> ]
1606 *****************************************************************************/
1608 ViewStmt: CREATE VIEW name AS RetrieveStmt
1610 ViewStmt *n = makeNode(ViewStmt);
1612 n->query = (Query *)$5;
1618 /*****************************************************************************
1623 *****************************************************************************/
1625 LoadStmt: LOAD file_name
1627 LoadStmt *n = makeNode(LoadStmt);
1634 /*****************************************************************************
1639 *****************************************************************************/
1641 CreatedbStmt: CREATE DATABASE database_name
1643 CreatedbStmt *n = makeNode(CreatedbStmt);
1650 /*****************************************************************************
1655 *****************************************************************************/
1657 DestroydbStmt: DROP DATABASE database_name
1659 DestroydbStmt *n = makeNode(DestroydbStmt);
1666 /*****************************************************************************
1669 * cluster <index_name> on <relation_name>
1671 *****************************************************************************/
1673 ClusterStmt: CLUSTER index_name ON relation_name
1675 ClusterStmt *n = makeNode(ClusterStmt);
1682 /*****************************************************************************
1687 *****************************************************************************/
1689 VacuumStmt: VACUUM opt_verbose opt_analyze
1691 VacuumStmt *n = makeNode(VacuumStmt);
1698 | VACUUM opt_verbose relation_name opt_analyze opt_va_list
1700 VacuumStmt *n = makeNode(VacuumStmt);
1705 if ( $5 != NIL && !$4 )
1706 elog(WARN,"parser: syntax error at or near \"(\"",NULL);
1711 opt_verbose: VERBOSE { $$ = TRUE; }
1712 | /* EMPTY */ { $$ = FALSE; }
1715 opt_analyze: ANALYZE { $$ = TRUE; }
1716 | /* EMPTY */ { $$ = FALSE; }
1719 opt_va_list: '(' va_list ')'
1726 { $$=lcons($1,NIL); }
1728 { $$=lappend($1,$3); }
1731 /*****************************************************************************
1736 *****************************************************************************/
1738 ExplainStmt: EXPLAIN opt_verbose OptimizableStmt
1740 ExplainStmt *n = makeNode(ExplainStmt);
1742 n->query = (Query*)$3;
1747 /*****************************************************************************
1749 * Optimizable Stmts: *
1751 * one of the five queries processed by the planner *
1753 * [ultimately] produces query-trees as specified *
1754 * in the query-spec document in ~postgres/ref *
1756 *****************************************************************************/
1758 OptimizableStmt: RetrieveStmt
1763 | DeleteStmt /* by default all are $$=$1 */
1767 /*****************************************************************************
1772 *****************************************************************************/
1774 AppendStmt: INSERT INTO relation_name opt_column_list insert_rest
1782 insert_rest: VALUES '(' res_target_list2 ')'
1784 $$ = makeNode(AppendStmt);
1785 $$->targetList = $3;
1786 $$->fromClause = NIL;
1787 $$->whereClause = NULL;
1789 | SELECT res_target_list2 from_clause where_clause
1791 $$ = makeNode(AppendStmt);
1792 $$->targetList = $2;
1793 $$->fromClause = $3;
1794 $$->whereClause = $4;
1798 opt_column_list: '(' columnList ')' { $$ = $2; }
1799 | /*EMPTY*/ { $$ = NIL; }
1803 columnList ',' columnElem
1804 { $$ = lappend($1, $3); }
1806 { $$ = lcons($1, NIL); }
1809 columnElem: Id opt_indirection
1811 Ident *id = makeNode(Ident);
1813 id->indirection = $2;
1818 /*****************************************************************************
1823 *****************************************************************************/
1825 DeleteStmt: DELETE FROM relation_name
1828 DeleteStmt *n = makeNode(DeleteStmt);
1830 n->whereClause = $4;
1836 /*****************************************************************************
1839 * ReplaceStmt (UPDATE)
1841 *****************************************************************************/
1843 ReplaceStmt: UPDATE relation_name
1848 ReplaceStmt *n = makeNode(ReplaceStmt);
1852 n->whereClause = $6;
1858 /*****************************************************************************
1863 *****************************************************************************/
1865 CursorStmt: DECLARE name opt_binary CURSOR FOR
1866 SELECT opt_unique res_target_list2
1867 from_clause where_clause group_clause sort_clause
1869 CursorStmt *n = makeNode(CursorStmt);
1871 /* from PORTAL name */
1873 * 15 august 1991 -- since 3.0 postgres does locking
1874 * right, we discovered that portals were violating
1875 * locking protocol. portal locks cannot span xacts.
1876 * as a short-term fix, we installed the check here.
1879 if (!IsTransactionBlock())
1880 elog(WARN,"Named portals may only be used in begin/end transaction blocks",NULL);
1887 n->whereClause = $10;
1888 n->groupClause = $11;
1889 n->sortClause = $12;
1895 /*****************************************************************************
1900 *****************************************************************************/
1902 /******************************************************************************
1903 RetrieveStmt: SELECT opt_unique res_target_list2
1904 result from_clause where_clause
1905 group_clause having_clause
1908 RetrieveStmt *n = makeNode(RetrieveStmt);
1913 n->whereClause = $6;
1914 n->groupClause = $7;
1915 n->havingClause = $8;
1921 RetrieveStmt: Select UNION select_list sort_clause
1922 | Select sort_clause
1923 Select: SELECT opt_unique res_target_list2
1924 result from_clause where_clause
1925 group_clause having_clause
1927 Select *n = makeNode(Select);
1932 n->whereClause = $6;
1933 n->groupClause = $7;
1934 n->havingClause = $8;
1938 ******************************************************************************/
1940 RetrieveStmt: SELECT opt_unique res_target_list2
1941 result from_clause where_clause
1942 group_clause having_clause
1943 union_clause sort_clause
1945 RetrieveStmt *n = makeNode(RetrieveStmt);
1950 n->whereClause = $6;
1951 n->groupClause = $7;
1952 n->havingClause = $8;
1953 n->selectClause = $9;
1954 n->sortClause = $10;
1959 union_clause: UNION select_list { $$ = $2; }
1960 | /*EMPTY*/ { $$ = NIL; }
1963 select_list: select_list UNION SubSelect
1964 { $$ = lappend($1, $3); }
1966 { $$ = lcons($1, NIL); }
1969 SubSelect: SELECT opt_unique res_target_list2
1970 result from_clause where_clause
1971 group_clause having_clause
1973 SubSelect *n = makeNode(SubSelect);
1977 n->whereClause = $6;
1978 n->groupClause = $7;
1979 n->havingClause = $8;
1984 result: INTO TABLE relation_name
1985 { $$= $3; /* should check for archive level */ }
1990 opt_unique: DISTINCT { $$ = "*"; }
1991 | DISTINCT ON Id { $$ = $3; }
1992 | /*EMPTY*/ { $$ = NULL;}
1995 sort_clause: ORDER BY sortby_list { $$ = $3; }
1996 | /*EMPTY*/ { $$ = NIL; }
2000 { $$ = lcons($1, NIL); }
2001 | sortby_list ',' sortby
2002 { $$ = lappend($1, $3); }
2007 $$ = makeNode(SortGroupBy);
2013 | Id '.' Id OptUseOp
2015 $$ = makeNode(SortGroupBy);
2023 $$ = makeNode(SortGroupBy);
2031 OptUseOp: USING Op { $$ = $2; }
2032 | USING '<' { $$ = "<"; }
2033 | USING '>' { $$ = ">"; }
2035 | DESC { $$ = ">"; }
2036 | /*EMPTY*/ { $$ = "<"; /*default*/ }
2039 index_params: index_list { $$ = $1; }
2040 | func_index { $$ = lcons($1,NIL); }
2044 index_list ',' index_elem
2045 { $$ = lappend($1, $3); }
2047 { $$ = lcons($1, NIL); }
2050 func_index: name '(' name_list ')' opt_type opt_class
2052 $$ = makeNode(IndexElem);
2060 index_elem: attr_name opt_type opt_class
2062 $$ = makeNode(IndexElem);
2070 opt_type: ':' Typename { $$ = $2;}
2071 | /*EMPTY*/ { $$ = NULL;}
2075 | WITH class { $$ = $2; }
2076 | /*EMPTY*/ { $$ = NULL; }
2080 * jimmy bell-style recursive queries aren't supported in the
2083 * ...however, recursive addattr and rename supported. make special
2086 * XXX i believe '*' should be the default behavior, but...
2088 opt_inh_star: '*' { $$ = TRUE; }
2089 | /*EMPTY*/ { $$ = FALSE; }
2092 relation_name_list: name_list;
2095 { $$ = lcons(makeString($1),NIL); }
2096 | name_list ',' name
2097 { $$ = lappend($1,makeString($3)); }
2100 group_clause: GROUP BY groupby_list { $$ = $3; }
2101 | /*EMPTY*/ { $$ = NIL; }
2104 groupby_list: groupby { $$ = lcons($1, NIL); }
2105 | groupby_list ',' groupby { $$ = lappend($1, $3); }
2110 $$ = makeNode(SortGroupBy);
2118 $$ = makeNode(SortGroupBy);
2126 $$ = makeNode(SortGroupBy);
2134 having_clause: HAVING a_expr { $$ = $2; }
2135 | /*EMPTY*/ { $$ = NULL; }
2138 /*****************************************************************************
2140 * clauses common to all Optimizable Stmts:
2144 *****************************************************************************/
2146 from_clause: FROM '(' relation_expr join_expr JOIN relation_expr join_spec ')'
2149 elog(WARN,"JOIN not yet implemented",NULL);
2151 | FROM from_list { $$ = $2; }
2152 | /*EMPTY*/ { $$ = NIL; }
2155 from_list: from_list ',' from_val
2156 { $$ = lappend($1, $3); }
2157 | from_val CROSS JOIN from_val
2158 { elog(WARN,"CROSS JOIN not yet implemented",NULL); }
2160 { $$ = lcons($1, NIL); }
2163 from_val: relation_expr AS Id
2165 $$ = makeNode(RangeVar);
2171 $$ = makeNode(RangeVar);
2177 $$ = makeNode(RangeVar);
2183 join_expr: NATURAL join_expr { $$ = NULL; }
2185 { elog(WARN,"FULL OUTER JOIN not yet implemented",NULL); }
2187 { elog(WARN,"LEFT OUTER JOIN not yet implemented",NULL); }
2189 { elog(WARN,"RIGHT OUTER JOIN not yet implemented",NULL); }
2191 { elog(WARN,"OUTER JOIN not yet implemented",NULL); }
2193 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2195 { elog(WARN,"UNION JOIN not yet implemented",NULL); }
2197 { elog(WARN,"INNER JOIN not yet implemented",NULL); }
2200 join_outer: OUTERJOIN { $$ = NULL; }
2201 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2204 join_spec: ON '(' a_expr ')' { $$ = NULL; }
2205 | USING '(' join_list ')' { $$ = NULL; }
2206 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2209 join_list: join_using { $$ = lcons($1, NIL); }
2210 | join_list ',' join_using { $$ = lappend($1, $3); }
2215 $$ = makeNode(SortGroupBy);
2223 $$ = makeNode(SortGroupBy);
2231 $$ = makeNode(SortGroupBy);
2239 where_clause: WHERE a_expr { $$ = $2; }
2240 | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ }
2243 relation_expr: relation_name
2245 /* normal relations */
2246 $$ = makeNode(RelExpr);
2249 $$->timeRange = NULL;
2251 | relation_name '*' %prec '='
2253 /* inheiritance query */
2254 $$ = makeNode(RelExpr);
2257 $$->timeRange = NULL;
2259 | relation_name time_range
2261 /* time-qualified query */
2262 $$ = makeNode(RelExpr);
2270 time_range: '[' opt_range_start ',' opt_range_end ']'
2272 $$ = makeNode(TimeRange);
2278 $$ = makeNode(TimeRange);
2284 opt_range_start: date
2285 | /*EMPTY*/ { $$ = "epoch"; }
2289 | /*EMPTY*/ { $$ = "now"; }
2292 opt_array_bounds: '[' ']' nest_array_bounds
2293 { $$ = lcons(makeInteger(-1), $3); }
2294 | '[' Iconst ']' nest_array_bounds
2295 { $$ = lcons(makeInteger($2), $4); }
2300 nest_array_bounds: '[' ']' nest_array_bounds
2301 { $$ = lcons(makeInteger(-1), $3); }
2302 | '[' Iconst ']' nest_array_bounds
2303 { $$ = lcons(makeInteger($2), $4); }
2309 * typname handles types without trailing parens for size specification.
2310 * Typename uses either typname or explicit txname(size).
2311 * So, must handle float in both places. - thomas 1997-09-20
2317 $$ = makeNode(TypeName);
2319 if (!strcasecmp($1, "float"))
2320 tname = xlateSqlType("float8");
2321 else if (!strcasecmp($1, "decimal"))
2322 tname = xlateSqlType("integer");
2323 else if (!strcasecmp($1, "numeric"))
2324 tname = xlateSqlType("integer");
2326 tname = xlateSqlType($1);
2329 /* Is this the name of a complex type? If so, implement
2332 if (!strcmp(saved_relname, tname))
2333 /* This attr is the same type as the relation
2334 * being defined. The classic example: create
2335 * emp(name=text,mgr=emp)
2338 else if (get_typrelid((Type)type(tname)) != InvalidOid)
2339 /* (Eventually add in here that the set can only
2340 * contain one element.)
2348 char *tname = xlateSqlType($2);
2349 $$ = makeNode(TypeName);
2355 txname: Id { $$ = $1; }
2356 | TIME { $$ = xlateSqlType("time"); }
2357 | INTERVAL interval_opts { $$ = xlateSqlType("interval"); }
2358 | CHARACTER char_type { $$ = $2; }
2359 | DOUBLE PRECISION { $$ = xlateSqlType("float8"); }
2360 | FLOAT { $$ = xlateSqlType("float"); }
2361 | DECIMAL { $$ = "decimal"; }
2362 | NUMERIC { $$ = "numeric"; }
2365 char_type: VARYING { $$ = xlateSqlType("varchar"); }
2366 | /*EMPTY*/ { $$ = xlateSqlType("char"); }
2369 interval_opts: YEARINTERVAL { $$ = lcons("year", NIL); }
2370 | MONTHINTERVAL { $$ = NIL; }
2371 | DAYINTERVAL { $$ = NIL; }
2372 | HOURINTERVAL { $$ = NIL; }
2373 | MINUTEINTERVAL { $$ = NIL; }
2374 | SECONDINTERVAL { $$ = NIL; }
2375 | YEARINTERVAL TO MONTHINTERVAL { $$ = NIL; }
2376 | DAYINTERVAL TO HOURINTERVAL { $$ = NIL; }
2377 | DAYINTERVAL TO MINUTEINTERVAL { $$ = NIL; }
2378 | DAYINTERVAL TO SECONDINTERVAL { $$ = NIL; }
2379 | HOURINTERVAL TO MINUTEINTERVAL { $$ = NIL; }
2380 | HOURINTERVAL TO SECONDINTERVAL { $$ = NIL; }
2381 | /* EMPTY */ { $$ = NIL; }
2384 Typename: typname opt_array_bounds
2387 $$->arrayBounds = $2;
2389 if (!strcasecmp($1->name, "varchar"))
2393 | txname '(' Iconst ')'
2396 * The following implements CHAR() and VARCHAR().
2397 * We do it here instead of the 'typname:' production
2398 * because we don't want to allow arrays of VARCHAR().
2399 * I haven't thought about whether that will work or not.
2401 * Also implements FLOAT().
2402 * Check precision limits assuming IEEE floating types.
2403 * - thomas 1997-09-18
2405 $$ = makeNode(TypeName);
2406 if (!strcasecmp($1, "float")) {
2408 elog(WARN,"precision for FLOAT must be at least 1",NULL);
2410 $$->name = xlateSqlType("float4");
2412 $$->name = xlateSqlType("float8");
2414 elog(WARN,"precision for FLOAT must be less than 16",NULL);
2415 } else if (!strcasecmp($1, "decimal")) {
2416 /* DECIMAL is allowed to have more precision than specified */
2418 elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$3);
2419 $$->name = xlateSqlType("integer");
2421 } else if (!strcasecmp($1, "numeric")) {
2422 /* integer holds 9.33 decimal places, so assume an even 9 for now */
2424 elog(WARN,"NUMERIC precision %d must be 9",$3);
2425 $$->name = xlateSqlType("integer");
2428 if (!strcasecmp($1, "char"))
2429 $$->name = xlateSqlType("bpchar");
2430 else if (!strcasecmp($1, "varchar"))
2431 $$->name = xlateSqlType("varchar");
2433 yyerror("parse error");
2435 elog(WARN,"length for '%s' type must be at least 1",$1);
2437 /* we can store a char() of length up to the size
2438 * of a page (8KB) - page headers and friends but
2439 * just to be safe here... - ay 6/95
2440 * XXX note this hardcoded limit - thomas 1997-07-13
2442 elog(WARN,"length for '%s' type cannot exceed 4096",$1);
2444 /* we actually implement this sort of like a varlen, so
2445 * the first 4 bytes is the length. (the difference
2446 * between this and "text" is that we blank-pad and
2447 * truncate where necessary
2449 $$->typlen = 4 + $3;
2452 | txname '(' Iconst ',' Iconst ')'
2454 $$ = makeNode(TypeName);
2455 if (!strcasecmp($1, "decimal")) {
2457 elog(WARN,"DECIMAL precision %d exceeds implementation limit of 9",$3);
2459 elog(WARN,"DECIMAL scale %d must be zero",$5);
2460 $$->name = xlateSqlType("integer");
2462 } else if (!strcasecmp($1, "numeric")) {
2464 elog(WARN,"NUMERIC precision %d must be 9",$3);
2466 elog(WARN,"NUMERIC scale %d must be zero",$5);
2467 $$->name = xlateSqlType("integer");
2470 elog(WARN,"%s(%d,%d) not implemented",$1,$3,$5);
2472 $$->name = xlateSqlType("integer");
2477 /*****************************************************************************
2479 * expression grammar, still needs some cleanup
2481 *****************************************************************************/
2483 a_expr_or_null: a_expr
2487 A_Const *n = makeNode(A_Const);
2488 n->val.type = T_Null;
2492 a_expr: attr opt_indirection
2494 $1->indirection = $2;
2499 | '-' a_expr %prec UMINUS
2500 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2502 { $$ = makeA_Expr(OP, "+", $1, $3); }
2504 { $$ = makeA_Expr(OP, "-", $1, $3); }
2506 { $$ = makeA_Expr(OP, "/", $1, $3); }
2508 { $$ = makeA_Expr(OP, "*", $1, $3); }
2510 { $$ = makeA_Expr(OP, "<", $1, $3); }
2512 { $$ = makeA_Expr(OP, ">", $1, $3); }
2514 { $$ = makeA_Expr(OP, "=", $1, $3); }
2516 { $$ = makeA_Expr(OP, ":", NULL, $2); }
2518 { $$ = makeA_Expr(OP, ";", NULL, $2); }
2520 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2521 | AexprConst TYPECAST Typename
2523 /* AexprConst can be either A_Const or ParamNo */
2524 if (nodeTag($1) == T_A_Const)
2525 ((A_Const *)$1)->typename = $3;
2527 ((ParamNo *)$1)->typename = $3;
2530 | CAST AexprConst AS Typename
2532 /* AexprConst can be either A_Const or ParamNo */
2533 if (nodeTag($2) == T_A_Const)
2534 ((A_Const *)$2)->typename = $4;
2536 ((ParamNo *)$2)->typename = $4;
2539 | '(' a_expr_or_null ')'
2542 { $$ = makeA_Expr(OP, $2, $1, $3); }
2543 | a_expr LIKE a_expr
2544 { $$ = makeA_Expr(OP, "~~", $1, $3); }
2545 | a_expr NOT LIKE a_expr
2546 { $$ = makeA_Expr(OP, "!~~", $1, $4); }
2548 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2550 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2553 /* could be a column name or a relation_name */
2554 Ident *n = makeNode(Ident);
2556 n->indirection = NULL;
2561 FuncCall *n = makeNode(FuncCall);
2562 Ident *star = makeNode(Ident);
2564 /* cheap hack for aggregate (eg. count) */
2567 n->args = lcons(star, NIL);
2572 FuncCall *n = makeNode(FuncCall);
2579 A_Const *n = makeNode(A_Const);
2580 TypeName *t = makeNode(TypeName);
2582 n->val.type = T_String;
2583 n->val.val.str = "now";
2586 t->name = xlateSqlType("date");
2593 A_Const *n = makeNode(A_Const);
2594 TypeName *t = makeNode(TypeName);
2596 n->val.type = T_String;
2597 n->val.val.str = "now";
2600 t->name = xlateSqlType("time");
2605 | CURRENT_TIME '(' AexprConst ')'
2607 FuncCall *n = makeNode(FuncCall);
2608 A_Const *s = makeNode(A_Const);
2609 TypeName *t = makeNode(TypeName);
2611 n->funcname = xlateSqlType("time");
2612 n->args = lcons(s, NIL);
2614 s->val.type = T_String;
2615 s->val.val.str = "now";
2618 t->name = xlateSqlType("time");
2621 elog(NOTICE,"CURRENT_TIME(p) precision not implemented",NULL);
2627 A_Const *n = makeNode(A_Const);
2628 TypeName *t = makeNode(TypeName);
2630 n->val.type = T_String;
2631 n->val.val.str = "now";
2634 t->name = xlateSqlType("timestamp");
2639 | CURRENT_TIMESTAMP '(' AexprConst ')'
2641 FuncCall *n = makeNode(FuncCall);
2642 A_Const *s = makeNode(A_Const);
2643 TypeName *t = makeNode(TypeName);
2645 n->funcname = xlateSqlType("timestamp");
2646 n->args = lcons(s, NIL);
2648 s->val.type = T_String;
2649 s->val.val.str = "now";
2652 t->name = xlateSqlType("timestamp");
2655 elog(NOTICE,"CURRENT_TIMESTAMP(p) precision not implemented",NULL);
2659 /* We probably need to define an "exists" node,
2660 * since the optimizer could choose to find only one match.
2661 * Perhaps the first implementation could just check for
2662 * count(*) > 0? - thomas 1997-07-19
2664 | EXISTS '(' SubSelect ')'
2666 elog(WARN,"EXISTS not yet supported",NULL);
2669 | EXTRACT '(' extract_list ')'
2671 FuncCall *n = makeNode(FuncCall);
2672 n->funcname = "date_part";
2676 | POSITION '(' position_list ')'
2678 FuncCall *n = makeNode(FuncCall);
2679 n->funcname = "strpos";
2683 | SUBSTRING '(' substr_list ')'
2685 FuncCall *n = makeNode(FuncCall);
2686 n->funcname = "substr";
2690 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
2691 | TRIM '(' BOTH trim_list ')'
2693 FuncCall *n = makeNode(FuncCall);
2694 n->funcname = "btrim";
2698 | TRIM '(' LEADING trim_list ')'
2700 FuncCall *n = makeNode(FuncCall);
2701 n->funcname = "ltrim";
2705 | TRIM '(' TRAILING trim_list ')'
2707 FuncCall *n = makeNode(FuncCall);
2708 n->funcname = "rtrim";
2712 | TRIM '(' trim_list ')'
2714 FuncCall *n = makeNode(FuncCall);
2715 n->funcname = "btrim";
2719 | name '(' expr_list ')'
2721 FuncCall *n = makeNode(FuncCall);
2727 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2729 { $$ = makeA_Expr(ISNULL, NULL, $1, NULL); }
2731 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2732 | a_expr IS NOT PNULL
2733 { $$ = makeA_Expr(NOTNULL, NULL, $1, NULL); }
2734 | a_expr BETWEEN AexprConst AND AexprConst
2736 $$ = makeA_Expr(AND, NULL,
2737 makeA_Expr(OP, ">=", $1, $3),
2738 makeA_Expr(OP, "<=", $1, $5));
2740 | a_expr NOT BETWEEN AexprConst AND AexprConst
2742 $$ = makeA_Expr(OR, NULL,
2743 makeA_Expr(OP, "<", $1, $4),
2744 makeA_Expr(OP, ">", $1, $6));
2746 | a_expr IN { saved_In_Expr = $1; } '(' in_expr_nodes ')'
2748 | a_expr NOT IN { saved_In_Expr = $1; } '(' not_in_expr_nodes ')'
2751 { $$ = makeA_Expr(AND, NULL, $1, $3); }
2753 { $$ = makeA_Expr(OR, NULL, $1, $3); }
2755 { $$ = makeA_Expr(NOT, NULL, NULL, $2); }
2758 opt_indirection: '[' a_expr ']' opt_indirection
2760 A_Indices *ai = makeNode(A_Indices);
2765 | '[' a_expr ':' a_expr ']' opt_indirection
2767 A_Indices *ai = makeNode(A_Indices);
2776 expr_list: a_expr_or_null
2777 { $$ = lcons($1, NIL); }
2778 | expr_list ',' a_expr_or_null
2779 { $$ = lappend($1, $3); }
2780 | expr_list USING a_expr
2781 { $$ = lappend($1, $3); }
2784 extract_list: DateTime FROM a_expr
2786 A_Const *n = makeNode(A_Const);
2787 n->val.type = T_String;
2788 n->val.val.str = $1;
2790 printf( "string is %s\n", $1);
2792 $$ = lappend(lcons((Node *)n,NIL), $3);
2798 position_list: position_expr IN position_expr
2799 { $$ = makeList($3, $1, -1); }
2804 position_expr: attr opt_indirection
2806 $1->indirection = $2;
2811 | '-' position_expr %prec UMINUS
2812 { $$ = makeA_Expr(OP, "-", NULL, $2); }
2813 | position_expr '+' position_expr
2814 { $$ = makeA_Expr(OP, "+", $1, $3); }
2815 | position_expr '-' position_expr
2816 { $$ = makeA_Expr(OP, "-", $1, $3); }
2817 | position_expr '/' position_expr
2818 { $$ = makeA_Expr(OP, "/", $1, $3); }
2819 | position_expr '*' position_expr
2820 { $$ = makeA_Expr(OP, "*", $1, $3); }
2822 { $$ = makeA_Expr(OP, "|", NULL, $2); }
2823 | AexprConst TYPECAST Typename
2825 /* AexprConst can be either A_Const or ParamNo */
2826 if (nodeTag($1) == T_A_Const)
2827 ((A_Const *)$1)->typename = $3;
2829 ((ParamNo *)$1)->typename = $3;
2832 | CAST AexprConst AS Typename
2834 /* AexprConst can be either A_Const or ParamNo */
2835 if (nodeTag($2) == T_A_Const)
2836 ((A_Const *)$2)->typename = $4;
2838 ((ParamNo *)$2)->typename = $4;
2841 | '(' position_expr ')'
2843 | position_expr Op position_expr
2844 { $$ = makeA_Expr(OP, $2, $1, $3); }
2846 { $$ = makeA_Expr(OP, $1, NULL, $2); }
2848 { $$ = makeA_Expr(OP, $2, $1, NULL); }
2851 /* could be a column name or a relation_name */
2852 Ident *n = makeNode(Ident);
2854 n->indirection = NULL;
2859 FuncCall *n = makeNode(FuncCall);
2864 | POSITION '(' position_list ')'
2866 FuncCall *n = makeNode(FuncCall);
2867 n->funcname = "strpos";
2871 | SUBSTRING '(' substr_list ')'
2873 FuncCall *n = makeNode(FuncCall);
2874 n->funcname = "substr";
2878 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
2879 | TRIM '(' BOTH trim_list ')'
2881 FuncCall *n = makeNode(FuncCall);
2882 n->funcname = "btrim";
2886 | TRIM '(' LEADING trim_list ')'
2888 FuncCall *n = makeNode(FuncCall);
2889 n->funcname = "ltrim";
2893 | TRIM '(' TRAILING trim_list ')'
2895 FuncCall *n = makeNode(FuncCall);
2896 n->funcname = "rtrim";
2900 | TRIM '(' trim_list ')'
2902 FuncCall *n = makeNode(FuncCall);
2903 n->funcname = "btrim";
2907 | name '(' expr_list ')'
2909 FuncCall *n = makeNode(FuncCall);
2916 substr_list: expr_list substr_from substr_for
2918 $$ = nconc(nconc($1,$2),$3);
2924 substr_from: FROM expr_list
2928 A_Const *n = makeNode(A_Const);
2929 n->val.type = T_Integer;
2930 n->val.val.ival = 1;
2931 $$ = lcons((Node *)n,NIL);
2935 substr_for: FOR expr_list
2941 trim_list: a_expr FROM expr_list
2942 { $$ = lappend($3, $1); }
2949 in_expr_nodes: AexprConst
2950 { $$ = makeA_Expr(OP, "=", saved_In_Expr, $1); }
2951 | in_expr_nodes ',' AexprConst
2952 { $$ = makeA_Expr(OR, NULL, $1,
2953 makeA_Expr(OP, "=", saved_In_Expr, $3));
2957 not_in_expr_nodes: AexprConst
2958 { $$ = makeA_Expr(OP, "<>", saved_In_Expr, $1); }
2959 | not_in_expr_nodes ',' AexprConst
2960 { $$ = makeA_Expr(AND, NULL, $1,
2961 makeA_Expr(OP, "<>", saved_In_Expr, $3));
2965 attr: relation_name '.' attrs
2967 $$ = makeNode(Attr);
2971 $$->indirection = NULL;
2975 $$ = makeNode(Attr);
2979 $$->indirection = NULL;
2984 { $$ = lcons(makeString($1), NIL); }
2985 | attrs '.' attr_name
2986 { $$ = lappend($1, makeString($3)); }
2988 { $$ = lappend($1, makeString("*")); }
2991 DateTime: YEARINTERVAL { $$ = "year"; }
2992 | MONTHINTERVAL { $$ = "month"; }
2993 | DAYINTERVAL { $$ = "day"; }
2994 | HOURINTERVAL { $$ = "hour"; }
2995 | MINUTEINTERVAL { $$ = "minute"; }
2996 | SECONDINTERVAL { $$ = "second"; }
2999 /*****************************************************************************
3003 *****************************************************************************/
3005 res_target_list: res_target_list ',' res_target_el
3006 { $$ = lappend($1,$3); }
3008 { $$ = lcons($1, NIL); }
3011 ResTarget *rt = makeNode(ResTarget);
3012 Attr *att = makeNode(Attr);
3014 att->paramNo = NULL;
3016 att->indirection = NIL;
3018 rt->indirection = NULL;
3019 rt->val = (Node *)att;
3020 $$ = lcons(rt, NIL);
3024 res_target_el: Id opt_indirection '=' a_expr_or_null
3026 $$ = makeNode(ResTarget);
3028 $$->indirection = $2;
3029 $$->val = (Node *)$4;
3031 | attr opt_indirection
3033 $$ = makeNode(ResTarget);
3035 $$->indirection = $2;
3036 $$->val = (Node *)$1;
3038 | relation_name '.' '*'
3040 Attr *att = makeNode(Attr);
3042 att->paramNo = NULL;
3043 att->attrs = lcons(makeString("*"), NIL);
3044 att->indirection = NIL;
3045 $$ = makeNode(ResTarget);
3047 $$->indirection = NULL;
3048 $$->val = (Node *)att;
3053 ** target list for select.
3054 ** should get rid of the other but is still needed by the defunct retrieve into
3055 ** and update (uses a subset)
3057 res_target_list2: res_target_list2 ',' res_target_el2
3058 { $$ = lappend($1, $3); }
3060 { $$ = lcons($1, NIL); }
3063 /* AS is not optional because shift/red conflict with unary ops */
3064 res_target_el2: a_expr_or_null AS ColId
3066 $$ = makeNode(ResTarget);
3068 $$->indirection = NULL;
3069 $$->val = (Node *)$1;
3073 $$ = makeNode(ResTarget);
3075 $$->indirection = NULL;
3076 $$->val = (Node *)$1;
3078 | relation_name '.' '*'
3080 Attr *att = makeNode(Attr);
3082 att->paramNo = NULL;
3083 att->attrs = lcons(makeString("*"), NIL);
3084 att->indirection = NIL;
3085 $$ = makeNode(ResTarget);
3087 $$->indirection = NULL;
3088 $$->val = (Node *)att;
3092 Attr *att = makeNode(Attr);
3094 att->paramNo = NULL;
3096 att->indirection = NIL;
3097 $$ = makeNode(ResTarget);
3099 $$->indirection = NULL;
3100 $$->val = (Node *)att;
3104 opt_id: Id { $$ = $1; }
3105 | /* EMPTY */ { $$ = NULL; }
3108 relation_name: SpecialRuleRelation
3111 strNcpy(saved_relname, $1, NAMEDATALEN-1);
3115 /* disallow refs to magic system tables */
3116 if (strcmp(LogRelationName, $1) == 0
3117 || strcmp(VariableRelationName, $1) == 0
3118 || strcmp(TimeRelationName, $1) == 0
3119 || strcmp(MagicRelationName, $1) == 0)
3120 elog(WARN,"%s cannot be accessed by users",$1);
3123 strNcpy(saved_relname, $1, NAMEDATALEN-1);
3127 database_name: Id { $$ = $1; };
3128 access_method: Id { $$ = $1; };
3129 attr_name: ColId { $$ = $1; };
3130 class: Id { $$ = $1; };
3131 index_name: Id { $$ = $1; };
3133 name: Id { $$ = $1; }
3134 | TIME { $$ = xlateSqlType("time"); }
3137 date: Sconst { $$ = $1; };
3138 file_name: Sconst { $$ = $1; };
3139 recipe_name: Id { $$ = $1; };
3143 A_Const *n = makeNode(A_Const);
3144 n->val.type = T_Integer;
3145 n->val.val.ival = $1;
3150 A_Const *n = makeNode(A_Const);
3151 n->val.type = T_Float;
3152 n->val.val.dval = $1;
3157 A_Const *n = makeNode(A_Const);
3158 n->val.type = T_String;
3159 n->val.val.str = $1;
3163 { $$ = (Node *)$1; }
3168 $$ = makeNode(ParamNo);
3173 NumConst: Iconst { $$ = makeInteger($1); }
3174 | FCONST { $$ = makeFloat($1); }
3177 Iconst: ICONST { $$ = $1; };
3178 Sconst: SCONST { $$ = $1; };
3180 Id: IDENT { $$ = $1; };
3182 ColId: Id { $$ = $1; }
3183 | DateTime { $$ = $1; }
3186 SpecialRuleRelation: CURRENT
3191 elog(WARN,"CURRENT used in non-rule query",NULL);
3198 elog(WARN,"NEW used in non-rule query",NULL);
3208 static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr)
3210 A_Expr *a = makeNode(A_Expr);
3219 * Convert alternate type names to internal Postgres types.
3220 * Do not convert "float", since that is handled elsewhere
3221 * for FLOAT(p) syntax.
3224 xlateSqlType(char *name)
3226 if (!strcasecmp(name,"int") ||
3227 !strcasecmp(name,"integer"))
3228 return "int4"; /* strdup("int4") -- strdup leaks memory here */
3229 else if (!strcasecmp(name, "smallint"))
3231 else if (!strcasecmp(name, "real"))
3233 else if (!strcasecmp(name, "interval"))
3239 void parser_init(Oid *typev, int nargs)
3241 QueryIsRule = FALSE;
3242 saved_relname[0]= '\0';
3243 saved_In_Expr = NULL;
3245 param_type_init(typev, nargs);
3248 /* FlattenStringList()
3249 * Traverse list of string nodes and convert to a single string.
3250 * Used for reconstructing string form of complex expressions.
3252 * Allocate at least one byte for terminator.
3255 FlattenStringList(List *list)
3263 nlist = length(list);
3265 printf( "list has %d elements\n", nlist);
3269 v = (Value *)lfirst(l);
3273 printf( "sp is x%8p; length of %s is %d\n", sp, sp, strlen(sp));
3279 s = (char*) palloc(len+1);
3284 v = (Value *)lfirst(l);
3288 printf( "length of %s is %d\n", sp, strlen(sp));
3291 if (l != NIL) strcat(s," ");
3296 printf( "flattened string is \"%s\"\n", s);
3300 } /* FlattenStringList() */
3302 /* makeConstantList()
3303 * Convert constant value node into string node.
3306 makeConstantList( A_Const *n)
3308 char *defval = NULL;
3310 printf( "in AexprConst\n");
3312 if (nodeTag(n) != T_A_Const) {
3313 elog(WARN,"Cannot handle non-constant parameter",NULL);
3315 } else if (n->val.type == T_Float) {
3317 printf( "AexprConst float is %f\n", n->val.val.dval);
3319 defval = (char*) palloc(20+1);
3320 sprintf( defval, "%g", n->val.val.dval);
3322 } else if (n->val.type == T_Integer) {
3324 printf( "AexprConst integer is %ld\n", n->val.val.ival);
3326 defval = (char*) palloc(20+1);
3327 sprintf( defval, "%ld", n->val.val.ival);
3329 } else if (n->val.type == T_String) {
3332 printf( "AexprConst string is \"%s\"\n", n->val.val.str);
3335 defval = (char*) palloc(strlen( ((A_Const *) n)->val.val.str) + 3);
3336 strcpy( defval, "'");
3337 strcat( defval, ((A_Const *) n)->val.val.str);
3338 strcat( defval, "'");
3341 elog(WARN,"Internal error: cannot encode node",NULL);
3345 printf( "AexprConst argument is \"%s\"\n", defval);
3348 return( lcons( makeString(defval), NIL));
3349 } /* makeConstantList() */