gram.y
上传用户:blenddy
上传日期:2007-01-07
资源大小:6495k
文件大小:141k
源码类别:

数据库系统

开发平台:

Unix_Linux

  1. %{ /* -*-text-*- */
  2. /*#define YYDEBUG 1*/
  3. /*-------------------------------------------------------------------------
  4.  *
  5.  * gram.y
  6.  *   POSTGRES SQL YACC rules/actions
  7.  *
  8.  * Copyright (c) 1994, Regents of the University of California
  9.  *
  10.  *
  11.  * IDENTIFICATION
  12.  *   $Header: /usr/local/cvsroot/pgsql/src/backend/parser/gram.y,v 2.88.2.2 1999/09/14 06:07:35 thomas Exp $
  13.  *
  14.  * HISTORY
  15.  *   AUTHOR DATE MAJOR EVENT
  16.  *   Andrew Yu Sept, 1994 POSTQUEL to SQL conversion
  17.  *   Andrew Yu Oct, 1994 lispy code conversion
  18.  *
  19.  * NOTES
  20.  *   CAPITALS are used to represent terminal symbols.
  21.  *   non-capitals are used to represent non-terminals.
  22.  *   SQL92-specific syntax is separated from plain SQL/Postgres syntax
  23.  *   to help isolate the non-extensible portions of the parser.
  24.  *
  25.  *   if you use list, make sure the datum is a node so that the printing
  26.  *   routines work
  27.  *
  28.  * WARNING
  29.  *   sometimes we assign constants to makeStrings. Make sure we don't free
  30.  *   those.
  31.  *
  32.  *-------------------------------------------------------------------------
  33.  */
  34. #include <string.h>
  35. #include <ctype.h>
  36. #include "postgres.h"
  37. #include "access/htup.h"
  38. #include "nodes/parsenodes.h"
  39. #include "nodes/print.h"
  40. #include "parser/gramparse.h"
  41. #include "parser/parse_type.h"
  42. #include "utils/acl.h"
  43. #include "utils/palloc.h"
  44. #include "catalog/catname.h"
  45. #include "utils/elog.h"
  46. #include "access/xact.h"
  47. #include "storage/lmgr.h"
  48. #include "utils/numeric.h"
  49. #include "parser/analyze.h"
  50. #include "catalog/pg_type.h"
  51. #ifdef MULTIBYTE
  52. #include "mb/pg_wchar.h"
  53. #endif
  54. static char saved_relname[NAMEDATALEN];  /* need this for complex attributes */
  55. static bool QueryIsRule = FALSE;
  56. static List *saved_In_Expr = NIL;
  57. static Oid *param_type_info;
  58. static int pfunc_num_args;
  59. extern List *parsetree;
  60. /*
  61.  * If you need access to certain yacc-generated variables and find that
  62.  * they're static by default, uncomment the next line.  (this is not a
  63.  * problem, yet.)
  64.  */
  65. /*#define __YYSCLASS*/
  66. static char *xlateSqlFunc(char *);
  67. static char *xlateSqlType(char *);
  68. static Node *makeA_Expr(int oper, char *opname, Node *lexpr, Node *rexpr);
  69. static Node *makeRowExpr(char *opr, List *largs, List *rargs);
  70. static void mapTargetColumns(List *source, List *target);
  71. static List *makeConstantList( A_Const *node);
  72. static char *FlattenStringList(List *list);
  73. static char *fmtId(char *rawid);
  74. static Node *makeIndexable(char *opname, Node *lexpr, Node *rexpr);
  75. static void param_type_init(Oid *typev, int nargs);
  76. static Node *doNegate(Node *n);
  77. Oid param_type(int t); /* used in parse_expr.c */
  78. /* old versions of flex define this as a macro */
  79. #if defined(yywrap)
  80. #undef yywrap
  81. #endif /* yywrap */
  82. %}
  83. %union
  84. {
  85. double dval;
  86. int ival;
  87. char chr;
  88. char *str;
  89. bool boolean;
  90. bool* pboolean; /* for pg_shadow privileges */
  91. List *list;
  92. Node *node;
  93. Value *value;
  94. Attr *attr;
  95. TypeName *typnam;
  96. DefElem *defelt;
  97. ParamString *param;
  98. SortGroupBy *sortgroupby;
  99. JoinExpr *joinexpr;
  100. IndexElem *ielem;
  101. RangeVar *range;
  102. RelExpr *relexp;
  103. A_Indices *aind;
  104. ResTarget *target;
  105. ParamNo *paramno;
  106. VersionStmt *vstmt;
  107. DefineStmt *dstmt;
  108. RuleStmt *rstmt;
  109. InsertStmt *astmt;
  110. }
  111. %type <node> stmt,
  112. AddAttrStmt, ClosePortalStmt,
  113. CopyStmt, CreateStmt, CreateAsStmt, CreateSeqStmt, DefineStmt, DestroyStmt,
  114. ExtendStmt, FetchStmt, GrantStmt, CreateTrigStmt, DropTrigStmt,
  115. CreatePLangStmt, DropPLangStmt,
  116. IndexStmt, ListenStmt, UnlistenStmt, LockStmt, OptimizableStmt,
  117. ProcedureStmt, RemoveAggrStmt, RemoveOperStmt,
  118. RemoveFuncStmt, RemoveStmt,
  119. RenameStmt, RevokeStmt, RuleStmt, TransactionStmt, ViewStmt, LoadStmt,
  120. CreatedbStmt, DestroydbStmt, VacuumStmt, CursorStmt, SubSelect,
  121. UpdateStmt, InsertStmt, select_clause, SelectStmt, NotifyStmt, DeleteStmt, 
  122. ClusterStmt, ExplainStmt, VariableSetStmt, VariableShowStmt, VariableResetStmt,
  123. CreateUserStmt, AlterUserStmt, DropUserStmt, RuleActionStmt
  124. %type <str> opt_database1, opt_database2, location, encoding
  125. %type <ival> opt_lock, lock_type
  126. %type <boolean> opt_lmode
  127. %type <pboolean> user_createdb_clause, user_createuser_clause
  128. %type <str> user_passwd_clause
  129. %type <str> user_valid_clause
  130. %type <list> user_group_list, user_group_clause
  131. %type <boolean> TriggerActionTime, TriggerForSpec, PLangTrusted
  132. %type <str> TriggerEvents, TriggerFuncArg
  133. %type <str> relation_name, copy_file_name, copy_delimiter, def_name,
  134. database_name, access_method_clause, access_method, attr_name,
  135. class, index_name, name, func_name, file_name, aggr_argtype
  136. %type <str> opt_id, opt_portal_name,
  137. all_Op, MathOp, opt_name, opt_unique,
  138. OptUseOp, opt_class, SpecialRuleRelation
  139. %type <str> opt_level
  140. %type <str> privileges, operation_commalist, grantee
  141. %type <chr> operation, TriggerOneEvent
  142. %type <list> stmtblock, stmtmulti,
  143. result, relation_name_list, OptTableElementList,
  144. OptInherit, definition,
  145. opt_with, func_args, func_args_list,
  146. oper_argtypes, RuleActionList, RuleActionBlock, RuleActionMulti,
  147. opt_column_list, columnList, opt_va_list, va_list,
  148. sort_clause, sortby_list, index_params, index_list, name_list,
  149. from_clause, from_expr, table_list, opt_array_bounds, nest_array_bounds,
  150. expr_list, attrs, res_target_list, res_target_list2,
  151. def_list, opt_indirection, group_clause, TriggerFuncArgs,
  152. opt_select_limit
  153. %type <node> func_return
  154. %type <boolean> set_opt
  155. %type <boolean> TriggerForOpt, TriggerForType, OptTemp, OptTempType, OptTempScope
  156. %type <list> for_update_clause, update_list
  157. %type <boolean> opt_union
  158. %type <boolean> opt_table
  159. %type <boolean> opt_trans
  160. %type <list> join_clause_with_union, join_clause, join_list, join_qual, using_list
  161. %type <node> join_expr, using_expr
  162. %type <str> join_outer
  163. %type <ival> join_type
  164. %type <node> position_expr
  165. %type <list> extract_list, position_list
  166. %type <list> substr_list, substr_from, substr_for, trim_list
  167. %type <list> opt_interval
  168. %type <boolean> opt_inh_star, opt_binary, opt_instead, opt_with_copy,
  169. index_opt_unique, opt_verbose, opt_analyze
  170. %type <boolean> opt_cursor
  171. %type <ival> copy_dirn, def_type, opt_direction, remove_type,
  172. opt_column, event
  173. %type <ival> fetch_how_many
  174. %type <node> select_limit_value, select_offset_value
  175. %type <list> OptSeqList
  176. %type <defelt> OptSeqElem
  177. %type <dstmt> def_rest
  178. %type <astmt> insert_rest
  179. %type <node> OptTableElement, ConstraintElem
  180. %type <node> columnDef, alter_clause
  181. %type <defelt> def_elem
  182. %type <node> def_arg, columnElem, where_clause,
  183. a_expr, a_expr_or_null, b_expr, AexprConst,
  184. in_expr, in_expr_nodes, not_in_expr, not_in_expr_nodes,
  185. having_clause
  186. %type <list> row_descriptor, row_list, c_list, c_expr
  187. %type <node> row_expr
  188. %type <str> row_op
  189. %type <node> case_expr, case_arg, when_clause, case_default
  190. %type <list> when_clause_list
  191. %type <ival> sub_type
  192. %type <list> OptCreateAs, CreateAsList
  193. %type <node> CreateAsElement
  194. %type <value> NumericOnly, FloatOnly, IntegerOnly
  195. %type <attr> event_object, attr
  196. %type <sortgroupby> sortby
  197. %type <ielem> index_elem, func_index
  198. %type <range> table_expr
  199. %type <relexp> relation_expr
  200. %type <target> res_target_el, res_target_el2
  201. %type <paramno> ParamNo
  202. %type <typnam> Typename, opt_type, Array, Generic, Character, Datetime, Numeric
  203. %type <str> generic, numeric, character, datetime
  204. %type <str> extract_arg
  205. %type <str> opt_charset, opt_collate
  206. %type <str> opt_float
  207. %type <ival> opt_numeric, opt_decimal
  208. %type <boolean> opt_varying, opt_timezone
  209. %type <ival> Iconst
  210. %type <str> Sconst
  211. %type <str> UserId, var_value, zone_value
  212. %type <str> ColId, ColLabel
  213. %type <str> TypeId
  214. %type <node> TableConstraint
  215. %type <list> constraint_list, constraint_expr
  216. %type <list> default_list, default_expr
  217. %type <list> ColPrimaryKey, ColQualList, ColQualifier
  218. %type <node> ColConstraint, ColConstraintElem
  219. %type <list> key_actions, key_action
  220. %type <str> key_match, key_reference
  221. /*
  222.  * If you make any token changes, remember to:
  223.  * - use "yacc -d" and update parse.h
  224.  * - update the keyword table in parser/keywords.c
  225.  */
  226. /* Reserved word tokens
  227.  * SQL92 syntax has many type-specific constructs.
  228.  * So, go ahead and make these types reserved words,
  229.  *  and call-out the syntax explicitly.
  230.  * This gets annoying when trying to also retain Postgres' nice
  231.  *  type-extensible features, but we don't really have a choice.
  232.  * - thomas 1997-10-11
  233.  */
  234. /* Keywords (in SQL92 reserved words) */
  235. %token ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
  236. BEGIN_TRANS, BETWEEN, BOTH, BY,
  237. CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
  238. COALESCE, COLLATE, COLUMN, COMMIT,
  239. CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
  240. CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
  241. DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
  242. ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
  243. FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
  244. GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
  245. IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
  246. ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
  247. MATCH, MINUTE_P, MONTH_P, NAMES,
  248. NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
  249. OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
  250. PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
  251. READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
  252. SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
  253. TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
  254. TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
  255. UNION, UNIQUE, UPDATE, USER, USING,
  256. VALUES, VARCHAR, VARYING, VIEW,
  257. WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
  258. /* Keywords (in SQL3 reserved words) */
  259. %token TRIGGER
  260. /* Keywords (in SQL92 non-reserved words) */
  261. %token COMMITTED, SERIALIZABLE, TYPE_P
  262. /* Keywords for Postgres support (not in SQL92 reserved words)
  263.  *
  264.  * The CREATEDB and CREATEUSER tokens should go away
  265.  * when some sort of pg_privileges relation is introduced.
  266.  * - Todd A. Brandys 1998-01-01?
  267.  */
  268. %token ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
  269. BACKWARD, BEFORE, BINARY, 
  270. CACHE, CLUSTER, COPY, CREATEDB, CREATEUSER, CYCLE,
  271. DATABASE, DELIMITERS, DO,
  272. EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
  273. FORWARD, FUNCTION, HANDLER,
  274. INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
  275. LANCOMPILER, LIMIT, LISTEN, LOAD, LOCATION, LOCK_P,
  276. MAXVALUE, MINVALUE, MODE, MOVE,
  277. NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
  278. OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
  279. RENAME, RESET, RETURNS, ROW, RULE,
  280. SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT,
  281. TRUSTED, 
  282. UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
  283. /* Special keywords, not in the query language - see the "lex" file */
  284. %token <str> IDENT, SCONST, Op
  285. %token <ival> ICONST, PARAM
  286. %token <dval> FCONST
  287. /* these are not real. they are here so that they get generated as #define's*/
  288. %token OP
  289. /* precedence */
  290. %left OR
  291. %left AND
  292. %right NOT
  293. %right '='
  294. %nonassoc '<' '>'
  295. %nonassoc LIKE
  296. %nonassoc BETWEEN
  297. %nonassoc IN
  298. %left Op /* multi-character ops and user-defined operators */
  299. %nonassoc NOTNULL
  300. %nonassoc ISNULL
  301. %nonassoc NULL_P
  302. %nonassoc IS
  303. %left '+' '-'
  304. %left '*' '/' '%'
  305. %left '^'
  306. %left '|' /* this is the relation union op, not logical or */
  307. /* Unary Operators */
  308. %right ':'
  309. %left ';' /* end of statement or natural log */
  310. %right UMINUS
  311. %left '.'
  312. %left '[' ']'
  313. %nonassoc TYPECAST
  314. %left UNION INTERSECT EXCEPT
  315. %%
  316. stmtblock:  stmtmulti opt_semi
  317. { parsetree = $1; }
  318. ;
  319. stmtmulti:  stmtmulti ';' stmt
  320. { $$ = lappend($1, $3); }
  321. | stmt
  322. { $$ = lcons($1,NIL); }
  323. ;
  324. opt_semi: ';'
  325. | /*EMPTY*/
  326. ;
  327. stmt :   AddAttrStmt
  328. | AlterUserStmt
  329. | ClosePortalStmt
  330. | CopyStmt
  331. | CreateStmt
  332. | CreateAsStmt
  333. | CreateSeqStmt
  334. | CreatePLangStmt
  335. | CreateTrigStmt
  336. | CreateUserStmt
  337. | ClusterStmt
  338. | DefineStmt
  339. | DestroyStmt
  340. | DropPLangStmt
  341. | DropTrigStmt
  342. | DropUserStmt
  343. | ExtendStmt
  344. | ExplainStmt
  345. | FetchStmt
  346. | GrantStmt
  347. | IndexStmt
  348. | ListenStmt
  349. | UnlistenStmt
  350. | LockStmt
  351. | ProcedureStmt
  352. | RemoveAggrStmt
  353. | RemoveOperStmt
  354. | RemoveFuncStmt
  355. | RemoveStmt
  356. | RenameStmt
  357. | RevokeStmt
  358. | OptimizableStmt
  359. | RuleStmt
  360. | TransactionStmt
  361. | ViewStmt
  362. | LoadStmt
  363. | CreatedbStmt
  364. | DestroydbStmt
  365. | VacuumStmt
  366. | VariableSetStmt
  367. | VariableShowStmt
  368. | VariableResetStmt
  369. ;
  370. /*****************************************************************************
  371.  *
  372.  * Create a new Postgres DBMS user
  373.  *
  374.  *
  375.  *****************************************************************************/
  376. CreateUserStmt:  CREATE USER UserId user_passwd_clause user_createdb_clause
  377. user_createuser_clause user_group_clause user_valid_clause
  378. {
  379. CreateUserStmt *n = makeNode(CreateUserStmt);
  380. n->user = $3;
  381. n->password = $4;
  382. n->createdb = $5;
  383. n->createuser = $6;
  384. n->groupElts = $7;
  385. n->validUntil = $8;
  386. $$ = (Node *)n;
  387. }
  388. ;
  389. /*****************************************************************************
  390.  *
  391.  * Alter a postresql DBMS user
  392.  *
  393.  *
  394.  *****************************************************************************/
  395. AlterUserStmt:  ALTER USER UserId user_passwd_clause user_createdb_clause
  396. user_createuser_clause user_group_clause user_valid_clause
  397. {
  398. AlterUserStmt *n = makeNode(AlterUserStmt);
  399. n->user = $3;
  400. n->password = $4;
  401. n->createdb = $5;
  402. n->createuser = $6;
  403. n->groupElts = $7;
  404. n->validUntil = $8;
  405. $$ = (Node *)n;
  406. }
  407. ;
  408. /*****************************************************************************
  409.  *
  410.  * Drop a postresql DBMS user
  411.  *
  412.  *
  413.  *****************************************************************************/
  414. DropUserStmt:  DROP USER UserId
  415. {
  416. DropUserStmt *n = makeNode(DropUserStmt);
  417. n->user = $3;
  418. $$ = (Node *)n;
  419. }
  420. ;
  421. user_passwd_clause:  WITH PASSWORD UserId { $$ = $3; }
  422. | /*EMPTY*/ { $$ = NULL; }
  423. ;
  424. user_createdb_clause:  CREATEDB
  425. {
  426. bool*  b;
  427. $$ = (b = (bool*)palloc(sizeof(bool)));
  428. *b = true;
  429. }
  430. | NOCREATEDB
  431. {
  432. bool*  b;
  433. $$ = (b = (bool*)palloc(sizeof(bool)));
  434. *b = false;
  435. }
  436. | /*EMPTY*/ { $$ = NULL; }
  437. ;
  438. user_createuser_clause:  CREATEUSER
  439. {
  440. bool*  b;
  441. $$ = (b = (bool*)palloc(sizeof(bool)));
  442. *b = true;
  443. }
  444. | NOCREATEUSER
  445. {
  446. bool*  b;
  447. $$ = (b = (bool*)palloc(sizeof(bool)));
  448. *b = false;
  449. }
  450. | /*EMPTY*/ { $$ = NULL; }
  451. ;
  452. user_group_list:  user_group_list ',' UserId
  453. {
  454. $$ = lcons((void*)makeString($3), $1);
  455. }
  456. | UserId
  457. {
  458. $$ = lcons((void*)makeString($1), NIL);
  459. }
  460. ;
  461. user_group_clause:  IN GROUP user_group_list { $$ = $3; }
  462. | /*EMPTY*/ { $$ = NULL; }
  463. ;
  464. user_valid_clause:  VALID UNTIL SCONST { $$ = $3; }
  465. | /*EMPTY*/ { $$ = NULL; }
  466. ;
  467. /*****************************************************************************
  468.  *
  469.  * Set PG internal variable
  470.  *   SET name TO 'var_value'
  471.  * Include SQL92 syntax (thomas 1997-10-22):
  472.  *    SET TIME ZONE 'var_value'
  473.  *
  474.  *****************************************************************************/
  475. VariableSetStmt:  SET ColId TO var_value
  476. {
  477. VariableSetStmt *n = makeNode(VariableSetStmt);
  478. n->name  = $2;
  479. n->value = $4;
  480. $$ = (Node *) n;
  481. }
  482. | SET ColId '=' var_value
  483. {
  484. VariableSetStmt *n = makeNode(VariableSetStmt);
  485. n->name  = $2;
  486. n->value = $4;
  487. $$ = (Node *) n;
  488. }
  489. | SET TIME ZONE zone_value
  490. {
  491. VariableSetStmt *n = makeNode(VariableSetStmt);
  492. n->name  = "timezone";
  493. n->value = $4;
  494. $$ = (Node *) n;
  495. }
  496. | SET TRANSACTION ISOLATION LEVEL opt_level
  497. {
  498. VariableSetStmt *n = makeNode(VariableSetStmt);
  499. n->name  = "XactIsoLevel";
  500. n->value = $5;
  501. $$ = (Node *) n;
  502. }
  503. | SET NAMES encoding
  504. {
  505. #ifdef MULTIBYTE
  506. VariableSetStmt *n = makeNode(VariableSetStmt);
  507. n->name  = "client_encoding";
  508. n->value = $3;
  509. $$ = (Node *) n;
  510. #else
  511. elog(ERROR, "SET NAMES is not supported");
  512. #endif
  513. }
  514. ;
  515. opt_level:  READ COMMITTED { $$ = "committed"; }
  516. | SERIALIZABLE { $$ = "serializable"; }
  517. ;
  518. var_value:  Sconst { $$ = $1; }
  519. | DEFAULT { $$ = NULL; }
  520. ;
  521. zone_value:  Sconst { $$ = $1; }
  522. | DEFAULT { $$ = NULL; }
  523. | LOCAL { $$ = NULL; }
  524. ;
  525. VariableShowStmt:  SHOW ColId
  526. {
  527. VariableShowStmt *n = makeNode(VariableShowStmt);
  528. n->name  = $2;
  529. $$ = (Node *) n;
  530. }
  531. | SHOW TIME ZONE
  532. {
  533. VariableShowStmt *n = makeNode(VariableShowStmt);
  534. n->name  = "timezone";
  535. $$ = (Node *) n;
  536. }
  537. | SHOW TRANSACTION ISOLATION LEVEL
  538. {
  539. VariableShowStmt *n = makeNode(VariableShowStmt);
  540. n->name  = "XactIsoLevel";
  541. $$ = (Node *) n;
  542. }
  543. ;
  544. VariableResetStmt: RESET ColId
  545. {
  546. VariableResetStmt *n = makeNode(VariableResetStmt);
  547. n->name  = $2;
  548. $$ = (Node *) n;
  549. }
  550. | RESET TIME ZONE
  551. {
  552. VariableResetStmt *n = makeNode(VariableResetStmt);
  553. n->name  = "timezone";
  554. $$ = (Node *) n;
  555. }
  556. | RESET TRANSACTION ISOLATION LEVEL
  557. {
  558. VariableResetStmt *n = makeNode(VariableResetStmt);
  559. n->name  = "XactIsoLevel";
  560. $$ = (Node *) n;
  561. }
  562. ;
  563. /*****************************************************************************
  564.  *
  565.  * QUERY :
  566.  * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
  567.  *
  568.  *****************************************************************************/
  569. AddAttrStmt:  ALTER TABLE relation_name opt_inh_star alter_clause
  570. {
  571. AddAttrStmt *n = makeNode(AddAttrStmt);
  572. n->relname = $3;
  573. n->inh = $4;
  574. n->colDef = $5;
  575. $$ = (Node *)n;
  576. }
  577. ;
  578. alter_clause:  ADD opt_column columnDef
  579. {
  580. $$ = $3;
  581. }
  582. | ADD '(' OptTableElementList ')'
  583. {
  584. Node *lp = lfirst($3);
  585. if (length($3) != 1)
  586. elog(ERROR,"ALTER TABLE/ADD() allows one column only");
  587. $$ = lp;
  588. }
  589. | DROP opt_column ColId
  590. { elog(ERROR,"ALTER TABLE/DROP COLUMN not yet implemented"); }
  591. | ALTER opt_column ColId SET DEFAULT default_expr
  592. { elog(ERROR,"ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
  593. | ALTER opt_column ColId DROP DEFAULT
  594. { elog(ERROR,"ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
  595. | ADD ConstraintElem
  596. { elog(ERROR,"ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
  597. ;
  598. /*****************************************************************************
  599.  *
  600.  * QUERY :
  601.  * close <optname>
  602.  *
  603.  *****************************************************************************/
  604. ClosePortalStmt:  CLOSE opt_id
  605. {
  606. ClosePortalStmt *n = makeNode(ClosePortalStmt);
  607. n->portalname = $2;
  608. $$ = (Node *)n;
  609. }
  610. ;
  611. /*****************************************************************************
  612.  *
  613.  * QUERY :
  614.  * COPY [BINARY] <relname> FROM/TO
  615.  * [USING DELIMITERS <delimiter>]
  616.  *
  617.  *****************************************************************************/
  618. CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
  619. {
  620. CopyStmt *n = makeNode(CopyStmt);
  621. n->binary = $2;
  622. n->relname = $3;
  623. n->oids = $4;
  624. n->direction = $5;
  625. n->filename = $6;
  626. n->delimiter = $7;
  627. $$ = (Node *)n;
  628. }
  629. ;
  630. copy_dirn: TO
  631. { $$ = TO; }
  632. | FROM
  633. { $$ = FROM; }
  634. ;
  635. /*
  636.  * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
  637.  * used depends on the direction. (It really doesn't make sense to copy from
  638.  * stdout. We silently correct the "typo".  - AY 9/94
  639.  */
  640. copy_file_name:  Sconst { $$ = $1; }
  641. | STDIN { $$ = NULL; }
  642. | STDOUT { $$ = NULL; }
  643. ;
  644. opt_binary:  BINARY { $$ = TRUE; }
  645. | /*EMPTY*/ { $$ = FALSE; }
  646. ;
  647. opt_with_copy: WITH OIDS { $$ = TRUE; }
  648. | /*EMPTY*/ { $$ = FALSE; }
  649. ;
  650. /*
  651.  * the default copy delimiter is tab but the user can configure it
  652.  */
  653. copy_delimiter:  USING DELIMITERS Sconst { $$ = $3; }
  654. | /*EMPTY*/ { $$ = "t"; }
  655. ;
  656. /*****************************************************************************
  657.  *
  658.  * QUERY :
  659.  * CREATE relname
  660.  *
  661.  *****************************************************************************/
  662. CreateStmt:  CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
  663. OptInherit
  664. {
  665. CreateStmt *n = makeNode(CreateStmt);
  666. n->istemp = $2;
  667. n->relname = $4;
  668. n->tableElts = $6;
  669. n->inhRelnames = $8;
  670. n->constraints = NIL;
  671. $$ = (Node *)n;
  672. }
  673. ;
  674. OptTemp:  OptTempType { $$ = $1; }
  675. | OptTempScope OptTempType { $$ = $2; }
  676. ;
  677. OptTempType:  TEMP { $$ = TRUE; }
  678. | TEMPORARY { $$ = TRUE; }
  679. | /*EMPTY*/ { $$ = FALSE; }
  680. ;
  681. OptTempScope:  GLOBAL
  682. {
  683. elog(ERROR, "GLOBAL TEMPORARY TABLE is not currently supported");
  684. $$ = TRUE;
  685. }
  686. | LOCAL
  687. {
  688.  $$ = FALSE;
  689. }
  690. ;
  691. OptTableElementList:  OptTableElementList ',' OptTableElement
  692. {
  693. if ($3 != NULL)
  694. $$ = lappend($1, $3);
  695. else
  696. $$ = $1;
  697. }
  698. | OptTableElement
  699. {
  700. if ($1 != NULL)
  701. $$ = lcons($1, NIL);
  702. else
  703. $$ = NULL;
  704. }
  705. | /*EMPTY*/ { $$ = NULL; }
  706. ;
  707. OptTableElement:  columnDef { $$ = $1; }
  708. | TableConstraint { $$ = $1; }
  709. ;
  710. columnDef:  ColId Typename ColQualifier
  711. {
  712. ColumnDef *n = makeNode(ColumnDef);
  713. n->colname = $1;
  714. n->typename = $2;
  715. n->defval = NULL;
  716. n->is_not_null = FALSE;
  717. n->constraints = $3;
  718. $$ = (Node *)n;
  719. }
  720. | ColId SERIAL ColPrimaryKey
  721. {
  722. ColumnDef *n = makeNode(ColumnDef);
  723. n->colname = $1;
  724. n->typename = makeNode(TypeName);
  725. n->typename->name = xlateSqlType("integer");
  726. n->defval = NULL;
  727. n->is_not_null = TRUE;
  728. n->is_sequence = TRUE;
  729. n->constraints = $3;
  730. $$ = (Node *)n;
  731. }
  732. ;
  733. ColQualifier:  ColQualList { $$ = $1; }
  734. | /*EMPTY*/ { $$ = NULL; }
  735. ;
  736. ColQualList:  ColQualList ColConstraint
  737. {
  738. if ($2 != NULL)
  739. $$ = lappend($1, $2);
  740. else
  741. $$ = $1;
  742. }
  743. | ColConstraint
  744. {
  745. if ($1 != NULL)
  746. $$ = lcons($1, NIL);
  747. else
  748. $$ = NULL;
  749. }
  750. ;
  751. ColPrimaryKey:  PRIMARY KEY
  752. {
  753. Constraint *n = makeNode(Constraint);
  754. n->contype = CONSTR_PRIMARY;
  755. n->name = NULL;
  756. n->def = NULL;
  757. n->keys = NULL;
  758. $$ = lcons((Node *)n, NIL);
  759. }
  760. | /*EMPTY*/ { $$ = NULL; }
  761. ;
  762. ColConstraint:
  763. CONSTRAINT name ColConstraintElem
  764. {
  765. Constraint *n = (Constraint *)$3;
  766. if (n != NULL) n->name = fmtId($2);
  767. $$ = $3;
  768. }
  769. | ColConstraintElem
  770. { $$ = $1; }
  771. ;
  772. /* DEFAULT NULL is already the default for Postgres.
  773.  * Bue define it here and carry it forward into the system
  774.  * to make it explicit.
  775.  * - thomas 1998-09-13
  776.  * WITH NULL and NULL are not SQL92-standard syntax elements,
  777.  * so leave them out. Use DEFAULT NULL to explicitly indicate
  778.  * that a column may have that value. WITH NULL leads to
  779.  * shift/reduce conflicts with WITH TIME ZONE anyway.
  780.  * - thomas 1999-01-08
  781.  */
  782. ColConstraintElem:  CHECK '(' constraint_expr ')'
  783. {
  784. Constraint *n = makeNode(Constraint);
  785. n->contype = CONSTR_CHECK;
  786. n->name = NULL;
  787. n->def = FlattenStringList($3);
  788. n->keys = NULL;
  789. $$ = (Node *)n;
  790. }
  791. | DEFAULT NULL_P
  792. {
  793. Constraint *n = makeNode(Constraint);
  794. n->contype = CONSTR_DEFAULT;
  795. n->name = NULL;
  796. n->def = NULL;
  797. n->keys = NULL;
  798. $$ = (Node *)n;
  799. }
  800. | DEFAULT default_expr
  801. {
  802. Constraint *n = makeNode(Constraint);
  803. n->contype = CONSTR_DEFAULT;
  804. n->name = NULL;
  805. n->def = FlattenStringList($2);
  806. n->keys = NULL;
  807. $$ = (Node *)n;
  808. }
  809. | NOT NULL_P
  810. {
  811. Constraint *n = makeNode(Constraint);
  812. n->contype = CONSTR_NOTNULL;
  813. n->name = NULL;
  814. n->def = NULL;
  815. n->keys = NULL;
  816. $$ = (Node *)n;
  817. }
  818. | UNIQUE
  819. {
  820. Constraint *n = makeNode(Constraint);
  821. n->contype = CONSTR_UNIQUE;
  822. n->name = NULL;
  823. n->def = NULL;
  824. n->keys = NULL;
  825. $$ = (Node *)n;
  826. }
  827. | PRIMARY KEY
  828. {
  829. Constraint *n = makeNode(Constraint);
  830. n->contype = CONSTR_PRIMARY;
  831. n->name = NULL;
  832. n->def = NULL;
  833. n->keys = NULL;
  834. $$ = (Node *)n;
  835. }
  836. | REFERENCES ColId opt_column_list key_match key_actions
  837. {
  838. elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
  839. $$ = NULL;
  840. }
  841. ;
  842. default_list:  default_list ',' default_expr
  843. {
  844. $$ = lappend($1,makeString(","));
  845. $$ = nconc($$, $3);
  846. }
  847. | default_expr
  848. {
  849. $$ = $1;
  850. }
  851. ;
  852. /* The Postgres default column value is NULL.
  853.  * Rather than carrying DEFAULT NULL forward as a clause,
  854.  * let's just have it be a no-op.
  855. | NULL_P
  856. { $$ = lcons( makeString("NULL"), NIL); }
  857.  * - thomas 1998-09-13
  858.  */
  859. default_expr:  AexprConst
  860. { $$ = makeConstantList((A_Const *) $1); }
  861. | '-' default_expr %prec UMINUS
  862. { $$ = lcons( makeString( "-"), $2); }
  863. | default_expr '+' default_expr
  864. { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
  865. | default_expr '-' default_expr
  866. { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
  867. | default_expr '/' default_expr
  868. { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
  869. | default_expr '%' default_expr
  870. { $$ = nconc( $1, lcons( makeString( "%"), $3)); }
  871. | default_expr '*' default_expr
  872. { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
  873. | default_expr '^' default_expr
  874. { $$ = nconc( $1, lcons( makeString( "^"), $3)); }
  875. | default_expr '=' default_expr
  876. { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
  877. | default_expr '<' default_expr
  878. { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
  879. | default_expr '>' default_expr
  880. { elog(ERROR,"boolean expressions not supported in DEFAULT"); }
  881. | ':' default_expr
  882. { $$ = lcons( makeString( ":"), $2); }
  883. | ';' default_expr
  884. { $$ = lcons( makeString( ";"), $2); }
  885. | '|' default_expr
  886. { $$ = lcons( makeString( "|"), $2); }
  887. | default_expr TYPECAST Typename
  888. {
  889. $3->name = fmtId($3->name);
  890. $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
  891. }
  892. | CAST '(' default_expr AS Typename ')'
  893. {
  894. $5->name = fmtId($5->name);
  895. $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
  896. }
  897. | '(' default_expr ')'
  898. { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
  899. | func_name '(' ')'
  900. {
  901. $$ = makeList( makeString($1), makeString("("), -1);
  902. $$ = lappend( $$, makeString(")"));
  903. }
  904. | func_name '(' default_list ')'
  905. {
  906. $$ = makeList( makeString($1), makeString("("), -1);
  907. $$ = nconc( $$, $3);
  908. $$ = lappend( $$, makeString(")"));
  909. }
  910. | default_expr Op default_expr
  911. {
  912. if (!strcmp("<=", $2) || !strcmp(">=", $2))
  913. elog(ERROR,"boolean expressions not supported in DEFAULT");
  914. $$ = nconc( $1, lcons( makeString( $2), $3));
  915. }
  916. | Op default_expr
  917. { $$ = lcons( makeString( $1), $2); }
  918. | default_expr Op
  919. { $$ = lappend( $1, makeString( $2)); }
  920. /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
  921. | CURRENT_DATE
  922. { $$ = lcons( makeString( "date( 'current'::datetime + '0 sec')"), NIL); }
  923. | CURRENT_TIME
  924. { $$ = lcons( makeString( "'now'::time"), NIL); }
  925. | CURRENT_TIME '(' Iconst ')'
  926. {
  927. if ($3 != 0)
  928. elog(NOTICE,"CURRENT_TIME(%d) precision not implemented; zero used instead",$3);
  929. $$ = lcons( makeString( "'now'::time"), NIL);
  930. }
  931. | CURRENT_TIMESTAMP
  932. { $$ = lcons( makeString( "now()"), NIL); }
  933. | CURRENT_TIMESTAMP '(' Iconst ')'
  934. {
  935. if ($3 != 0)
  936. elog(NOTICE,"CURRENT_TIMESTAMP(%d) precision not implemented; zero used instead",$3);
  937. $$ = lcons( makeString( "now()"), NIL);
  938. }
  939. | CURRENT_USER
  940. { $$ = lcons( makeString( "CURRENT_USER"), NIL); }
  941. | USER
  942. { $$ = lcons( makeString( "USER"), NIL); }
  943. ;
  944. /* ConstraintElem specifies constraint syntax which is not embedded into
  945.  *  a column definition. ColConstraintElem specifies the embedded form.
  946.  * - thomas 1997-12-03
  947.  */
  948. TableConstraint:  CONSTRAINT name ConstraintElem
  949. {
  950. Constraint *n = (Constraint *)$3;
  951. if (n != NULL) n->name = fmtId($2);
  952. $$ = $3;
  953. }
  954. | ConstraintElem
  955. { $$ = $1; }
  956. ;
  957. ConstraintElem:  CHECK '(' constraint_expr ')'
  958. {
  959. Constraint *n = makeNode(Constraint);
  960. n->contype = CONSTR_CHECK;
  961. n->name = NULL;
  962. n->def = FlattenStringList($3);
  963. $$ = (Node *)n;
  964. }
  965. | UNIQUE '(' columnList ')'
  966. {
  967. Constraint *n = makeNode(Constraint);
  968. n->contype = CONSTR_UNIQUE;
  969. n->name = NULL;
  970. n->def = NULL;
  971. n->keys = $3;
  972. $$ = (Node *)n;
  973. }
  974. | PRIMARY KEY '(' columnList ')'
  975. {
  976. Constraint *n = makeNode(Constraint);
  977. n->contype = CONSTR_PRIMARY;
  978. n->name = NULL;
  979. n->def = NULL;
  980. n->keys = $4;
  981. $$ = (Node *)n;
  982. }
  983. | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
  984. {
  985. elog(NOTICE,"CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
  986. $$ = NULL;
  987. }
  988. ;
  989. constraint_list:  constraint_list ',' constraint_expr
  990. {
  991. $$ = lappend($1,makeString(","));
  992. $$ = nconc($$, $3);
  993. }
  994. | constraint_expr
  995. {
  996. $$ = $1;
  997. }
  998. ;
  999. constraint_expr:  AexprConst
  1000. { $$ = makeConstantList((A_Const *) $1); }
  1001. | NULL_P
  1002. { $$ = lcons( makeString("NULL"), NIL); }
  1003. | ColId
  1004. {
  1005. $$ = lcons( makeString(fmtId($1)), NIL);
  1006. }
  1007. | '-' constraint_expr %prec UMINUS
  1008. { $$ = lcons( makeString( "-"), $2); }
  1009. | constraint_expr '+' constraint_expr
  1010. { $$ = nconc( $1, lcons( makeString( "+"), $3)); }
  1011. | constraint_expr '-' constraint_expr
  1012. { $$ = nconc( $1, lcons( makeString( "-"), $3)); }
  1013. | constraint_expr '/' constraint_expr
  1014. { $$ = nconc( $1, lcons( makeString( "/"), $3)); }
  1015. | constraint_expr '%' constraint_expr
  1016. { $$ = nconc( $1, lcons( makeString( "%"), $3)); }
  1017. | constraint_expr '*' constraint_expr
  1018. { $$ = nconc( $1, lcons( makeString( "*"), $3)); }
  1019. | constraint_expr '^' constraint_expr
  1020. { $$ = nconc( $1, lcons( makeString( "^"), $3)); }
  1021. | constraint_expr '=' constraint_expr
  1022. { $$ = nconc( $1, lcons( makeString( "="), $3)); }
  1023. | constraint_expr '<' constraint_expr
  1024. { $$ = nconc( $1, lcons( makeString( "<"), $3)); }
  1025. | constraint_expr '>' constraint_expr
  1026. { $$ = nconc( $1, lcons( makeString( ">"), $3)); }
  1027. | ':' constraint_expr
  1028. { $$ = lcons( makeString( ":"), $2); }
  1029. | ';' constraint_expr
  1030. { $$ = lcons( makeString( ";"), $2); }
  1031. | '|' constraint_expr
  1032. { $$ = lcons( makeString( "|"), $2); }
  1033. | constraint_expr TYPECAST Typename
  1034. {
  1035. $3->name = fmtId($3->name);
  1036. $$ = nconc( lcons( makeString( "CAST"), $1), makeList( makeString("AS"), $3, -1));
  1037. }
  1038. | CAST '(' constraint_expr AS Typename ')'
  1039. {
  1040. $5->name = fmtId($5->name);
  1041. $$ = nconc( lcons( makeString( "CAST"), $3), makeList( makeString("AS"), $5, -1));
  1042. }
  1043. | '(' constraint_expr ')'
  1044. { $$ = lappend( lcons( makeString( "("), $2), makeString( ")")); }
  1045. | func_name '(' ')'
  1046. {
  1047. $$ = makeList( makeString($1), makeString("("), -1);
  1048. $$ = lappend( $$, makeString(")"));
  1049. }
  1050. | func_name '(' constraint_list ')'
  1051. {
  1052. $$ = makeList( makeString($1), makeString("("), -1);
  1053. $$ = nconc( $$, $3);
  1054. $$ = lappend( $$, makeString(")"));
  1055. }
  1056. | constraint_expr Op constraint_expr
  1057. { $$ = nconc( $1, lcons( makeString( $2), $3)); }
  1058. | constraint_expr LIKE constraint_expr
  1059. { $$ = nconc( $1, lcons( makeString( "LIKE"), $3)); }
  1060. | constraint_expr NOT LIKE constraint_expr
  1061. { $$ = nconc( $1, lcons( makeString( "NOT LIKE"), $4)); }
  1062. | constraint_expr AND constraint_expr
  1063. { $$ = nconc( $1, lcons( makeString( "AND"), $3)); }
  1064. | constraint_expr OR constraint_expr
  1065. { $$ = nconc( $1, lcons( makeString( "OR"), $3)); }
  1066. | NOT constraint_expr
  1067. { $$ = lcons( makeString( "NOT"), $2); }
  1068. | Op constraint_expr
  1069. { $$ = lcons( makeString( $1), $2); }
  1070. | constraint_expr Op
  1071. { $$ = lappend( $1, makeString( $2)); }
  1072. | constraint_expr ISNULL
  1073. { $$ = lappend( $1, makeString( "IS NULL")); }
  1074. | constraint_expr IS NULL_P
  1075. { $$ = lappend( $1, makeString( "IS NULL")); }
  1076. | constraint_expr NOTNULL
  1077. { $$ = lappend( $1, makeString( "IS NOT NULL")); }
  1078. | constraint_expr IS NOT NULL_P
  1079. { $$ = lappend( $1, makeString( "IS NOT NULL")); }
  1080. | constraint_expr IS TRUE_P
  1081. { $$ = lappend( $1, makeString( "IS TRUE")); }
  1082. | constraint_expr IS FALSE_P
  1083. { $$ = lappend( $1, makeString( "IS FALSE")); }
  1084. | constraint_expr IS NOT TRUE_P
  1085. { $$ = lappend( $1, makeString( "IS NOT TRUE")); }
  1086. | constraint_expr IS NOT FALSE_P
  1087. { $$ = lappend( $1, makeString( "IS NOT FALSE")); }
  1088. | constraint_expr IN '(' c_list ')'
  1089. {
  1090. $$ = lappend( $1, makeString("IN"));
  1091. $$ = lappend( $$, makeString("("));
  1092. $$ = nconc( $$, $4);
  1093. $$ = lappend( $$, makeString(")"));
  1094. }
  1095. | constraint_expr NOT IN '(' c_list ')'
  1096. {
  1097. $$ = lappend( $1, makeString("NOT IN"));
  1098. $$ = lappend( $$, makeString("("));
  1099. $$ = nconc( $$, $5);
  1100. $$ = lappend( $$, makeString(")"));
  1101. }
  1102. | constraint_expr BETWEEN c_expr AND c_expr
  1103. {
  1104. $$ = lappend( $1, makeString("BETWEEN"));
  1105. $$ = nconc( $$, $3);
  1106. $$ = lappend( $$, makeString("AND"));
  1107. $$ = nconc( $$, $5);
  1108. }
  1109. | constraint_expr NOT BETWEEN c_expr AND c_expr
  1110. {
  1111. $$ = lappend( $1, makeString("NOT BETWEEN"));
  1112. $$ = nconc( $$, $4);
  1113. $$ = lappend( $$, makeString("AND"));
  1114. $$ = nconc( $$, $6);
  1115. }
  1116. ;
  1117. c_list:  c_list ',' c_expr
  1118. {
  1119. $$ = lappend($1, makeString(","));
  1120. $$ = nconc($$, $3);
  1121. }
  1122. | c_expr
  1123. {
  1124. $$ = $1;
  1125. }
  1126. ;
  1127. c_expr:  AexprConst
  1128. { $$ = makeConstantList((A_Const *) $1); }
  1129. ;
  1130. key_match:  MATCH FULL { $$ = NULL; }
  1131. | MATCH PARTIAL { $$ = NULL; }
  1132. | /*EMPTY*/ { $$ = NULL; }
  1133. ;
  1134. key_actions:  key_action key_action { $$ = NIL; }
  1135. | key_action { $$ = NIL; }
  1136. | /*EMPTY*/ { $$ = NIL; }
  1137. ;
  1138. key_action:  ON DELETE key_reference { $$ = NIL; }
  1139. | ON UPDATE key_reference { $$ = NIL; }
  1140. ;
  1141. key_reference:  NO ACTION { $$ = NULL; }
  1142. | CASCADE { $$ = NULL; }
  1143. | SET DEFAULT { $$ = NULL; }
  1144. | SET NULL_P { $$ = NULL; }
  1145. ;
  1146. OptInherit:  INHERITS '(' relation_name_list ')' { $$ = $3; }
  1147. | /*EMPTY*/ { $$ = NIL; }
  1148. ;
  1149. CreateAsStmt:  CREATE OptTemp TABLE relation_name OptCreateAs AS SubSelect
  1150. {
  1151. SelectStmt *n = (SelectStmt *)$7;
  1152. if ($5 != NIL)
  1153. mapTargetColumns($5, n->targetList);
  1154. n->istemp = $2;
  1155. n->into = $4;
  1156. $$ = (Node *)n;
  1157. }
  1158. ;
  1159. OptCreateAs:  '(' CreateAsList ')' { $$ = $2; }
  1160. | /*EMPTY*/ { $$ = NULL; }
  1161. ;
  1162. CreateAsList:  CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); }
  1163. | CreateAsElement { $$ = lcons($1, NIL); }
  1164. ;
  1165. CreateAsElement:  ColId
  1166. {
  1167. ColumnDef *n = makeNode(ColumnDef);
  1168. n->colname = $1;
  1169. n->typename = NULL;
  1170. n->defval = NULL;
  1171. n->is_not_null = FALSE;
  1172. n->constraints = NULL;
  1173. $$ = (Node *)n;
  1174. }
  1175. ;
  1176. /*****************************************************************************
  1177.  *
  1178.  * QUERY :
  1179.  * CREATE SEQUENCE seqname
  1180.  *
  1181.  *****************************************************************************/
  1182. CreateSeqStmt:  CREATE SEQUENCE relation_name OptSeqList
  1183. {
  1184. CreateSeqStmt *n = makeNode(CreateSeqStmt);
  1185. n->seqname = $3;
  1186. n->options = $4;
  1187. $$ = (Node *)n;
  1188. }
  1189. ;
  1190. OptSeqList:  OptSeqList OptSeqElem
  1191. { $$ = lappend($1, $2); }
  1192. | { $$ = NIL; }
  1193. ;
  1194. OptSeqElem:  CACHE IntegerOnly
  1195. {
  1196. $$ = makeNode(DefElem);
  1197. $$->defname = "cache";
  1198. $$->arg = (Node *)$2;
  1199. }
  1200. | CYCLE
  1201. {
  1202. $$ = makeNode(DefElem);
  1203. $$->defname = "cycle";
  1204. $$->arg = (Node *)NULL;
  1205. }
  1206. | INCREMENT IntegerOnly
  1207. {
  1208. $$ = makeNode(DefElem);
  1209. $$->defname = "increment";
  1210. $$->arg = (Node *)$2;
  1211. }
  1212. | MAXVALUE IntegerOnly
  1213. {
  1214. $$ = makeNode(DefElem);
  1215. $$->defname = "maxvalue";
  1216. $$->arg = (Node *)$2;
  1217. }
  1218. | MINVALUE IntegerOnly
  1219. {
  1220. $$ = makeNode(DefElem);
  1221. $$->defname = "minvalue";
  1222. $$->arg = (Node *)$2;
  1223. }
  1224. | START IntegerOnly
  1225. {
  1226. $$ = makeNode(DefElem);
  1227. $$->defname = "start";
  1228. $$->arg = (Node *)$2;
  1229. }
  1230. ;
  1231. NumericOnly:  FloatOnly { $$ = $1; }
  1232. | IntegerOnly { $$ = $1; }
  1233. FloatOnly:  FCONST
  1234. {
  1235. $$ = makeFloat($1);
  1236. }
  1237. | '-' FCONST
  1238. {
  1239. $$ = makeFloat($2);
  1240. $$->val.dval = - $$->val.dval;
  1241. }
  1242. ;
  1243. IntegerOnly:  Iconst
  1244. {
  1245. $$ = makeInteger($1);
  1246. }
  1247. | '-' Iconst
  1248. {
  1249. $$ = makeInteger($2);
  1250. $$->val.ival = - $$->val.ival;
  1251. }
  1252. ;
  1253. /*****************************************************************************
  1254.  *
  1255.  * QUERIES :
  1256.  * CREATE PROCEDURAL LANGUAGE ...
  1257.  * DROP PROCEDURAL LANGUAGE ...
  1258.  *
  1259.  *****************************************************************************/
  1260. CreatePLangStmt:  CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst 
  1261. HANDLER def_name LANCOMPILER Sconst
  1262. {
  1263. CreatePLangStmt *n = makeNode(CreatePLangStmt);
  1264. n->plname = $5;
  1265. n->plhandler = $7;
  1266. n->plcompiler = $9;
  1267. n->pltrusted = $2;
  1268. $$ = (Node *)n;
  1269. }
  1270. ;
  1271. PLangTrusted: TRUSTED { $$ = TRUE; }
  1272. | { $$ = FALSE; }
  1273. DropPLangStmt:  DROP PROCEDURAL LANGUAGE Sconst
  1274. {
  1275. DropPLangStmt *n = makeNode(DropPLangStmt);
  1276. n->plname = $4;
  1277. $$ = (Node *)n;
  1278. }
  1279. ;
  1280. /*****************************************************************************
  1281.  *
  1282.  * QUERIES :
  1283.  * CREATE TRIGGER ...
  1284.  * DROP TRIGGER ...
  1285.  *
  1286.  *****************************************************************************/
  1287. CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
  1288. relation_name TriggerForSpec EXECUTE PROCEDURE
  1289. name '(' TriggerFuncArgs ')'
  1290. {
  1291. CreateTrigStmt *n = makeNode(CreateTrigStmt);
  1292. n->trigname = $3;
  1293. n->relname = $7;
  1294. n->funcname = $11;
  1295. n->args = $13;
  1296. n->before = $4;
  1297. n->row = $8;
  1298. memcpy (n->actions, $5, 4);
  1299. $$ = (Node *)n;
  1300. }
  1301. ;
  1302. TriggerActionTime:  BEFORE { $$ = TRUE; }
  1303. | AFTER { $$ = FALSE; }
  1304. ;
  1305. TriggerEvents: TriggerOneEvent
  1306. {
  1307. char *e = palloc (4);
  1308. e[0] = $1; e[1] = 0; $$ = e;
  1309. }
  1310. | TriggerOneEvent OR TriggerOneEvent
  1311. {
  1312. char *e = palloc (4);
  1313. e[0] = $1; e[1] = $3; e[2] = 0; $$ = e;
  1314. }
  1315. | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
  1316. {
  1317. char *e = palloc (4);
  1318. e[0] = $1; e[1] = $3; e[2] = $5; e[3] = 0;
  1319. $$ = e;
  1320. }
  1321. ;
  1322. TriggerOneEvent:  INSERT { $$ = 'i'; }
  1323. | DELETE { $$ = 'd'; }
  1324. | UPDATE { $$ = 'u'; }
  1325. ;
  1326. TriggerForSpec:  FOR TriggerForOpt TriggerForType
  1327. {
  1328. $$ = $3;
  1329. }
  1330. ;
  1331. TriggerForOpt:  EACH { $$ = TRUE; }
  1332. | /*EMPTY*/ { $$ = FALSE; }
  1333. ;
  1334. TriggerForType:  ROW { $$ = TRUE; }
  1335. | STATEMENT { $$ = FALSE; }
  1336. ;
  1337. TriggerFuncArgs:  TriggerFuncArg
  1338. { $$ = lcons($1, NIL); }
  1339. | TriggerFuncArgs ',' TriggerFuncArg
  1340. { $$ = lappend($1, $3); }
  1341. | /*EMPTY*/
  1342. { $$ = NIL; }
  1343. ;
  1344. TriggerFuncArg:  ICONST
  1345. {
  1346. char *s = (char *) palloc (256);
  1347. sprintf (s, "%d", $1);
  1348. $$ = s;
  1349. }
  1350. | FCONST
  1351. {
  1352. char *s = (char *) palloc (256);
  1353. sprintf (s, "%g", $1);
  1354. $$ = s;
  1355. }
  1356. | Sconst {  $$ = $1; }
  1357. | IDENT {  $$ = $1; }
  1358. ;
  1359. DropTrigStmt:  DROP TRIGGER name ON relation_name
  1360. {
  1361. DropTrigStmt *n = makeNode(DropTrigStmt);
  1362. n->trigname = $3;
  1363. n->relname = $5;
  1364. $$ = (Node *) n;
  1365. }
  1366. ;
  1367. /*****************************************************************************
  1368.  *
  1369.  * QUERY :
  1370.  * define (type,operator,aggregate)
  1371.  *
  1372.  *****************************************************************************/
  1373. DefineStmt:  CREATE def_type def_rest
  1374. {
  1375. $3->defType = $2;
  1376. $$ = (Node *)$3;
  1377. }
  1378. ;
  1379. def_rest:  def_name definition
  1380. {
  1381. $$ = makeNode(DefineStmt);
  1382. $$->defname = $1;
  1383. $$->definition = $2;
  1384. }
  1385. ;
  1386. def_type:  OPERATOR { $$ = OPERATOR; }
  1387. | TYPE_P { $$ = TYPE_P; }
  1388. | AGGREGATE { $$ = AGGREGATE; }
  1389. ;
  1390. def_name:  PROCEDURE { $$ = "procedure"; }
  1391. | JOIN { $$ = "join"; }
  1392. | ColId { $$ = $1; }
  1393. | MathOp { $$ = $1; }
  1394. | Op { $$ = $1; }
  1395. ;
  1396. definition:  '(' def_list ')' { $$ = $2; }
  1397. ;
  1398. def_list:  def_elem { $$ = lcons($1, NIL); }
  1399. | def_list ',' def_elem { $$ = lappend($1, $3); }
  1400. ;
  1401. def_elem:  def_name '=' def_arg
  1402. {
  1403. $$ = makeNode(DefElem);
  1404. $$->defname = $1;
  1405. $$->arg = (Node *)$3;
  1406. }
  1407. | def_name
  1408. {
  1409. $$ = makeNode(DefElem);
  1410. $$->defname = $1;
  1411. $$->arg = (Node *)NULL;
  1412. }
  1413. | DEFAULT '=' def_arg
  1414. {
  1415. $$ = makeNode(DefElem);
  1416. $$->defname = "default";
  1417. $$->arg = (Node *)$3;
  1418. }
  1419. ;
  1420. def_arg:  ColId {  $$ = (Node *)makeString($1); }
  1421. | all_Op {  $$ = (Node *)makeString($1); }
  1422. | NumericOnly {  $$ = (Node *)$1; }
  1423. | Sconst {  $$ = (Node *)makeString($1); }
  1424. | SETOF ColId
  1425. {
  1426. TypeName *n = makeNode(TypeName);
  1427. n->name = $2;
  1428. n->setof = TRUE;
  1429. n->arrayBounds = NULL;
  1430. n->typmod = -1;
  1431. $$ = (Node *)n;
  1432. }
  1433. ;
  1434. /*****************************************************************************
  1435.  *
  1436.  * QUERY:
  1437.  * destroy <relname1> [, <relname2> .. <relnameN> ]
  1438.  *
  1439.  *****************************************************************************/
  1440. DestroyStmt:  DROP TABLE relation_name_list
  1441. {
  1442. DestroyStmt *n = makeNode(DestroyStmt);
  1443. n->relNames = $3;
  1444. n->sequence = FALSE;
  1445. $$ = (Node *)n;
  1446. }
  1447. | DROP SEQUENCE relation_name_list
  1448. {
  1449. DestroyStmt *n = makeNode(DestroyStmt);
  1450. n->relNames = $3;
  1451. n->sequence = TRUE;
  1452. $$ = (Node *)n;
  1453. }
  1454. ;
  1455. /*****************************************************************************
  1456.  *
  1457.  * QUERY:
  1458.  * fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
  1459.  * fetch [ forward | backward | absolute | relative ]
  1460.  *       [ # | all | next | prior ] [ [ in | from ] <portalname> ]
  1461.  *
  1462.  *****************************************************************************/
  1463. FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name
  1464. {
  1465. FetchStmt *n = makeNode(FetchStmt);
  1466. if ($2 == RELATIVE)
  1467. {
  1468. if ($3 == 0)
  1469. elog(ERROR,"FETCH/RELATIVE at current position is not supported");
  1470. $2 = FORWARD;
  1471. }
  1472. if ($3 < 0)
  1473. {
  1474. $3 = -$3;
  1475. $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
  1476. }
  1477. n->direction = $2;
  1478. n->howMany = $3;
  1479. n->portalname = $4;
  1480. n->ismove = false;
  1481. $$ = (Node *)n;
  1482. }
  1483. | MOVE opt_direction fetch_how_many opt_portal_name
  1484. {
  1485. FetchStmt *n = makeNode(FetchStmt);
  1486. if ($3 < 0)
  1487. {
  1488. $3 = -$3;
  1489. $2 = (($2 == FORWARD)? BACKWARD: FORWARD);
  1490. }
  1491. n->direction = $2;
  1492. n->howMany = $3;
  1493. n->portalname = $4;
  1494. n->ismove = TRUE;
  1495. $$ = (Node *)n;
  1496. }
  1497. ;
  1498. opt_direction: FORWARD { $$ = FORWARD; }
  1499. | BACKWARD { $$ = BACKWARD; }
  1500. | RELATIVE { $$ = RELATIVE; }
  1501. | ABSOLUTE
  1502. {
  1503. elog(NOTICE,"FETCH/ABSOLUTE not supported, using RELATIVE");
  1504. $$ = RELATIVE;
  1505. }
  1506. | /*EMPTY*/ { $$ = FORWARD; /* default */ }
  1507. ;
  1508. fetch_how_many:  Iconst { $$ = $1; }
  1509. | '-' Iconst { $$ = - $2; }
  1510. | ALL { $$ = 0; /* 0 means fetch all tuples*/ }
  1511. | NEXT { $$ = 1; }
  1512. | PRIOR { $$ = -1; }
  1513. | /*EMPTY*/ { $$ = 1; /*default*/ }
  1514. ;
  1515. opt_portal_name:  IN name { $$ = $2; }
  1516. | FROM name { $$ = $2; }
  1517. | /*EMPTY*/ { $$ = NULL; }
  1518. ;
  1519. /*****************************************************************************
  1520.  *
  1521.  * QUERY:
  1522.  * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
  1523.  *
  1524.  *****************************************************************************/
  1525. GrantStmt:  GRANT privileges ON relation_name_list TO grantee opt_with_grant
  1526. {
  1527. $$ = (Node*)makeAclStmt($2,$4,$6,'+');
  1528. }
  1529. ;
  1530. privileges:  ALL PRIVILEGES
  1531. {
  1532.  $$ = aclmakepriv("rwaR",0);
  1533. }
  1534. | ALL
  1535. {
  1536.  $$ = aclmakepriv("rwaR",0);
  1537. }
  1538. | operation_commalist
  1539. {
  1540.  $$ = $1;
  1541. }
  1542. ;
  1543. operation_commalist:  operation
  1544. {
  1545. $$ = aclmakepriv("",$1);
  1546. }
  1547. | operation_commalist ',' operation
  1548. {
  1549. $$ = aclmakepriv($1,$3);
  1550. }
  1551. ;
  1552. operation:  SELECT
  1553. {
  1554. $$ = ACL_MODE_RD_CHR;
  1555. }
  1556. | INSERT
  1557. {
  1558. $$ = ACL_MODE_AP_CHR;
  1559. }
  1560. | UPDATE
  1561. {
  1562. $$ = ACL_MODE_WR_CHR;
  1563. }
  1564. | DELETE
  1565. {
  1566. $$ = ACL_MODE_WR_CHR;
  1567. }
  1568. | RULE
  1569. {
  1570. $$ = ACL_MODE_RU_CHR;
  1571. }
  1572. ;
  1573. grantee:  PUBLIC
  1574. {
  1575. $$ = aclmakeuser("A","");
  1576. }
  1577. | GROUP ColId
  1578. {
  1579. $$ = aclmakeuser("G",$2);
  1580. }
  1581. | ColId
  1582. {
  1583. $$ = aclmakeuser("U",$1);
  1584. }
  1585. ;
  1586. opt_with_grant:  WITH GRANT OPTION
  1587. {
  1588. yyerror("WITH GRANT OPTION is not supported.  Only relation owners can set privileges");
  1589.  }
  1590. | /*EMPTY*/
  1591. ;
  1592. /*****************************************************************************
  1593.  *
  1594.  * QUERY:
  1595.  * REVOKE [privileges] ON [relation_name] FROM [user]
  1596.  *
  1597.  *****************************************************************************/
  1598. RevokeStmt:  REVOKE privileges ON relation_name_list FROM grantee
  1599. {
  1600. $$ = (Node*)makeAclStmt($2,$4,$6,'-');
  1601. }
  1602. ;
  1603. /*****************************************************************************
  1604.  *
  1605.  * QUERY:
  1606.  * create index <indexname> on <relname>
  1607.  *   using <access> "(" (<col> with <op>)+ ")" [with
  1608.  *   <target_list>]
  1609.  *
  1610.  * [where <qual>] is not supported anymore
  1611.  *****************************************************************************/
  1612. IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
  1613. access_method_clause '(' index_params ')' opt_with
  1614. {
  1615. /* should check that access_method is valid,
  1616.    etc ... but doesn't */
  1617. IndexStmt *n = makeNode(IndexStmt);
  1618. n->unique = $2;
  1619. n->idxname = $4;
  1620. n->relname = $6;
  1621. n->accessMethod = $7;
  1622. n->indexParams = $9;
  1623. n->withClause = $11;
  1624. n->whereClause = NULL;
  1625. $$ = (Node *)n;
  1626. }
  1627. ;
  1628. index_opt_unique:  UNIQUE { $$ = TRUE; }
  1629. | /*EMPTY*/ { $$ = FALSE; }
  1630. ;
  1631. access_method_clause:  USING access_method { $$ = $2; }
  1632. | /*EMPTY*/ { $$ = "btree"; }
  1633. ;
  1634. index_params:  index_list { $$ = $1; }
  1635. | func_index { $$ = lcons($1,NIL); }
  1636. ;
  1637. index_list:  index_list ',' index_elem { $$ = lappend($1, $3); }
  1638. | index_elem { $$ = lcons($1, NIL); }
  1639. ;
  1640. func_index:  func_name '(' name_list ')' opt_type opt_class
  1641. {
  1642. $$ = makeNode(IndexElem);
  1643. $$->name = $1;
  1644. $$->args = $3;
  1645. $$->class = $6;
  1646. $$->typename = $5;
  1647. }
  1648.   ;
  1649. index_elem:  attr_name opt_type opt_class
  1650. {
  1651. $$ = makeNode(IndexElem);
  1652. $$->name = $1;
  1653. $$->args = NIL;
  1654. $$->class = $3;
  1655. $$->typename = $2;
  1656. }
  1657. ;
  1658. opt_type:  ':' Typename { $$ = $2; }
  1659. | FOR Typename { $$ = $2; }
  1660. | /*EMPTY*/ { $$ = NULL; }
  1661. ;
  1662. /* opt_class "WITH class" conflicts with preceeding opt_type
  1663.  *  for Typename of "TIMESTAMP WITH TIME ZONE"
  1664.  * So, remove "WITH class" from the syntax. OK??
  1665.  * - thomas 1997-10-12
  1666.  * | WITH class { $$ = $2; }
  1667.  */
  1668. opt_class:  class { $$ = $1; }
  1669. | USING class { $$ = $2; }
  1670. | /*EMPTY*/ { $$ = NULL; }
  1671. ;
  1672. /*****************************************************************************
  1673.  *
  1674.  * QUERY:
  1675.  * extend index <indexname> [where <qual>]
  1676.  *
  1677.  *****************************************************************************/
  1678. ExtendStmt:  EXTEND INDEX index_name where_clause
  1679. {
  1680. ExtendStmt *n = makeNode(ExtendStmt);
  1681. n->idxname = $3;
  1682. n->whereClause = $4;
  1683. $$ = (Node *)n;
  1684. }
  1685. ;
  1686. /*****************************************************************************
  1687.  *
  1688.  * QUERY:
  1689.  * execute recipe <recipeName>
  1690.  *
  1691.  *****************************************************************************/
  1692. /* NOT USED
  1693. RecipeStmt:  EXECUTE RECIPE recipe_name
  1694. {
  1695. RecipeStmt *n;
  1696. if (!IsTransactionBlock())
  1697. elog(ERROR,"EXECUTE RECIPE may only be used in begin/end transaction blocks");
  1698. n = makeNode(RecipeStmt);
  1699. n->recipeName = $3;
  1700. $$ = (Node *)n;
  1701. }
  1702. ;
  1703. */
  1704. /*****************************************************************************
  1705.  *
  1706.  * QUERY:
  1707.  * define function <fname>
  1708.  *    (language = <lang>, returntype = <typename>
  1709.  * [, arch_pct = <percentage | pre-defined>]
  1710.  * [, disk_pct = <percentage | pre-defined>]
  1711.  * [, byte_pct = <percentage | pre-defined>]
  1712.  * [, perbyte_cpu = <int | pre-defined>]
  1713.  * [, percall_cpu = <int | pre-defined>]
  1714.  * [, iscachable])
  1715.  * [arg is (<type-1> { , <type-n>})]
  1716.  * as <filename or code in language as appropriate>
  1717.  *
  1718.  *****************************************************************************/
  1719. ProcedureStmt: CREATE FUNCTION func_name func_args
  1720.  RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
  1721. {
  1722. ProcedureStmt *n = makeNode(ProcedureStmt);
  1723. n->funcname = $3;
  1724. n->defArgs = $4;
  1725. n->returnType = $6;
  1726. n->withClause = $7;
  1727. n->as = $9;
  1728. n->language = $11;
  1729. $$ = (Node *)n;
  1730. };
  1731. opt_with:  WITH definition { $$ = $2; }
  1732. | /*EMPTY*/ { $$ = NIL; }
  1733. ;
  1734. func_args:  '(' func_args_list ')' { $$ = $2; }
  1735. | '(' ')' { $$ = NIL; }
  1736. ;
  1737. func_args_list:  TypeId
  1738. { $$ = lcons(makeString($1),NIL); }
  1739. | func_args_list ',' TypeId
  1740. { $$ = lappend($1,makeString($3)); }
  1741. ;
  1742. func_return:  set_opt TypeId
  1743. {
  1744. TypeName *n = makeNode(TypeName);
  1745. n->name = $2;
  1746. n->setof = $1;
  1747. n->arrayBounds = NULL;
  1748. $$ = (Node *)n;
  1749. }
  1750. ;
  1751. set_opt:  SETOF { $$ = TRUE; }
  1752. | /*EMPTY*/ { $$ = FALSE; }
  1753. ;
  1754. /*****************************************************************************
  1755.  *
  1756.  * QUERY:
  1757.  *
  1758.  * remove function <funcname>
  1759.  * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
  1760.  * remove aggregate <aggname>
  1761.  * (REMOVE AGGREGATE "aggname" "aggtype")
  1762.  * remove operator <opname>
  1763.  * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
  1764.  * remove type <typename>
  1765.  * (REMOVE TYPE "typename")
  1766.  * remove rule <rulename>
  1767.  * (REMOVE RULE "rulename")
  1768.  *
  1769.  *****************************************************************************/
  1770. RemoveStmt:  DROP remove_type name
  1771. {
  1772. RemoveStmt *n = makeNode(RemoveStmt);
  1773. n->removeType = $2;
  1774. n->name = $3;
  1775. $$ = (Node *)n;
  1776. }
  1777. ;
  1778. remove_type:  TYPE_P {  $$ = TYPE_P; }
  1779. | INDEX {  $$ = INDEX; }
  1780. | RULE {  $$ = RULE; }
  1781. | VIEW {  $$ = VIEW; }
  1782. ;
  1783. RemoveAggrStmt:  DROP AGGREGATE name aggr_argtype
  1784. {
  1785. RemoveAggrStmt *n = makeNode(RemoveAggrStmt);
  1786. n->aggname = $3;
  1787. n->aggtype = $4;
  1788. $$ = (Node *)n;
  1789. }
  1790. ;
  1791. aggr_argtype:  name { $$ = $1; }
  1792. | '*' { $$ = NULL; }
  1793. ;
  1794. RemoveFuncStmt:  DROP FUNCTION func_name func_args
  1795. {
  1796. RemoveFuncStmt *n = makeNode(RemoveFuncStmt);
  1797. n->funcname = $3;
  1798. n->args = $4;
  1799. $$ = (Node *)n;
  1800. }
  1801. ;
  1802. RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')'
  1803. {
  1804. RemoveOperStmt *n = makeNode(RemoveOperStmt);
  1805. n->opname = $3;
  1806. n->args = $5;
  1807. $$ = (Node *)n;
  1808. }
  1809. ;
  1810. all_Op:  Op | MathOp;
  1811. MathOp: '+' { $$ = "+"; }
  1812. | '-' { $$ = "-"; }
  1813. | '*' { $$ = "*"; }
  1814. | '/' { $$ = "/"; }
  1815. | '%' { $$ = "%"; }
  1816. | '<' { $$ = "<"; }
  1817. | '>' { $$ = ">"; }
  1818. | '=' { $$ = "="; }
  1819. ;
  1820. oper_argtypes: name
  1821. {
  1822.    elog(ERROR,"parser: argument type missing (use NONE for unary operators)");
  1823. }
  1824. | name ',' name
  1825. { $$ = makeList(makeString($1), makeString($3), -1); }
  1826. | NONE ',' name /* left unary */
  1827. { $$ = makeList(NULL, makeString($3), -1); }
  1828. | name ',' NONE /* right unary */
  1829. { $$ = makeList(makeString($1), NULL, -1); }
  1830. ;
  1831. /*****************************************************************************
  1832.  *
  1833.  * QUERY:
  1834.  * rename <attrname1> in <relname> [*] to <attrname2>
  1835.  * rename <relname1> to <relname2>
  1836.  *
  1837.  *****************************************************************************/
  1838. RenameStmt:  ALTER TABLE relation_name opt_inh_star
  1839.   RENAME opt_column opt_name TO name
  1840. {
  1841. RenameStmt *n = makeNode(RenameStmt);
  1842. n->relname = $3;
  1843. n->inh = $4;
  1844. n->column = $7;
  1845. n->newname = $9;
  1846. $$ = (Node *)n;
  1847. }
  1848. ;
  1849. opt_name:  name { $$ = $1; }
  1850. | /*EMPTY*/ { $$ = NULL; }
  1851. ;
  1852. opt_column:  COLUMN { $$ = COLUMN; }
  1853. | /*EMPTY*/ { $$ = 0; }
  1854. ;
  1855. /*****************************************************************************
  1856.  *
  1857.  * QUERY: Define Rewrite Rule , Define Tuple Rule
  1858.  * Define Rule <old rules >
  1859.  *
  1860.  * only rewrite rule is supported -- ay 9/94
  1861.  *
  1862.  *****************************************************************************/
  1863. RuleStmt:  CREATE RULE name AS
  1864.    { QueryIsRule=TRUE; }
  1865.    ON event TO event_object where_clause
  1866.    DO opt_instead RuleActionList
  1867. {
  1868. RuleStmt *n = makeNode(RuleStmt);
  1869. n->rulename = $3;
  1870. n->event = $7;
  1871. n->object = $9;
  1872. n->whereClause = $10;
  1873. n->instead = $12;
  1874. n->actions = $13;
  1875. $$ = (Node *)n;
  1876. }
  1877. ;
  1878. RuleActionList:  NOTHING { $$ = NIL; }
  1879. | SelectStmt { $$ = lcons($1, NIL); }
  1880. | RuleActionStmt { $$ = lcons($1, NIL); }
  1881. | '[' RuleActionBlock ']' { $$ = $2; }
  1882. | '(' RuleActionBlock ')' { $$ = $2; } 
  1883. ;
  1884. RuleActionBlock:  RuleActionMulti {  $$ = $1; }
  1885. | RuleActionStmt { $$ = lcons($1, NIL); }
  1886. ;
  1887. RuleActionMulti:  RuleActionMulti RuleActionStmt
  1888. {  $$ = lappend($1, $2); }
  1889. | RuleActionMulti RuleActionStmt ';'
  1890. {  $$ = lappend($1, $2); }
  1891. | RuleActionStmt ';'
  1892. { $$ = lcons($1, NIL); }
  1893. ;
  1894. RuleActionStmt: InsertStmt
  1895. | UpdateStmt
  1896. | DeleteStmt
  1897. | NotifyStmt
  1898. ;
  1899. event_object:  relation_name '.' attr_name
  1900. {
  1901. $$ = makeNode(Attr);
  1902. $$->relname = $1;
  1903. $$->paramNo = NULL;
  1904. $$->attrs = lcons(makeString($3), NIL);
  1905. $$->indirection = NIL;
  1906. }
  1907. | relation_name
  1908. {
  1909. $$ = makeNode(Attr);
  1910. $$->relname = $1;
  1911. $$->paramNo = NULL;
  1912. $$->attrs = NIL;
  1913. $$->indirection = NIL;
  1914. }
  1915. ;
  1916. /* change me to select, update, etc. some day */
  1917. event: SELECT { $$ = CMD_SELECT; }
  1918. | UPDATE { $$ = CMD_UPDATE; }
  1919. | DELETE { $$ = CMD_DELETE; }
  1920. | INSERT { $$ = CMD_INSERT; }
  1921.  ;
  1922. opt_instead:  INSTEAD { $$ = TRUE; }
  1923. | /*EMPTY*/ { $$ = FALSE; }
  1924. ;
  1925. /*****************************************************************************
  1926.  *
  1927.  * QUERY:
  1928.  * NOTIFY <relation_name> can appear both in rule bodies and
  1929.  * as a query-level command
  1930.  *
  1931.  *****************************************************************************/
  1932. NotifyStmt:  NOTIFY relation_name
  1933. {
  1934. NotifyStmt *n = makeNode(NotifyStmt);
  1935. n->relname = $2;
  1936. $$ = (Node *)n;
  1937. }
  1938. ;
  1939. ListenStmt:  LISTEN relation_name
  1940. {
  1941. ListenStmt *n = makeNode(ListenStmt);
  1942. n->relname = $2;
  1943. $$ = (Node *)n;
  1944. }
  1945. ;
  1946. UnlistenStmt:  UNLISTEN relation_name
  1947. {
  1948. UnlistenStmt *n = makeNode(UnlistenStmt);
  1949. n->relname = $2;
  1950. $$ = (Node *)n;
  1951. }
  1952. | UNLISTEN '*'
  1953. {
  1954. UnlistenStmt *n = makeNode(UnlistenStmt);
  1955. n->relname = "*";
  1956. $$ = (Node *)n;
  1957. }
  1958. ;
  1959. /*****************************************************************************
  1960.  *
  1961.  * Transactions:
  1962.  *
  1963.  * abort transaction
  1964.  * (ABORT)
  1965.  * begin transaction
  1966.  * (BEGIN)
  1967.  * end transaction
  1968.  * (END)
  1969.  *
  1970.  *****************************************************************************/
  1971. TransactionStmt: ABORT_TRANS opt_trans
  1972. {
  1973. TransactionStmt *n = makeNode(TransactionStmt);
  1974. n->command = ABORT_TRANS;
  1975. $$ = (Node *)n;
  1976. }
  1977. | BEGIN_TRANS opt_trans
  1978. {
  1979. TransactionStmt *n = makeNode(TransactionStmt);
  1980. n->command = BEGIN_TRANS;
  1981. $$ = (Node *)n;
  1982. }
  1983. | COMMIT opt_trans
  1984. {
  1985. TransactionStmt *n = makeNode(TransactionStmt);
  1986. n->command = END_TRANS;
  1987. $$ = (Node *)n;
  1988. }
  1989. | END_TRANS opt_trans
  1990. {
  1991. TransactionStmt *n = makeNode(TransactionStmt);
  1992. n->command = END_TRANS;
  1993. $$ = (Node *)n;
  1994. }
  1995. | ROLLBACK opt_trans
  1996. {
  1997. TransactionStmt *n = makeNode(TransactionStmt);
  1998. n->command = ABORT_TRANS;
  1999. $$ = (Node *)n;
  2000. }
  2001. ;
  2002. opt_trans: WORK { $$ = TRUE; }
  2003. | TRANSACTION { $$ = TRUE; }
  2004. | /*EMPTY*/ { $$ = TRUE; }
  2005. ;
  2006. /*****************************************************************************
  2007.  *
  2008.  * QUERY:
  2009.  * define view <viewname> '('target-list ')' [where <quals> ]
  2010.  *
  2011.  *****************************************************************************/
  2012. ViewStmt:  CREATE VIEW name AS SelectStmt
  2013. {
  2014. ViewStmt *n = makeNode(ViewStmt);
  2015. n->viewname = $3;
  2016. n->query = (Query *)$5;
  2017. if (((SelectStmt *)n->query)->sortClause != NULL)
  2018. elog(ERROR,"Order by and Distinct on views is not implemented.");
  2019. if (((SelectStmt *)n->query)->unionClause != NULL)
  2020. elog(ERROR,"Views on unions not implemented.");
  2021. if (((SelectStmt *)n->query)->forUpdate != NULL)
  2022. elog(ERROR, "SELECT FOR UPDATE is not allowed in CREATE VIEW");
  2023. $$ = (Node *)n;
  2024. }
  2025. ;
  2026. /*****************************************************************************
  2027.  *
  2028.  * QUERY:
  2029.  * load "filename"
  2030.  *
  2031.  *****************************************************************************/
  2032. LoadStmt:  LOAD file_name
  2033. {
  2034. LoadStmt *n = makeNode(LoadStmt);
  2035. n->filename = $2;
  2036. $$ = (Node *)n;
  2037. }
  2038. ;
  2039. /*****************************************************************************
  2040.  *
  2041.  * QUERY:
  2042.  * createdb dbname
  2043.  *
  2044.  *****************************************************************************/
  2045. CreatedbStmt:  CREATE DATABASE database_name WITH opt_database1 opt_database2
  2046. {
  2047. CreatedbStmt *n = makeNode(CreatedbStmt);
  2048. if ($5 == NULL && $6 == NULL) {
  2049. elog(ERROR, "CREATE DATABASE WITH requires at least an option");
  2050. }
  2051. n->dbname = $3;
  2052. n->dbpath = $5;
  2053. #ifdef MULTIBYTE
  2054. if ($6 != NULL) {
  2055. n->encoding = pg_char_to_encoding($6);
  2056. if (n->encoding < 0) {
  2057. elog(ERROR, "invalid encoding name %s", $6);
  2058. }
  2059. } else {
  2060. n->encoding = GetTemplateEncoding();
  2061. }
  2062. #else
  2063. if ($6 != NULL)
  2064. elog(ERROR, "WITH ENCODING is not supported");
  2065. n->encoding = 0;
  2066. #endif
  2067. $$ = (Node *)n;
  2068. }
  2069. | CREATE DATABASE database_name
  2070. {
  2071. CreatedbStmt *n = makeNode(CreatedbStmt);
  2072. n->dbname = $3;
  2073. n->dbpath = NULL;
  2074. #ifdef MULTIBYTE
  2075. n->encoding = GetTemplateEncoding();
  2076. #else
  2077. n->encoding = 0;
  2078. #endif
  2079. $$ = (Node *)n;
  2080. }
  2081. ;
  2082. opt_database1:  LOCATION '=' location { $$ = $3; }
  2083. | /*EMPTY*/ { $$ = NULL; }
  2084. ;
  2085. opt_database2:  ENCODING '=' encoding { $$ = $3; }
  2086. | /*EMPTY*/ { $$ = NULL; }
  2087. ;
  2088. location:  Sconst { $$ = $1; }
  2089. | DEFAULT { $$ = NULL; }
  2090. | /*EMPTY*/ { $$ = NULL; }
  2091. ;
  2092. encoding:  Sconst { $$ = $1; }
  2093. | DEFAULT { $$ = NULL; }
  2094. | /*EMPTY*/ { $$ = NULL; }
  2095. ;
  2096. /*****************************************************************************
  2097.  *
  2098.  * QUERY:
  2099.  * destroydb dbname
  2100.  *
  2101.  *****************************************************************************/
  2102. DestroydbStmt: DROP DATABASE database_name
  2103. {
  2104. DestroydbStmt *n = makeNode(DestroydbStmt);
  2105. n->dbname = $3;
  2106. $$ = (Node *)n;
  2107. }
  2108. ;
  2109. /*****************************************************************************
  2110.  *
  2111.  * QUERY:
  2112.  * cluster <index_name> on <relation_name>
  2113.  *
  2114.  *****************************************************************************/
  2115. ClusterStmt:  CLUSTER index_name ON relation_name
  2116. {
  2117.    ClusterStmt *n = makeNode(ClusterStmt);
  2118.    n->relname = $4;
  2119.    n->indexname = $2;
  2120.    $$ = (Node*)n;
  2121. }
  2122. ;
  2123. /*****************************************************************************
  2124.  *
  2125.  * QUERY:
  2126.  * vacuum
  2127.  *
  2128.  *****************************************************************************/
  2129. VacuumStmt:  VACUUM opt_verbose opt_analyze
  2130. {
  2131. VacuumStmt *n = makeNode(VacuumStmt);
  2132. n->verbose = $2;
  2133. n->analyze = $3;
  2134. n->vacrel = NULL;
  2135. n->va_spec = NIL;
  2136. $$ = (Node *)n;
  2137. }
  2138. | VACUUM opt_verbose opt_analyze relation_name opt_va_list
  2139. {
  2140. VacuumStmt *n = makeNode(VacuumStmt);
  2141. n->verbose = $2;
  2142. n->analyze = $3;
  2143. n->vacrel = $4;
  2144. n->va_spec = $5;
  2145. if ( $5 != NIL && !$4 )
  2146. elog(ERROR,"parser: syntax error at or near "("");
  2147. $$ = (Node *)n;
  2148. }
  2149. ;
  2150. opt_verbose:  VERBOSE { $$ = TRUE; }
  2151. | /*EMPTY*/ { $$ = FALSE; }
  2152. ;
  2153. opt_analyze:  ANALYZE { $$ = TRUE; }
  2154. | /*EMPTY*/ { $$ = FALSE; }
  2155. ;
  2156. opt_va_list:  '(' va_list ')' { $$ = $2; }
  2157. | /*EMPTY*/ { $$ = NIL; }
  2158. ;
  2159. va_list:  name
  2160. { $$=lcons($1,NIL); }
  2161. | va_list ',' name
  2162. { $$=lappend($1,$3); }
  2163. ;
  2164. /*****************************************************************************
  2165.  *
  2166.  * QUERY:
  2167.  * EXPLAIN query
  2168.  *
  2169.  *****************************************************************************/
  2170. ExplainStmt:  EXPLAIN opt_verbose OptimizableStmt
  2171. {
  2172. ExplainStmt *n = makeNode(ExplainStmt);
  2173. n->verbose = $2;
  2174. n->query = (Query*)$3;
  2175. $$ = (Node *)n;
  2176. }
  2177. ;
  2178. /*****************************************************************************
  2179.  *  *
  2180.  * Optimizable Stmts:  *
  2181.  *  *
  2182.  * one of the five queries processed by the planner  *
  2183.  *  *
  2184.  * [ultimately] produces query-trees as specified  *
  2185.  * in the query-spec document in ~postgres/ref  *
  2186.  *  *
  2187.  *****************************************************************************/
  2188. OptimizableStmt:  SelectStmt
  2189. | CursorStmt
  2190. | UpdateStmt
  2191. | InsertStmt
  2192. | NotifyStmt
  2193. | DeleteStmt /* by default all are $$=$1 */
  2194. ;
  2195. /*****************************************************************************
  2196.  *
  2197.  * QUERY:
  2198.  * INSERT STATEMENTS
  2199.  *
  2200.  *****************************************************************************/
  2201. /***S*I***/
  2202. /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
  2203.  * originally. When the second rule of 'insert_rest' was changed to use
  2204.  * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce
  2205.  * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
  2206.  * the same statements without any shift/reduce conflicts */
  2207. InsertStmt:  INSERT INTO relation_name  insert_rest
  2208. {
  2209.   $4->relname = $3;
  2210. $$ = (Node *)$4;
  2211. }
  2212. ;
  2213. insert_rest:  VALUES '(' res_target_list2 ')'
  2214. {
  2215. $$ = makeNode(InsertStmt);
  2216. $$->cols = NULL;
  2217. $$->unique = NULL;
  2218. $$->targetList = $3;
  2219. $$->fromClause = NIL;
  2220. $$->whereClause = NULL;
  2221. $$->groupClause = NIL;
  2222. $$->havingClause = NULL;
  2223. $$->unionClause = NIL;
  2224. }
  2225. | DEFAULT VALUES
  2226. {
  2227. $$ = makeNode(InsertStmt);
  2228. $$->unique = NULL;
  2229. $$->targetList = NIL;
  2230. $$->fromClause = NIL;
  2231. $$->whereClause = NULL;
  2232. $$->groupClause = NIL;
  2233. $$->havingClause = NULL;
  2234. $$->unionClause = NIL;
  2235. /***S*I***/
  2236.   $$->intersectClause = NIL;
  2237. }
  2238. /***S*I***/
  2239. /* We want the full power of SelectStatements including INTERSECT and EXCEPT
  2240.                  * for insertion */
  2241. | SelectStmt
  2242. {
  2243. SelectStmt *n;
  2244. n = (SelectStmt *)$1;
  2245. $$ = makeNode(InsertStmt);
  2246. $$->cols = NULL;
  2247. $$->unique = n->unique;
  2248. $$->targetList = n->targetList;
  2249. $$->fromClause = n->fromClause;
  2250. $$->whereClause = n->whereClause;
  2251. $$->groupClause = n->groupClause;
  2252. $$->havingClause = n->havingClause;
  2253. $$->unionClause = n->unionClause;
  2254. $$->intersectClause = n->intersectClause;
  2255. $$->forUpdate = n->forUpdate;
  2256. }
  2257. | '(' columnList ')' VALUES '(' res_target_list2 ')'
  2258. {
  2259. $$ = makeNode(InsertStmt);
  2260. $$->cols = $2;
  2261. $$->unique = NULL;
  2262. $$->targetList = $6;
  2263. $$->fromClause = NIL;
  2264. $$->whereClause = NULL;
  2265. $$->groupClause = NIL;
  2266. $$->havingClause = NULL;
  2267. $$->unionClause = NIL; 
  2268. /***S*I***/
  2269.   $$->intersectClause = NIL;
  2270. }
  2271. | '(' columnList ')' SelectStmt
  2272. {
  2273. SelectStmt *n;
  2274. n = (SelectStmt *)$4;
  2275. $$ = makeNode(InsertStmt);
  2276. $$->cols = $2;
  2277. $$->unique = n->unique;
  2278. $$->targetList = n->targetList;
  2279. $$->fromClause = n->fromClause;
  2280. $$->whereClause = n->whereClause;
  2281. $$->groupClause = n->groupClause;
  2282. $$->havingClause = n->havingClause;
  2283. $$->unionClause = n->unionClause;
  2284. $$->intersectClause = n->intersectClause;
  2285. }
  2286. ;
  2287. opt_column_list:  '(' columnList ')' { $$ = $2; }
  2288. | /*EMPTY*/ { $$ = NIL; }
  2289. ;
  2290. columnList:
  2291.   columnList ',' columnElem
  2292. { $$ = lappend($1, $3); }
  2293. | columnElem
  2294. { $$ = lcons($1, NIL); }
  2295. ;
  2296. columnElem:  ColId opt_indirection
  2297. {
  2298. Ident *id = makeNode(Ident);
  2299. id->name = $1;
  2300. id->indirection = $2;
  2301. $$ = (Node *)id;
  2302. }
  2303. ;
  2304. /*****************************************************************************
  2305.  *
  2306.  * QUERY:
  2307.  * DELETE STATEMENTS
  2308.  *
  2309.  *****************************************************************************/
  2310. DeleteStmt:  DELETE FROM relation_name
  2311.  where_clause
  2312. {
  2313. DeleteStmt *n = makeNode(DeleteStmt);
  2314. n->relname = $3;
  2315. n->whereClause = $4;
  2316. $$ = (Node *)n;
  2317. }
  2318. ;
  2319. LockStmt: LOCK_P opt_table relation_name opt_lock
  2320. {
  2321. LockStmt *n = makeNode(LockStmt);
  2322. n->relname = $3;
  2323. n->mode = $4;
  2324. $$ = (Node *)n;
  2325. }
  2326. ;
  2327. opt_lock:  IN lock_type MODE { $$ = $2; }
  2328. | /*EMPTY*/ { $$ = AccessExclusiveLock; }
  2329. ;
  2330. lock_type:  SHARE ROW EXCLUSIVE { $$ = ShareRowExclusiveLock; }
  2331. | ROW opt_lmode { $$ = ($2? RowShareLock: RowExclusiveLock); }
  2332. | ACCESS opt_lmode { $$ = ($2? AccessShareLock: AccessExclusiveLock); }
  2333. | opt_lmode { $$ = ($1? ShareLock: ExclusiveLock); }
  2334. ;
  2335. opt_lmode: SHARE { $$ = TRUE; }
  2336. | EXCLUSIVE { $$ = FALSE; }
  2337. ;
  2338. /*****************************************************************************
  2339.  *
  2340.  * QUERY:
  2341.  * UpdateStmt (UPDATE)
  2342.  *
  2343.  *****************************************************************************/
  2344. UpdateStmt:  UPDATE relation_name
  2345.   SET res_target_list
  2346.   from_clause
  2347.   where_clause
  2348. {
  2349. UpdateStmt *n = makeNode(UpdateStmt);
  2350. n->relname = $2;
  2351. n->targetList = $4;
  2352. n->fromClause = $5;
  2353. n->whereClause = $6;
  2354. $$ = (Node *)n;
  2355. }
  2356. ;
  2357. /*****************************************************************************
  2358.  *
  2359.  * QUERY:
  2360.  * CURSOR STATEMENTS
  2361.  *
  2362.  *****************************************************************************/
  2363. /***S*I***/
  2364. CursorStmt:  DECLARE name opt_cursor CURSOR FOR SelectStmt
  2365.    {
  2366.   SelectStmt *n;
  2367.   
  2368.   n= (SelectStmt *)$6;
  2369.    /* from PORTAL name */
  2370.    /*
  2371.     * 15 august 1991 -- since 3.0 postgres does locking
  2372.  * right, we discovered that portals were violating
  2373.  * locking protocol.  portal locks cannot span xacts.
  2374.  * as a short-term fix, we installed the check here.
  2375.  * -- mao
  2376.  */
  2377. if (!IsTransactionBlock())
  2378. elog(ERROR,"Named portals may only be used in begin/end transaction blocks");
  2379. n->portalname = $2;
  2380. n->binary = $3;
  2381. if (n->forUpdate != NULL)
  2382. elog(ERROR,"DECLARE/UPDATE not supported;"
  2383.   " Cursors must be READ ONLY.");
  2384. $$ = (Node *)n;
  2385. }
  2386. ;
  2387. opt_cursor:  BINARY { $$ = TRUE; }
  2388. | INSENSITIVE { $$ = FALSE; }
  2389. | SCROLL { $$ = FALSE; }
  2390. | INSENSITIVE SCROLL { $$ = FALSE; }
  2391. | /*EMPTY*/ { $$ = FALSE; }
  2392. ;
  2393. /*****************************************************************************
  2394.  *
  2395.  * QUERY:
  2396.  * SELECT STATEMENTS
  2397.  *
  2398.  *****************************************************************************/
  2399. /***S*I***/
  2400. /* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT and UNION
  2401.  * accepts the use of '(' and ')' to select an order of set operations.
  2402.  * 
  2403.  * The rule returns a SelectStmt Node having the set operations attached to 
  2404.  * unionClause and intersectClause (NIL if no set operations were present)
  2405.  */
  2406. SelectStmt:   select_clause sort_clause for_update_clause opt_select_limit
  2407. {
  2408. /* There were no set operations, so just attach the sortClause */
  2409. if IsA($1, SelectStmt)
  2410. {
  2411.   SelectStmt *n = (SelectStmt *)$1;
  2412.      n->sortClause = $2;
  2413.   n->forUpdate = $3;
  2414.   n->limitOffset = nth(0, $4);
  2415.   n->limitCount = nth(1, $4);
  2416.   $$ = (Node *)n;
  2417.                 }
  2418. /* There were set operations: The root of the operator tree
  2419.  * is delivered by $1 but we cannot hand back an A_Expr Node.
  2420.  * So we search for the leftmost 'SelectStmt' in the operator
  2421.  * tree $1 (which is the first Select Statement in the query 
  2422.  * typed in by the user or where ever it came from). 
  2423.  * 
  2424.  * Then we attach the whole operator tree to 'intersectClause', 
  2425.  * and a list of all 'SelectStmt' Nodes to 'unionClause' and 
  2426.  * hand back the leftmost 'SelectStmt' Node. (We do it this way
  2427.  * because the following functions (e.g. parse_analyze etc.)
  2428.  * excpect a SelectStmt node and not an operator tree! The whole
  2429.  * tree attached to 'intersectClause' won't be touched by 
  2430.  * parse_analyze() etc. until the function 
  2431.  * Except_Intersect_Rewrite() (in rewriteHandler.c) which performs
  2432.  * the necessary steps to be able create a plan!) */
  2433. else
  2434. {
  2435.   List *select_list = NIL;
  2436.   SelectStmt *first_select;
  2437.   Node *op = (Node *) $1;
  2438.   bool intersect_present = FALSE, unionall_present = FALSE;
  2439.   /* Take the operator tree as an argument and 
  2440.    * create a list of all SelectStmt Nodes found in the tree.
  2441.    *
  2442.    * If one of the SelectStmt Nodes has the 'unionall' flag
  2443.    * set to true the 'unionall_present' flag is also set to
  2444.    * true */
  2445.   create_select_list((Node *)op, &select_list, &unionall_present);
  2446.   /* Replace all the A_Expr Nodes in the operator tree by
  2447.    * Expr Nodes.
  2448.    *
  2449.    * If an INTERSECT or an EXCEPT is present, the 
  2450.    * 'intersect_present' flag is set to true */
  2451.   op = A_Expr_to_Expr(op, &intersect_present);
  2452.   /* If both flags are set to true we have a UNION ALL
  2453.    * statement mixed up with INTERSECT or EXCEPT 
  2454.    * which can not be handled at the moment */
  2455.   if (intersect_present && unionall_present)
  2456.   {
  2457.    elog(ERROR,"UNION ALL not allowed in mixed set operations!");
  2458.   }
  2459.   /* Get the leftmost SeletStmt Node (which automatically
  2460.    * represents the first Select Statement of the query!) */
  2461.   first_select = (SelectStmt *)lfirst(select_list);
  2462.   /* Attach the list of all SeletStmt Nodes to unionClause */
  2463.   first_select->unionClause = select_list;
  2464.   /* Attach the whole operator tree to intersectClause */
  2465.   first_select->intersectClause = (List *) op;
  2466.   /* finally attach the sort clause */
  2467.   first_select->sortClause = $2;
  2468.   first_select->forUpdate = $3;
  2469.   $$ = (Node *)first_select;
  2470. }
  2471. if (((SelectStmt *)$$)->forUpdate != NULL && QueryIsRule)
  2472. elog(ERROR, "SELECT FOR UPDATE is not allowed in RULES");
  2473. }
  2474. ;
  2475. /***S*I***/ 
  2476. /* This rule parses Select statements including UNION INTERSECT and EXCEPT.
  2477.  * '(' and ')' can be used to specify the order of the operations 
  2478.  * (UNION EXCEPT INTERSECT). Without the use of '(' and ')' we want the
  2479.  * operations to be left associative.
  2480.  *
  2481.  *  The sort_clause is not handled here!
  2482.  * 
  2483.  * The rule builds up an operator tree using A_Expr Nodes. AND Nodes represent
  2484.  * INTERSECTs OR Nodes represent UNIONs and AND NOT nodes represent EXCEPTs. 
  2485.  * The SelectStatements to be connected are the left and right arguments to
  2486.  * the A_Expr Nodes.
  2487.  * If no set operations show up in the query the tree consists only of one
  2488.  * SelectStmt Node */
  2489. select_clause: '(' select_clause ')'
  2490. {
  2491. $$ = $2; 
  2492. }
  2493. | SubSelect
  2494. {
  2495. $$ = $1; 
  2496. }
  2497. | select_clause EXCEPT select_clause
  2498. {
  2499. $$ = (Node *)makeA_Expr(AND,NULL,$1,
  2500. makeA_Expr(NOT,NULL,NULL,$3));
  2501. }
  2502. | select_clause UNION opt_union select_clause
  2503. {
  2504. if (IsA($4, SelectStmt))
  2505.   {
  2506.      SelectStmt *n = (SelectStmt *)$4;
  2507.      n->unionall = $3;
  2508.   }
  2509. $$ = (Node *)makeA_Expr(OR,NULL,$1,$4);
  2510. }
  2511. | select_clause INTERSECT select_clause
  2512. {
  2513. $$ = (Node *)makeA_Expr(AND,NULL,$1,$3);
  2514. }
  2515. /***S*I***/
  2516. SubSelect: SELECT opt_unique res_target_list2
  2517.  result from_clause where_clause
  2518.  group_clause having_clause
  2519. {
  2520. SelectStmt *n = makeNode(SelectStmt);
  2521. n->unique = $2;
  2522. n->unionall = FALSE;
  2523. n->targetList = $3;
  2524. /***S*I***/
  2525. /* This is new: Subselects support the INTO clause
  2526.  * which allows queries that are not part of the
  2527.  * SQL92 standard and should not be formulated!
  2528.  * We need it for INTERSECT and EXCEPT and I did not
  2529.  * want to create a new rule 'SubSelect1' including the
  2530.  * feature. If it makes troubles we will have to add 
  2531.  * a new rule and change this to prevent INTOs in 
  2532.  * Subselects again */
  2533. n->istemp = (bool) ((Value *) lfirst($4))->val.ival;
  2534. n->into = (char *) lnext($4);
  2535. n->fromClause = $5;
  2536. n->whereClause = $6;
  2537. n->groupClause = $7;
  2538. n->havingClause = $8;
  2539. $$ = (Node *)n;
  2540. }
  2541. ;
  2542. /* easy way to return two values. Can someone improve this?  bjm */
  2543. result:  INTO OptTemp opt_table relation_name { $$ = lcons(makeInteger($2), (List *)$4); }
  2544. | /*EMPTY*/ { $$ = lcons(makeInteger(false), NIL); }
  2545. ;
  2546. opt_table:  TABLE { $$ = TRUE; }
  2547. | /*EMPTY*/ { $$ = FALSE; }
  2548. ;
  2549. opt_union:  ALL { $$ = TRUE; }
  2550. | /*EMPTY*/ { $$ = FALSE; }
  2551. ;
  2552. opt_unique:  DISTINCT { $$ = "*"; }
  2553. | DISTINCT ON ColId { $$ = $3; }
  2554. | ALL { $$ = NULL; }
  2555. | /*EMPTY*/ { $$ = NULL; }
  2556. ;