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

数据库系统

开发平台:

Unix_Linux

  1. /* Copyright comment */
  2. %{
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include "postgres.h"
  7. #include "access/htup.h"
  8. #include "catalog/catname.h"
  9. #include "utils/numeric.h"
  10. #include "extern.h"
  11. #ifdef MULTIBYTE
  12. #include "mb/pg_wchar.h"
  13. #endif
  14. #define STRUCT_DEPTH 128
  15. /*
  16.  * Variables containing simple states.
  17.  */
  18. int struct_level = 0;
  19. char errortext[128];
  20. static char *connection = NULL;
  21. static int      QueryIsRule = 0, ForUpdateNotAllowed = 0;
  22. static struct this_type actual_type[STRUCT_DEPTH];
  23. static char     *actual_storage[STRUCT_DEPTH];
  24. /* temporarily store struct members while creating the data structure */
  25. struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
  26. struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
  27. struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
  28. struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, {NULL}};
  29. /*
  30.  * Handle the filename and line numbering.
  31.  */
  32. char * input_filename = NULL;
  33. void
  34. output_line_number()
  35. {
  36.     if (input_filename)
  37.        fprintf(yyout, "n#line %d "%s"n", yylineno + 1, input_filename);
  38. }
  39. static void
  40. output_simple_statement(char *cmd)
  41. {
  42. fputs(cmd, yyout);
  43. output_line_number();
  44.         free(cmd);
  45. }
  46. /*
  47.  * store the whenever action here
  48.  */
  49. static struct when when_error, when_nf, when_warn;
  50. static void
  51. print_action(struct when *w)
  52. {
  53. switch (w->code)
  54. {
  55. case W_SQLPRINT: fprintf(yyout, "sqlprint();");
  56.                                  break;
  57. case W_GOTO:  fprintf(yyout, "goto %s;", w->command);
  58.  break;
  59. case W_DO:  fprintf(yyout, "%s;", w->command);
  60.  break;
  61. case W_STOP:  fprintf(yyout, "exit (1);");
  62.  break;
  63. case W_BREAK:  fprintf(yyout, "break;");
  64.  break;
  65. default:  fprintf(yyout, "{/* %d not implemented yet */}", w->code);
  66.  break;
  67. }
  68. }
  69. static void
  70. whenever_action(int mode)
  71. {
  72. if ((mode&1) ==  1 && when_nf.code != W_NOTHING)
  73. {
  74. output_line_number();
  75. fprintf(yyout, "nif (sqlca.sqlcode == ECPG_NOT_FOUND) ");
  76. print_action(&when_nf);
  77. }
  78. if (when_warn.code != W_NOTHING)
  79.         {
  80. output_line_number();
  81.                 fprintf(yyout, "nif (sqlca.sqlwarn[0] == 'W') ");
  82. print_action(&when_warn);
  83.         }
  84. if (when_error.code != W_NOTHING)
  85.         {
  86. output_line_number();
  87.                 fprintf(yyout, "nif (sqlca.sqlcode < 0) ");
  88. print_action(&when_error);
  89.         }
  90. if ((mode&2) == 2)
  91. fputc('}', yyout);
  92. output_line_number();
  93. }
  94. /*
  95.  * Handling of variables.
  96.  */
  97. /*
  98.  * brace level counter
  99.  */
  100. int braces_open;
  101. static struct variable * allvariables = NULL;
  102. static struct variable *
  103. new_variable(const char * name, struct ECPGtype * type)
  104. {
  105.     struct variable * p = (struct variable*) mm_alloc(sizeof(struct variable));
  106.     p->name = mm_strdup(name);
  107.     p->type = type;
  108.     p->brace_level = braces_open;
  109.     p->next = allvariables;
  110.     allvariables = p;
  111.     return(p);
  112. }
  113. static struct variable * find_variable(char * name);
  114. static struct variable *
  115. find_struct_member(char *name, char *str, struct ECPGstruct_member *members)
  116. {
  117.     char *next = strchr(++str, '.'), c = '';
  118.     if (next != NULL)
  119.     {
  120. c = *next;
  121. *next = '';
  122.     }
  123.     for (; members; members = members->next)
  124.     {
  125.         if (strcmp(members->name, str) == 0)
  126. {
  127. if (c == '')
  128. {
  129. /* found the end */
  130. switch (members->typ->typ)
  131. {
  132.    case ECPGt_array:
  133. return(new_variable(name, ECPGmake_array_type(members->typ->u.element, members->typ->size)));
  134.    case ECPGt_struct:
  135.    case ECPGt_union:
  136. return(new_variable(name, ECPGmake_struct_type(members->typ->u.members, members->typ->typ)));
  137.    default:
  138. return(new_variable(name, ECPGmake_simple_type(members->typ->typ, members->typ->size)));
  139. }
  140. }
  141. else
  142. {
  143. *next = c;
  144. if (c == '-')
  145. {
  146. next++;
  147. return(find_struct_member(name, next, members->typ->u.element->u.members));
  148. }
  149. else return(find_struct_member(name, next, members->typ->u.members));
  150. }
  151. }
  152.     }
  153.     return(NULL);
  154. }
  155. static struct variable *
  156. find_struct(char * name, char *next)
  157. {
  158.     struct variable * p;
  159.     char c = *next;
  160.     /* first get the mother structure entry */
  161.     *next = '';
  162.     p = find_variable(name);
  163.     if (c == '-')
  164.     {
  165. if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
  166.         {
  167.                 sprintf(errortext, "variable %s is not a pointer", name);
  168.                 yyerror (errortext);
  169.         }
  170. if (p->type->u.element->typ  != ECPGt_struct && p->type->u.element->typ != ECPGt_union)
  171.         {
  172.                 sprintf(errortext, "variable %s is not a pointer to a structure or a union", name);
  173.                 yyerror (errortext);
  174.         }
  175. /* restore the name, we will need it later on */
  176. *next = c;
  177. next++;
  178. return find_struct_member(name, next, p->type->u.element->u.members);
  179.     }
  180.     else
  181.     {
  182. if (p->type->typ != ECPGt_struct && p->type->typ != ECPGt_union)
  183. {
  184. sprintf(errortext, "variable %s is neither a structure nor a union", name);
  185. yyerror (errortext);
  186. }
  187. /* restore the name, we will need it later on */
  188. *next = c;
  189. return find_struct_member(name, next, p->type->u.members);
  190.     }
  191. }
  192. static struct variable *
  193. find_simple(char * name)
  194. {
  195.     struct variable * p;
  196.     for (p = allvariables; p; p = p->next)
  197.     {
  198.         if (strcmp(p->name, name) == 0)
  199.     return p;
  200.     }
  201.     return(NULL);
  202. }
  203. /* Note that this function will end the program in case of an unknown */
  204. /* variable */
  205. static struct variable *
  206. find_variable(char * name)
  207. {
  208.     char * next;
  209.     struct variable * p;
  210.     if ((next = strchr(name, '.')) != NULL)
  211. p = find_struct(name, next);
  212.     else if ((next = strstr(name, "->")) != NULL)
  213. p = find_struct(name, next);
  214.     else
  215. p = find_simple(name);
  216.     if (p == NULL)
  217.     {
  218. sprintf(errortext, "The variable %s is not declared", name);
  219. yyerror(errortext);
  220.     }
  221.     return(p);
  222. }
  223. static void
  224. remove_variables(int brace_level)
  225. {
  226.     struct variable * p, *prev;
  227.     for (p = prev = allvariables; p; p = p ? p->next : NULL)
  228.     {
  229. if (p->brace_level >= brace_level)
  230. {
  231.     /* remove it */
  232.     if (p == allvariables)
  233. prev = allvariables = p->next;
  234.     else
  235. prev->next = p->next;
  236.     ECPGfree_type(p->type);
  237.     free(p->name);
  238.     free(p);
  239.     p = prev;
  240. }
  241. else
  242.     prev = p;
  243.     }
  244. }
  245. /*
  246.  * Here are the variables that need to be handled on every request.
  247.  * These are of two kinds: input and output.
  248.  * I will make two lists for them.
  249.  */
  250. struct arguments * argsinsert = NULL;
  251. struct arguments * argsresult = NULL;
  252. static void
  253. reset_variables(void)
  254. {
  255.     argsinsert = NULL;
  256.     argsresult = NULL;
  257. }
  258. /* Add a variable to a request. */
  259. static void
  260. add_variable(struct arguments ** list, struct variable * var, struct variable * ind)
  261. {
  262.     struct arguments * p = (struct arguments *)mm_alloc(sizeof(struct arguments));
  263.     p->variable = var;
  264.     p->indicator = ind;
  265.     p->next = *list;
  266.     *list = p;
  267. }
  268. /* Dump out a list of all the variable on this list.
  269.    This is a recursive function that works from the end of the list and
  270.    deletes the list as we go on.
  271.  */
  272. static void
  273. dump_variables(struct arguments * list, int mode)
  274. {
  275.     if (list == NULL)
  276.     {
  277.         return;
  278.     }
  279.     /* The list is build up from the beginning so lets first dump the
  280.        end of the list:
  281.      */
  282.     dump_variables(list->next, mode);
  283.     /* Then the current element and its indicator */
  284.     ECPGdump_a_type(yyout, list->variable->name, list->variable->type,
  285. (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL,
  286. (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);
  287.     /* Then release the list element. */
  288.     if (mode != 0)
  289.      free(list);
  290. }
  291. static void
  292. check_indicator(struct ECPGtype *var)
  293. {
  294. /* make sure this is a valid indicator variable */
  295. switch (var->typ)
  296. {
  297. struct ECPGstruct_member *p;
  298. case ECPGt_short:
  299. case ECPGt_int:
  300. case ECPGt_long:
  301. case ECPGt_unsigned_short:
  302. case ECPGt_unsigned_int:
  303. case ECPGt_unsigned_long:
  304. break;
  305. case ECPGt_struct:
  306. case ECPGt_union:
  307. for (p = var->u.members; p; p = p->next)
  308. check_indicator(p->typ);
  309. break;
  310. case ECPGt_array:
  311. check_indicator(var->u.element);
  312. break;
  313. default: 
  314. yyerror ("indicator variable must be integer type");
  315. break;
  316. }
  317. }
  318. static char *
  319. make1_str(const char *str)
  320. {
  321.         char * res_str = (char *)mm_alloc(strlen(str) + 1);
  322. strcpy(res_str, str);
  323. return res_str;
  324. }
  325. static char *
  326. make2_str(char *str1, char *str2)
  327. char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
  328. strcpy(res_str, str1);
  329. strcat(res_str, str2);
  330. free(str1);
  331. free(str2);
  332. return(res_str);
  333. }
  334. static char *
  335. cat2_str(char *str1, char *str2)
  336. char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
  337. strcpy(res_str, str1);
  338. strcat(res_str, " ");
  339. strcat(res_str, str2);
  340. free(str1);
  341. free(str2);
  342. return(res_str);
  343. }
  344. static char *
  345. make3_str(char *str1, char *str2, char * str3)
  346. {    
  347.         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 1);
  348.      
  349.         strcpy(res_str, str1);
  350.         strcat(res_str, str2);
  351. strcat(res_str, str3);
  352. free(str1);
  353. free(str2);
  354. free(str3);
  355.         return(res_str);
  356. }    
  357. static char *
  358. cat3_str(char *str1, char *str2, char * str3)
  359. {    
  360.         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + 3);
  361.      
  362.         strcpy(res_str, str1);
  363. strcat(res_str, " ");
  364.         strcat(res_str, str2);
  365. strcat(res_str, " ");
  366. strcat(res_str, str3);
  367. free(str1);
  368. free(str2);
  369. free(str3);
  370.         return(res_str);
  371. }    
  372. static char *
  373. make4_str(char *str1, char *str2, char *str3, char *str4)
  374. {    
  375.         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1);
  376.      
  377.         strcpy(res_str, str1);
  378.         strcat(res_str, str2);
  379. strcat(res_str, str3);
  380. strcat(res_str, str4);
  381. free(str1);
  382. free(str2);
  383. free(str3);
  384. free(str4);
  385.         return(res_str);
  386. }
  387. static char *
  388. cat4_str(char *str1, char *str2, char *str3, char *str4)
  389. {    
  390.         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 4);
  391.      
  392.         strcpy(res_str, str1);
  393. strcat(res_str, " ");
  394.         strcat(res_str, str2);
  395. strcat(res_str, " ");
  396. strcat(res_str, str3);
  397. strcat(res_str, " ");
  398. strcat(res_str, str4);
  399. free(str1);
  400. free(str2);
  401. free(str3);
  402. free(str4);
  403.         return(res_str);
  404. }
  405. static char *
  406. make5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
  407. {    
  408.         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 1);
  409.      
  410.         strcpy(res_str, str1);
  411.         strcat(res_str, str2);
  412. strcat(res_str, str3);
  413. strcat(res_str, str4);
  414. strcat(res_str, str5);
  415. free(str1);
  416. free(str2);
  417. free(str3);
  418. free(str4);
  419. free(str5);
  420.         return(res_str);
  421. }    
  422. static char *
  423. cat5_str(char *str1, char *str2, char *str3, char *str4, char *str5)
  424. {    
  425.         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + strlen(str5) + 5);
  426.      
  427.         strcpy(res_str, str1);
  428. strcat(res_str, " ");
  429.         strcat(res_str, str2);
  430. strcat(res_str, " ");
  431. strcat(res_str, str3);
  432. strcat(res_str, " ");
  433. strcat(res_str, str4);
  434. strcat(res_str, " ");
  435. strcat(res_str, str5);
  436. free(str1);
  437. free(str2);
  438. free(str3);
  439. free(str4);
  440. free(str5);
  441.         return(res_str);
  442. }    
  443. static char *
  444. make_name(void)
  445. {
  446. char * name = (char *)mm_alloc(yyleng + 1);
  447. strncpy(name, yytext, yyleng);
  448. name[yyleng] = '';
  449. return(name);
  450. }
  451. static void
  452. output_statement(char * stmt, int mode)
  453. {
  454. int i, j=strlen(stmt);
  455. fprintf(yyout, "{ ECPGdo(__LINE__, %s, "", connection ? connection : "NULL");
  456. /* do this char by char as we have to filter '"' */
  457. for (i = 0;i < j; i++)
  458. if (stmt[i] != '"')
  459. fputc(stmt[i], yyout);
  460. fputs("", ", yyout);
  461. /* dump variables to C file*/
  462. dump_variables(argsinsert, 1);
  463. fputs("ECPGt_EOIT, ", yyout);
  464. dump_variables(argsresult, 1);
  465. fputs("ECPGt_EORT);", yyout);
  466. mode |= 2;
  467. whenever_action(mode);
  468. free(stmt);
  469. if (connection != NULL)
  470. free(connection);
  471. }
  472. static struct typedefs *
  473. get_typedef(char *name)
  474. {
  475. struct typedefs *this;
  476. for (this = types; this && strcmp(this->name, name); this = this->next);
  477. if (!this)
  478. {
  479. sprintf(errortext, "invalid datatype '%s'", name);
  480. yyerror(errortext);
  481. }
  482. return(this);
  483. }
  484. static void
  485. adjust_array(enum ECPGttype type_enum, int *dimension, int *length, int type_dimension, int type_index, bool pointer)
  486. {
  487. if (type_index >= 0) 
  488. {
  489. if (*length >= 0)
  490.                        yyerror("No multi-dimensional array support");
  491. *length = type_index;
  492. }
  493.        
  494. if (type_dimension >= 0)
  495. {
  496. if (*dimension >= 0 && *length >= 0)
  497. yyerror("No multi-dimensional array support");
  498. if (*dimension >= 0)
  499. *length = *dimension;
  500. *dimension = type_dimension;
  501. }
  502. if (*length >= 0 && *dimension >= 0 && pointer)
  503. yyerror("No multi-dimensional array support");
  504. switch (type_enum)
  505. {
  506.    case ECPGt_struct:
  507.    case ECPGt_union:
  508.         /* pointer has to get dimension 0 */
  509.                 if (pointer)
  510.         {
  511.     *length = *dimension;
  512.                     *dimension = 0;
  513.         }
  514.                 if (*length >= 0)
  515.                    yyerror("No multi-dimensional array support for structures");
  516.                 break;
  517.            case ECPGt_varchar:
  518.         /* pointer has to get dimension 0 */
  519.                 if (pointer)
  520.                     *dimension = 0;
  521.                 /* one index is the string length */
  522.                 if (*length < 0)
  523.                 {
  524.                    *length = *dimension;
  525.                    *dimension = -1;
  526.                 }
  527.                 break;
  528.            case ECPGt_char:
  529.            case ECPGt_unsigned_char:
  530.         /* pointer has to get length 0 */
  531.                 if (pointer)
  532.                     *length=0;
  533.                 /* one index is the string length */
  534.                 if (*length < 0)
  535.                 {
  536.                    *length = (*dimension < 0) ? 1 : *dimension;
  537.                    *dimension = -1;
  538.                 }
  539.                 break;
  540.            default:
  541.           /* a pointer has dimension = 0 */
  542.                 if (pointer) {
  543.                     *length = *dimension;
  544.     *dimension = 0;
  545.         }
  546.                 if (*length >= 0)
  547.                    yyerror("No multi-dimensional array support for simple data types");
  548.                 break;
  549. }
  550. }
  551. %}
  552. %union {
  553. double                  dval;
  554.         int                     ival;
  555. char *                  str;
  556. struct when             action;
  557. struct index index;
  558. int tagname;
  559. struct this_type type;
  560. enum ECPGttype type_enum;
  561. }
  562. /* special embedded SQL token */
  563. %token SQL_AT SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK 
  564. %token SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE
  565. %token SQL_DEALLOCATE SQL_DISCONNECT SQL_ENUM 
  566. %token SQL_FOUND SQL_FREE SQL_GO SQL_GOTO
  567. %token SQL_IDENTIFIED SQL_IMMEDIATE SQL_INDICATOR SQL_INT SQL_LONG
  568. %token SQL_OFF SQL_OPEN SQL_PREPARE SQL_RELEASE SQL_REFERENCE
  569. %token SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQLERROR SQL_SQLPRINT
  570. %token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED
  571. %token SQL_VAR SQL_WHENEVER
  572. /* C token */
  573. %token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_ENUM S_EXTERN
  574. %token S_FLOAT S_INT S
  575. %token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
  576. %token S_UNION S_UNSIGNED S_VARCHAR
  577. /* I need this and don't know where it is defined inside the backend */
  578. %token TYPECAST
  579. /* Keywords (in SQL92 reserved words) */
  580. %token  ABSOLUTE, ACTION, ADD, ALL, ALTER, AND, ANY, AS, ASC,
  581.                 BEGIN_TRANS, BETWEEN, BOTH, BY,
  582.                 CASCADE, CASE, CAST, CHAR, CHARACTER, CHECK, CLOSE,
  583. COALESCE, COLLATE, COLUMN, COMMIT, 
  584.                 CONSTRAINT, CREATE, CROSS, CURRENT, CURRENT_DATE, CURRENT_TIME, 
  585.                 CURRENT_TIMESTAMP, CURRENT_USER, CURSOR,
  586.                 DAY_P, DECIMAL, DECLARE, DEFAULT, DELETE, DESC, DISTINCT, DOUBLE, DROP,
  587.                 ELSE, END_TRANS, EXCEPT, EXECUTE, EXISTS, EXTRACT,
  588.                 FALSE_P, FETCH, FLOAT, FOR, FOREIGN, FROM, FULL,
  589.                 GLOBAL, GRANT, GROUP, HAVING, HOUR_P,
  590.                 IN, INNER_P, INSENSITIVE, INSERT, INTERSECT, INTERVAL, INTO, IS,
  591.                 ISOLATION, JOIN, KEY, LANGUAGE, LEADING, LEFT, LEVEL, LIKE, LOCAL,
  592.                 MATCH, MINUTE_P, MONTH_P, NAMES,
  593.                 NATIONAL, NATURAL, NCHAR, NEXT, NO, NOT, NULLIF, NULL_P, NUMERIC,
  594.                 OF, ON, ONLY, OPTION, OR, ORDER, OUTER_P,
  595.                 PARTIAL, POSITION, PRECISION, PRIMARY, PRIOR, PRIVILEGES, PROCEDURE, PUBLIC,
  596.                 READ, REFERENCES, RELATIVE, REVOKE, RIGHT, ROLLBACK,
  597.                 SCROLL, SECOND_P, SELECT, SET, SUBSTRING,
  598.                 TABLE, TEMP, TEMPORARY, THEN, TIME, TIMESTAMP, TIMEZONE_HOUR,
  599. TIMEZONE_MINUTE, TO, TRAILING, TRANSACTION, TRIM, TRUE_P,
  600.                 UNION, UNIQUE, UPDATE, USER, USING,
  601.                 VALUES, VARCHAR, VARYING, VIEW,
  602.                 WHEN, WHERE, WITH, WORK, YEAR_P, ZONE
  603. /* Keywords (in SQL3 reserved words) */
  604. %token  TRIGGER
  605. /* Keywords (in SQL92 non-reserved words) */
  606. %token  COMMITTED, SERIALIZABLE, TYPE_P
  607. /* Keywords for Postgres support (not in SQL92 reserved words)
  608.  *
  609.  * The CREATEDB and CREATEUSER tokens should go away
  610.  * when some sort of pg_privileges relation is introduced.
  611.  * - Todd A. Brandys 1998-01-01?
  612.  */
  613. %token  ABORT_TRANS, ACCESS, AFTER, AGGREGATE, ANALYZE,
  614. BACKWARD, BEFORE, BINARY,
  615. CACHE, CLUSTER, COPY, CREATEDB, CREATEUSER, CYCLE,
  616.                 DATABASE, DELIMITERS, DO,
  617. EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND,
  618.                 FORWARD, FUNCTION, HANDLER,
  619.                 INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL,
  620.                 LANCOMPILER, LIMIT, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P,
  621. MAXVALUE, MINVALUE, MODE, MOVE,
  622.                 NEW,  NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL,
  623. OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
  624.                 RENAME, RESET, RETURNS, ROW, RULE,
  625.                 SERIAL, SEQUENCE, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT,
  626. TRUSTED,
  627.                 UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
  628. /* Special keywords, not in the query language - see the "lex" file */
  629. %token <str>    IDENT SCONST Op CSTRING CVARIABLE CPP_LINE
  630. %token <ival>   ICONST PARAM
  631. %token <dval>   FCONST
  632. /* these are not real. they are here so that they get generated as #define's*/
  633. %token                  OP
  634. /* precedence */
  635. %left OR
  636. %left AND
  637. %right NOT
  638. %right '='
  639. %nonassoc '<' '>'
  640. %nonassoc LIKE
  641. %nonassoc BETWEEN
  642. %nonassoc IN
  643. %left Op /* multi-character ops and user-defined operators */
  644. %nonassoc NOTNULL
  645. %nonassoc ISNULL
  646. %nonassoc NULL_P
  647. %nonassoc IS
  648. %left '+' '-'
  649. %left '*' '/' '%'
  650. %left '|' /* this is the relation union op, not logical or */
  651. /* Unary Operators */
  652. %right ':'
  653. %left ';' /* end of statement or natural log */
  654. %right UMINUS
  655. %left '.'
  656. %left '[' ']'
  657. %nonassoc TYPECAST
  658. %left UNION INTERSECT EXCEPT
  659. %type  <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
  660. %type  <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
  661. %type  <str> OptInherit key_reference key_action
  662. %type  <str>    key_match constraint_expr ColLabel SpecialRuleRelation
  663. %type  <str>  ColId default_expr ColQualifier columnDef ColQualList
  664. %type  <str>    ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
  665. %type  <str>    OptTableElementList OptTableElement TableConstraint
  666. %type  <str>    ConstraintElem key_actions constraint_list ColPrimaryKey
  667. %type  <str>    res_target_list res_target_el res_target_list2
  668. %type  <str>    res_target_el2 opt_id relation_name database_name
  669. %type  <str>    access_method attr_name class index_name name func_name
  670. %type  <str>    file_name AexprConst ParamNo TypeId
  671. %type  <str> in_expr_nodes not_in_expr_nodes a_expr b_expr
  672. %type  <str>  opt_indirection expr_list extract_list extract_arg
  673. %type  <str> position_list position_expr substr_list substr_from
  674. %type  <str> trim_list in_expr substr_for not_in_expr attr attrs
  675. %type  <str> Typename Array Generic Numeric generic opt_float opt_numeric
  676. %type  <str>  opt_decimal Character character opt_varying opt_charset
  677. %type  <str> opt_collate Datetime datetime opt_timezone opt_interval
  678. %type  <str> numeric a_expr_or_null row_expr row_descriptor row_list
  679. %type  <str> SelectStmt SubSelect result OptTemp OptTempType OptTempScope
  680. %type  <str> opt_table opt_union opt_unique sort_clause sortby_list
  681. %type  <str> sortby OptUseOp opt_inh_star relation_name_list name_list
  682. %type  <str> group_clause having_clause from_clause c_list 
  683. %type  <str> table_list join_outer where_clause relation_expr row_op sub_type
  684. %type  <str> opt_column_list insert_rest InsertStmt OptimizableStmt
  685. %type  <str>    columnList DeleteStmt LockStmt UpdateStmt CursorStmt
  686. %type  <str>    NotifyStmt columnElem copy_dirn c_expr UnlistenStmt
  687. %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
  688. %type  <str>    opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
  689. %type  <str>    ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
  690. %type  <str>    opt_analyze opt_va_list va_list ExplainStmt index_params
  691. %type  <str>    index_list func_index index_elem opt_type opt_class access_method_clause
  692. %type  <str>    index_opt_unique IndexStmt set_opt func_return def_rest
  693. %type  <str>    func_args_list func_args opt_with ProcedureStmt def_arg
  694. %type  <str>    def_elem def_list definition def_name def_type DefineStmt
  695. %type  <str>    opt_instead event event_object RuleActionList,
  696. %type  <str> RuleActionBlock RuleActionMulti join_list
  697. %type  <str>    RuleStmt opt_column opt_name oper_argtypes
  698. %type  <str>    MathOp RemoveFuncStmt aggr_argtype for_update_clause
  699. %type  <str>    RemoveAggrStmt remove_type RemoveStmt ExtendStmt
  700. %type  <str>    RemoveOperStmt RenameStmt all_Op user_valid_clause
  701. %type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
  702. %type  <str>    VariableResetStmt AddAttrStmt alter_clause DropUserStmt
  703. %type  <str>    user_passwd_clause user_createdb_clause opt_trans
  704. %type  <str>    user_createuser_clause user_group_list user_group_clause
  705. %type  <str>    CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
  706. %type  <str>    OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
  707. %type  <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
  708. %type  <str>    TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
  709. %type  <str>    CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
  710. %type  <str>    ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
  711. %type  <str>    DestroydbStmt ClusterStmt grantee RevokeStmt encoding
  712. %type  <str> GrantStmt privileges operation_commalist operation
  713. %type  <str> opt_cursor opt_lmode
  714. %type  <str> case_expr when_clause_list case_default case_arg when_clause
  715. %type  <str>    select_clause opt_select_limit select_limit_value
  716. %type  <str>    select_offset_value table_list using_expr join_expr
  717. %type  <str> using_list from_expr table_expr join_clause join_type
  718. %type  <str> join_qual update_list join_clause join_clause_with_union
  719. %type  <str> opt_level opt_lock lock_type
  720. %type  <str> ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
  721. %type  <str> indicator ECPGExecute ecpg_expr dotext ECPGPrepare
  722. %type  <str>    storage_clause opt_initializer vartext c_anything blockstart
  723. %type  <str>    blockend variable_list variable var_anything do_anything
  724. %type  <str> opt_pointer cvariable ECPGDisconnect dis_name
  725. %type  <str> stmt symbol opt_symbol ECPGRelease execstring server_name
  726. %type  <str> connection_object opt_server opt_port c_thing opt_reference
  727. %type  <str>    user_name opt_user char_variable ora_user ident
  728. %type  <str>    db_prefix server opt_options opt_connection_name
  729. %type  <str> ECPGSetConnection c_line cpp_line s_enum ECPGTypedef
  730. %type  <str> enum_type civariableonly ECPGCursorStmt ECPGDeallocate
  731. %type  <str> ECPGFree ECPGDeclare ECPGVar sql_variable_declarations
  732. %type  <str> sql_declaration sql_variable_list sql_variable opt_at
  733. %type  <str>    struct_type s_struct declaration variable_declarations
  734. %type  <str>    s_struct s_union union_type ECPGSetAutocommit on_off
  735. %type  <type_enum> simple_type varchar_type
  736. %type  <type> type ctype
  737. %type  <action> action
  738. %type  <index> opt_array_bounds nest_array_bounds opt_type_array_bounds
  739. %type  <index>  nest_type_array_bounds
  740. %type  <ival> Iresult
  741. %%
  742. prog: statements;
  743. statements: /* empty */
  744. | statements statement
  745. statement: ecpgstart opt_at stmt ';' { connection = NULL; }
  746. | ecpgstart stmt ';'
  747. | ECPGDeclaration
  748. | c_thing  { fprintf(yyout, "%s", $1); free($1); }
  749. | cpp_line { fprintf(yyout, "%s", $1); free($1); }
  750. | blockstart { fputs($1, yyout); free($1); }
  751. | blockend { fputs($1, yyout); free($1); }
  752. opt_at: SQL_AT connection_target { connection = $2; }
  753. stmt:  AddAttrStmt { output_statement($1, 0); }
  754. | AlterUserStmt { output_statement($1, 0); }
  755. | ClosePortalStmt { output_statement($1, 0); }
  756. | CopyStmt { output_statement($1, 0); }
  757. | CreateStmt { output_statement($1, 0); }
  758. | CreateAsStmt { output_statement($1, 0); }
  759. | CreateSeqStmt { output_statement($1, 0); }
  760. | CreatePLangStmt { output_statement($1, 0); }
  761. | CreateTrigStmt { output_statement($1, 0); }
  762. | CreateUserStmt { output_statement($1, 0); }
  763.    | ClusterStmt { output_statement($1, 0); }
  764. | DefineStmt  { output_statement($1, 0); }
  765. | DestroyStmt { output_statement($1, 0); }
  766. | DropPLangStmt { output_statement($1, 0); }
  767. | DropTrigStmt { output_statement($1, 0); }
  768. | DropUserStmt { output_statement($1, 0); }
  769. | ExtendStmt  { output_statement($1, 0); }
  770. | ExplainStmt { output_statement($1, 0); }
  771. | FetchStmt { output_statement($1, 1); }
  772. | GrantStmt { output_statement($1, 0); }
  773. | IndexStmt { output_statement($1, 0); }
  774. | ListenStmt { output_statement($1, 0); }
  775. | UnlistenStmt { output_statement($1, 0); }
  776. | LockStmt { output_statement($1, 0); }
  777. | ProcedureStmt { output_statement($1, 0); }
  778. | RemoveAggrStmt { output_statement($1, 0); }
  779. | RemoveOperStmt { output_statement($1, 0); }
  780. | RemoveFuncStmt { output_statement($1, 0); }
  781. | RemoveStmt { output_statement($1, 0); }
  782. | RenameStmt { output_statement($1, 0); }
  783. | RevokeStmt { output_statement($1, 0); }
  784.                 | OptimizableStmt {
  785. if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
  786. output_simple_statement($1);
  787. else
  788. output_statement($1, 1);
  789. }
  790. | RuleStmt { output_statement($1, 0); }
  791. | TransactionStmt {
  792. fprintf(yyout, "{ ECPGtrans(__LINE__, %s, "%s");", connection ? connection : "NULL", $1);
  793. whenever_action(2);
  794. free($1);
  795. }
  796. | ViewStmt { output_statement($1, 0); }
  797. | LoadStmt { output_statement($1, 0); }
  798. | CreatedbStmt { output_statement($1, 0); }
  799. | DestroydbStmt { output_statement($1, 0); }
  800. | VacuumStmt { output_statement($1, 0); }
  801. | VariableSetStmt { output_statement($1, 0); }
  802. | VariableShowStmt { output_statement($1, 0); }
  803. | VariableResetStmt { output_statement($1, 0); }
  804. | ECPGConnect {
  805. if (connection)
  806. yyerror("no at option for connect statement.n");
  807. fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d);", $1, autocommit);
  808. whenever_action(2);
  809. free($1);
  810. | ECPGCursorStmt {
  811. output_simple_statement($1);
  812. }
  813. | ECPGDeallocate {
  814. if (connection)
  815. yyerror("no at option for connect statement.n");
  816. fputc('{', yyout);
  817. fputs($1, yyout);
  818. whenever_action(2);
  819. free($1);
  820. }
  821. | ECPGDeclare {
  822. output_simple_statement($1);
  823. }
  824. | ECPGDisconnect {
  825. if (connection)
  826. yyerror("no at option for disconnect statement.n");
  827. fprintf(yyout, "{ ECPGdisconnect(__LINE__, "%s");", $1); 
  828. whenever_action(2);
  829. free($1);
  830. | ECPGExecute {
  831. output_statement($1, 0);
  832. }
  833. | ECPGFree {
  834. fprintf(yyout, "{ ECPGdeallocate(__LINE__, %s, "%s");", connection ? connection : "NULL", $1); 
  835. whenever_action(2);
  836. free($1);
  837. }
  838. | ECPGOpen {
  839. struct cursor *ptr;
  840.  
  841. for (ptr = cur; ptr != NULL; ptr=ptr->next)
  842. {
  843.                if (strcmp(ptr->name, $1) == 0)
  844.         break;
  845. }
  846. if (ptr == NULL)
  847. {
  848. sprintf(errortext, "trying to open undeclared cursor %sn", $1);
  849. yyerror(errortext);
  850. }
  851.                   
  852. fprintf(yyout, "{ ECPGdo(__LINE__, %s, "%s",", ptr->connection ? ptr->connection : "NULL", ptr->command);
  853. /* dump variables to C file*/
  854. dump_variables(ptr->argsinsert, 0);
  855. dump_variables(argsinsert, 0);
  856. fputs("ECPGt_EOIT, ", yyout);
  857. dump_variables(ptr->argsresult, 0);
  858. fputs("ECPGt_EORT);", yyout);
  859. whenever_action(2);
  860. free($1);
  861. }
  862. | ECPGPrepare {
  863. if (connection)
  864. yyerror("no at option for set connection statement.n");
  865. fprintf(yyout, "{ ECPGprepare(__LINE__, %s);", $1); 
  866. whenever_action(2);
  867. free($1);
  868. }
  869. | ECPGRelease { /* output already done */ }
  870. | ECPGSetAutocommit     {
  871. fprintf(yyout, "{ ECPGsetcommit(__LINE__, "%s", %s);", $1, connection ? connection : "NULL");
  872. whenever_action(2);
  873.                                         free($1);
  874. }
  875. | ECPGSetConnection     {
  876. if (connection)
  877. yyerror("no at option for set connection statement.n");
  878. fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
  879. whenever_action(2);
  880.                                         free($1);
  881. }
  882. | ECPGTypedef {
  883. if (connection)
  884. yyerror("no at option for typedef statement.n");
  885. output_simple_statement($1);
  886. }
  887. | ECPGVar {
  888. if (connection)
  889. yyerror("no at option for var statement.n");
  890. output_simple_statement($1);
  891. }
  892. | ECPGWhenever {
  893. if (connection)
  894. yyerror("no at option for whenever statement.n");
  895. output_simple_statement($1);
  896. }
  897. ;
  898. /*
  899.  * We start with a lot of stuff that's very similar to the backend's parsing
  900.  */
  901. /*****************************************************************************
  902.  *
  903.  * Create a new Postgres DBMS user
  904.  *
  905.  *
  906.  *****************************************************************************/
  907. CreateUserStmt:  CREATE USER UserId user_passwd_clause user_createdb_clause
  908. user_createuser_clause user_group_clause user_valid_clause
  909. {
  910. $$ = cat3_str(cat5_str(make1_str("create user"), $3, $4, $5, $6), $7, $8);
  911. }
  912. ;
  913. /*****************************************************************************
  914.  *
  915.  * Alter a postresql DBMS user
  916.  *
  917.  *
  918.  *****************************************************************************/
  919. AlterUserStmt:  ALTER USER UserId user_passwd_clause user_createdb_clause
  920. user_createuser_clause user_group_clause user_valid_clause
  921. {
  922. $$ = cat3_str(cat5_str(make1_str("alter user"), $3, $4, $5, $6), $7, $8);
  923. }
  924. ;
  925. /*****************************************************************************
  926.  *
  927.  * Drop a postresql DBMS user
  928.  *
  929.  *
  930.  *****************************************************************************/
  931. DropUserStmt:  DROP USER UserId
  932. {
  933. $$ = cat2_str(make1_str("drop user"), $3);
  934. }
  935. ;
  936. user_passwd_clause:  WITH PASSWORD UserId { $$ = cat2_str(make1_str("with password") , $3); }
  937. | /*EMPTY*/ { $$ = make1_str(""); }
  938. ;
  939. user_createdb_clause:  CREATEDB
  940. {
  941. $$ = make1_str("createdb");
  942. }
  943. | NOCREATEDB
  944. {
  945. $$ = make1_str("nocreatedb");
  946. }
  947. | /*EMPTY*/ { $$ = make1_str(""); }
  948. ;
  949. user_createuser_clause:  CREATEUSER
  950. {
  951. $$ = make1_str("createuser");
  952. }
  953. | NOCREATEUSER
  954. {
  955. $$ = make1_str("nocreateuser");
  956. }
  957. | /*EMPTY*/ { $$ = NULL; }
  958. ;
  959. user_group_list:  user_group_list ',' UserId
  960. {
  961. $$ = cat3_str($1, make1_str(","), $3);
  962. }
  963. | UserId
  964. {
  965. $$ = $1;
  966. }
  967. ;
  968. user_group_clause:  IN GROUP user_group_list { $$ = cat2_str(make1_str("in group"), $3); }
  969. | /*EMPTY*/ { $$ = make1_str(""); }
  970. ;
  971. user_valid_clause:  VALID UNTIL Sconst { $$ = cat2_str(make1_str("valid until"), $3); }
  972. | /*EMPTY*/ { $$ = make1_str(""); }
  973. ;
  974. /*****************************************************************************
  975.  *
  976.  * Set PG internal variable
  977.  *   SET name TO 'var_value'
  978.  * Include SQL92 syntax (thomas 1997-10-22):
  979.  *    SET TIME ZONE 'var_value'
  980.  *
  981.  *****************************************************************************/
  982. VariableSetStmt:  SET ColId TO var_value
  983. {
  984. $$ = cat4_str(make1_str("set"), $2, make1_str("to"), $4);
  985. }
  986. | SET ColId '=' var_value
  987. {
  988. $$ = cat4_str(make1_str("set"), $2, make1_str("="), $4);
  989. }
  990. | SET TIME ZONE zone_value
  991. {
  992. $$ = cat2_str(make1_str("set time zone"), $4);
  993. }
  994. | SET TRANSACTION ISOLATION LEVEL opt_level
  995. {
  996. $$ = cat2_str(make1_str("set transaction isolation level"), $5);
  997. }
  998. | SET NAMES encoding
  999.                                 {
  1000. #ifdef MB
  1001. $$ = cat2_str(make1_str("set names"), $3);
  1002. #else
  1003.                                         yyerror("SET NAMES is not supported");
  1004. #endif
  1005.                                 }
  1006.                 ;
  1007. opt_level:  READ COMMITTED      { $$ = make1_str("read committed"); }
  1008.                | SERIALIZABLE   { $$ = make1_str("serializable"); }
  1009.                ;
  1010. var_value:  Sconst { $$ = $1; }
  1011. | DEFAULT { $$ = make1_str("default"); }
  1012. ;
  1013. zone_value:  Sconst { $$ = $1; }
  1014. | DEFAULT { $$ = make1_str("default"); }
  1015. | LOCAL { $$ = make1_str("local"); }
  1016. ;
  1017. VariableShowStmt:  SHOW ColId
  1018. {
  1019. $$ = cat2_str(make1_str("show"), $2);
  1020. }
  1021. | SHOW TIME ZONE
  1022. {
  1023. $$ = make1_str("show time zone");
  1024. }
  1025. | SHOW TRANSACTION ISOLATION LEVEL
  1026. {
  1027. $$ = make1_str("show transaction isolation level");
  1028. }
  1029. ;
  1030. VariableResetStmt: RESET ColId
  1031. {
  1032. $$ = cat2_str(make1_str("reset"), $2);
  1033. }
  1034. | RESET TIME ZONE
  1035. {
  1036. $$ = make1_str("reset time zone");
  1037. }
  1038. | RESET TRANSACTION ISOLATION LEVEL
  1039. {
  1040. $$ = make1_str("reset transaction isolation level");
  1041. }
  1042. ;
  1043. /*****************************************************************************
  1044.  *
  1045.  * QUERY :
  1046.  * addattr ( attr1 = type1 .. attrn = typen ) to <relname> [*]
  1047.  *
  1048.  *****************************************************************************/
  1049. AddAttrStmt:  ALTER TABLE relation_name opt_inh_star alter_clause
  1050. {
  1051. $$ = cat4_str(make1_str("alter table"), $3, $4, $5);
  1052. }
  1053. ;
  1054. alter_clause:  ADD opt_column columnDef
  1055. {
  1056. $$ = cat3_str(make1_str("add"), $2, $3);
  1057. }
  1058. | ADD '(' OptTableElementList ')'
  1059. {
  1060. $$ = make3_str(make1_str("add("), $3, make1_str(")"));
  1061. }
  1062. | DROP opt_column ColId
  1063. { yyerror("ALTER TABLE/DROP COLUMN not yet implemented"); }
  1064. | ALTER opt_column ColId SET DEFAULT default_expr
  1065. { yyerror("ALTER TABLE/ALTER COLUMN/SET DEFAULT not yet implemented"); }
  1066. | ALTER opt_column ColId DROP DEFAULT
  1067. { yyerror("ALTER TABLE/ALTER COLUMN/DROP DEFAULT not yet implemented"); }
  1068. | ADD ConstraintElem
  1069. { yyerror("ALTER TABLE/ADD CONSTRAINT not yet implemented"); }
  1070. ;
  1071. /*****************************************************************************
  1072.  *
  1073.  * QUERY :
  1074.  * close <optname>
  1075.  *
  1076.  *****************************************************************************/
  1077. ClosePortalStmt:  CLOSE opt_id
  1078. {
  1079. $$ = cat2_str(make1_str("close"), $2);
  1080. }
  1081. ;
  1082. /*****************************************************************************
  1083.  *
  1084.  * QUERY :
  1085.  * COPY [BINARY] <relname> FROM/TO
  1086.  * [USING DELIMITERS <delimiter>]
  1087.  *
  1088.  *****************************************************************************/
  1089. CopyStmt:  COPY opt_binary relation_name opt_with_copy copy_dirn copy_file_name copy_delimiter
  1090. {
  1091. $$ = cat3_str(cat5_str(make1_str("copy"), $2, $3, $4, $5), $6, $7);
  1092. }
  1093. ;
  1094. copy_dirn: TO
  1095. { $$ = make1_str("to"); }
  1096. | FROM
  1097. { $$ = make1_str("from"); }
  1098. ;
  1099. /*
  1100.  * copy_file_name NULL indicates stdio is used. Whether stdin or stdout is
  1101.  * used depends on the direction. (It really doesn't make sense to copy from
  1102.  * stdout. We silently correct the "typo".  - AY 9/94
  1103.  */
  1104. copy_file_name:  Sconst { $$ = $1; }
  1105. | STDIN { $$ = make1_str("stdin"); }
  1106. | STDOUT { $$ = make1_str("stdout"); }
  1107. ;
  1108. opt_binary:  BINARY { $$ = make1_str("binary"); }
  1109. | /*EMPTY*/ { $$ = make1_str(""); }
  1110. ;
  1111. opt_with_copy: WITH OIDS { $$ = make1_str("with oids"); }
  1112. | /*EMPTY*/ { $$ = make1_str(""); }
  1113. ;
  1114. /*
  1115.  * the default copy delimiter is tab but the user can configure it
  1116.  */
  1117. copy_delimiter:  USING DELIMITERS Sconst { $$ = cat2_str(make1_str("using delimiters"), $3); }
  1118. | /*EMPTY*/ { $$ = make1_str(""); }
  1119. ;
  1120. /*****************************************************************************
  1121.  *
  1122.  * QUERY :
  1123.  * CREATE relname
  1124.  *
  1125.  *****************************************************************************/
  1126. CreateStmt:  CREATE OptTemp TABLE relation_name '(' OptTableElementList ')'
  1127. OptInherit
  1128. {
  1129. $$ = cat3_str(cat4_str(make1_str("create"), $2, make1_str("table"), $4), make3_str(make1_str("("), $6, make1_str(")")), $8);
  1130. }
  1131. ;
  1132. OptTemp:  OptTempType                           { $$ = $1; }
  1133.                 | OptTempScope OptTempType { $$ = cat2_str($1,$2); }
  1134.                 ;
  1135. OptTempType:   TEMP { $$ = make1_str("temp"); }
  1136. | TEMPORARY { $$ = make1_str("temporary"); }
  1137. | /* EMPTY */ { $$ = make1_str(""); }
  1138. ;
  1139. OptTempScope:  GLOBAL
  1140.                {
  1141.                     yyerror("GLOBAL TEMPORARY TABLE is not currently supported");
  1142.                     $$ = make1_str("global");
  1143.                }
  1144.              | LOCAL { $$ = make1_str("local"); }
  1145.              ;
  1146. OptTableElementList:  OptTableElementList ',' OptTableElement
  1147. {
  1148. $$ = cat3_str($1, make1_str(","), $3);
  1149. }
  1150. | OptTableElement
  1151. {
  1152. $$ = $1;
  1153. }
  1154. | /*EMPTY*/ { $$ = make1_str(""); }
  1155. ;
  1156. OptTableElement:  columnDef { $$ = $1; }
  1157. | TableConstraint { $$ = $1; }
  1158. ;
  1159. columnDef:  ColId Typename ColQualifier
  1160. {
  1161. $$ = cat3_str($1, $2, $3);
  1162. }
  1163. | ColId SERIAL ColPrimaryKey
  1164. {
  1165. $$ = make3_str($1, make1_str(" serial "), $3);
  1166. }
  1167. ;
  1168. ColQualifier:  ColQualList { $$ = $1; }
  1169. | /*EMPTY*/ { $$ = make1_str(""); }
  1170. ;
  1171. ColQualList:  ColQualList ColConstraint { $$ = cat2_str($1,$2); }
  1172. | ColConstraint { $$ = $1; }
  1173. ;
  1174. ColPrimaryKey:  PRIMARY KEY
  1175.                 {
  1176. $$ = make1_str("primary key");
  1177.                 }
  1178.               | /*EMPTY*/
  1179. {
  1180. $$ = make1_str("");
  1181. }
  1182.                 ;
  1183. ColConstraint:
  1184. CONSTRAINT name ColConstraintElem
  1185. {
  1186. $$ = cat3_str(make1_str("constraint"), $2, $3);
  1187. }
  1188. | ColConstraintElem
  1189. { $$ = $1; }
  1190. ;
  1191. /* DEFAULT NULL is already the default for Postgres.
  1192.  * Bue define it here and carry it forward into the system
  1193.  * to make it explicit.
  1194.  * - thomas 1998-09-13
  1195.  * WITH NULL and NULL are not SQL92-standard syntax elements,
  1196.  * so leave them out. Use DEFAULT NULL to explicitly indicate
  1197.  * that a column may have that value. WITH NULL leads to
  1198.  * shift/reduce conflicts with WITH TIME ZONE anyway.
  1199.  * - thomas 1999-01-08
  1200.  */
  1201. ColConstraintElem:  CHECK '(' constraint_expr ')'
  1202. {
  1203. $$ = make3_str(make1_str("check("), $3, make1_str(")"));
  1204. }
  1205. | DEFAULT NULL_P
  1206. {
  1207. $$ = make1_str("default null");
  1208. }
  1209. | DEFAULT default_expr
  1210. {
  1211. $$ = cat2_str(make1_str("default"), $2);
  1212. }
  1213. | NOT NULL_P
  1214. {
  1215. $$ = make1_str("not null");
  1216. }
  1217. | UNIQUE
  1218. {
  1219. $$ = make1_str("unique");
  1220. }
  1221. | PRIMARY KEY
  1222. {
  1223. $$ = make1_str("primary key");
  1224. }
  1225. | REFERENCES ColId opt_column_list key_match key_actions
  1226. {
  1227. fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
  1228. $$ = make1_str("");
  1229. }
  1230. ;
  1231. default_list:  default_list ',' default_expr
  1232. {
  1233. $$ = cat3_str($1, make1_str(","), $3);
  1234. }
  1235. | default_expr
  1236. {
  1237. $$ = $1;
  1238. }
  1239. ;
  1240. /* The Postgres default column value is NULL.
  1241.  * Rather than carrying DEFAULT NULL forward as a clause,
  1242.  * let's just have it be a no-op.
  1243.                         | NULL_P
  1244. { $$ = make1_str("null"); }
  1245.  * - thomas 1998-09-13
  1246.  */
  1247. default_expr:  AexprConst
  1248. { $$ = $1; }
  1249. | '-' default_expr %prec UMINUS
  1250. { $$ = cat2_str(make1_str("-"), $2); }
  1251. | default_expr '+' default_expr
  1252. { $$ = cat3_str($1, make1_str("+"), $3); }
  1253. | default_expr '-' default_expr
  1254. { $$ = cat3_str($1, make1_str("-"), $3); }
  1255. | default_expr '/' default_expr
  1256. { $$ = cat3_str($1, make1_str("/"), $3); }
  1257. | default_expr '%' default_expr
  1258. { $$ = cat3_str($1, make1_str("%"), $3); }
  1259. | default_expr '*' default_expr
  1260. { $$ = cat3_str($1, make1_str("*"), $3); }
  1261. | default_expr '=' default_expr
  1262. { yyerror("boolean expressions not supported in DEFAULT"); }
  1263. | default_expr '<' default_expr
  1264. { yyerror("boolean expressions not supported in DEFAULT"); }
  1265. | default_expr '>' default_expr
  1266. { yyerror("boolean expressions not supported in DEFAULT"); }
  1267. /* not possible in embedded sql 
  1268. | ':' default_expr
  1269. { $$ = cat2_str(make1_str(":"), $2); }
  1270. */
  1271. | ';' default_expr
  1272. { $$ = cat2_str(make1_str(";"), $2); }
  1273. | '|' default_expr
  1274. { $$ = cat2_str(make1_str("|"), $2); }
  1275. | default_expr TYPECAST Typename
  1276. { $$ = cat3_str($1, make1_str("::"), $3); }
  1277. | CAST '(' default_expr AS Typename ')'
  1278. {
  1279. $$ = cat3_str(make2_str(make1_str("cast("), $3) , make1_str("as"), make2_str($5, make1_str(")")));
  1280. }
  1281. | '(' default_expr ')'
  1282. { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  1283. | func_name '(' ')'
  1284. { $$ = cat2_str($1, make1_str("()")); }
  1285. | func_name '(' default_list ')'
  1286. { $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")"))); }
  1287. | default_expr Op default_expr
  1288. {
  1289. if (!strcmp("<=", $2) || !strcmp(">=", $2))
  1290. yyerror("boolean expressions not supported in DEFAULT");
  1291. $$ = cat3_str($1, $2, $3);
  1292. }
  1293. | Op default_expr
  1294. { $$ = cat2_str($1, $2); }
  1295. | default_expr Op
  1296. { $$ = cat2_str($1, $2); }
  1297. /* XXX - thomas 1997-10-07 v6.2 function-specific code to be changed */
  1298. | CURRENT_DATE
  1299. { $$ = make1_str("current_date"); }
  1300. | CURRENT_TIME
  1301. { $$ = make1_str("current_time"); }
  1302. | CURRENT_TIME '(' Iconst ')'
  1303. {
  1304. if ($3 != 0)
  1305. fprintf(stderr, "CURRENT_TIME(%s) precision not implemented; zero used instead",$3);
  1306. $$ = "current_time";
  1307. }
  1308. | CURRENT_TIMESTAMP
  1309. { $$ = make1_str("current_timestamp"); }
  1310. | CURRENT_TIMESTAMP '(' Iconst ')'
  1311. {
  1312. if ($3 != 0)
  1313. fprintf(stderr, "CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
  1314. $$ = "current_timestamp";
  1315. }
  1316. | CURRENT_USER
  1317. { $$ = make1_str("current_user"); }
  1318. | USER
  1319. {       $$ = make1_str("user"); }
  1320. ;
  1321. /* ConstraintElem specifies constraint syntax which is not embedded into
  1322.  *  a column definition. ColConstraintElem specifies the embedded form.
  1323.  * - thomas 1997-12-03
  1324.  */
  1325. TableConstraint:  CONSTRAINT name ConstraintElem
  1326. {
  1327. $$ = cat3_str(make1_str("constraint"), $2, $3);
  1328. }
  1329. | ConstraintElem
  1330. { $$ = $1; }
  1331. ;
  1332. ConstraintElem:  CHECK '(' constraint_expr ')'
  1333. {
  1334. $$ = make3_str(make1_str("check("), $3, make1_str(")"));
  1335. }
  1336. | UNIQUE '(' columnList ')'
  1337. {
  1338. $$ = make3_str(make1_str("unique("), $3, make1_str(")"));
  1339. }
  1340. | PRIMARY KEY '(' columnList ')'
  1341. {
  1342. $$ = make3_str(make1_str("primary key("), $4, make1_str(")"));
  1343. }
  1344. | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions
  1345. {
  1346. fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
  1347. $$ = "";
  1348. }
  1349. ;
  1350. constraint_list:  constraint_list ',' constraint_expr
  1351. {
  1352. $$ = cat3_str($1, make1_str(","), $3);
  1353. }
  1354. | constraint_expr
  1355. {
  1356. $$ = $1;
  1357. }
  1358. ;
  1359. constraint_expr:  AexprConst
  1360. { $$ = $1; }
  1361. | NULL_P
  1362. { $$ = make1_str("null"); }
  1363. | ColId
  1364. {
  1365. $$ = $1;
  1366. }
  1367. | '-' constraint_expr %prec UMINUS
  1368. { $$ = cat2_str(make1_str("-"), $2); }
  1369. | constraint_expr '+' constraint_expr
  1370. { $$ = cat3_str($1, make1_str("+"), $3); }
  1371. | constraint_expr '-' constraint_expr
  1372. { $$ = cat3_str($1, make1_str("-"), $3); }
  1373. | constraint_expr '/' constraint_expr
  1374. { $$ = cat3_str($1, make1_str("/"), $3); }
  1375. | constraint_expr '%' constraint_expr
  1376. { $$ = cat3_str($1, make1_str("%"), $3); }
  1377. | constraint_expr '*' constraint_expr
  1378. { $$ = cat3_str($1, make1_str("*"), $3); }
  1379. | constraint_expr '=' constraint_expr
  1380. { $$ = cat3_str($1, make1_str("="), $3); }
  1381. | constraint_expr '<' constraint_expr
  1382. { $$ = cat3_str($1, make1_str("<"), $3); }
  1383. | constraint_expr '>' constraint_expr
  1384. { $$ = cat3_str($1, make1_str(">"), $3); }
  1385. /* this one doesn't work with embedded sql anyway
  1386. | ':' constraint_expr
  1387. { $$ = cat2_str(make1_str(":"), $2); }
  1388. */
  1389. | ';' constraint_expr
  1390. { $$ = cat2_str(make1_str(";"), $2); }
  1391. | '|' constraint_expr
  1392. { $$ = cat2_str(make1_str("|"), $2); }
  1393. | constraint_expr TYPECAST Typename
  1394. {
  1395. $$ = cat3_str($1, make1_str("::"), $3);
  1396. }
  1397. | CAST '(' constraint_expr AS Typename ')'
  1398. {
  1399. $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")"))); 
  1400. }
  1401. | '(' constraint_expr ')'
  1402. { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  1403. | func_name '(' ')'
  1404. {
  1405. { $$ = cat2_str($1, make1_str("()")); }
  1406. }
  1407. | func_name '(' constraint_list ')'
  1408. {
  1409. $$ = cat2_str($1, make3_str(make1_str("("), $3, make1_str(")")));
  1410. }
  1411. | constraint_expr Op constraint_expr
  1412. { $$ = cat3_str($1, $2, $3); }
  1413. | constraint_expr LIKE constraint_expr
  1414. { $$ = cat3_str($1, make1_str("like"), $3); }
  1415. | constraint_expr NOT LIKE constraint_expr
  1416. { $$ = cat3_str($1, make1_str("not like"), $4); }
  1417. | constraint_expr AND constraint_expr
  1418. { $$ = cat3_str($1, make1_str("and"), $3); }
  1419. | constraint_expr OR constraint_expr
  1420. { $$ = cat3_str($1, make1_str("or"), $3); }
  1421. | NOT constraint_expr
  1422. { $$ = cat2_str(make1_str("not"), $2); }
  1423. | Op constraint_expr
  1424. { $$ = cat2_str($1, $2); }
  1425. | constraint_expr Op
  1426. { $$ = cat2_str($1, $2); }
  1427. | constraint_expr ISNULL
  1428. { $$ = cat2_str($1, make1_str("isnull")); }
  1429. | constraint_expr IS NULL_P
  1430. { $$ = cat2_str($1, make1_str("is null")); }
  1431. | constraint_expr NOTNULL
  1432. { $$ = cat2_str($1, make1_str("notnull")); }
  1433. | constraint_expr IS NOT NULL_P
  1434. { $$ = cat2_str($1, make1_str("is not null")); }
  1435. | constraint_expr IS TRUE_P
  1436. { $$ = cat2_str($1, make1_str("is true")); }
  1437. | constraint_expr IS FALSE_P
  1438. { $$ = cat2_str($1, make1_str("is false")); }
  1439. | constraint_expr IS NOT TRUE_P
  1440. { $$ = cat2_str($1, make1_str("is not true")); }
  1441. | constraint_expr IS NOT FALSE_P
  1442. { $$ = cat2_str($1, make1_str("is not false")); }
  1443. | constraint_expr IN '(' c_list ')'
  1444. { $$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
  1445. | constraint_expr NOT IN '(' c_list ')'
  1446. { $$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
  1447. | constraint_expr BETWEEN c_expr AND c_expr
  1448. { $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
  1449. | constraint_expr NOT BETWEEN c_expr AND c_expr
  1450. { $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
  1451. ;
  1452. c_list:  c_list ',' c_expr
  1453. {
  1454. $$ = make3_str($1, make1_str(", "), $3);
  1455. }
  1456. | c_expr
  1457. {
  1458. $$ = $1;
  1459. }
  1460. c_expr:  AexprConst
  1461. {
  1462. $$ = $1;
  1463. }
  1464. key_match:  MATCH FULL { $$ = make1_str("match full"); }
  1465. | MATCH PARTIAL { $$ = make1_str("match partial"); }
  1466. | /*EMPTY*/ { $$ = make1_str(""); }
  1467. ;
  1468. key_actions:  key_action key_action { $$ = cat2_str($1, $2); }
  1469. | key_action { $$ = $1; }
  1470. | /*EMPTY*/ { $$ = make1_str(""); }
  1471. ;
  1472. key_action:  ON DELETE key_reference { $$ = cat2_str(make1_str("on delete"), $3); }
  1473. | ON UPDATE key_reference { $$ = cat2_str(make1_str("on update"), $3); }
  1474. ;
  1475. key_reference:  NO ACTION { $$ = make1_str("no action"); }
  1476. | CASCADE { $$ = make1_str("cascade"); }
  1477. | SET DEFAULT { $$ = make1_str("set default"); }
  1478. | SET NULL_P { $$ = make1_str("set null"); }
  1479. ;
  1480. OptInherit:  INHERITS '(' relation_name_list ')' { $$ = make3_str(make1_str("inherits ("), $3, make1_str(")")); }
  1481. | /*EMPTY*/ { $$ = make1_str(""); }
  1482. ;
  1483. CreateAsStmt:  CREATE OptTemp TABLE relation_name OptCreateAs AS SubSelect
  1484. {
  1485. $$ = cat5_str(cat3_str(make1_str("create"), $2, make1_str("table")), $4, $5, make1_str("as"), $7); 
  1486. }
  1487. ;
  1488. OptCreateAs:  '(' CreateAsList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  1489. | /*EMPTY*/ { $$ = make1_str(""); }
  1490. ;
  1491. CreateAsList:  CreateAsList ',' CreateAsElement { $$ = cat3_str($1, make1_str(","), $3); }
  1492. | CreateAsElement { $$ = $1; }
  1493. ;
  1494. CreateAsElement:  ColId { $$ = $1; }
  1495. ;
  1496. /*****************************************************************************
  1497.  *
  1498.  * QUERY :
  1499.  * CREATE SEQUENCE seqname
  1500.  *
  1501.  *****************************************************************************/
  1502. CreateSeqStmt:  CREATE SEQUENCE relation_name OptSeqList
  1503. {
  1504. $$ = cat3_str(make1_str("create sequence"), $3, $4);
  1505. }
  1506. ;
  1507. OptSeqList:  OptSeqList OptSeqElem
  1508. { $$ = cat2_str($1, $2); }
  1509. | { $$ = make1_str(""); }
  1510. ;
  1511. OptSeqElem:  CACHE IntegerOnly
  1512. {
  1513. $$ = cat2_str(make1_str("cache"), $2);
  1514. }
  1515. | CYCLE
  1516. {
  1517. $$ = make1_str("cycle");
  1518. }
  1519. | INCREMENT IntegerOnly
  1520. {
  1521. $$ = cat2_str(make1_str("increment"), $2);
  1522. }
  1523. | MAXVALUE IntegerOnly
  1524. {
  1525. $$ = cat2_str(make1_str("maxvalue"), $2);
  1526. }
  1527. | MINVALUE IntegerOnly
  1528. {
  1529. $$ = cat2_str(make1_str("minvalue"), $2);
  1530. }
  1531. | START IntegerOnly
  1532. {
  1533. $$ = cat2_str(make1_str("start"), $2);
  1534. }
  1535. ;
  1536. NumericOnly:  FloatOnly         { $$ = $1; }
  1537. | IntegerOnly   { $$ = $1; }
  1538. FloatOnly:  Fconst
  1539.                                {
  1540.                                        $$ = $1;
  1541.                                }
  1542.                        | '-' Fconst
  1543.                                {
  1544.                                        $$ = cat2_str(make1_str("-"), $2);
  1545.                                }
  1546.                ;
  1547. IntegerOnly:  Iconst
  1548. {
  1549. $$ = $1;
  1550. }
  1551. | '-' Iconst
  1552. {
  1553. $$ = cat2_str(make1_str("-"), $2);
  1554. }
  1555. ;
  1556. /*****************************************************************************
  1557.  *
  1558.  * QUERIES :
  1559.  * CREATE PROCEDURAL LANGUAGE ...
  1560.  * DROP PROCEDURAL LANGUAGE ...
  1561.  *
  1562.  *****************************************************************************/
  1563. CreatePLangStmt:  CREATE PLangTrusted PROCEDURAL LANGUAGE Sconst 
  1564. HANDLER def_name LANCOMPILER Sconst
  1565. {
  1566. $$ = cat4_str(cat5_str(make1_str("create"), $2, make1_str("precedural language"), $5, make1_str("handler")), $7, make1_str("langcompiler"), $9);
  1567. }
  1568. ;
  1569. PLangTrusted: TRUSTED { $$ = make1_str("trusted"); }
  1570. | { $$ = make1_str(""); }
  1571. DropPLangStmt:  DROP PROCEDURAL LANGUAGE Sconst
  1572. {
  1573. $$ = cat2_str(make1_str("drop procedural language"), $4);
  1574. }
  1575. ;
  1576. /*****************************************************************************
  1577.  *
  1578.  * QUERIES :
  1579.  * CREATE TRIGGER ...
  1580.  * DROP TRIGGER ...
  1581.  *
  1582.  *****************************************************************************/
  1583. CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
  1584. relation_name TriggerForSpec EXECUTE PROCEDURE
  1585. name '(' TriggerFuncArgs ')'
  1586. {
  1587. $$ = cat2_str(cat5_str(cat5_str(make1_str("create trigger"), $3, $4, $5, make1_str("on")), $7, $8, make1_str("execute procedure"), $11), make3_str(make1_str("("), $13, make1_str(")")));
  1588. }
  1589. ;
  1590. TriggerActionTime:  BEFORE { $$ = make1_str("before"); }
  1591. | AFTER { $$ = make1_str("after"); }
  1592. ;
  1593. TriggerEvents: TriggerOneEvent
  1594. {
  1595. $$ = $1;
  1596. }
  1597. | TriggerOneEvent OR TriggerOneEvent
  1598. {
  1599. $$ = cat3_str($1, make1_str("or"), $3);
  1600. }
  1601. | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
  1602. {
  1603. $$ = cat5_str($1, make1_str("or"), $3, make1_str("or"), $5);
  1604. }
  1605. ;
  1606. TriggerOneEvent:  INSERT { $$ = make1_str("insert"); }
  1607. | DELETE { $$ = make1_str("delete"); }
  1608. | UPDATE { $$ = make1_str("update"); }
  1609. ;
  1610. TriggerForSpec:  FOR TriggerForOpt TriggerForType
  1611. {
  1612. $$ = cat3_str(make1_str("for"), $2, $3);
  1613. }
  1614. ;
  1615. TriggerForOpt:  EACH { $$ = make1_str("each"); }
  1616. | /*EMPTY*/ { $$ = make1_str(""); }
  1617. ;
  1618. TriggerForType:  ROW { $$ = make1_str("row"); }
  1619. | STATEMENT { $$ = make1_str("statement"); }
  1620. ;
  1621. TriggerFuncArgs:  TriggerFuncArg
  1622. { $$ = $1; }
  1623. | TriggerFuncArgs ',' TriggerFuncArg
  1624. { $$ = cat3_str($1, make1_str(","), $3); }
  1625. | /*EMPTY*/
  1626. { $$ = make1_str(""); }
  1627. ;
  1628. TriggerFuncArg:  Iconst
  1629. {
  1630. $$ = $1;
  1631. }
  1632. | Fconst
  1633. {
  1634. $$ = $1;
  1635. }
  1636. | Sconst {  $$ = $1; }
  1637. | ident {  $$ = $1; }
  1638. ;
  1639. DropTrigStmt:  DROP TRIGGER name ON relation_name
  1640. {
  1641. $$ = cat4_str(make1_str("drop trigger"), $3, make1_str("on"), $5);
  1642. }
  1643. ;
  1644. /*****************************************************************************
  1645.  *
  1646.  * QUERY :
  1647.  * define (type,operator,aggregate)
  1648.  *
  1649.  *****************************************************************************/
  1650. DefineStmt:  CREATE def_type def_rest
  1651. {
  1652. $$ = cat3_str(make1_str("create"), $2, $3);
  1653. }
  1654. ;
  1655. def_rest:  def_name definition
  1656. {
  1657. $$ = cat2_str($1, $2);
  1658. }
  1659. ;
  1660. def_type:  OPERATOR { $$ = make1_str("operator"); }
  1661. | TYPE_P { $$ = make1_str("type"); }
  1662. | AGGREGATE { $$ = make1_str("aggregate"); }
  1663. ;
  1664. def_name:  PROCEDURE { $$ = make1_str("procedure"); }
  1665. | JOIN { $$ = make1_str("join"); }
  1666. | ColId { $$ = $1; }
  1667. | MathOp { $$ = $1; }
  1668. | Op { $$ = $1; }
  1669. ;
  1670. definition:  '(' def_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  1671. ;
  1672. def_list:  def_elem { $$ = $1; }
  1673. | def_list ',' def_elem { $$ = cat3_str($1, make1_str(","), $3); }
  1674. ;
  1675. def_elem:  def_name '=' def_arg {
  1676. $$ = cat3_str($1, make1_str("="), $3);
  1677. }
  1678. | def_name
  1679. {
  1680. $$ = $1;
  1681. }
  1682. | DEFAULT '=' def_arg
  1683. {
  1684. $$ = cat2_str(make1_str("default ="), $3);
  1685. }
  1686. ;
  1687. def_arg:  ColId {  $$ = $1; }
  1688. | all_Op {  $$ = $1; }
  1689. | NumericOnly {  $$ = $1; }
  1690. | Sconst {  $$ = $1; }
  1691. | SETOF ColId
  1692. {
  1693. $$ = cat2_str(make1_str("setof"), $2);
  1694. }
  1695. ;
  1696. /*****************************************************************************
  1697.  *
  1698.  * QUERY:
  1699.  * destroy <relname1> [, <relname2> .. <relnameN> ]
  1700.  *
  1701.  *****************************************************************************/
  1702. DestroyStmt:  DROP TABLE relation_name_list
  1703. {
  1704. $$ = cat2_str(make1_str("drop table"), $3);
  1705. }
  1706. | DROP SEQUENCE relation_name_list
  1707. {
  1708. $$ = cat2_str(make1_str("drop sequence"), $3);
  1709. }
  1710. ;
  1711. /*****************************************************************************
  1712.  *
  1713.  * QUERY:
  1714.  *                     fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
  1715.  *                     fetch [ forward | backward | absolute | relative ]
  1716.  *                           [ # | all | next | prior ] [ [ in | from ] <portalname> ]
  1717.  *
  1718.  *****************************************************************************/
  1719. FetchStmt: FETCH opt_direction fetch_how_many opt_portal_name INTO into_list
  1720. {
  1721. if (strncmp($2, "relative", strlen("relative")) == 0 && atol($3) == 0L)
  1722. yyerror("FETCH/RELATIVE at current position is not supported");
  1723. $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
  1724. }
  1725. | MOVE opt_direction fetch_how_many opt_portal_name
  1726. {
  1727. $$ = cat4_str(make1_str("fetch"), $2, $3, $4);
  1728. }
  1729. ;
  1730. opt_direction: FORWARD { $$ = make1_str("forward"); }
  1731. | BACKWARD { $$ = make1_str("backward"); }
  1732. | RELATIVE      { $$ = make1_str("relative"); }
  1733.                 | ABSOLUTE
  1734.   {
  1735. fprintf(stderr, "FETCH/ABSOLUTE not supported, using RELATIVE");
  1736. $$ = make1_str("absolute");
  1737. }
  1738. | /*EMPTY*/ { $$ = make1_str(""); /* default */ }
  1739. ;
  1740. fetch_how_many:   Iconst        { $$ = $1; }
  1741. | '-' Iconst    { $$ = make2_str(make1_str("-"), $2); }
  1742. | ALL { $$ = make1_str("all"); }
  1743. | NEXT { $$ = make1_str("next"); }
  1744. | PRIOR { $$ = make1_str("prior"); }
  1745. | /*EMPTY*/ { $$ = make1_str(""); /*default*/ }
  1746. ;
  1747. opt_portal_name:  IN name { $$ = cat2_str(make1_str("in"), $2); }
  1748. | FROM name { $$ = cat2_str(make1_str("from"), $2); }
  1749. /* | name { $$ = cat2_str(make1_str("in"), $1); */
  1750. | /*EMPTY*/ { $$ = make1_str(""); }
  1751. ;
  1752. /*****************************************************************************
  1753.  *
  1754.  * QUERY:
  1755.  * GRANT [privileges] ON [relation_name_list] TO [GROUP] grantee
  1756.  *
  1757.  *****************************************************************************/
  1758. GrantStmt:  GRANT privileges ON relation_name_list TO grantee opt_with_grant
  1759. {
  1760. $$ = cat2_str(cat5_str(make1_str("grant"), $2, make1_str("on"), $4, make1_str("to")), $6);
  1761. }
  1762. ;
  1763. privileges:  ALL PRIVILEGES
  1764. {
  1765.  $$ = make1_str("all privileges");
  1766. }
  1767. | ALL
  1768. {
  1769.  $$ = make1_str("all");
  1770. }
  1771. | operation_commalist
  1772. {
  1773.  $$ = $1;
  1774. }
  1775. ;
  1776. operation_commalist:  operation
  1777. {
  1778. $$ = $1;
  1779. }
  1780. | operation_commalist ',' operation
  1781. {
  1782. $$ = cat3_str($1, make1_str(","), $3);
  1783. }
  1784. ;
  1785. operation:  SELECT
  1786. {
  1787. $$ = make1_str("select");
  1788. }
  1789. | INSERT
  1790. {
  1791. $$ = make1_str("insert");
  1792. }
  1793. | UPDATE
  1794. {
  1795. $$ = make1_str("update");
  1796. }
  1797. | DELETE
  1798. {
  1799. $$ = make1_str("delete");
  1800. }
  1801. | RULE
  1802. {
  1803. $$ = make1_str("rule");
  1804. }
  1805. ;
  1806. grantee:  PUBLIC
  1807. {
  1808. $$ = make1_str("public");
  1809. }
  1810. | GROUP ColId
  1811. {
  1812. $$ = cat2_str(make1_str("group"), $2);
  1813. }
  1814. | ColId
  1815. {
  1816. $$ = $1;
  1817. }
  1818. ;
  1819. opt_with_grant:  WITH GRANT OPTION
  1820. {
  1821. yyerror("WITH GRANT OPTION is not supported.  Only relation owners can set privileges");
  1822.  }
  1823. | /*EMPTY*/ 
  1824. ;
  1825. /*****************************************************************************
  1826.  *
  1827.  * QUERY:
  1828.  * REVOKE [privileges] ON [relation_name] FROM [user]
  1829.  *
  1830.  *****************************************************************************/
  1831. RevokeStmt:  REVOKE privileges ON relation_name_list FROM grantee
  1832. {
  1833. $$ = cat2_str(cat5_str(make1_str("revoke"), $2, make1_str("on"), $4, make1_str("from")), $6);
  1834. }
  1835. ;
  1836. /*****************************************************************************
  1837.  *
  1838.  * QUERY:
  1839.  * create index <indexname> on <relname>
  1840.  *   using <access> "(" (<col> with <op>)+ ")" [with
  1841.  *   <target_list>]
  1842.  *
  1843.  * [where <qual>] is not supported anymore
  1844.  *****************************************************************************/
  1845. IndexStmt: CREATE index_opt_unique INDEX index_name ON relation_name
  1846. access_method_clause '(' index_params ')' opt_with
  1847. {
  1848. /* should check that access_method is valid,
  1849.    etc ... but doesn't */
  1850. $$ = cat5_str(cat5_str(make1_str("create"), $2, make1_str("index"), $4, make1_str("on")), $6, $7, make3_str(make1_str("("), $9, make1_str(")")), $11);
  1851. }
  1852. ;
  1853. index_opt_unique:  UNIQUE { $$ = make1_str("unique"); }
  1854. | /*EMPTY*/ { $$ = make1_str(""); }
  1855. ;
  1856. access_method_clause:  USING access_method { $$ = cat2_str(make1_str("using"), $2); }
  1857. | /*EMPTY*/ { $$ = make1_str(""); }
  1858. ;
  1859. index_params:  index_list { $$ = $1; }
  1860. | func_index { $$ = $1; }
  1861. ;
  1862. index_list:  index_list ',' index_elem { $$ = cat3_str($1, make1_str(","), $3); }
  1863. | index_elem { $$ = $1; }
  1864. ;
  1865. func_index:  func_name '(' name_list ')' opt_type opt_class
  1866. {
  1867. $$ = cat4_str($1, make3_str(make1_str("("), $3, ")"), $5, $6);
  1868. }
  1869.   ;
  1870. index_elem:  attr_name opt_type opt_class
  1871. {
  1872. $$ = cat3_str($1, $2, $3);
  1873. }
  1874. ;
  1875. opt_type:  ':' Typename { $$ = cat2_str(make1_str(":"), $2); }
  1876. | FOR Typename { $$ = cat2_str(make1_str("for"), $2); }
  1877. | /*EMPTY*/ { $$ = make1_str(""); }
  1878. ;
  1879. /* opt_class "WITH class" conflicts with preceeding opt_type
  1880.  *  for Typename of "TIMESTAMP WITH TIME ZONE"
  1881.  * So, remove "WITH class" from the syntax. OK??
  1882.  * - thomas 1997-10-12
  1883.  * | WITH class { $$ = $2; }
  1884.  */
  1885. opt_class:  class { $$ = $1; }
  1886. | USING class { $$ = cat2_str(make1_str("using"), $2); }
  1887. | /*EMPTY*/ { $$ = make1_str(""); }
  1888. ;
  1889. /*****************************************************************************
  1890.  *
  1891.  * QUERY:
  1892.  * extend index <indexname> [where <qual>]
  1893.  *
  1894.  *****************************************************************************/
  1895. ExtendStmt:  EXTEND INDEX index_name where_clause
  1896. {
  1897. $$ = cat3_str(make1_str("extend index"), $3, $4);
  1898. }
  1899. ;
  1900. /*****************************************************************************
  1901.  *
  1902.  * QUERY:
  1903.  * execute recipe <recipeName>
  1904.  *
  1905.  *****************************************************************************/
  1906. /* NOT USED
  1907. RecipeStmt:  EXECUTE RECIPE recipe_name
  1908. {
  1909. $$ = cat2_str(make1_str("execute recipe"), $3);
  1910. }
  1911. ;
  1912. */
  1913. /*****************************************************************************
  1914.  *
  1915.  * QUERY:
  1916.  * define function <fname>
  1917.  *    (language = <lang>, returntype = <typename>
  1918.  * [, arch_pct = <percentage | pre-defined>]
  1919.  * [, disk_pct = <percentage | pre-defined>]
  1920.  * [, byte_pct = <percentage | pre-defined>]
  1921.  * [, perbyte_cpu = <int | pre-defined>]
  1922.  * [, percall_cpu = <int | pre-defined>]
  1923.  * [, iscachable])
  1924.  * [arg is (<type-1> { , <type-n>})]
  1925.  * as <filename or code in language as appropriate>
  1926.  *
  1927.  *****************************************************************************/
  1928. ProcedureStmt: CREATE FUNCTION func_name func_args
  1929.  RETURNS func_return opt_with AS Sconst LANGUAGE Sconst
  1930. {
  1931. $$ = cat2_str(cat5_str(cat5_str(make1_str("create function"), $3, $4, make1_str("returns"), $6), $7, make1_str("as"), $9, make1_str("language")), $11);
  1932. }
  1933. opt_with:  WITH definition { $$ = cat2_str(make1_str("with"), $2); }
  1934. | /*EMPTY*/ { $$ = make1_str(""); }
  1935. ;
  1936. func_args:  '(' func_args_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  1937. | '(' ')' { $$ = make1_str("()"); }
  1938. ;
  1939. func_args_list:  TypeId { $$ = $1; }
  1940. | func_args_list ',' TypeId
  1941. { $$ = cat3_str($1, make1_str(","), $3); }
  1942. ;
  1943. func_return:  set_opt TypeId
  1944. {
  1945. $$ = cat2_str($1, $2);
  1946. }
  1947. ;
  1948. set_opt:  SETOF { $$ = make1_str("setof"); }
  1949. | /*EMPTY*/ { $$ = make1_str(""); }
  1950. ;
  1951. /*****************************************************************************
  1952.  *
  1953.  * QUERY:
  1954.  *
  1955.  * remove function <funcname>
  1956.  * (REMOVE FUNCTION "funcname" (arg1, arg2, ...))
  1957.  * remove aggregate <aggname>
  1958.  * (REMOVE AGGREGATE "aggname" "aggtype")
  1959.  * remove operator <opname>
  1960.  * (REMOVE OPERATOR "opname" (leftoperand_typ rightoperand_typ))
  1961.  * remove type <typename>
  1962.  * (REMOVE TYPE "typename")
  1963.  * remove rule <rulename>
  1964.  * (REMOVE RULE "rulename")
  1965.  *
  1966.  *****************************************************************************/
  1967. RemoveStmt:  DROP remove_type name
  1968. {
  1969. $$ = cat3_str(make1_str("drop"), $2, $3);
  1970. }
  1971. ;
  1972. remove_type:  TYPE_P {  $$ = make1_str("type"); }
  1973. | INDEX {  $$ = make1_str("index"); }
  1974. | RULE {  $$ = make1_str("rule"); }
  1975. | VIEW {  $$ = make1_str("view"); }
  1976. ;
  1977. RemoveAggrStmt:  DROP AGGREGATE name aggr_argtype
  1978. {
  1979. $$ = cat3_str(make1_str("drop aggregate"), $3, $4);
  1980. }
  1981. ;
  1982. aggr_argtype:  name { $$ = $1; }
  1983. | '*' { $$ = make1_str("*"); }
  1984. ;
  1985. RemoveFuncStmt:  DROP FUNCTION func_name func_args
  1986. {
  1987. $$ = cat3_str(make1_str("drop function"), $3, $4);
  1988. }
  1989. ;
  1990. RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')'
  1991. {
  1992. $$ = cat3_str(make1_str("drop operator"), $3, make3_str(make1_str("("), $5, make1_str(")")));
  1993. }
  1994. ;
  1995. all_Op:  Op | MathOp;
  1996. MathOp: '+' { $$ = make1_str("+"); }
  1997. | '-' { $$ = make1_str("-"); }
  1998. | '*' { $$ = make1_str("*"); }
  1999. | '%' { $$ = make1_str("%"); }
  2000. | '/' { $$ = make1_str("/"); }
  2001. | '<' { $$ = make1_str("<"); }
  2002. | '>' { $$ = make1_str(">"); }
  2003. | '=' { $$ = make1_str("="); }
  2004. ;
  2005. oper_argtypes: name
  2006. {
  2007.    yyerror("parser: argument type missing (use NONE for unary operators)");
  2008. }
  2009. | name ',' name
  2010. { $$ = cat3_str($1, make1_str(","), $3); }
  2011. | NONE ',' name /* left unary */
  2012. { $$ = cat2_str(make1_str("none,"), $3); }
  2013. | name ',' NONE /* right unary */
  2014. { $$ = cat2_str($1, make1_str(", none")); }
  2015. ;
  2016. /*****************************************************************************
  2017.  *
  2018.  * QUERY:
  2019.  * rename <attrname1> in <relname> [*] to <attrname2>
  2020.  * rename <relname1> to <relname2>
  2021.  *
  2022.  *****************************************************************************/
  2023. RenameStmt:  ALTER TABLE relation_name opt_inh_star
  2024.   RENAME opt_column opt_name TO name
  2025. {
  2026. $$ = cat4_str(cat5_str(make1_str("alter table"), $3, $4, make1_str("rename"), $6), $7, make1_str("to"), $9);
  2027. }
  2028. ;
  2029. opt_name:  name { $$ = $1; }
  2030. | /*EMPTY*/ { $$ = make1_str(""); }
  2031. ;
  2032. opt_column:  COLUMN { $$ = make1_str("colmunn"); }
  2033. | /*EMPTY*/ { $$ = make1_str(""); }
  2034. ;
  2035. /*****************************************************************************
  2036.  *
  2037.  * QUERY: Define Rewrite Rule , Define Tuple Rule
  2038.  * Define Rule <old rules >
  2039.  *
  2040.  * only rewrite rule is supported -- ay 9/94
  2041.  *
  2042.  *****************************************************************************/
  2043. RuleStmt:  CREATE RULE name AS
  2044.    { QueryIsRule=1; }
  2045.    ON event TO event_object where_clause
  2046.    DO opt_instead RuleActionList
  2047. {
  2048. $$ = cat2_str(cat5_str(cat5_str(make1_str("create rule"), $3, make1_str("as on"), $7, make1_str("to")), $9, $10, make1_str("do"), $12), $13);
  2049. }
  2050. ;
  2051. RuleActionList:  NOTHING                               { $$ = make1_str("nothing"); }
  2052.                | SelectStmt                            { $$ = $1; }
  2053.                | RuleActionStmt                        { $$ = $1; }
  2054.                | '[' RuleActionBlock ']'               { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
  2055.                | '(' RuleActionBlock ')'               { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
  2056.                 ;
  2057. RuleActionBlock:  RuleActionMulti              {  $$ = $1; }
  2058.                | RuleActionStmt                {  $$ = $1; }
  2059. ;
  2060. RuleActionMulti:  RuleActionMulti RuleActionStmt
  2061.                                 {  $$ = cat2_str($1, $2); }
  2062. | RuleActionMulti RuleActionStmt ';'
  2063. {  $$ = cat3_str($1, $2, make1_str(";")); }
  2064. | RuleActionStmt ';'
  2065. { $$ = cat2_str($1, make1_str(";")); }
  2066. ;
  2067. RuleActionStmt:        InsertStmt
  2068.                 | UpdateStmt
  2069.                 | DeleteStmt
  2070. | NotifyStmt
  2071.                 ;
  2072. event_object:  relation_name '.' attr_name
  2073. {
  2074. $$ = make3_str($1, make1_str("."), $3);
  2075. }
  2076. | relation_name
  2077. {
  2078. $$ = $1;
  2079. }
  2080. ;
  2081. /* change me to select, update, etc. some day */
  2082. event: SELECT { $$ = make1_str("select"); }
  2083. | UPDATE { $$ = make1_str("update"); }
  2084. | DELETE { $$ = make1_str("delete"); }
  2085. | INSERT { $$ = make1_str("insert"); }
  2086.  ;
  2087. opt_instead:  INSTEAD { $$ = make1_str("instead"); }
  2088. | /*EMPTY*/ { $$ = make1_str(""); }
  2089. ;
  2090. /*****************************************************************************
  2091.  *
  2092.  * QUERY:
  2093.  * NOTIFY <relation_name> can appear both in rule bodies and
  2094.  * as a query-level command
  2095.  *
  2096.  *****************************************************************************/
  2097. NotifyStmt:  NOTIFY relation_name
  2098. {
  2099. $$ = cat2_str(make1_str("notify"), $2);
  2100. }
  2101. ;
  2102. ListenStmt:  LISTEN relation_name
  2103. {
  2104. $$ = cat2_str(make1_str("listen"), $2);
  2105.                                 }
  2106. ;
  2107. UnlistenStmt:  UNLISTEN relation_name
  2108. {
  2109. $$ = cat2_str(make1_str("unlisten"), $2);
  2110.                                 }
  2111. | UNLISTEN '*'
  2112. {
  2113. $$ = make1_str("unlisten *");
  2114.                                 }
  2115. ;
  2116. /*****************************************************************************
  2117.  *
  2118.  *              Transactions:
  2119.  *
  2120.  *              abort transaction
  2121.  *                              (ABORT)
  2122.  *              begin transaction
  2123.  *                              (BEGIN)
  2124.  *              end transaction  
  2125.  *                              (END)
  2126.  *
  2127.  *****************************************************************************/
  2128. TransactionStmt:  ABORT_TRANS opt_trans { $$ = make1_str("rollback"); }
  2129. | BEGIN_TRANS opt_trans { $$ = make1_str("begin transaction"); }
  2130. | COMMIT opt_trans { $$ = make1_str("commit"); }
  2131. | END_TRANS opt_trans { $$ = make1_str("commit"); }
  2132. | ROLLBACK opt_trans { $$ = make1_str("rollback"); }
  2133. opt_trans: WORK  { $$ = ""; }
  2134. | TRANSACTION { $$ = ""; }
  2135. | /*EMPTY*/ { $$ = ""; }
  2136.                 ;
  2137. /*****************************************************************************
  2138.  *
  2139.  * QUERY:
  2140.  * define view <viewname> '('target-list ')' [where <quals> ]
  2141.  *
  2142.  *****************************************************************************/
  2143. ViewStmt:  CREATE VIEW name AS SelectStmt
  2144. {
  2145. $$ = cat4_str(make1_str("create view"), $3, make1_str("as"), $5);
  2146. }
  2147. ;
  2148. /*****************************************************************************
  2149.  *
  2150.  * QUERY:
  2151.  * load make1_str("filename")
  2152.  *
  2153.  *****************************************************************************/
  2154. LoadStmt:  LOAD file_name
  2155. {
  2156. $$ = cat2_str(make1_str("load"), $2);
  2157. }
  2158. ;
  2159. /*****************************************************************************
  2160.  *
  2161.  * QUERY:
  2162.  * createdb dbname
  2163.  *
  2164.  *****************************************************************************/
  2165. CreatedbStmt:  CREATE DATABASE database_name WITH opt_database1 opt_database2
  2166. {
  2167. if (strlen($5) == 0 || strlen($6) == 0) 
  2168. yyerror("CREATE DATABASE WITH requires at least an option");
  2169. #ifndef MULTIBYTE
  2170. if (strlen($6) != 0)
  2171. yyerror("WITH ENCODING is not supported");
  2172. #endif
  2173. $$ = cat5_str(make1_str("create database"), $3, make1_str("with"), $5, $6);
  2174. }
  2175. | CREATE DATABASE database_name
  2176.          {
  2177. $$ = cat2_str(make1_str("create database"), $3);
  2178. }
  2179. ;
  2180. opt_database1:  LOCATION '=' location { $$ = cat2_str(make1_str("location ="), $3); }
  2181. | /*EMPTY*/ { $$ = make1_str(""); }
  2182. ;
  2183. opt_database2:  ENCODING '=' encoding   { $$ = cat2_str(make1_str("encoding ="), $3); }
  2184.                 | /*EMPTY*/         { $$ = NULL; }
  2185.                 ;
  2186. location:  Sconst { $$ = $1; }
  2187. | DEFAULT { $$ = make1_str("default"); }
  2188. | /*EMPTY*/ { $$ = make1_str(""); }
  2189. ;
  2190. encoding:  Sconst { $$ = $1; }
  2191. | DEFAULT { $$ = make1_str("default"); }
  2192. | /*EMPTY*/ { $$ = make1_str(""); }
  2193.                ;
  2194. /*****************************************************************************
  2195.  *
  2196.  * QUERY:
  2197.  * destroydb dbname
  2198.  *
  2199.  *****************************************************************************/
  2200. DestroydbStmt: DROP DATABASE database_name
  2201. {
  2202. $$ = cat2_str(make1_str("drop database"), $3);
  2203. }
  2204. ;
  2205. /*****************************************************************************
  2206.  *
  2207.  * QUERY:
  2208.  * cluster <index_name> on <relation_name>
  2209.  *
  2210.  *****************************************************************************/
  2211. ClusterStmt:  CLUSTER index_name ON relation_name
  2212. {
  2213.    $$ = cat4_str(make1_str("cluster"), $2, make1_str("on"), $4);
  2214. }
  2215. ;
  2216. /*****************************************************************************
  2217.  *
  2218.  * QUERY:
  2219.  * vacuum
  2220.  *
  2221.  *****************************************************************************/
  2222. VacuumStmt:  VACUUM opt_verbose opt_analyze
  2223. {
  2224. $$ = cat3_str(make1_str("vacuum"), $2, $3);
  2225. }
  2226. | VACUUM opt_verbose opt_analyze relation_name opt_va_list
  2227. {
  2228. if ( strlen($5) > 0 && strlen($4) == 0 )
  2229. yyerror("parser: syntax error at or near "("");
  2230. $$ = cat5_str(make1_str("vacuum"), $2, $3, $4, $5);
  2231. }
  2232. ;
  2233. opt_verbose:  VERBOSE { $$ = make1_str("verbose"); }
  2234. | /*EMPTY*/ { $$ = make1_str(""); }
  2235. ;
  2236. opt_analyze:  ANALYZE { $$ = make1_str("analyse"); }
  2237. | /*EMPTY*/ { $$ = make1_str(""); }
  2238. ;
  2239. opt_va_list:  '(' va_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  2240. | /*EMPTY*/ { $$ = make1_str(""); }
  2241. ;
  2242. va_list:  name
  2243. { $$=$1; }
  2244. | va_list ',' name
  2245. { $$=cat3_str($1, make1_str(","), $3); }
  2246. ;
  2247. /*****************************************************************************
  2248.  *
  2249.  * QUERY:
  2250.  * EXPLAIN query
  2251.  *
  2252.  *****************************************************************************/
  2253. ExplainStmt:  EXPLAIN opt_verbose OptimizableStmt
  2254. {
  2255. $$ = cat3_str(make1_str("explain"), $2, $3);
  2256. }
  2257. ;
  2258. /*****************************************************************************
  2259.  *  *
  2260.  * Optimizable Stmts:  *
  2261.  *  *
  2262.  * one of the five queries processed by the planner  *
  2263.  *  *
  2264.  * [ultimately] produces query-trees as specified  *
  2265.  * in the query-spec document in ~postgres/ref  *
  2266.  *  *
  2267.  *****************************************************************************/
  2268. OptimizableStmt:  SelectStmt
  2269. | CursorStmt
  2270. | UpdateStmt
  2271. | InsertStmt
  2272. | NotifyStmt
  2273. | DeleteStmt
  2274. ;
  2275. /*****************************************************************************
  2276.  *
  2277.  * QUERY:
  2278.  * INSERT STATEMENTS
  2279.  *
  2280.  *****************************************************************************/
  2281. /***S*I***/
  2282. /* This rule used 'opt_column_list' between 'relation_name' and 'insert_rest'
  2283.  * originally. When the second rule of 'insert_rest' was changed to use
  2284.  * the new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/red uce
  2285.  * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to accept
  2286.  * the same statements without any shift/reduce conflicts */
  2287. InsertStmt:  INSERT INTO relation_name insert_rest
  2288. {
  2289. $$ = cat3_str(make1_str("insert into"), $3, $4);
  2290. }
  2291. ;
  2292. insert_rest:  VALUES '(' res_target_list2 ')'
  2293. {
  2294. $$ = make3_str(make1_str("values("), $3, make1_str(")"));
  2295. }
  2296. | DEFAULT VALUES
  2297. {
  2298. $$ = make1_str("default values");
  2299. }
  2300. | SelectStmt
  2301. {
  2302. $$ = $1;
  2303. }
  2304. | '(' columnList ')' VALUES '(' res_target_list2 ')'
  2305. {
  2306. $$ = make5_str(make1_str("("), $2, make1_str(") values ("), $6, make1_str(")"));
  2307. }
  2308. | '(' columnList ')' SelectStmt
  2309. {
  2310. $$ = make4_str(make1_str("("), $2, make1_str(")"), $4);
  2311. }
  2312. ;
  2313. opt_column_list:  '(' columnList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  2314. | /*EMPTY*/ { $$ = make1_str(""); }
  2315. ;
  2316. columnList:
  2317.   columnList ',' columnElem
  2318. { $$ = cat3_str($1, make1_str(","), $3); }
  2319. | columnElem
  2320. { $$ = $1; }
  2321. ;
  2322. columnElem:  ColId opt_indirection
  2323. {
  2324. $$ = cat2_str($1, $2);
  2325. }
  2326. ;
  2327. /*****************************************************************************
  2328.  *
  2329.  * QUERY:
  2330.  * DELETE STATEMENTS
  2331.  *
  2332.  *****************************************************************************/
  2333. DeleteStmt:  DELETE FROM relation_name
  2334.  where_clause
  2335. {
  2336. $$ = cat3_str(make1_str("delete from"), $3, $4);
  2337. }
  2338. ;
  2339. LockStmt:  LOCK_P opt_table relation_name opt_lock
  2340. {
  2341. $$ = cat4_str(make1_str("lock"), $2, $3, $4);
  2342. }
  2343. ;
  2344. opt_lock:  IN lock_type MODE            { $$ = cat3_str(make1_str("in"), $2, make1_str("mode")); }
  2345.                 | /*EMPTY*/             { $$ = make1_str("");}
  2346.                 ;
  2347. lock_type:  SHARE ROW EXCLUSIVE  { $$ = make1_str("share row exclusive"); }
  2348.                 | ROW opt_lmode         { $$ = cat2_str(make1_str("row"), $2);}
  2349.                 | ACCESS opt_lmode      { $$ = cat2_str(make1_str("access"), $2);}
  2350.                 | opt_lmode             { $$ = $1; }
  2351.                 ;
  2352. opt_lmode:      SHARE                           { $$ = make1_str("share"); }
  2353.                 | EXCLUSIVE                     { $$ = make1_str("exclusive"); }
  2354.                 ;
  2355. /*****************************************************************************
  2356.  *
  2357.  * QUERY:
  2358.  * UpdateStmt (UPDATE)
  2359.  *
  2360.  *****************************************************************************/
  2361. UpdateStmt:  UPDATE relation_name
  2362.   SET res_target_list
  2363.   from_clause
  2364.   where_clause
  2365. {
  2366. $$ = cat2_str(cat5_str(make1_str("update"), $2, make1_str("set"), $4, $5), $6);
  2367. }
  2368. ;
  2369. /*****************************************************************************
  2370.  *
  2371.  * QUERY:
  2372.  * CURSOR STATEMENTS
  2373.  *
  2374.  *****************************************************************************/
  2375. CursorStmt:  DECLARE name opt_cursor CURSOR FOR
  2376. { ForUpdateNotAllowed = 1; }
  2377.      SelectStmt
  2378. {
  2379. struct cursor *ptr, *this;
  2380. for (ptr = cur; ptr != NULL; ptr = ptr->next)
  2381. {
  2382. if (strcmp($2, ptr->name) == 0)
  2383. {
  2384.         /* re-definition is a bug */
  2385. sprintf(errortext, "cursor %s already defined", $2);
  2386. yyerror(errortext);
  2387.                 }
  2388.          }
  2389.                         
  2390.          this = (struct cursor *) mm_alloc(sizeof(struct cursor));
  2391.          /* initial definition */
  2392.         this->next = cur;
  2393.         this->name = $2;
  2394. this->connection = connection;
  2395.         this->command =  cat5_str(make1_str("declare"), mm_strdup($2), $3, make1_str("cursor for"), $7);
  2396. this->argsinsert = argsinsert;
  2397. this->argsresult = argsresult;
  2398. argsinsert = argsresult = NULL;
  2399.          cur = this;
  2400. $$ = cat3_str(make1_str("/*"), mm_strdup(this->command), make1_str("*/"));
  2401. }
  2402. ;
  2403. opt_cursor:  BINARY             { $$ = make1_str("binary"); }
  2404.                | INSENSITIVE { $$ = make1_str("insensitive"); }
  2405.                | SCROLL         { $$ = make1_str("scroll"); }
  2406.                | INSENSITIVE SCROLL { $$ = make1_str("insensitive scroll"); }
  2407.                | /*EMPTY*/      { $$ = make1_str(""); }
  2408.                ;
  2409. /*****************************************************************************
  2410.  *
  2411.  * QUERY:
  2412.  * SELECT STATEMENTS
  2413.  *
  2414.  *****************************************************************************/
  2415. /***S*I***/
  2416. /* The new 'SelectStmt' rule adapted for the optional use of INTERSECT EXCEPT a nd UNION
  2417.  * accepts the use of '(' and ')' to select an order of set operations.
  2418.  * The rule returns a SelectStmt Node having the set operations attached to
  2419.  * unionClause and intersectClause (NIL if no set operations were present)
  2420.  */
  2421. SelectStmt:      select_clause sort_clause for_update_clause opt_select_limit
  2422. {
  2423. if (strlen($3) > 0 && ForUpdateNotAllowed != 0)
  2424. yyerror("FOR UPDATE is not allowed in this context");
  2425. ForUpdateNotAllowed = 0;
  2426. $$ = cat4_str($1, $2, $3, $4);
  2427. }
  2428. /***S*I***/ 
  2429. /* This rule parses Select statements including UNION INTERSECT and EXCEPT.
  2430.  * '(' and ')' can be used to specify the order of the operations 
  2431.  * (UNION EXCEPT INTERSECT). Without the use of '(' and ')' we want the
  2432.  * operations to be left associative.
  2433.  *
  2434.  *  The sort_clause is not handled here!
  2435.  */
  2436. select_clause: '(' select_clause ')'
  2437.                         {
  2438.                                $$ = make3_str(make1_str("("), $2, make1_str(")")); 
  2439.                         }
  2440.                 | SubSelect
  2441.                         {
  2442.                                $$ = $1; 
  2443.                         }
  2444.                 | select_clause EXCEPT select_clause
  2445. {
  2446. $$ = cat3_str($1, make1_str("except"), $3);
  2447. ForUpdateNotAllowed = 1;
  2448. }
  2449. | select_clause UNION opt_union select_clause
  2450. {
  2451. $$ = cat4_str($1, make1_str("union"), $3, $4);
  2452. ForUpdateNotAllowed = 1;
  2453. }
  2454. | select_clause INTERSECT opt_union select_clause
  2455. {
  2456. $$ = cat3_str($1, make1_str("intersect"), $3);
  2457. ForUpdateNotAllowed = 1;
  2458. }
  2459. ;
  2460. /***S*I***/
  2461. SubSelect:     SELECT opt_unique res_target_list2
  2462.                          result from_clause where_clause
  2463.                          group_clause having_clause
  2464. {
  2465. $$ = cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
  2466. if (strlen($7) > 0 || strlen($8) > 0)
  2467. ForUpdateNotAllowed = 1;
  2468. }
  2469. ;
  2470. result:  INTO OptTemp opt_table relation_name { $$= cat4_str(make1_str("into"), $2, $3, $4); }
  2471. | INTO into_list { $$ = make1_str(""); }
  2472. | /*EMPTY*/ { $$ = make1_str(""); }
  2473. ;
  2474. opt_table:  TABLE { $$ = make1_str("table"); }
  2475. | /*EMPTY*/ { $$ = make1_str(""); }
  2476. ;
  2477. opt_union:  ALL { $$ = make1_str("all"); }
  2478. | /*EMPTY*/ { $$ = make1_str(""); }
  2479. ;
  2480. opt_unique:  DISTINCT { $$ = make1_str("distinct"); }
  2481. | DISTINCT ON ColId { $$ = cat2_str(make1_str("distinct on"), $3); }
  2482. | ALL { $$ = make1_str("all"); }
  2483. | /*EMPTY*/ { $$ = make1_str(""); }
  2484. ;
  2485. sort_clause:  ORDER BY sortby_list { $$ = cat2_str(make1_str("order by"), $3); }
  2486. | /*EMPTY*/ { $$ = make1_str(""); }
  2487. ;
  2488. sortby_list:  sortby { $$ = $1; }
  2489. | sortby_list ',' sortby { $$ = cat3_str($1, make1_str(","), $3); }
  2490. ;
  2491. sortby: a_expr OptUseOp
  2492. {
  2493.  $$ = cat2_str($1, $2);
  2494.                                 }
  2495. ;
  2496. OptUseOp:  USING Op { $$ = cat2_str(make1_str("using"), $2); }
  2497. | USING '<' { $$ = make1_str("using <"); }
  2498. | USING '>' { $$ = make1_str("using >"); }
  2499. | ASC { $$ = make1_str("asc"); }
  2500. | DESC { $$ = make1_str("desc"); }
  2501. | /*EMPTY*/ { $$ = make1_str(""); }
  2502. ;
  2503. opt_select_limit:      LIMIT select_limit_value ',' select_offset_value
  2504.                        { $$ = cat4_str(make1_str("limit"), $2, make1_str(","), $4); }
  2505.                | LIMIT select_limit_value OFFSET select_offset_value
  2506.                        { $$ = cat4_str(make1_str("limit"), $2, make1_str("offset"), $4); }
  2507.                | LIMIT select_limit_value
  2508.                        { $$ = cat2_str(make1_str("limit"), $2); }
  2509.                | OFFSET select_offset_value LIMIT select_limit_value
  2510.                        { $$ = cat4_str(make1_str("offset"), $2, make1_str("limit"), $4); }
  2511.                | OFFSET select_offset_value
  2512.                        { $$ = cat2_str(make1_str("offset"), $2); }
  2513.                | /* EMPTY */
  2514.                        { $$ = make1_str(""); }
  2515.                ;
  2516. select_limit_value: Iconst { $$ = $1; }
  2517.            | ALL { $$ = make1_str("all"); }
  2518. | PARAM { $$ = make_name(); }
  2519.                ;
  2520. select_offset_value:   Iconst { $$ = $1; }
  2521. | PARAM { $$ = make_name(); }
  2522.                ;
  2523. /*
  2524.  * jimmy bell-style recursive queries aren't supported in the
  2525.  * current system.
  2526.  *
  2527.  * ...however, recursive addattr and rename supported.  make special
  2528.  * cases for these.
  2529.  */
  2530. opt_inh_star:  '*' { $$ = make1_str("*"); }
  2531. | /*EMPTY*/ { $$ = make1_str(""); }
  2532. ;
  2533. relation_name_list:  name_list { $$ = $1; };
  2534. name_list:  name
  2535. { $$ = $1; }
  2536. | name_list ',' name
  2537. { $$ = cat3_str($1, make1_str(","), $3); }
  2538. ;
  2539. group_clause:  GROUP BY expr_list { $$ = cat2_str(make1_str("group by"), $3); }
  2540. | /*EMPTY*/ { $$ = make1_str(""); }
  2541. ;
  2542. having_clause:  HAVING a_expr
  2543. {
  2544. $$ = cat2_str(make1_str("having"), $2);
  2545. }
  2546. | /*EMPTY*/ { $$ = make1_str(""); }
  2547. ;
  2548. for_update_clause:  FOR UPDATE update_list
  2549. {
  2550.                  $$ = make1_str("for update"); 
  2551. }
  2552. | FOR READ ONLY
  2553. {
  2554. $$ = make1_str("for read only");
  2555. }
  2556. | /* EMPTY */
  2557.                 {
  2558.                         $$ = make1_str("");
  2559.                 }
  2560.                 ;
  2561. update_list:  OF va_list
  2562.               {
  2563. $$ = cat2_str(make1_str("of"), $2);
  2564.       }
  2565.               | /* EMPTY */
  2566.               {
  2567.                         $$ = make1_str("");
  2568.               }
  2569.               ;
  2570. /*****************************************************************************
  2571.  *
  2572.  * clauses common to all Optimizable Stmts:
  2573.  * from_clause -
  2574.  * where_clause -
  2575.  *
  2576.  *****************************************************************************/
  2577. from_clause:  FROM from_expr
  2578. {
  2579. $$ = cat2_str(make1_str("from"), $2);
  2580. }
  2581. | /* EMPTY */
  2582. {
  2583. $$ = make1_str("");
  2584. }
  2585. from_expr:  '(' join_clause_with_union ')'
  2586.                                 { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
  2587.                 | join_clause
  2588.                                 { $$ = $1; }
  2589.                 | table_list
  2590.                                 { $$ = $1; }
  2591.                 ;
  2592. table_list:  table_list ',' table_expr
  2593.                                 { $$ = make3_str($1, make1_str(","), $3); }
  2594.                 | table_expr
  2595.                                 { $$ = $1; }
  2596.                 ;
  2597. table_expr:  relation_expr AS ColLabel
  2598.                                 {
  2599.                                         $$ = cat3_str($1, make1_str("as"), $3);
  2600.                                 }
  2601.                 | relation_expr ColId
  2602.                                 {
  2603.                                         $$ = cat2_str($1, $2);
  2604.                                 }
  2605.                 | relation_expr
  2606.                                 {
  2607.                                         $$ = $1;
  2608.                                 }
  2609.                 ;
  2610. /* A UNION JOIN is the same as a FULL OUTER JOIN which *omits*
  2611.  * all result rows which would have matched on an INNER JOIN.
  2612.  * Let's reject this for now. - thomas 1999-01-08