]> granicus.if.org Git - postgresql/blob - src/interfaces/ecpg/preproc/preproc.y
Synced parser and keyword list.
[postgresql] / src / interfaces / ecpg / preproc / preproc.y
1 /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.354 2007/10/10 06:33:17 meskes Exp $ */
2
3 /* Copyright comment */
4 %{
5 #include "postgres_fe.h"
6
7 #include "extern.h"
8 #include <unistd.h>
9
10 /* Location tracking support --- simpler than bison's default */
11 #define YYLLOC_DEFAULT(Current, Rhs, N) \
12         do { \
13                 if (N) \
14                         (Current) = (Rhs)[1]; \
15                 else \
16                         (Current) = (Rhs)[0]; \
17         } while (0)
18
19 /*
20  * The %name-prefix option below will make bison call base_yylex, but we
21  * really want it to call filtered_base_yylex (see parser.c).
22  */
23 #define base_yylex filtered_base_yylex
24
25 /*
26  * Variables containing simple states.
27  */
28 int struct_level = 0;
29 int braces_open; /* brace level counter */
30 int ecpg_informix_var = 0;
31 char    *connection = NULL;
32 char    *input_filename = NULL;
33
34 static int      QueryIsRule = 0, FoundInto = 0;
35 static int      initializer = 0;
36 static int      pacounter = 1;
37 static char     pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the size we need */
38 static struct this_type actual_type[STRUCT_DEPTH];
39 static char *actual_startline[STRUCT_DEPTH];
40
41 /* temporarily store struct members while creating the data structure */
42 struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
43
44 /* also store struct type so we can do a sizeof() later */
45 static char *ECPGstruct_sizeof = NULL;
46
47 /* for forward declarations we have to store some data as well */
48 static char *forward_name = NULL;
49
50 struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
51 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
52
53 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
54
55 /*
56  * Handle parsing errors and warnings
57  */
58 void
59 mmerror(int error_code, enum errortype type, char * error, ...)
60 {
61         va_list ap;
62
63         fprintf(stderr, "%s:%d: ", input_filename, yylineno);
64
65         switch(type)
66         {
67                 case ET_WARNING:
68                         fprintf(stderr, "WARNING: ");
69                         break;
70                 case ET_ERROR:
71                 case ET_FATAL:
72                         fprintf(stderr, "ERROR: ");
73                         break;
74         }
75
76         va_start(ap, error);
77         vfprintf(stderr, error, ap);
78         va_end(ap);
79
80         fprintf(stderr, "\n");
81
82         switch(type)
83         {
84                 case ET_WARNING:
85                         break;
86                 case ET_ERROR:
87                         ret_value = error_code;
88                         break;
89                 case ET_FATAL:
90                         fclose(yyin);
91                         fclose(yyout);
92                         if (unlink(output_filename) != 0 && *output_filename != '-')
93                                 fprintf(stderr, "Could not remove output file %s!\n", output_filename);
94                         exit(error_code);
95         }
96 }
97
98 /*
99  * string concatenation
100  */
101
102 static char *
103 cat2_str(char *str1, char *str2)
104 {
105         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
106
107         strcpy(res_str, str1);
108         strcat(res_str, " ");
109         strcat(res_str, str2);
110         free(str1);
111         free(str2);
112         return(res_str);
113 }
114
115 static char *
116 cat_str(int count, ...)
117 {
118         va_list         args;
119         int                     i;
120         char            *res_str;
121
122         va_start(args, count);
123
124         res_str = va_arg(args, char *);
125
126         /* now add all other strings */
127         for (i = 1; i < count; i++)
128                 res_str = cat2_str(res_str, va_arg(args, char *));
129
130         va_end(args);
131
132         return(res_str);
133 }
134
135 char *
136 make_str(const char *str)
137 {
138         char * res_str = (char *)mm_alloc(strlen(str) + 1);
139
140         strcpy(res_str, str);
141         return res_str;
142 }
143
144 static char *
145 make2_str(char *str1, char *str2)
146 {
147         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
148
149         strcpy(res_str, str1);
150         strcat(res_str, str2);
151         free(str1);
152         free(str2);
153         return(res_str);
154 }
155
156 static char *
157 make3_str(char *str1, char *str2, char *str3)
158 {
159         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
160
161         strcpy(res_str, str1);
162         strcat(res_str, str2);
163         strcat(res_str, str3);
164         free(str1);
165         free(str2);
166         free(str3);
167         return(res_str);
168 }
169
170 /* and the rest */
171 static char *
172 make_name(void)
173 {
174         char * name = (char *)mm_alloc(yyleng + 1);
175
176         strncpy(name, yytext, yyleng);
177         name[yyleng] = '\0';
178         return(name);
179 }
180
181 static char *
182 create_questionmarks(char *name, bool array)
183 {
184         struct variable *p = find_variable(name);
185         int count;
186         char *result = EMPTY;
187
188         /* In case we have a struct, we have to print as many "?" as there are attributes in the struct
189          * An array is only allowed together with an element argument
190          * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else
191          * so we don't have to worry here. */
192
193         if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
194         {
195                 struct ECPGstruct_member *m;
196
197                 if (p->type->type == ECPGt_struct)
198                         m = p->type->u.members;
199                 else
200                         m = p->type->u.element->u.members;
201
202                 for (count = 0; m != NULL; m=m->next, count++);
203         }
204         else
205                 count = 1;
206
207         for (; count > 0; count --)
208         {
209                 sprintf(pacounter_buffer, "$%d", pacounter++);
210                 result = cat_str(3, result, strdup(pacounter_buffer), make_str(" , "));
211         }
212
213         /* removed the trailing " ," */
214
215         result[strlen(result)-3] = '\0';
216         return(result);
217 }
218
219 static char *
220 adjust_informix(struct arguments *list)
221 {
222         /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
223          * for instance you can declare variables in a function, and then subsequently use them
224          * {
225          *      declare_vars();
226          *      exec sql ... which uses vars declared in the above function
227          *
228          * This breaks standard and leads to some very dangerous programming.
229          * Since they do, we have to work around and accept their syntax as well.
230          * But we will do so ONLY in Informix mode.
231          * We have to change the variables to our own struct and just store the pointer instead of the variable
232          */
233
234          struct arguments *ptr;
235          char *result = make_str("");
236
237          for (ptr = list; ptr != NULL; ptr = ptr->next)
238          {
239                 char temp[20]; /* this should be sufficient unless you have 8 byte integers */
240                 char *original_var;
241
242                 /* change variable name to "ECPG_informix_get_var(<counter>)" */
243                 original_var = ptr->variable->name;
244                 sprintf(temp, "%d))", ecpg_informix_var);
245
246                 if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
247                 {
248                         ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
249                         sprintf(temp, "%d, (", ecpg_informix_var++);
250                 }
251                 else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
252                 {
253                         ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
254                         sprintf(temp, "%d, (", ecpg_informix_var++);
255                 }
256                 else
257                 {
258                         ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
259                         sprintf(temp, "%d, &(", ecpg_informix_var++);
260                 }
261
262                 /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
263                 result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
264
265                 /* now the indicator if there is one */
266                 if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
267                 {
268                         /* change variable name to "ECPG_informix_get_var(<counter>)" */
269                         original_var = ptr->indicator->name;
270                         sprintf(temp, "%d))", ecpg_informix_var);
271
272                         /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
273                         if (atoi(ptr->indicator->type->size) > 1)
274                         {
275                                 ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
276                                 sprintf(temp, "%d, (", ecpg_informix_var++);
277                         }
278                         else
279                         {
280                                 ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
281                                 sprintf(temp, "%d, &(", ecpg_informix_var++);
282                         }
283                         result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
284                 }
285          }
286
287          return result;
288 }
289
290 static struct cursor *
291 add_additional_variables(char *name, bool insert)
292 {
293         struct cursor *ptr;
294         struct arguments *p;
295
296         for (ptr = cur; ptr != NULL; ptr=ptr->next)
297         {
298                 if (strcmp(ptr->name, name) == 0)
299                         break;
300         }
301
302         if (ptr == NULL)
303         {
304                 mmerror(PARSE_ERROR, ET_ERROR, "trying to access an undeclared cursor %s\n", name);
305                 return NULL;
306         }
307
308         if (insert)
309         {
310                 /* add all those input variables that were given earlier
311                  * note that we have to append here but have to keep the existing order */
312                 for (p = ptr->argsinsert; p; p = p->next)
313                         add_variable_to_tail(&argsinsert, p->variable, p->indicator);
314         }
315
316         /* add all those output variables that were given earlier */
317         for (p = ptr->argsresult; p; p = p->next)
318                 add_variable_to_tail(&argsresult, p->variable, p->indicator);
319
320         return ptr;
321 }
322
323 static void
324 add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
325 {
326         /* add entry to list */
327         struct typedefs *ptr, *this;
328
329         if ((type_enum == ECPGt_struct ||
330              type_enum == ECPGt_union) &&
331             initializer == 1)
332                 mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
333         else
334         {
335                 for (ptr = types; ptr != NULL; ptr = ptr->next)
336                 {
337                         if (strcmp(name, ptr->name) == 0)
338                                 /* re-definition is a bug */
339                                 mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", name);
340                 }
341                 adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
342
343                 this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
344
345                 /* initial definition */
346                 this->next = types;
347                 this->name = name;
348                 this->brace_level = braces_open;
349                 this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
350                 this->type->type_enum = type_enum;
351                 this->type->type_str = mm_strdup(name);
352                 this->type->type_dimension = dimension; /* dimension of array */
353                 this->type->type_index = length;        /* length of string */
354                 this->type->type_sizeof = ECPGstruct_sizeof;
355                 this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
356                 ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
357
358                 if (type_enum != ECPGt_varchar &&
359                         type_enum != ECPGt_char &&
360                         type_enum != ECPGt_unsigned_char &&
361                         atoi(this->type->type_index) >= 0)
362                         mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
363
364                 types = this;
365         }
366 }
367 %}
368
369 %name-prefix="base_yy"
370 %locations
371
372 %union {
373         double  dval;
374         char    *str;
375         int     ival;
376         struct  when            action;
377         struct  index           index;
378         int             tagname;
379         struct  this_type       type;
380         enum    ECPGttype       type_enum;
381         enum    ECPGdtype       dtype_enum;
382         struct  fetch_desc      descriptor;
383         struct  su_symbol       struct_union;
384         struct  prep            prep;
385 }
386
387 /* special embedded SQL token */
388 %token  SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
389                 SQL_CALL SQL_CARDINALITY SQL_CONNECT
390                 SQL_CONTINUE SQL_COUNT SQL_DATA
391                 SQL_DATETIME_INTERVAL_CODE
392                 SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
393                 SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND
394                 SQL_FREE SQL_GO SQL_GOTO SQL_IDENTIFIED
395                 SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
396                 SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
397                 SQL_OPEN SQL_OUTPUT SQL_REFERENCE
398                 SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
399                 SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
400                 SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
401                 SQL_STRUCT SQL_UNSIGNED SQL_VAR SQL_WHENEVER
402
403 /* C token */
404 %token  S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV
405                 S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
406                 S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
407                 S_STATIC S_SUB S_VOLATILE
408                 S_TYPEDEF
409
410 /* I need this and don't know where it is defined inside the backend */
411 %token  TYPECAST
412
413 /* ordinary key words in alphabetical order */
414 %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
415         AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
416         ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
417
418         BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
419         BOOLEAN_P BOTH BY
420
421         CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
422         CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
423         CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
424         COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
425         CONTENT_P CONVERSION_P COPY COST CREATE CREATEDB
426         CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
427         CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
428
429         DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
430         DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
431         DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
432
433         EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT EXCLUSIVE EXCLUDING
434         EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
435
436         FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
437         FULL FUNCTION
438
439         GET GLOBAL GRANT GRANTED GREATEST GROUP_P
440
441         HANDLER HAVING HEADER_P HOLD HOUR_P
442
443         IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
444         INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
445         INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
446         INTERVAL INTO INVOKER IS ISNULL ISOLATION
447
448         JOIN
449
450         KEY
451
452         LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
453         LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
454         LOCK_P LOGIN_P
455
456         MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
457
458         NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
459         NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
460         NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC
461
462         OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
463         OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
464
465         PARSER PARTIAL PASSWORD PLACING PLANS POSITION
466         PRECISION PRESERVE PREPARE PREPARED PRIMARY
467         PRIOR PRIVILEGES PROCEDURAL PROCEDURE
468
469         QUOTE
470
471         READ REAL REASSIGN RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
472         REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
473         RIGHT ROLE ROLLBACK ROW ROWS RULE
474
475         SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
476         SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
477         SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
478         STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
479         SYMMETRIC SYSID SYSTEM_P
480
481         TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO 
482         TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
483
484         UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
485         UPDATE USER USING
486
487         VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
488         VERBOSE VERSION_P VIEW VOLATILE
489         WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
490
491         XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
492         XMLPI XMLROOT XMLSERIALIZE
493
494         YEAR_P YES_P
495
496         ZONE
497
498 /* The grammar thinks these are keywords, but they are not in the keywords.c
499  * list and so can never be entered directly.  The filter in parser.c
500  * creates these tokens when required.
501  */
502 %token           NULLS_FIRST NULLS_LAST WITH_CASCADED WITH_LOCAL WITH_CHECK
503
504 /* Special token types, not actually keywords - see the "lex" file */
505 %token <str>    IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST
506 %token <str>    XCONST DOLCONST ECONST NCONST
507 %token <ival>   ICONST PARAM
508 %token <dval>   FCONST
509
510 /* precedence: lowest to highest */
511 %nonassoc       SET                             /* see relation_expr_opt_alias */
512 %left           UNION EXCEPT
513 %left           INTERSECT
514 %left           OR
515 %left           AND
516 %right          NOT
517 %right          '='
518 %nonassoc       '<' '>'
519 %nonassoc       LIKE ILIKE SIMILAR
520 %nonassoc       ESCAPE
521 %nonassoc       OVERLAPS
522 %nonassoc       BETWEEN
523 %nonassoc       IN_P
524 %left           POSTFIXOP                                       /* dummy for postfix Op rules */
525 %left           Op OPERATOR                             /* multi-character ops and user-defined operators */
526 %nonassoc       NOTNULL
527 %nonassoc       ISNULL
528 %nonassoc       IS NULL_P TRUE_P FALSE_P UNKNOWN
529 %left           '+' '-'
530 %left           '*' '/' '%'
531 %left           '^'
532 /* Unary Operators */
533 %left           AT ZONE
534 %right          UMINUS
535 %left           '[' ']'
536 %left           '(' ')'
537 %left           TYPECAST
538 %left           '.'
539 %left           JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
540 /* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
541 %right         PRESERVE STRIP_P
542
543 %type  <str>    Iconst Fconst Sconst TransactionStmt CreateStmt RoleId
544 %type  <str>    CreateAsElement OptCreateAs CreateAsList CreateAsStmt
545 %type  <str>    comment_text ConstraintDeferrabilitySpec TableElementList
546 %type  <str>    key_match ColLabel SpecialRuleRelation ColId columnDef
547 %type  <str>    ColConstraint ColConstraintElem drop_type Bconst Iresult
548 %type  <str>    TableConstraint OptTableElementList Xconst opt_transaction
549 %type  <str>    ConstraintElem key_actions ColQualList cluster_index_specification
550 %type  <str>    target_list target_el alias_clause type_func_name_keyword
551 %type  <str>    qualified_name database_name alter_using type_function_name
552 %type  <str>    access_method attr_name index_name name func_name
553 %type  <str>    file_name AexprConst c_expr ConstTypename var_list
554 %type  <str>    a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
555 %type  <str>    opt_indirection expr_list extract_list extract_arg
556 %type  <str>    position_list substr_list substr_from alter_column_default
557 %type  <str>    trim_list in_expr substr_for attrs TableFuncElement
558 %type  <str>    Typename SimpleTypename Numeric opt_float DiscardStmt
559 %type  <str>    Character character opt_varying opt_charset enum_val_list
560 %type  <str>    opt_timezone opt_interval table_ref fetch_direction
561 %type  <str>    ConstDatetime AlterDomainStmt AlterSeqStmt alter_rel_cmds
562 %type  <str>    SelectStmt into_clause OptTemp ConstraintAttributeSpec
563 %type  <str>    opt_table opt_all sort_clause sortby_list ConstraintAttr
564 %type  <str>    sortby qualified_name_list name_list ColId_or_Sconst
565 %type  <str>    group_clause having_clause from_clause opt_distinct opt_hold
566 %type  <str>    join_outer where_clause relation_expr sub_type arg_class
567 %type  <str>    opt_column_list insert_rest InsertStmt param_name
568 %type  <str>    columnList DeleteStmt UpdateStmt DeclareCursorStmt
569 %type  <str>    NotifyStmt columnElem UnlistenStmt TableElement
570 %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
571 %type  <str>    FetchStmt from_in CreateOpClassStmt returning_clause
572 %type  <str>    ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
573 %type  <str>    opt_full func_arg OptWith opt_freeze alter_table_cmd
574 %type  <str>    analyze_keyword opt_name_list ExplainStmt index_params
575 %type  <str>    index_elem opt_class access_method_clause alter_table_cmds
576 %type  <str>    index_opt_unique IndexStmt func_return ConstInterval
577 %type  <str>    func_args_list func_args opt_with def_arg overlay_placing
578 %type  <str>    def_elem def_list definition DefineStmt select_with_parens
579 %type  <str>    opt_instead event RuleActionList opt_using CreateAssertStmt
580 %type  <str>    RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
581 %type  <str>    RuleStmt opt_column oper_argtypes NumConst var_name
582 %type  <str>    MathOp RemoveFuncStmt ECPGunreserved_con opt_database_name
583 %type  <str>    RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
584 %type  <str>    RemoveOperStmt RenameStmt all_Op opt_trusted opt_lancompiler
585 %type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
586 %type  <str>    VariableResetStmt AlterTableStmt from_list overlay_list
587 %type  <str>    relation_name OptTableSpace LockStmt opt_lock 
588 %type  <str>    CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
589 %type  <str>    OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
590 %type  <str>    DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
591 %type  <str>    TriggerActionTime CreateTrigStmt DropPLangStmt DropCastStmt
592 %type  <str>    CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
593 %type  <str>    ViewStmt LoadStmt CreatedbStmt createdb_opt_item ExplainableStmt
594 %type  <str>    createdb_opt_list opt_encoding OptInherit opt_equal
595 %type  <str>    privilege_list privilege privilege_target opt_if_exists
596 %type  <str>    opt_grant_grant_option cursor_options DropOwnedStmt
597 %type  <str>    transaction_mode_list_or_empty transaction_mode_list
598 %type  <str>    function_with_argtypes_list function_with_argtypes IntConstVar
599 %type  <str>    DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
600 %type  <str>    GrantStmt privileges PosAllConst constraints_set_list
601 %type  <str>    ConstraintsSetStmt AllConst CreateDomainStmt opt_nowait
602 %type  <str>    case_expr when_clause_list case_default case_arg when_clause
603 %type  <str>    select_clause opt_select_limit select_limit_value opt_recheck
604 %type  <str>    ConstraintTimeSpec AlterDatabaseSetStmt DropAssertStmt
605 %type  <str>    select_offset_value ReindexStmt join_type opt_boolean
606 %type  <str>    join_qual joined_table opclass_item relation_expr_opt_alias
607 %type  <str>    lock_type array_expr_list ReassignOwnedStmt for_locking_item
608 %type  <str>    OptConstrFromTable OptTempTableName StringConst array_expr
609 %type  <str>    constraints_set_mode comment_type opt_check_option
610 %type  <str>    CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
611 %type  <str>    opt_force key_update CreateSchemaStmt PosIntStringConst
612 %type  <str>    IntConst PosIntConst grantee_list func_type opt_or_replace
613 %type  <str>    select_limit CheckPointStmt ECPGColId old_aggr_list
614 %type  <str>    OptSchemaName OptSchemaEltList schema_stmt opt_drop_behavior
615 %type  <str>    handler_name any_name_list any_name opt_as insert_column_list
616 %type  <str>    columnref values_clause AllConstVar prep_type_clause ExecuteStmt
617 %type  <str>    insert_column_item DropRuleStmt ctext_expr execute_param_clause 
618 %type  <str>    createfunc_opt_item set_rest alter_rel_cmd
619 %type  <str>    CreateFunctionStmt createfunc_opt_list func_table
620 %type  <str>    DropUserStmt copy_from copy_opt_list copy_opt_item
621 %type  <str>    opt_oids TableLikeClause key_action opt_definition
622 %type  <str>    cast_context row qual_Op qual_all_Op opt_default
623 %type  <str>    CreateConversionStmt any_operator opclass_item_list
624 %type  <str>    iso_level type_list CharacterWithLength ConstCharacter
625 %type  <str>    CharacterWithoutLength BitWithLength BitWithoutLength
626 %type  <str>    ConstBit GenericType TableFuncElementList opt_analyze
627 %type  <str>    opt_sort_clause subquery_Op transaction_mode_item
628 %type  <str>    ECPGWhenever ECPGConnect connection_target ECPGOpen
629 %type  <str>    indicator ecpg_using ecpg_into DeallocateStmt
630 %type  <str>    storage_declaration storage_clause opt_initializer c_anything
631 %type  <str>    variable_list variable c_thing c_term ECPGKeywords_vanames
632 %type  <str>    opt_pointer ECPGDisconnect dis_name storage_modifier
633 %type  <str>    execstring server_name ECPGVarDeclaration func_expr
634 %type  <str>    connection_object opt_server opt_port c_stuff c_stuff_item
635 %type  <str>    user_name opt_user char_variable ora_user ident opt_reference
636 %type  <str>    var_type_declarations quoted_ident_stringvar ECPGKeywords_rest
637 %type  <str>    db_prefix server opt_options opt_connection_name c_list
638 %type  <str>    ECPGSetConnection ECPGTypedef c_args ECPGKeywords ECPGCKeywords
639 %type  <str>    enum_type civar civarind ECPGCursorStmt PreparableStmt
640 %type  <str>    ECPGFree ECPGDeclare ECPGVar at enum_definition
641 %type  <str>    struct_union_type s_struct_union vt_declarations execute_rest
642 %type  <str>    var_declaration type_declaration single_vt_declaration
643 %type  <str>    ECPGSetAutocommit on_off variable_declarations ECPGDescribe
644 %type  <str>    ECPGAllocateDescr ECPGDeallocateDescr symbol opt_output
645 %type  <str>    ECPGGetDescriptorHeader ECPGColLabel SetResetClause AlterUserSetStmt
646 %type  <str>    reserved_keyword unreserved_keyword ecpg_interval opt_ecpg_using
647 %type  <str>    col_name_keyword precision opt_scale ECPGExecuteImmediateStmt
648 %type  <str>    ECPGTypeName using_list ECPGColLabelCommon UsingConst 
649 %type  <str>    using_descriptor into_descriptor opt_nulls_order opt_asc_desc
650 %type  <str>    prepared_name struct_union_type_with_symbol OptConsTableSpace
651 %type  <str>    ECPGunreserved ECPGunreserved_interval cvariable opt_bit_field
652 %type  <str>    AlterOwnerStmt OptTableSpaceOwner CreateTableSpaceStmt
653 %type  <str>    DropTableSpaceStmt indirection indirection_el ECPGSetDescriptorHeader
654 %type  <str>    AlterDatabaseStmt CreateRoleStmt OptRoleList AlterRoleStmt AlterRoleSetStmt
655 %type  <str>    DropRoleStmt add_drop opt_validator common_func_opt_item
656 %type  <str>    opt_grant_admin_option AlterFunctionStmt alterfunc_opt_list opt_restrict
657 %type  <str>    AlterObjectSchemaStmt alterdb_opt_list for_locking_clause opt_for_locking_clause
658 %type  <str>    locked_rels_list opt_granted_by RevokeRoleStmt alterdb_opt_item using_clause
659 %type  <str>    GrantRoleStmt opt_asymmetric aggr_args old_aggr_definition
660 %type  <str>    old_aggr_elem for_locking_items TableLikeOptionList TableLikeOption
661 %type  <str>    set_target_list set_clause_list set_clause multiple_set_clause
662 %type  <str>    ctext_expr_list ctext_row single_set_clause set_target opt_type_modifiers
663 %type  <str>    opclass_drop_list opclass_drop DropOpFamilyStmt opt_opfamily
664 %type  <str>    CreateOpFamilyStmt AlterOpFamilyStmt create_as_target
665 %type  <str>    xml_attributes xml_attribute_list document_or_content xml_whitespace_option
666 %type  <str>    opt_xml_root_standalone xml_root_version xml_attribute_el 
667 %type  <str>    where_or_current_clause AlterTSConfigurationStmt AlterTSDictionaryStmt
668
669 %type  <struct_union> s_struct_union_symbol
670
671 %type  <descriptor> ECPGGetDescriptor ECPGSetDescriptor
672
673 %type  <type_enum> simple_type signed_type unsigned_type
674
675 %type  <dtype_enum> descriptor_item desc_header_item
676
677 %type  <type>   var_type
678
679 %type  <prep>   PrepareStmt
680
681 %type  <action> action
682
683 %type  <index>  opt_array_bounds
684
685 %%
686 prog: statements;
687
688 statements: /*EMPTY*/
689                 | statements statement
690                 ;
691
692 statement: ecpgstart at stmt ';'        { connection = NULL; }
693                 | ecpgstart stmt ';'
694                 | ecpgstart ECPGVarDeclaration
695                 {
696                         fprintf(yyout, "%s", $2);
697                         free($2);
698                         output_line_number();
699                 }
700                 | ECPGDeclaration
701                 | c_thing               { fprintf(yyout, "%s", $1); free($1); }
702                 | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
703                 | '{'                   { braces_open++; fputs("{", yyout); }
704                 | '}'                   { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); }
705                 ;
706
707 at: AT connection_object
708                 {
709                         connection = $2;
710                         /*
711                          *      Do we have a variable as connection target?
712                          *      Remove the variable from the variable
713                          *      list or else it will be used twice
714                          */
715                         if (argsinsert != NULL)
716                                 argsinsert = NULL;
717                 }
718         ;
719
720 stmt:  AlterDatabaseStmt                { output_statement($1, 0, ECPGst_normal); }
721                 | AlterDatabaseSetStmt  { output_statement($1, 0, ECPGst_normal); }
722                 | AlterDomainStmt       { output_statement($1, 0, ECPGst_normal); }
723                 | AlterFunctionStmt     { output_statement($1, 0, ECPGst_normal); }
724                 | AlterGroupStmt        { output_statement($1, 0, ECPGst_normal); }
725                 | AlterObjectSchemaStmt { output_statement($1, 0, ECPGst_normal); }
726                 | AlterOwnerStmt        { output_statement($1, 0, ECPGst_normal); }
727                 | AlterSeqStmt          { output_statement($1, 0, ECPGst_normal); }
728                 | AlterTableStmt        { output_statement($1, 0, ECPGst_normal); }
729                 | AlterRoleSetStmt      { output_statement($1, 0, ECPGst_normal); }
730                 | AlterRoleStmt         { output_statement($1, 0, ECPGst_normal); }
731                 | AlterTSConfigurationStmt      { output_statement($1, 0, ECPGst_normal); }
732                 | AlterTSDictionaryStmt { output_statement($1, 0, ECPGst_normal); }
733                 | AlterUserStmt         { output_statement($1, 0, ECPGst_normal); }
734                 | AlterUserSetStmt      { output_statement($1, 0, ECPGst_normal); }
735                 | AnalyzeStmt           { output_statement($1, 0, ECPGst_normal); }
736                 | CheckPointStmt        { output_statement($1, 0, ECPGst_normal); }
737                 | ClosePortalStmt
738                 {
739                         if (INFORMIX_MODE)
740                         {
741                                 /*
742                                  *      Informix also has a CLOSE DATABASE command that
743                                  *      essantially works like a DISCONNECT CURRENT
744                                  *      as far as I know.
745                                  */
746                                 if (pg_strcasecmp($1+strlen("close "), "database") == 0)
747                                 {
748                                         if (connection)
749                                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement.\n");
750
751                                         fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
752                                         whenever_action(2);
753                                         free($1);
754                                 }
755                                 else
756                                         output_statement($1, 0, ECPGst_normal);
757                         }
758                         else
759                                 output_statement($1, 0, ECPGst_normal);
760                 }
761                 | ClusterStmt           { output_statement($1, 0, ECPGst_normal); }
762                 | CommentStmt           { output_statement($1, 0, ECPGst_normal); }
763                 | ConstraintsSetStmt    { output_statement($1, 0, ECPGst_normal); }
764                 | CopyStmt              { output_statement($1, 0, ECPGst_normal); }
765                 | CreateAsStmt          { output_statement($1, 0, ECPGst_normal); }
766                 | CreateAssertStmt      { output_statement($1, 0, ECPGst_normal); }
767                 | CreateCastStmt        { output_statement($1, 0, ECPGst_normal); }
768                 | CreateConversionStmt  { output_statement($1, 0, ECPGst_normal); }
769                 | CreateDomainStmt      { output_statement($1, 0, ECPGst_normal); }
770                 | CreateFunctionStmt    { output_statement($1, 0, ECPGst_normal); }
771                 | CreateGroupStmt       { output_statement($1, 0, ECPGst_normal); }
772                 | CreatePLangStmt       { output_statement($1, 0, ECPGst_normal); }
773                 | CreateOpClassStmt     { output_statement($1, 0, ECPGst_normal); }
774                 | CreateOpFamilyStmt    { output_statement($1, 0, ECPGst_normal); }
775                 | AlterOpFamilyStmt     { output_statement($1, 0, ECPGst_normal); }
776                 | CreateRoleStmt        { output_statement($1, 0, ECPGst_normal); }
777                 | CreateSchemaStmt      { output_statement($1, 0, ECPGst_normal); }
778                 | CreateSeqStmt         { output_statement($1, 0, ECPGst_normal); }
779                 | CreateStmt            { output_statement($1, 0, ECPGst_normal); }
780                 | CreateTableSpaceStmt  { output_statement($1, 0, ECPGst_normal); }
781                 | CreateTrigStmt        { output_statement($1, 0, ECPGst_normal); }
782                 | CreateUserStmt        { output_statement($1, 0, ECPGst_normal); }
783                 | CreatedbStmt          { output_statement($1, 0, ECPGst_normal); }
784                 | DeallocateStmt
785                 {
786                         if (connection)
787                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement.\n");
788                                 
789                         output_deallocate_prepare_statement($1);
790                 }
791                 | DeclareCursorStmt     { output_simple_statement($1); }
792                 | DefineStmt            { output_statement($1, 0, ECPGst_normal); }
793                 | DeleteStmt            { output_statement($1, 1, ECPGst_normal); }
794                 | DiscardStmt           { output_statement($1, 1, ECPGst_normal); }
795                 | DropAssertStmt        { output_statement($1, 0, ECPGst_normal); }
796                 | DropCastStmt          { output_statement($1, 0, ECPGst_normal); }
797                 | DropGroupStmt         { output_statement($1, 0, ECPGst_normal); }
798                 | DropOpClassStmt       { output_statement($1, 0, ECPGst_normal); }
799                 | DropOpFamilyStmt      { output_statement($1, 0, ECPGst_normal); }
800                 | DropOwnedStmt         { output_statement($1, 0, ECPGst_normal); }
801                 | DropPLangStmt         { output_statement($1, 0, ECPGst_normal); }
802                 | DropRoleStmt          { output_statement($1, 0, ECPGst_normal); }
803                 | DropRuleStmt          { output_statement($1, 0, ECPGst_normal); }
804                 | DropStmt              { output_statement($1, 0, ECPGst_normal); }
805                 | DropTableSpaceStmt    { output_statement($1, 0, ECPGst_normal); }
806                 | DropTrigStmt          { output_statement($1, 0, ECPGst_normal); }
807                 | DropUserStmt          { output_statement($1, 0, ECPGst_normal); }
808                 | DropdbStmt            { output_statement($1, 0, ECPGst_normal); }
809                 | ExplainStmt           { output_statement($1, 0, ECPGst_normal); }
810                 | ExecuteStmt           { output_statement($1, 0, ECPGst_execute); }
811                 | FetchStmt             { output_statement($1, 1, ECPGst_normal); }
812                 | GrantStmt             { output_statement($1, 0, ECPGst_normal); }
813                 | GrantRoleStmt         { output_statement($1, 0, ECPGst_normal); }
814                 | IndexStmt             { output_statement($1, 0, ECPGst_normal); }
815                 | InsertStmt            { output_statement($1, 1, ECPGst_normal); }
816                 | ListenStmt            { output_statement($1, 0, ECPGst_normal); }
817                 | LoadStmt              { output_statement($1, 0, ECPGst_normal); }
818                 | LockStmt              { output_statement($1, 0, ECPGst_normal); }
819                 | NotifyStmt            { output_statement($1, 0, ECPGst_normal); }
820                 | PrepareStmt           { 
821                                                 if ($1.type == NULL || strlen($1.type) == 0) /* use PQprepare without type parameters */
822                                                         output_prepare_statement($1.name, $1.stmt);  
823                                                 else    /* use PQexec and let backend do its stuff */
824                                                 {
825                                                         char *txt = cat_str(5, make_str("prepare"), $1.name, $1.type, make_str("as"), $1.stmt);
826                                                         output_statement(txt, 0, ECPGst_normal);
827                                                 }
828                                         }               
829                 | ReassignOwnedStmt     { output_statement($1, 0, ECPGst_normal); }
830                 | ReindexStmt           { output_statement($1, 0, ECPGst_normal); }
831                 | RemoveAggrStmt        { output_statement($1, 0, ECPGst_normal); }
832                 | RemoveOperStmt        { output_statement($1, 0, ECPGst_normal); }
833                 | RemoveFuncStmt        { output_statement($1, 0, ECPGst_normal); }
834                 | RenameStmt            { output_statement($1, 0, ECPGst_normal); }
835                 | RevokeStmt            { output_statement($1, 0, ECPGst_normal); }
836                 | RevokeRoleStmt        { output_statement($1, 0, ECPGst_normal); }
837                 | RuleStmt              { output_statement($1, 0, ECPGst_normal); }
838                 | SelectStmt            { output_statement($1, 1, ECPGst_normal); }
839                 | TransactionStmt
840                 {
841                         fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
842                         whenever_action(2);
843                         free($1);
844                 }
845                 | TruncateStmt          { output_statement($1, 0, ECPGst_normal); }
846                 | UnlistenStmt          { output_statement($1, 0, ECPGst_normal); }
847                 | UpdateStmt            { output_statement($1, 1, ECPGst_normal); }
848                 | VacuumStmt            { output_statement($1, 0, ECPGst_normal); }
849                 | VariableSetStmt       { output_statement($1, 0, ECPGst_normal); }
850                 | VariableShowStmt      { output_statement($1, 0, ECPGst_normal); }
851                 | VariableResetStmt     { output_statement($1, 0, ECPGst_normal); }
852                 | ViewStmt              { output_statement($1, 0, ECPGst_normal); }
853                 | ECPGAllocateDescr
854                 {
855                         fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
856                         whenever_action(0);
857                         free($1);
858                 }
859                 | ECPGConnect
860                 {
861                         if (connection)
862                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
863
864                         fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
865                         reset_variables();
866                         whenever_action(2);
867                         free($1);
868                 }
869                 | ECPGCursorStmt
870                 {
871                         output_simple_statement($1);
872                 }
873                 | ECPGDeallocateDescr
874                 {
875                         if (connection)
876                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement.\n");
877                         fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
878                         whenever_action(0);
879                         free($1);
880                 }
881                 | ECPGDeclare
882                 {
883                         output_simple_statement($1);
884                 }
885                 | ECPGDescribe
886                 {
887                         fprintf(yyout, "{ ECPGdescribe(__LINE__, %s,", $1);
888                         dump_variables(argsresult, 1);
889                         fputs("ECPGt_EORT);", yyout);
890                         fprintf(yyout, "}");
891                         output_line_number();
892
893                         /* whenever_action(2); */
894                         free($1);
895                 }
896                 | ECPGDisconnect
897                 {
898                         if (connection)
899                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement.\n");
900
901                         fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);",
902                                         $1 ? $1 : "\"CURRENT\"");
903                         whenever_action(2);
904                         free($1);
905                 }
906                 | ECPGExecuteImmediateStmt      { output_statement($1, 0, ECPGst_exec_immediate); }
907                 | ECPGFree
908                 {
909                         const char *con = connection ? connection : "NULL";
910                         if (strcmp($1, "all"))
911                                 fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, \"%s\");", compat, con, $1);
912                         else
913                                 fprintf(yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
914
915                         whenever_action(2);
916                         free($1);
917                 }
918                 | ECPGGetDescriptor
919                 {
920                         lookup_descriptor($1.name, connection);
921                         output_get_descr($1.name, $1.str);
922                         free($1.name);
923                         free($1.str);
924                 }
925                 | ECPGGetDescriptorHeader
926                 {
927                         lookup_descriptor($1, connection);
928                         output_get_descr_header($1);
929                         free($1);
930                 }
931                 | ECPGOpen
932                 {
933                         struct cursor *ptr;
934
935                         if ((ptr = add_additional_variables($1, true)) != NULL)
936                         {
937                                 connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
938                                 output_statement(mm_strdup(ptr->command), 0, 0);
939                                 ptr->opened = true;
940                         }
941                 }
942                 | ECPGSetAutocommit
943                 {
944                         fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
945                         whenever_action(2);
946                         free($1);
947                 }
948                 | ECPGSetConnection
949                 {
950                         if (connection)
951                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
952
953                         fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
954                         whenever_action(2);
955                         free($1);
956                 }
957                 | ECPGSetDescriptor
958                 {
959                         lookup_descriptor($1.name, connection);
960                         output_set_descr($1.name, $1.str);
961                         free($1.name);
962                         free($1.str);
963                 }
964                 | ECPGSetDescriptorHeader
965                 {
966                         lookup_descriptor($1, connection);
967                         output_set_descr_header($1);
968                         free($1);
969                 }
970                 | ECPGTypedef
971                 {
972                         if (connection)
973                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement.\n");
974
975                         fprintf(yyout, "%s", $1);
976                         free($1);
977                         output_line_number();
978                 }
979                 | ECPGVar
980                 {
981                         if (connection)
982                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement.\n");
983
984                         output_simple_statement($1);
985                 }
986                 | ECPGWhenever
987                 {
988                         if (connection)
989                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement.\n");
990
991                         output_simple_statement($1);
992                 }
993                 ;
994
995
996 /*
997  * We start with a lot of stuff that's very similar to the backend's parsing
998  */
999
1000 /*****************************************************************************
1001  *
1002  * Create a new Postgres DBMS role
1003  *
1004  *
1005  *****************************************************************************/
1006
1007 CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList
1008                         { $$ = cat_str(4, make_str("create role"), $3, make_str("with"), $5); }
1009                 ;
1010
1011 opt_with:  WITH                 { $$ = make_str("with"); }
1012                 | /*EMPTY*/     { $$ = EMPTY; }
1013                 ;
1014
1015 /*
1016  * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER
1017  * for backwards compatibility).  Note: the only option required by SQL99
1018  * is "WITH ADMIN name".
1019  */
1020 OptRoleList:
1021         PASSWORD Sconst                 { $$ = cat2_str(make_str("password"), $2); }
1022         | PASSWORD NULL_P               { $$ = make_str("password null"); }
1023         | ENCRYPTED PASSWORD Sconst     { $$ = cat2_str(make_str("encrypted password"), $3); }
1024         | UNENCRYPTED PASSWORD Sconst   { $$ = cat2_str(make_str("unencrypted password"), $3); }
1025         | SUPERUSER_P                   { $$ = make_str("superuser"); }
1026         | NOSUPERUSER                   { $$ = make_str("nosuperuser"); }
1027         | INHERIT                               { $$ = make_str("inherit"); }
1028         | NOINHERIT                             { $$ = make_str("noinherit"); }
1029         | CREATEDB                              { $$ = make_str("createdb"); }
1030         | NOCREATEDB                    { $$ = make_str("nocreatedb"); }
1031         | CREATEROLE                    { $$ = make_str("createrole"); }
1032         | NOCREATEROLE                  { $$ = make_str("nocreaterole"); }
1033         | LOGIN_P                               { $$ = make_str("login"); }
1034         | NOLOGIN_P                             { $$ = make_str("nologin"); }
1035         | CONNECTION LIMIT IntConst     { $$ = cat2_str(make_str("connection limit"), $3); }
1036         | VALID UNTIL Sconst            { $$ = cat2_str(make_str("valid until"), $3); }
1037         | USER name_list                { $$ = cat2_str(make_str("user"), $2); }
1038         | SYSID PosIntConst             { $$ = cat2_str(make_str("sysid"), $2); }
1039         | ADMIN name_list               { $$ = cat2_str(make_str("admin"), $2); }
1040         | ROLE name_list                { $$ = cat2_str(make_str("role"), $2); }
1041         | IN_P ROLE name_list   { $$ = cat2_str(make_str("in role"), $3); }
1042         | IN_P GROUP_P name_list        { $$ = cat2_str(make_str("in group"), $3); }
1043         ;
1044
1045 /*****************************************************************************
1046  *
1047  * Create a new Postgres DBMS user (role with implied login ability)
1048  *
1049  *****************************************************************************/
1050
1051 CreateUserStmt:
1052         CREATE USER RoleId opt_with OptRoleList
1053                 {$$ = cat_str(4, make_str("create user"), $3, $4, $5); }
1054         ;
1055
1056         /*****************************************************************************
1057          *
1058          * Alter a postgresql DBMS role
1059          *
1060          *
1061          *****************************************************************************/
1062
1063         AlterRoleStmt: ALTER ROLE RoleId opt_with OptRoleList
1064                         { $$ = cat_str(4, make_str("alter role"), $3, $4, $5); }
1065                 ;
1066
1067         AlterRoleSetStmt: ALTER ROLE RoleId SetResetClause
1068                         { $$ = cat_str(3, make_str("alter role"), $3, $4); }
1069                 ;
1070
1071         /*****************************************************************************
1072          *
1073          * Alter a postgresql DBMS user
1074          *
1075          *****************************************************************************/
1076
1077         AlterUserStmt: ALTER USER RoleId opt_with OptRoleList
1078                 { $$ = cat_str(4, make_str("alter user"), $3, $4, $5); };
1079
1080         AlterUserSetStmt: ALTER USER RoleId SetResetClause
1081                         { $$ = cat_str(3, make_str("alter user"), $3, $4); }
1082                 ;
1083
1084         /*****************************************************************************
1085          *
1086          * Drop a postgresql DBMS role
1087          *
1088          *
1089          *****************************************************************************/
1090         DropRoleStmt:  DROP ROLE name_list
1091                         { $$ = cat2_str(make_str("drop role"), $3);}
1092                      | DROP ROLE IF_P EXISTS name_list
1093                         { $$ = cat2_str(make_str("drop role if exists"), $5);}
1094                 ;
1095
1096         /*****************************************************************************
1097          *
1098          * Drop a postgresql DBMS user
1099          *
1100          *
1101          *****************************************************************************/
1102         DropUserStmt:  DROP USER name_list
1103                         { $$ = cat2_str(make_str("drop user"), $3);}
1104                      | DROP USER IF_P EXISTS name_list
1105                         { $$ = cat2_str(make_str("drop user if exists"), $5);}
1106
1107                 ;
1108
1109         /*****************************************************************************
1110          *
1111          * Create a postgresql group
1112          *
1113          *
1114          ****************************************************************************/
1115         CreateGroupStmt:  CREATE GROUP_P RoleId opt_with OptRoleList
1116                         { $$ = cat_str(4, make_str("create group"), $3, $4, $5); }
1117                 ;
1118
1119         /*****************************************************************************
1120          *
1121          * Alter a postgresql group
1122          *
1123          *
1124          *****************************************************************************/
1125         AlterGroupStmt: ALTER GROUP_P RoleId add_drop USER name_list
1126                         { $$ = cat_str(5, make_str("alter group"), $3, $4, make_str("user"), $6); }
1127                 ;
1128
1129         add_drop: ADD_P         { $$ = make_str("add"); }
1130                 | DROP          { $$ = make_str("drop"); }
1131                 ;
1132
1133         /*****************************************************************************
1134          *
1135          * Drop a postgresql group
1136          *
1137          *
1138          *****************************************************************************/
1139         DropGroupStmt: DROP GROUP_P name_list
1140                         { $$ = cat2_str(make_str("drop group"), $3); }
1141                      | DROP GROUP_P IF_P EXISTS name_list
1142                         { $$ = cat2_str(make_str("drop group if exists"), $5); }
1143                 ;
1144
1145         /*****************************************************************************
1146          *
1147          * Manipulate a schema
1148          *
1149          *
1150          *****************************************************************************/
1151
1152         CreateSchemaStmt:  CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
1153                         { $$ = cat_str(5, make_str("create schema"), $3, make_str("authorization"), $5, $6); }
1154                 | CREATE SCHEMA ColId OptSchemaEltList
1155                         { $$ = cat_str(3, make_str("create schema"), $3, $4); }
1156                 ;
1157
1158         OptSchemaName: ColId            { $$ = $1; }
1159                 | /* EMPTY */   { $$ = EMPTY; }
1160                 ;
1161
1162 OptSchemaEltList: OptSchemaEltList schema_stmt         { $$ = cat2_str($1, $2); }
1163                 | /* EMPTY */   { $$ = EMPTY; }
1164                 ;
1165
1166 /*
1167  *     schema_stmt are the ones that can show up inside a CREATE SCHEMA
1168  *     statement (in addition to by themselves).
1169  */
1170 schema_stmt: CreateStmt         { $$ = $1; }
1171                    | IndexStmt          { $$ = $1; }
1172                    | CreateSeqStmt      { $$ = $1; }
1173                    | CreateTrigStmt { $$ = $1; }
1174                    | GrantStmt          { $$ = $1; }
1175                    | ViewStmt           { $$ = $1; }
1176                    ;
1177
1178
1179
1180 /*****************************************************************************
1181  *
1182  * Set PG internal variable
1183  *        SET name TO 'var_value'
1184  * Include SQL92 syntax (thomas 1997-10-22):
1185  *        SET TIME ZONE 'var_value'
1186  *
1187  *****************************************************************************/
1188 VariableSetStmt:  SET set_rest
1189                         { $$ = cat2_str(make_str("set"), $2 ); }
1190                 | SET LOCAL set_rest
1191                         { $$ = cat2_str(make_str("set local"), $3 ); }
1192                 | SET SESSION set_rest
1193                         { $$ = cat2_str(make_str("set session"), $3 ); }
1194                 ;
1195
1196 set_rest:       /* Generic SET syntaxes: */
1197                 var_name TO var_list
1198                         { $$ = cat_str(3, $1, make_str("to"), $3); }
1199                 | var_name "=" var_list
1200                         { $$ = cat_str(3, $1, make_str("="), $3); }
1201                 | var_name TO DEFAULT
1202                         { $$ = cat2_str($1, make_str("to default")); }
1203                 | var_name "=" DEFAULT
1204                         { $$ = cat2_str($1, make_str("= default")); }
1205                 | var_name FROM CURRENT_P
1206                         { $$ = cat2_str($1, make_str("from current")); }
1207                 /* Special syntaxes mandated by SQL standard: */
1208                 | TIME ZONE zone_value
1209                         { $$ = cat2_str(make_str("time zone"), $3); }
1210                 | TRANSACTION transaction_mode_list
1211                         { $$ = cat2_str(make_str("transaction"), $2); }
1212                 | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
1213                         { $$ = cat2_str(make_str("session characteristics as transaction"), $5); }
1214                 | NAMES opt_encoding
1215                         { $$ = cat2_str(make_str("names"), $2); }
1216                 | ROLE ColId_or_Sconst
1217                         { $$ = cat2_str(make_str("role"), $2); }
1218                 | SESSION AUTHORIZATION ColId_or_Sconst
1219                         { $$ = cat2_str(make_str("session authorization"), $3); }
1220                 | SESSION AUTHORIZATION DEFAULT
1221                         { $$ = make_str("session authorization default"); }
1222                 | XML_P OPTION document_or_content
1223                         { $$ = cat2_str(make_str("xml option"), $3); }
1224                 ;
1225
1226 var_name:       ECPGColId               { $$ = $1; }
1227                 | var_name '.' ColId    { $$ = cat_str(3, $1, make_str("."), $3); }
1228                 ;
1229
1230
1231 var_list:  var_value
1232                         { $$ = $1; }
1233                 | var_list ',' var_value
1234                         { $$ = cat_str(3, $1, make_str(","), $3); }
1235                 ;
1236
1237 iso_level:      READ UNCOMMITTED        { $$ = make_str("read uncommitted"); }
1238                 | READ COMMITTED                { $$ = make_str("read committed"); }
1239                 | REPEATABLE READ               { $$ = make_str("repeatable read"); }
1240                 | SERIALIZABLE                  { $$ = make_str("serializable"); }
1241                 ;
1242
1243 var_value:      opt_boolean             { $$ = $1; }
1244                 | AllConst                      { $$ = $1; }
1245                 | ColId                         { $$ = $1; }
1246                 ;
1247
1248 opt_boolean:  TRUE_P            { $$ = make_str("true"); }
1249                 | FALSE_P                       { $$ = make_str("false"); }
1250                 | ON                            { $$ = make_str("on"); }
1251                 | OFF                           { $$ = make_str("off"); }
1252                 ;
1253 /* Timezone values can be:
1254  * - a string such as 'pst8pdt'
1255  * - a column identifier such as "pst8pdt"
1256  * - an integer or floating point number
1257  * - a time interval per SQL99
1258  * ConstInterval and ColId give shift/reduce errors,
1259  * so use IDENT and reject anything which is a reserved word.
1260  */
1261 zone_value:  AllConst           { $$ = $1; }
1262                 | ident         { $$ = $1; }
1263                 | ConstInterval StringConst opt_interval
1264                         { $$ = cat_str(3, $1, $2, $3); }
1265                 | ConstInterval '(' PosIntConst ')' StringConst opt_interval
1266                         { $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
1267                 | DEFAULT
1268                         { $$ = make_str("default"); }
1269                 | LOCAL
1270                         { $$ = make_str("local"); }
1271                 ;
1272
1273 opt_encoding:   StringConst             { $$ = $1; }
1274                 | DEFAULT                               { $$ = make_str("default"); }
1275                 | /*EMPTY*/                             { $$ = EMPTY; }
1276                 ;
1277
1278 ColId_or_Sconst: ColId                  { $$ = $1; }
1279                 | StringConst                   { $$ = $1; }
1280                 ;
1281
1282 VariableShowStmt:  SHOW var_name ecpg_into
1283                         { $$ = cat2_str(make_str("show"), $2); }
1284                 | SHOW TIME ZONE ecpg_into
1285                         { $$ = make_str("show time zone"); }
1286                 | SHOW TRANSACTION ISOLATION LEVEL ecpg_into
1287                         { $$ = make_str("show transaction isolation level"); }
1288                 | SHOW SESSION AUTHORIZATION ecpg_into
1289                         { $$ = make_str("show session authorization"); }
1290                 | SHOW ALL
1291                         { mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL not implemented"); }
1292                 ;
1293
1294 VariableResetStmt:      RESET var_name
1295                         { $$ = cat2_str(make_str("reset"), $2); }
1296                 | RESET TIME ZONE
1297                         { $$ = make_str("reset time zone"); }
1298                 | RESET TRANSACTION ISOLATION LEVEL
1299                         { $$ = make_str("reset transaction isolation level"); }
1300                 | RESET SESSION AUTHORIZATION
1301                         { $$ = make_str("reset session authorization"); }
1302                 | RESET ALL
1303                         { $$ = make_str("reset all"); }
1304                 ;
1305
1306 /* SetResetClause allows SET or RESET without LOCAL */
1307 SetResetClause:
1308                 SET set_rest            { $$ = cat2_str(make_str("set"), $2); }
1309                 | VariableResetStmt     { $$ = $1; }
1310                 ;
1311
1312 ConstraintsSetStmt:    SET CONSTRAINTS constraints_set_list constraints_set_mode
1313                         { $$ = cat_str(3, make_str("set constraints"), $3, $4); }
1314                 ;
1315
1316 constraints_set_list:  ALL
1317                         { $$ = make_str("all"); }
1318                 | qualified_name_list
1319                         { $$ = $1; }
1320                 ;
1321
1322 constraints_set_mode:  DEFERRED         { $$ = make_str("deferred"); }
1323                 | IMMEDIATE             { $$ = make_str("immediate"); }
1324                 ;
1325
1326 /*
1327  * Checkpoint statement
1328  */
1329 CheckPointStmt: CHECKPOINT         { $$= make_str("checkpoint"); }
1330                 ;
1331
1332 DiscardStmt:
1333                 DISCARD ALL             { $$ = make_str("discard all"); }
1334                 | DISCARD TEMP          { $$ = make_str("discard temp"); }
1335                 | DISCARD TEMPORARY     { $$ = make_str("discard temporary"); }
1336                 | DISCARD PLANS         { $$ = make_str("discard plans"); }
1337                 ;
1338
1339 /*****************************************************************************
1340  *
1341  *      ALTER [ TABLE | INDEX ] variations
1342  *
1343  *****************************************************************************/
1344
1345 AlterTableStmt:
1346                 ALTER TABLE relation_expr alter_table_cmds
1347                         { $$ = cat_str(3, make_str("alter table"), $3, $4); }
1348                 |       ALTER INDEX relation_expr alter_rel_cmds
1349                         { $$ = cat_str(3, make_str("alter table"), $3, $4); }
1350                 ;
1351
1352 /* Subcommands that are for ALTER TABLE only */
1353 alter_table_cmds:
1354                 alter_table_cmd                         { $$ = $1; }
1355                 | alter_table_cmds ',' alter_table_cmd  { $$ = cat_str(3, $1, make_str(","), $3); }
1356                 ;
1357
1358 alter_table_cmd:
1359                 ADD_P opt_column columnDef
1360 /* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
1361                         { $$ = cat_str(3, make_str("add"), $2, $3); }
1362 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
1363                 | ALTER opt_column ColId alter_column_default
1364                         { $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
1365 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
1366                 | ALTER opt_column ColId DROP NOT NULL_P
1367                         { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
1368 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
1369                 | ALTER opt_column ColId SET NOT NULL_P
1370                         { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
1371 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
1372                 | ALTER opt_column ColId SET STATISTICS PosIntConst
1373                         { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
1374 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
1375                 | ALTER opt_column ColId SET STORAGE ColId
1376                         { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
1377 /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
1378                 | DROP opt_column ColId opt_drop_behavior
1379                         { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
1380 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
1381                 | ALTER opt_column ColId TYPE_P Typename alter_using
1382                         { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
1383 /* ALTER TABLE <relation> ADD CONSTRAINT ... */
1384                 | ADD_P TableConstraint
1385                         { $$ = cat_str(2, make_str("add"), $2); }
1386 /* ALTER TABLE <relation> DROP CONSTRAINT ... */
1387                 | DROP CONSTRAINT name opt_drop_behavior
1388                         { $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
1389 /* ALTER TABLE <relation> SET WITHOUT OIDS  */
1390                 | SET WITHOUT OIDS
1391                         { $$ = make_str("set without oids"); }
1392 /* ALTER TABLE <name> CLUSTER ON <indexname> */
1393                 | CLUSTER ON name
1394                         { $$ = cat_str(2, make_str("cluster on"), $3); }
1395 /* ALTER TABLE <name> SET WITHOUT CLUSTER */
1396                 | SET WITHOUT CLUSTER
1397                         { $$ = make_str("set without cluster"); }
1398 /* ALTER TABLE <name> ENABLE TRIGGER <trig> */
1399                 | ENABLE_P TRIGGER name
1400                         { $$ = cat2_str(make_str("enable trigger"), $3); }
1401 /* ALTER TABLE <name> ENABLE ALWAYS TRIGGER <trig> */
1402                 | ENABLE_P ALWAYS TRIGGER name
1403                         { $$ = cat2_str(make_str("enable always trigger"), $4); }
1404 /* ALTER TABLE <name> ENABLE REPLICA TRIGGER <trig> */
1405                 | ENABLE_P REPLICA TRIGGER name
1406                         { $$ = cat2_str(make_str("enable replica trigger"), $4); }
1407 /* ALTER TABLE <name> ENABLE TRIGGER ALL */
1408                 | ENABLE_P TRIGGER ALL
1409                         { $$ = make_str("enable trigger all"); }
1410 /* ALTER TABLE <name> ENABLE TRIGGER USER */
1411                 | ENABLE_P TRIGGER USER
1412                         { $$ = make_str("enable trigger user"); }
1413 /* ALTER TABLE <name> DISABLE TRIGGER <trig> */
1414                 | DISABLE_P TRIGGER name
1415                         { $$ = cat2_str(make_str("disable trigger"), $3); }
1416 /* ALTER TABLE <name> DISABLE TRIGGER ALL */
1417                 | DISABLE_P TRIGGER ALL
1418                         { $$ = make_str("disable trigger all"); }
1419 /* ALTER TABLE <name> DISABLE TRIGGER USER */
1420                 | DISABLE_P TRIGGER USER
1421                         { $$ = make_str("disable trigger user"); }
1422 /* ALTER TABLE <name> ENABLE RULE <rule> */
1423                 | ENABLE_P RULE name
1424                         { $$ = cat2_str(make_str("enable rule"), $3); }
1425 /* ALTER TABLE <name> ENABLE ALWAYS RULE <rule> */
1426                 | ENABLE_P ALWAYS RULE name
1427                         { $$ = cat2_str(make_str("enable always rule"), $4); }
1428 /* ALTER TABLE <name> ENABLE REPLICA RULE <rule> */
1429                 | ENABLE_P REPLICA RULE name
1430                         { $$ = cat2_str(make_str("enable replica rule"), $4); }
1431 /* ALTER TABLE <name> DISABLE RULE <rule> */
1432                 | DISABLE_P RULE name
1433                         { $$ = cat2_str(make_str("disable rule"), $3); }
1434 /* ALTER TABLE <name> ALTER INHERITS ADD <parent> */
1435                 | INHERIT qualified_name
1436                         { $$ = cat2_str(make_str("inherit"), $2); }
1437 /* ALTER TABLE <name> NO INHERITS <parent> */
1438                 | NO INHERIT qualified_name
1439                         { $$ = cat2_str(make_str("no inherit"), $3); }
1440                 | alter_rel_cmd
1441                         { $$ = $1; }
1442                 ;
1443
1444 alter_rel_cmds: alter_rel_cmd                           { $$ = $1; }
1445                 | alter_rel_cmds ',' alter_rel_cmd      { $$ = cat_str(3, $1, make_str(","), $3); }
1446                 ;
1447
1448 /* Subcommands that are for ALTER TABLE or ALTER INDEX */
1449 alter_rel_cmd:
1450                 /* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
1451                 OWNER TO RoleId
1452                         { $$ = cat2_str(make_str("owner to"), $3); }
1453                 /* ALTER [TABLE|INDEX] <name> SET TABLESPACE <tablespacename> */
1454                 | SET TABLESPACE name
1455                         { $$ = cat2_str(make_str("set tablespace"), $3); }
1456                 | SET definition
1457                         { $$ = cat2_str(make_str("set"), $2); }
1458                 | RESET definition
1459                         { $$ = cat2_str(make_str("reset"), $2); }
1460                 ;
1461
1462 alter_column_default:
1463                 SET DEFAULT a_expr              { $$ = cat2_str(make_str("set default"), $3); }
1464                 | DROP DEFAULT                  { $$ = make_str("drop default"); }
1465                 ;
1466
1467 opt_drop_behavior: CASCADE              { $$ = make_str("cascade"); }
1468                 | RESTRICT                              { $$ = make_str("restrict"); }
1469                 | /* EMPTY */                   { $$ = EMPTY; }
1470                 ;
1471
1472 alter_using:    USING a_expr    { $$ = cat2_str(make_str("using"), $2); }
1473                 | /* EMPTY */                   { $$ = EMPTY; }
1474                 ;
1475
1476 /*****************************************************************************
1477  *
1478  *              QUERY :
1479  *                              close <portalname>
1480  *
1481  *****************************************************************************/
1482
1483 ClosePortalStmt:  CLOSE name
1484                         { $$ = cat2_str(make_str("close"), $2); }
1485                 | CLOSE ALL
1486                         { $$ = make_str("close all"); }
1487                 ;
1488
1489 CopyStmt:  COPY opt_binary qualified_name opt_oids copy_from
1490                 copy_file_name copy_delimiter opt_with copy_opt_list
1491                         {
1492                                 if (strcmp($5, "to") == 0 && strcmp($6, "stdin") == 0)
1493                                         mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible.\n");
1494                                 else if (strcmp($5, "from") == 0 && strcmp($6, "stdout") == 0)
1495                                         mmerror(PARSE_ERROR, ET_ERROR, "copy from stdout not possible.\n");
1496                                 else if (strcmp($5, "from") == 0 && strcmp($6, "stdin") == 0)
1497                                         mmerror(PARSE_ERROR, ET_WARNING, "copy from stdin not implemented.\n");
1498                                 
1499                                 $$ = cat_str(9, make_str("copy"), $2, $3, $4, $5, $6, $7, $8, $9);
1500                         }
1501                 | COPY select_with_parens TO copy_file_name opt_with copy_opt_list
1502                         {
1503                                 if (strcmp($4, "stdin") == 0)
1504                                         mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible.\n");
1505                                 
1506                                 $$ = cat_str(6, make_str("copy"), $2, make_str("to"), $4, $5, $6);
1507                         }
1508                 ;
1509
1510 copy_from:      TO                                      { $$ = make_str("to"); }
1511                 | FROM                                  { $$ = make_str("from"); }
1512                 ;
1513
1514 copy_file_name:  StringConst                            { $$ = $1; }
1515                 | STDIN                                 { $$ = make_str("stdin"); }
1516                 | STDOUT                                { $$ = make_str("stdout"); }
1517                 ;
1518
1519 copy_opt_list: copy_opt_list copy_opt_item      { $$ = cat2_str($1, $2); }
1520                 | /* EMPTY */                   { $$ = EMPTY; }
1521                 ;
1522
1523 copy_opt_item:  BINARY          { $$ = make_str("binary"); }
1524                 | OIDS          { $$ = make_str("oids"); }
1525                 | DELIMITER opt_as StringConst
1526                         { $$ = cat_str(3, make_str("delimiter"), $2, $3); }
1527                 | NULL_P opt_as StringConst
1528                         { $$ = cat_str(3, make_str("null"), $2, $3); }
1529                 | CSV           { $$ = make_str("csv"); }
1530                 | HEADER_P      { $$ = make_str("header"); }
1531                 | QUOTE opt_as Sconst
1532                         { $$ = cat_str(3, make_str("quote"), $2, $3); }
1533                 | ESCAPE opt_as Sconst
1534                         { $$ = cat_str(3, make_str("escape"), $2, $3); }
1535                 | FORCE QUOTE columnList
1536                         { $$ = cat2_str(make_str("force quote"), $3); }
1537                 | FORCE NOT NULL_P columnList
1538                         { $$ = cat2_str(make_str("force not null"), $4); }
1539
1540                 ;
1541
1542 opt_binary:     BINARY          { $$ = make_str("binary"); }
1543                 | /* EMPTY */   { $$ = EMPTY; }
1544                 ;
1545
1546 opt_oids:       WITH OIDS       { $$ = make_str("with oids"); }
1547                 | /* EMPTY */   { $$ = EMPTY; }
1548                 ;
1549
1550
1551 /*
1552  * the default copy delimiter is tab but the user can configure it
1553  */
1554 copy_delimiter:  opt_using DELIMITERS StringConst
1555                         { $$ = cat_str(3, $1, make_str("delimiters"), $3); }
1556                 | /*EMPTY*/
1557                         { $$ = EMPTY; }
1558                 ;
1559
1560 opt_using:      USING           { $$ = make_str("using"); }
1561                 | /* EMPTY */   { $$ = EMPTY; }
1562                 ;
1563
1564 /*****************************************************************************
1565  *
1566  *              QUERY :
1567  *                              CREATE TABLE relname
1568  *
1569  *****************************************************************************/
1570
1571 CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
1572                                 OptInherit OptWith OnCommitOption OptTableSpace
1573                         { $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9, $10, $11); }
1574                 | CREATE OptTemp TABLE qualified_name OF qualified_name
1575                         '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
1576                         { $$ = cat_str(12, make_str("create"), $2, make_str("table"), $4, make_str("of"), $6, make_str("("), $8, make_str(")"), $10, $11, $12); }
1577                 ;
1578
1579 /*
1580  * Redundancy here is needed to avoid shift/reduce conflicts,
1581  * since TEMP is not a reserved word.  See also OptTempTableName.
1582  */
1583
1584 OptTemp: TEMPORARY                      { $$ = make_str("temporary"); }
1585                 | TEMP                          { $$ = make_str("temp"); }
1586                 | LOCAL TEMPORARY       { $$ = make_str("local temporary"); }
1587                 | LOCAL TEMP            { $$ = make_str("local temp"); }
1588                 | GLOBAL TEMPORARY      { $$ = make_str("global temporary"); }
1589                 | GLOBAL TEMP           { $$ = make_str("global temp"); }
1590                 | /*EMPTY*/                     { $$ = EMPTY; }
1591                 ;
1592
1593
1594 OptTableElementList:  TableElementList
1595                         { $$ = $1; }
1596                 | /*EMPTY*/
1597                         { $$ = EMPTY; }
1598                 ;
1599 TableElementList: TableElement
1600                         { $$ = $1; }
1601                 | TableElementList ',' TableElement
1602                         { $$ = cat_str(3, $1, make_str(","), $3); }
1603                 ;
1604
1605 TableElement:  columnDef                { $$ = $1; }
1606                 | TableLikeClause       { $$ = $1; }
1607                 | TableConstraint       { $$ = $1; }
1608                 ;
1609
1610 columnDef:      ColId Typename ColQualList
1611                         {$$ = cat_str(3, $1, $2, $3); }
1612                 ;
1613
1614 ColQualList:  ColQualList ColConstraint { $$ = cat2_str($1,$2); }
1615                 | /*EMPTY*/                                             { $$ = EMPTY; }
1616                 ;
1617
1618 ColConstraint:  CONSTRAINT name ColConstraintElem
1619                         { $$ = cat_str(3, make_str("constraint"), $2, $3); }
1620                 | ColConstraintElem             { $$ = $1; }
1621                 | ConstraintAttr                { $$ = $1; }
1622                 ;
1623
1624 /* DEFAULT NULL is already the default for Postgres.
1625  * But define it here and carry it forward into the system
1626  * to make it explicit.
1627  * - thomas 1998-09-13
1628  *
1629  * WITH NULL and NULL are not SQL92-standard syntax elements,
1630  * so leave them out. Use DEFAULT NULL to explicitly indicate
1631  * that a column may have that value. WITH NULL leads to
1632  * shift/reduce conflicts with WITH TIME ZONE anyway.
1633  * - thomas 1999-01-08
1634  */
1635 ColConstraintElem:      NOT NULL_P
1636                         { $$ = make_str("not null"); }
1637                 | NULL_P
1638                         { $$ = make_str("null"); }
1639                 | UNIQUE opt_definition OptConsTableSpace
1640                         { $$ = cat_str(3, make_str("unique"), $2, $3); }
1641                 | PRIMARY KEY opt_definition OptConsTableSpace
1642                         { $$ = cat_str(3, make_str("primary key"), $3, $4); }
1643                 | CHECK '(' a_expr ')'
1644                         { $$ = cat_str(3, make_str("check ("), $3, make_str(")")); }
1645                 | DEFAULT b_expr
1646                         { $$ = cat2_str(make_str("default"), $2); }
1647                 |  REFERENCES qualified_name opt_column_list key_match key_actions
1648                         { $$ = cat_str(5, make_str("references"), $2, $3, $4, $5); }
1649                 ;
1650
1651 /*
1652  * ConstraintAttr represents constraint attributes, which we parse as if
1653  * they were independent constraint clauses, in order to avoid shift/reduce
1654  * conflicts (since NOT might start either an independent NOT NULL clause
1655  * or an attribute).  analyze.c is responsible for attaching the attribute
1656  * information to the preceding "real" constraint node, and for complaining
1657  * if attribute clauses appear in the wrong place or wrong combinations.
1658  *
1659  * See also ConstraintAttributeSpec, which can be used in places where
1660  * there is no parsing conflict.
1661  */
1662 ConstraintAttr: DEFERRABLE              { $$ = make_str("deferrable"); }
1663                 | NOT DEFERRABLE        { $$ = make_str("not deferrable"); }
1664                 | INITIALLY DEFERRED    { $$ = make_str("initially deferred"); }
1665                 | INITIALLY IMMEDIATE   { $$ = make_str("initially immediate"); }
1666                 ;
1667
1668 TableLikeClause:  LIKE qualified_name TableLikeOptionList
1669                         {$$ = cat_str(3, make_str("like"), $2, $3); }
1670                 ;
1671
1672 TableLikeOptionList: TableLikeOptionList TableLikeOption
1673                                 { $$ = cat2_str($1, $2); }
1674                 | /* EMPTY */   { $$ = EMPTY; }
1675                 ;
1676
1677 TableLikeOption:
1678                 INCLUDING DEFAULTS      { $$ = make_str("including defaults"); }
1679                 | EXCLUDING DEFAULTS    { $$ = make_str("excluding defaults"); }
1680                 | INCLUDING CONSTRAINTS { $$ = make_str("including constraints"); }
1681                 | EXCLUDING CONSTRAINTS { $$ = make_str("excluding constraints"); }
1682                 | INCLUDING INDEXES     { $$ = make_str("including indexes"); }
1683                 | EXCLUDING INDEXES     { $$ = make_str("excluding indexes"); }
1684                 ;
1685
1686 /* ConstraintElem specifies constraint syntax which is not embedded into
1687  *      a column definition. ColConstraintElem specifies the embedded form.
1688  * - thomas 1997-12-03
1689  */
1690 TableConstraint:  CONSTRAINT name ConstraintElem
1691                         { $$ = cat_str(3, make_str("constraint"), $2, $3); }
1692                 | ConstraintElem
1693                         { $$ = $1; }
1694                 ;
1695
1696 ConstraintElem:  CHECK '(' a_expr ')'
1697                         { $$ = cat_str(3, make_str("check("), $3, make_str(")")); }
1698                 | UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
1699                         { $$ = cat_str(5, make_str("unique("), $3, make_str(")"), $5, $6); }
1700                 | PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
1701                         { $$ = cat_str(5, make_str("primary key("), $4, make_str(")"), $6, $7); }
1702                 | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
1703                         key_match key_actions ConstraintAttributeSpec
1704                         { $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11); }
1705                 ;
1706
1707 opt_column_list:  '(' columnList ')'    { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1708                 | /*EMPTY*/             { $$ = EMPTY; }
1709                 ;
1710
1711 columnList:  columnList ',' columnElem
1712                         { $$ = cat_str(3, $1, make_str(","), $3); }
1713                 | columnElem
1714                         { $$ = $1; }
1715                 ;
1716
1717 columnElem:  ColId      { $$ = $1; }
1718                 ;
1719
1720 key_match:      MATCH FULL
1721                         { $$ = make_str("match full"); }
1722                 | MATCH PARTIAL
1723                 {
1724                         mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
1725                         $$ = make_str("match partial");
1726                 }
1727                 | /*EMPTY*/
1728                         { $$ = EMPTY; }
1729                 ;
1730
1731 key_actions:  key_delete                        { $$ = $1; }
1732                 | key_update                            { $$ = $1; }
1733                 | key_delete key_update         { $$ = cat2_str($1, $2); }
1734                 | key_update key_delete         { $$ = cat2_str($1, $2); }
1735                 | /*EMPTY*/                                     { $$ = EMPTY; }
1736                 ;
1737
1738 key_delete: ON DELETE_P key_action
1739                         { $$ = cat2_str(make_str("on delete"), $3); }
1740                 ;
1741
1742 key_update: ON UPDATE key_action
1743                         { $$ = cat2_str(make_str("on update"), $3); }
1744                 ;
1745
1746 key_action:     NO ACTION                               { $$ = make_str("no action"); }
1747                 | RESTRICT                                      { $$ = make_str("restrict"); }
1748                 | CASCADE                                       { $$ = make_str("cascade"); }
1749                 | SET DEFAULT                           { $$ = make_str("set default"); }
1750                 | SET NULL_P                            { $$ = make_str("set null"); }
1751                 ;
1752
1753 OptInherit:  INHERITS '(' qualified_name_list ')'
1754                         { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
1755                 | /*EMPTY*/
1756                         { $$ = EMPTY; }
1757                 ;
1758
1759 OptWith:        WITH definition                 { $$ = cat2_str(make_str("with"), $2); }
1760                 | WITH OIDS                     { $$ = make_str("with oids"); }
1761                 | WITHOUT OIDS                  { $$ = make_str("without oids"); }
1762                 | /*EMPTY*/                     { $$ = EMPTY; }
1763                 ;
1764
1765 OnCommitOption:   ON COMMIT DROP        { $$ = make_str("on commit drop"); }
1766                 | ON COMMIT DELETE_P ROWS       { $$ = make_str("on commit delete rows"); }
1767                 | ON COMMIT PRESERVE ROWS       { $$ = make_str("on commit preserve rows"); }
1768                 | /*EMPTY*/                                     { $$ = EMPTY; }
1769                 ;
1770
1771 OptTableSpace:  TABLESPACE name { $$ = cat2_str(make_str("tablespace"), $2); }
1772                 | /*EMPTY*/     { $$ = EMPTY; }
1773                 ;
1774
1775 OptConsTableSpace: USING INDEX TABLESPACE name  { $$ = cat2_str(make_str("using index tablespace"), $4); }
1776                         | /*EMPTY*/             { $$ = EMPTY; }
1777                         ;
1778
1779 /*
1780  * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1781  * SELECT ... INTO.
1782  */
1783
1784 CreateAsStmt:  CREATE OptTemp TABLE create_as_target AS
1785                 { FoundInto = 0; }
1786                 SelectStmt
1787                 {
1788                         if (FoundInto == 1)
1789                                 mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT cannot specify INTO");
1790
1791                         $$ = cat_str(6, make_str("create"), $2, make_str("table"), $4, make_str("as"), $7);
1792                 }
1793                 ;
1794
1795 create_as_target:  qualified_name OptCreateAs OptWith OnCommitOption OptTableSpace
1796                 {
1797                         $$ = cat_str(5, $1, $2, $3, $4, $5);
1798                 }
1799                 ;
1800
1801 OptCreateAs:  '(' CreateAsList ')'
1802                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1803                 | /*EMPTY*/
1804                         { $$ = EMPTY; }
1805                 ;
1806
1807 CreateAsList:  CreateAsList ',' CreateAsElement
1808                         { $$ = cat_str(3, $1, make_str(","), $3); }
1809                 | CreateAsElement
1810                         { $$ = $1; }
1811                 ;
1812
1813 CreateAsElement:  ColId { $$ = $1; }
1814                 ;
1815
1816 /*****************************************************************************
1817  *
1818  *              QUERY :
1819  *                              CREATE SEQUENCE seqname
1820  *                              ALTER SEQUENCE seqname
1821  *
1822  *****************************************************************************/
1823
1824 CreateSeqStmt:  CREATE OptTemp SEQUENCE qualified_name OptSeqList
1825                         { $$ = cat_str(5, make_str("create"), $2, make_str("sequence"), $4, $5); }
1826                 ;
1827
1828 AlterSeqStmt: ALTER SEQUENCE qualified_name OptSeqList
1829                         { $$ = cat_str(3,make_str("alter sequence"), $3, $4); }
1830                 ;
1831
1832 OptSeqList:  OptSeqList OptSeqElem      { $$ = cat2_str($1, $2); }
1833                 | /*EMPTY*/                                     { $$ = EMPTY; }
1834                 ;
1835
1836 OptSeqElem:  CACHE NumConst
1837                         { $$ = cat2_str(make_str("cache"), $2); }
1838                 | CYCLE
1839                         { $$ = make_str("cycle"); }
1840                 | NO CYCLE
1841                         { $$ = make_str("no cycle"); }
1842                 | INCREMENT opt_by NumConst
1843                         { $$ = cat_str(3, make_str("increment"), $2, $3); }
1844                 | MAXVALUE NumConst
1845                         { $$ = cat2_str(make_str("maxvalue"), $2); }
1846                 | MINVALUE NumConst
1847                         { $$ = cat2_str(make_str("minvalue"), $2); }
1848                 | NO MAXVALUE
1849                         { $$ = make_str("no maxvalue"); }
1850                 | NO MINVALUE
1851                         { $$ = make_str("no minvalue"); }
1852                 | OWNED BY any_name
1853                         { $$ = cat2_str(make_str("owned by"), $3); }
1854                 | START opt_with NumConst
1855                         { $$ = cat_str(3, make_str("start"), $2, $3); }
1856                 | RESTART opt_with NumConst
1857                         { $$ = cat_str(3, make_str("restart"), $2, $3); }
1858                 ;
1859
1860 opt_by:         BY      { $$ = make_str("by"); }
1861                 | /*EMPTY*/     { $$ = EMPTY; }
1862                 ;
1863
1864 /*****************************************************************************
1865  *
1866  *              QUERIES :
1867  *                              CREATE PROCEDURAL LANGUAGE ...
1868  *                              DROP PROCEDURAL LANGUAGE ...
1869  *
1870  *****************************************************************************/
1871
1872 CreatePLangStmt:  CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
1873                         { $$ = cat_str(5, make_str("create"), $2, $3, make_str("language"), $5); }
1874                 | CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
1875                         HANDLER handler_name opt_validator opt_lancompiler
1876                         { $$ = cat_str(9, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8, $9); }
1877                 ;
1878
1879 opt_trusted:    TRUSTED { $$ = make_str("trusted"); }
1880                 | /*EMPTY*/             { $$ = EMPTY; }
1881                 ;
1882
1883 /* This ought to be just func_name, but that causes reduce/reduce conflicts
1884  * (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
1885  * Work around by using simple names instead.
1886  */
1887 handler_name: name      { $$ = $1; }
1888                 | name attrs    { $$ = cat2_str($1, $2); }
1889                 ;
1890
1891 opt_validator: VALIDATOR handler_name
1892                         { $$ = cat2_str(make_str("validator"), $2); }
1893                 | /*EMPTY*/
1894                         { $$ = ""; }
1895                 ;
1896 opt_lancompiler: LANCOMPILER StringConst
1897                         { $$ = cat2_str(make_str("lancompiler"), $2); }
1898                 | /*EMPTY*/
1899                         { $$ = ""; }
1900                 ;
1901
1902 DropPLangStmt:  DROP opt_procedural LANGUAGE StringConst opt_drop_behavior
1903                         { $$ = cat_str(5, make_str("drop"), $2, make_str("language"), $4, $5); }
1904                 | DROP opt_procedural LANGUAGE IF_P EXISTS StringConst opt_drop_behavior
1905                         { $$ = cat_str(5, make_str("drop"), $2, make_str("language if exists"), $6, $7); }
1906                 ;
1907
1908 opt_procedural: PROCEDURAL      { $$ = make_str("prcedural"); }
1909                 | /*EMPTY*/                     { $$ = EMPTY; }
1910                 ;
1911
1912 /*****************************************************************************
1913  *
1914  *             QUERY:
1915  *             CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'
1916  *
1917  *****************************************************************************/
1918
1919 CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
1920                         { $$ = cat_str(5,make_str("create tablespace"), $3, $4, make_str("location"), $6); }
1921                 ;
1922
1923 OptTableSpaceOwner: OWNER name  { $$ = cat2_str(make_str("owner"), $2); }
1924                 | /*EMPTY*/     { $$ = EMPTY; }
1925                 ;
1926
1927 /*****************************************************************************
1928  *
1929  *             QUERY :
1930  *                             DROP TABLESPACE <tablespace>
1931  *
1932  *             No need for drop behaviour as we cannot implement dependencies for
1933  *             objects in other databases; we can only support RESTRICT.
1934  *
1935  ****************************************************************************/
1936
1937
1938 DropTableSpaceStmt: DROP TABLESPACE name
1939                         { $$ = cat2_str(make_str("drop tablespace"), $3); }
1940                 | DROP TABLESPACE IF_P EXISTS name
1941                         { $$ = cat2_str(make_str("drop tablespace if exists"), $5); }
1942                 ;
1943
1944
1945 /*****************************************************************************
1946  *
1947  *              QUERIES :
1948  *                              CREATE TRIGGER ...
1949  *                              DROP TRIGGER ...
1950  *
1951  *****************************************************************************/
1952
1953 CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1954                                 qualified_name TriggerForSpec EXECUTE PROCEDURE name
1955                                 '(' TriggerFuncArgs ')'
1956                         { $$ = cat_str(12, make_str("create trigger"), $3, $4, $5, make_str("on"), $7, $8, make_str("execute procedure"), $11, make_str("("), $13, make_str(")")); }
1957                 |       CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
1958                                 qualified_name OptConstrFromTable ConstraintAttributeSpec
1959                                 FOR EACH ROW EXECUTE PROCEDURE
1960                                 func_name '(' TriggerFuncArgs ')'
1961                         { $$ = cat_str(13, make_str("create constraint trigger"), $4, make_str("after"), $6, make_str("on"), $8, $9, $10, make_str("for each row execute procedure"), $16, make_str("("), $18, make_str(")")); }
1962                 ;
1963
1964 TriggerActionTime:      BEFORE          { $$ = make_str("before"); }
1965                 | AFTER                                 { $$ = make_str("after"); }
1966                 ;
1967
1968 TriggerEvents:  TriggerOneEvent
1969                         { $$ = $1; }
1970                 | TriggerOneEvent OR TriggerOneEvent
1971                         { $$ = cat_str(3, $1, make_str("or"), $3); }
1972                 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1973                         { $$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5); }
1974                 ;
1975
1976 TriggerOneEvent:  INSERT        { $$ = make_str("insert"); }
1977                 | DELETE_P                      { $$ = make_str("delete"); }
1978                 | UPDATE                        { $$ = make_str("update"); }
1979                 ;
1980
1981 TriggerForSpec:  FOR TriggerForOpt TriggerForType
1982                         { $$ = cat_str(3, make_str("for"), $2, $3); }
1983                 | /* EMPTY */
1984                         { $$ = EMPTY; }
1985                 ;
1986
1987 TriggerForOpt:  EACH            { $$ = make_str("each"); }
1988                 | /*EMPTY*/                     { $$ = EMPTY; }
1989                 ;
1990
1991 TriggerForType:  ROW            { $$ = make_str("row"); }
1992                 | STATEMENT                     { $$ = make_str("statement"); }
1993                 ;
1994
1995 TriggerFuncArgs:  TriggerFuncArg
1996                         { $$ = $1; }
1997                 | TriggerFuncArgs ',' TriggerFuncArg
1998                         { $$ = cat_str(3, $1, make_str(","), $3); }
1999                 | /*EMPTY*/
2000                         { $$ = EMPTY; }
2001                 ;
2002
2003 TriggerFuncArg:  PosAllConst    { $$ = $1; }
2004                 | ColId         { $$ = $1; }
2005                 ;
2006
2007 OptConstrFromTable: /* Empty */         { $$ = EMPTY; }
2008                 | FROM qualified_name           { $$ = cat2_str(make_str("from"), $2); }
2009                 ;
2010
2011 ConstraintAttributeSpec: ConstraintDeferrabilitySpec    { $$ = $1; }
2012                 | ConstraintDeferrabilitySpec ConstraintTimeSpec
2013                 {
2014                         if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
2015                                 mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2016
2017                         $$ = cat2_str($1, $2);
2018                 }
2019                 | ConstraintTimeSpec            { $$ = $1; }
2020                 | ConstraintTimeSpec ConstraintDeferrabilitySpec
2021                 {
2022                         if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
2023                                 mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2024
2025                         $$ = cat2_str($1, $2);
2026                 }
2027                 ;
2028
2029 ConstraintDeferrabilitySpec: NOT DEFERRABLE
2030                         { $$ = make_str("not deferrable"); }
2031                 | DEFERRABLE
2032                         { $$ = make_str("deferrable"); }
2033                 ;
2034
2035 ConstraintTimeSpec: INITIALLY IMMEDIATE
2036                         { $$ = make_str("initially immediate"); }
2037                 | INITIALLY DEFERRED
2038                         { $$ = make_str("initially deferred"); }
2039                 ;
2040
2041 DropTrigStmt:  DROP TRIGGER name ON qualified_name opt_drop_behavior
2042                         { $$ = cat_str(5, make_str("drop trigger"), $3, make_str("on"), $5, $6); }
2043                 | DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
2044                         { $$ = cat_str(5, make_str("drop trigger if exists"), $5, make_str("on"), $7, $8); }
2045                 ;
2046
2047 /*****************************************************************************
2048  *
2049  *             QUERIES :
2050  *                             CREATE ASSERTION ...
2051  *                             DROP ASSERTION ...
2052  *
2053  *****************************************************************************/
2054 CreateAssertStmt:  CREATE ASSERTION name
2055                 CHECK '(' a_expr ')' ConstraintAttributeSpec
2056                 {
2057                         mmerror(PARSE_ERROR, ET_ERROR, "CREATE ASSERTION is not yet supported");
2058                         $$ = cat_str(6, make_str("create assertion"), $3, make_str("check ("), $6, make_str(")"), $8);
2059                 }
2060                 ;
2061
2062 DropAssertStmt:  DROP ASSERTION name
2063                 {
2064                         mmerror(PARSE_ERROR, ET_ERROR, "DROP ASSERTION is not yet supported");
2065                         $$ = cat2_str(make_str("drop assertion"), $3);
2066                 }
2067                 ;
2068
2069
2070 /*****************************************************************************
2071  *
2072  *              QUERY :
2073  *                              define (type,operator,aggregate)
2074  *
2075  *****************************************************************************/
2076
2077 DefineStmt:  CREATE AGGREGATE func_name aggr_args definition
2078                         { $$ = cat_str(4, make_str("create aggregate"), $3, $4, $5); }
2079                 | CREATE AGGREGATE func_name old_aggr_definition
2080                         { $$ = cat_str(3, make_str("create aggregate"), $3, $4); }
2081                 | CREATE OPERATOR all_Op definition
2082                         { $$ = cat_str(3, make_str("create operator"), $3, $4); }
2083                 | CREATE TYPE_P any_name definition
2084                         { $$ = cat_str(3, make_str("create type"), $3, $4); }
2085                 | CREATE TYPE_P any_name
2086                         { $$ = cat2_str(make_str("create type"), $3); }
2087                 | CREATE TYPE_P any_name AS '(' TableFuncElementList ')'
2088                         { $$ = cat_str(5, make_str("create type"), $3, make_str("as ("), $6, make_str(")")); }
2089                 | CREATE TYPE_P any_name AS ENUM_P '(' enum_val_list ')'
2090                         { $$ = cat_str(5, make_str("create type"), $3, make_str("as enum ("), $7, make_str(")")); }
2091                 | CREATE TEXT_P SEARCH PARSER any_name definition
2092                         { $$ = cat_str(3, make_str("create text search parser"), $5, $6); }
2093                 | CREATE TEXT_P SEARCH DICTIONARY any_name definition
2094                         { $$ = cat_str(3, make_str("create text search dictionary"), $5, $6); }
2095                 | CREATE TEXT_P SEARCH TEMPLATE any_name definition
2096                         { $$ = cat_str(3, make_str("create text search template"), $5, $6); }
2097                 | CREATE TEXT_P SEARCH CONFIGURATION any_name definition
2098                         { $$ = cat_str(3, make_str("create text search configuration"), $5, $6); }
2099                 ;
2100
2101 definition:  '(' def_list ')'
2102                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2103                 ;
2104
2105 def_list:  def_elem                                     { $$ = $1; }
2106                 | def_list ',' def_elem         { $$ = cat_str(3, $1, make_str(","), $3); }
2107                 ;
2108
2109 def_elem:  ColLabel '=' def_arg         { $$ = cat_str(3, $1, make_str("="), $3); }
2110                 | ColLabel                                      { $$ = $1; }
2111                 ;
2112
2113 /* Note: any simple identifier will be returned as a type name! */
2114 def_arg:  func_type                             { $$ = $1; }
2115                 | reserved_keyword              { $$ = $1; }
2116                 | qual_all_Op                   { $$ = $1; }
2117                 | AllConst                      { $$ = $1; }
2118                 ;
2119
2120 aggr_args:      '(' type_list ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2121                 | '(' '*' ')'                   { $$ = make_str("(*)"); }
2122                 ;
2123
2124 old_aggr_definition: '(' old_aggr_list ')'      { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2125                 ;
2126
2127 old_aggr_list: old_aggr_elem                            { $$ = $1; }
2128                  | old_aggr_list ',' old_aggr_elem      { $$ = cat_str(3, $1, make_str(","), $3); }
2129                  ;
2130
2131 old_aggr_elem:  ident '=' def_arg       { $$ = cat_str(3, $1, make_str("="), $3); }
2132                 ;
2133
2134 enum_val_list:  StringConst                     { $$ = $1; }
2135                 | enum_val_list ',' StringConst { $$ = cat_str(3, $1, make_str(","), $3);}
2136                 ;
2137
2138 CreateOpClassStmt:      CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
2139                                                 USING access_method opt_opfamily AS opclass_item_list
2140                 {
2141                         $$ = cat_str(10, make_str("create operator class"), $4, $5, make_str("for type"), $8, make_str("using"), $10, $11, make_str("as"), $13);
2142                 }
2143                 ;
2144
2145 opclass_item_list:      opclass_item            { $$ = $1; }
2146                 | opclass_item_list ',' opclass_item    { $$ = cat_str(3, $1, make_str(","), $3); }
2147                 ;
2148
2149 opclass_item:   OPERATOR PosIntConst any_operator opt_recheck
2150                         { $$ = cat_str(4, make_str("operator"), $2, $3, $4); }
2151                 | OPERATOR PosIntConst any_operator '(' oper_argtypes ')' opt_recheck
2152                         { $$ =  cat_str(7, make_str("operator"), $2, $3, make_str("("), $5, make_str(")"), $7); }
2153                 | FUNCTION PosIntConst func_name func_args
2154                         { $$ = cat_str(4, make_str("function"), $2, $3, $4); }
2155                 | FUNCTION PosIntConst '(' type_list ')' func_name func_args
2156                         { $$ = cat_str(7, make_str("function"), $2, make_str("("), $4, make_str(")"), $6, $7); }
2157                 | STORAGE Typename
2158                         { $$ = cat2_str(make_str("storage"), $2); }
2159                 ;
2160
2161 opt_default:   DEFAULT  { $$ = make_str("default"); }
2162                 |  /*EMPTY*/    { $$ = EMPTY; }
2163                 ;
2164
2165 opt_opfamily:  FAMILY any_name          { $$ = cat2_str(make_str("family"), $2); }
2166                        | /*EMPTY*/      { $$ = EMPTY; }
2167                ;
2168
2169 opt_recheck:   RECHECK  { $$ = make_str("recheck"); }
2170                 |  /*EMPTY*/    { $$ = EMPTY; }
2171                 ;
2172
2173 CreateOpFamilyStmt: CREATE OPERATOR FAMILY any_name USING access_method
2174                 { $$ = cat_str(4, make_str("create operator family"), $4, make_str("using"), $6); }
2175                 ;
2176
2177 AlterOpFamilyStmt: ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list
2178                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("add"), $8); }
2179                  | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list
2180                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("drop"), $8); }
2181                  ;
2182
2183 opclass_drop_list: opclass_drop                         { $$ = $1; }
2184                 | opclass_drop_list ',' opclass_drop    { $$ = cat_str(3, $1, make_str(","), $3); }
2185                 ;
2186
2187 opclass_drop:
2188                 OPERATOR PosIntConst '(' type_list ')'
2189                         { $$ = cat_str(5, make_str("operator"), $2, make_str("("), $4, make_str(")")); }
2190                 | FUNCTION PosIntConst '(' type_list ')'
2191                         { $$ = cat_str(5, make_str("function"), $2, make_str("("), $4, make_str(")")); }
2192                 ;
2193
2194 DropOpClassStmt: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
2195                         { $$ = cat_str(5,make_str("drop operator class"), $4, make_str("using"), $6, $7); }
2196                 | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
2197                         { $$ = cat_str(5,make_str("drop operator class if exists"), $6, make_str("using"), $8, $9); }
2198                 ;
2199
2200 DropOpFamilyStmt: DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
2201                         { $$ = cat_str(5,make_str("drop operator family"), $4, make_str("using"), $6, $7); }
2202                 | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
2203                         { $$ = cat_str(5,make_str("drop operator family if exists"), $6, make_str("using"), $8, $9); }
2204                 ;
2205
2206 /*****************************************************************************
2207  *
2208  *              QUERY:
2209  *
2210  *              DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ]
2211  *              REASSIGN OWNED BY username [, username ...] TO username
2212  *
2213  *****************************************************************************/
2214 DropOwnedStmt:
2215         DROP OWNED BY name_list opt_drop_behavior
2216                         {$$ = cat_str(3, make_str("drop owned by"), $4, $5); }
2217                 ;
2218
2219 ReassignOwnedStmt:
2220         REASSIGN OWNED BY name_list TO name
2221                         {$$ = cat_str(4, make_str("reassign owned by"), $4, make_str("to"), $6); }
2222                 ;
2223
2224 /*****************************************************************************
2225  *
2226  *              QUERY:
2227  *
2228  *                         DROP itemtype [ IF EXISTS ] itemname [, itemname ...] [ RESTRICT | CASCADE ]
2229  *
2230  *****************************************************************************/
2231
2232 DropStmt:  DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
2233                         { $$ = cat_str(5, make_str("drop"), $2, make_str("if exists"), $5, $6); }
2234                 | DROP drop_type any_name_list opt_drop_behavior
2235                         { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
2236                 ;
2237
2238 drop_type:      TABLE                           { $$ = make_str("table"); }
2239                 | SEQUENCE                      { $$ = make_str("sequence"); }
2240                 | VIEW                          { $$ = make_str("view"); }
2241                 | INDEX                         { $$ = make_str("index"); }
2242                 | TYPE_P                        { $$ = make_str("type"); }
2243                 | DOMAIN_P                      { $$ = make_str("domain"); }
2244                 | CONVERSION_P                  { $$ = make_str("conversion"); }
2245                 | SCHEMA                        { $$ = make_str("schema"); }
2246                 | TEXT_P SEARCH PARSER          { $$ = make_str("text search parser"); }
2247                 | TEXT_P SEARCH DICTIONARY      { $$ = make_str("text search dictionary"); }
2248                 | TEXT_P SEARCH TEMPLATE        { $$ = make_str("text search template"); }
2249                 | TEXT_P SEARCH CONFIGURATION   { $$ = make_str("text search configuration"); }
2250                 ;
2251
2252 any_name_list:  any_name
2253                         { $$ = $1; }
2254                 | any_name_list ',' any_name
2255                         { $$ = cat_str(3, $1, make_str(","), $3); }
2256                 ;
2257
2258 any_name: ColId        { $$ = $1; }
2259                 | ColId attrs  { $$ = cat2_str($1, $2); }
2260                 ;
2261
2262 attrs: '.' attr_name            { $$ = cat2_str(make_str("."), $2); }
2263                 | attrs '.' attr_name   { $$ = cat_str(3, $1, make_str("."), $3); }
2264                 ;
2265
2266 /*****************************************************************************
2267  *
2268  *                         QUERY:
2269  *                                 truncate table relname1, relname2, ....
2270  *
2271  *****************************************************************************/
2272 TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_drop_behavior
2273                         { $$ = cat_str(4, make_str("truncate table"), $2, $3, $4); }
2274                 ;
2275
2276 /*****************************************************************************
2277  *
2278  *              QUERY:
2279  *                      fetch/move
2280  *
2281  *****************************************************************************/
2282
2283 /* This is different from the backend as we try to be compatible with many other
2284  * embedded SQL implementations. So we accept their syntax as well and
2285  * translate it to the PGSQL syntax. */
2286
2287 FetchStmt: FETCH fetch_direction from_in name ecpg_into
2288                         {
2289                                 add_additional_variables($4, false);
2290                                 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
2291                         }
2292                 | FETCH fetch_direction name ecpg_into
2293                         {
2294                                 add_additional_variables($3, false);
2295                                 $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
2296                         }
2297                 | FETCH from_in name ecpg_into
2298                         {
2299                         add_additional_variables($3, false);
2300                                 $$ = cat_str(3, make_str("fetch"), $2, $3);
2301                         }
2302                 | FETCH name ecpg_into
2303                         {
2304                         add_additional_variables($2, false);
2305                                 $$ = cat2_str(make_str("fetch"), $2);
2306                         }
2307                 | FETCH fetch_direction from_in name
2308                         {
2309                         add_additional_variables($4, false);
2310                                 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
2311                         }
2312                 | FETCH fetch_direction name
2313                         {
2314                         add_additional_variables($3, false);
2315                                 $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
2316                         }
2317                 | FETCH from_in name
2318                         {
2319                                 add_additional_variables($3, false);
2320                                 $$ = cat_str(3, make_str("fetch"), $2, $3);
2321                         }
2322                 | FETCH name
2323                         {
2324                         add_additional_variables($2, false);
2325                                 $$ = cat2_str(make_str("fetch"), $2);
2326                         }
2327                 | MOVE fetch_direction from_in name
2328                         { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
2329                 | MOVE name
2330                         { $$ = cat2_str(make_str("move"), $2); }
2331                 ;
2332
2333 fetch_direction:  NEXT                  { $$ = make_str("next"); }
2334                 | PRIOR                 { $$ = make_str("prior"); }
2335                 | FIRST_P               { $$ = make_str("first"); }
2336                 | LAST_P                { $$ = make_str("last"); }
2337                 | ABSOLUTE_P IntConst   { 
2338                                           if ($2[1] == '$')
2339                                                  mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2340                                           else
2341                                                 $$ = cat2_str(make_str("absolute"), $2);
2342                                         }
2343                 | RELATIVE_P IntConst   { 
2344                                           if ($2[1] == '$')
2345                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2346                                           else
2347                                                 $$ = cat2_str(make_str("relative"), $2);
2348                                         }
2349                 | IntConst              {  
2350                                           if ($1[1] == '$')
2351                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2352                                           else
2353                                                 $$ = $1;
2354                                         }
2355                 | ALL                   { $$ = make_str("all"); }
2356                 | FORWARD               { $$ = make_str("forward"); }
2357                 | FORWARD IntConst      {  
2358                                           if ($2[1] == '$')
2359                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2360                                           else
2361                                                 $$ = cat2_str(make_str("forward"), $2);
2362                                         }
2363                 | FORWARD ALL           { $$ = make_str("forward all"); }
2364                 | BACKWARD              { $$ = make_str("backward"); }
2365                 | BACKWARD IntConst     {  
2366                                           if ($2[1] == '$')
2367                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2368                                           else
2369                                                 $$ = cat2_str(make_str("backward"), $2);
2370                                         }
2371                 | BACKWARD ALL          { $$ = make_str("backward all"); }
2372                 ;
2373
2374 from_in: IN_P                   { $$ = make_str("in"); }
2375                 | FROM                  { $$ = make_str("from"); }
2376                 ;
2377
2378 CommentStmt:   COMMENT ON comment_type name IS comment_text
2379                         { $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6); }
2380                 | COMMENT ON AGGREGATE func_name aggr_args IS comment_text
2381                         { $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7); }
2382                 | COMMENT ON FUNCTION func_name func_args IS comment_text
2383                         { $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7); }
2384                 | COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
2385                         { $$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9); }
2386                 | COMMENT ON TRIGGER name ON any_name IS comment_text
2387                         { $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8); }
2388                 | COMMENT ON RULE name ON any_name IS comment_text
2389                         { $$ = cat_str(6, make_str("comment on rule"), $4, make_str("on"), $6, make_str("is"), $8); }
2390                 | COMMENT ON RULE name IS comment_text
2391                         { $$ = cat_str(4, make_str("comment on rule"), $4, make_str("is"), $6); }
2392                 | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text
2393                         { $$ = cat_str(6, make_str("comment on operator class"), $5, make_str("using"), $7, make_str("is"), $9); }
2394                 | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text
2395                         { $$ = cat_str(6, make_str("comment on operator family"), $5, make_str("using"), $7, make_str("is"), $9); }
2396                 | COMMENT ON LARGE_P OBJECT_P NumConst IS comment_text
2397                         { $$ = cat_str(4, make_str("comment on large object"), $5, make_str("is"), $7); }
2398                 | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text
2399                         { $$ = cat_str(6, make_str("comment on cast ("), $5, make_str("as"), $7, make_str(") is"), $10); }
2400                 | COMMENT ON opt_procedural LANGUAGE any_name IS comment_text
2401                         { $$ = cat_str(6, make_str("comment on"), $3, make_str("language"), $5, make_str("is"), $7); }
2402                 | COMMENT ON TEXT_P SEARCH PARSER any_name IS comment_text
2403                         { $$ = cat_str(4, make_str("comment on test search parser"), $6, make_str("is"), $8); }
2404                 | COMMENT ON TEXT_P SEARCH DICTIONARY any_name IS comment_text
2405                         { $$ = cat_str(4, make_str("comment on test search dictionary"), $6, make_str("is"), $8); }
2406                 | COMMENT ON TEXT_P SEARCH TEMPLATE any_name IS comment_text
2407                         { $$ = cat_str(4, make_str("comment on test search template"), $6, make_str("is"), $8); }
2408                 | COMMENT ON TEXT_P SEARCH CONFIGURATION any_name IS comment_text
2409                         { $$ = cat_str(4, make_str("comment on test search configuration"), $6, make_str("is"), $8); }
2410                 ;
2411
2412 comment_type:  COLUMN           { $$ = make_str("column"); }
2413                 | DATABASE                      { $$ = make_str("database"); }
2414                 | SCHEMA                        { $$ = make_str("schema"); }
2415                 | INDEX                         { $$ = make_str("idnex"); }
2416                 | SEQUENCE                      { $$ = make_str("sequence"); }
2417                 | TABLE                         { $$ = make_str("table"); }
2418                 | DOMAIN_P                      { $$ = make_str("domain"); }
2419                 | TYPE_P                        { $$ = make_str("type"); }
2420                 | VIEW                          { $$ = make_str("view"); }
2421                 | CONVERSION_P                  { $$ = make_str("conversion"); }
2422                 | TABLESPACE                    { $$ = make_str("tablespace"); }
2423                 | ROLE                          { $$ = make_str("role"); }
2424                 ;
2425
2426 comment_text:   StringConst { $$ = $1; }
2427                 | NULL_P                        { $$ = make_str("null"); }
2428                 ;
2429
2430 /*****************************************************************************
2431  *
2432  *              QUERY:
2433  * GRANT and REVOKE statements
2434  *
2435  *****************************************************************************/
2436
2437 GrantStmt:      GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
2438                         { $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6, $7); }
2439                 ;
2440
2441 RevokeStmt:  REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior
2442                         {$$ = cat_str(7, make_str("revoke"), $2, make_str("on"), $4, make_str("from"), $6, $7); }
2443                 | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior
2444                         {$$ = cat_str(7, make_str("revoke grant option for"), $5, make_str("on"), $7, make_str("from"), $9, $10); }
2445                 ;
2446
2447 privileges:  ALL PRIVILEGES             { $$ = make_str("all privileges"); }
2448                 | ALL                                   { $$ = make_str("all"); }
2449                 | privilege_list                { $$ = $1; }
2450                 ;
2451
2452 privilege_list:  privilege
2453                         { $$ = $1; }
2454                 | privilege_list ',' privilege
2455                         { $$ = cat_str(3, $1, make_str(","), $3); }
2456                 ;
2457
2458 privilege:      SELECT                  { $$ = make_str("select"); }
2459                 | REFERENCES            { $$ = make_str("references"); }
2460                 | CREATE                        { $$ = make_str("create"); }
2461                 | ColId                         { $$ = $1; }
2462                 ;
2463
2464 privilege_target: qualified_name_list
2465                         { $$ = $1; }
2466                 | TABLE qualified_name_list
2467                         { $$ = cat2_str(make_str("table"), $2); }
2468                 | SEQUENCE qualified_name_list
2469                         { $$ = cat2_str(make_str("sequence"), $2); }
2470                 | FUNCTION function_with_argtypes_list
2471                         { $$ = cat2_str(make_str("function"), $2); }
2472                 | DATABASE name_list
2473                         { $$ = cat2_str(make_str("database"), $2); }
2474                 | LANGUAGE name_list
2475                         { $$ = cat2_str(make_str("language") , $2); }
2476                 | SCHEMA name_list
2477                         { $$ = cat2_str(make_str("schema") , $2); }
2478                 | TABLESPACE name_list
2479                         { $$ = cat2_str(make_str("tablespace") , $2); }
2480                 ;
2481
2482 grantee_list: grantee
2483                         { $$ = $1; }
2484                 | grantee_list ',' grantee
2485                         { $$ = cat_str(3, $1, make_str(","), $3); }
2486                 ;
2487
2488 grantee:  RoleId                        { $$ = $1; }
2489                 | GROUP_P RoleId        { $$ = cat2_str(make_str("group"), $2); }
2490                 ;
2491
2492 opt_grant_grant_option:  WITH GRANT OPTION
2493                 {
2494                         mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
2495                         $$ = make_str("with grant option");
2496                 }
2497                 | /*EMPTY*/             { $$ = EMPTY; }
2498                 ;
2499
2500 function_with_argtypes_list: function_with_argtypes
2501                         { $$ = $1; }
2502                 | function_with_argtypes_list ',' function_with_argtypes
2503                         { $$ = cat_str(3, $1, make_str(","), $3); }
2504                 ;
2505
2506 function_with_argtypes: func_name func_args { $$ = cat2_str($1, $2); };
2507
2508 /*****************************************************************************
2509  *
2510  * GRANT and REVOKE ROLE statements
2511  *
2512  *****************************************************************************/
2513
2514 GrantRoleStmt:
2515                 GRANT privilege_list TO name_list opt_grant_admin_option opt_granted_by
2516                         { $$ = cat_str(6, make_str("grant"), $2, make_str("to"), $4, $5, $6); }
2517                 ;
2518
2519 RevokeRoleStmt:
2520                 REVOKE privilege_list FROM name_list opt_granted_by opt_drop_behavior
2521                         { $$ = cat_str(6, make_str("revoke"), $2, make_str("from"), $4, $5, $6); }
2522                 ;
2523
2524 opt_grant_admin_option: WITH ADMIN OPTION       { $$ = make_str("with admin option"); }
2525                 | /*EMPTY*/                     { $$ = EMPTY; }
2526                 ;
2527
2528 opt_granted_by: GRANTED BY RoleId        { $$ = cat2_str(make_str("granted by"), $3); }
2529                 | /*EMPTY*/              { $$ = EMPTY; }
2530                 ;
2531
2532 /*****************************************************************************
2533  *
2534  *              QUERY:
2535  *             QUERY: CREATE INDEX
2536  *
2537  * Note: we can't factor CONCURRENTLY into a separate production without
2538  * making it a reserved word.
2539  *
2540  * Note: we cannot put TABLESPACE clause after WHERE clause unless we are
2541  * willing to make TABLESPACE a fully reserved word.
2542  *
2543  *****************************************************************************/
2544
2545 IndexStmt:      CREATE index_opt_unique INDEX index_name ON qualified_name
2546                                 access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
2547                         { $$ = cat_str(13, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12, $13); }
2548                 | CREATE index_opt_unique INDEX CONCURRENTLY index_name ON qualified_name
2549                                 access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
2550                         { $$ = cat_str(13, make_str("create"), $2, make_str("index concurrently"), $5, make_str("on"), $7, $8, make_str("("), $10, make_str(")"), $12, $13, $14); }
2551                 ;
2552
2553 index_opt_unique:  UNIQUE       { $$ = make_str("unique"); }
2554                 | /*EMPTY*/             { $$ = EMPTY; }
2555                 ;
2556
2557 access_method_clause:  USING access_method
2558                         { $$ = cat2_str(make_str("using"), $2); }
2559                 | /*EMPTY*/
2560                         { $$ = EMPTY; }
2561                 ;
2562
2563 index_params:  index_elem                       { $$ = $1; }
2564                 | index_params ',' index_elem   { $$ = cat_str(3, $1, make_str(","), $3); }
2565                 ;
2566
2567 index_elem:  ColId opt_class opt_asc_desc opt_nulls_order
2568                         { $$ = cat_str(4, $1, $2, $3, $4); }
2569                 | func_expr opt_class opt_asc_desc opt_nulls_order
2570                         { $$ = cat_str(4, $1, $2, $3, $4); }
2571                 | '(' a_expr ')' opt_class opt_asc_desc opt_nulls_order
2572                         { $$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6); }
2573                 ;
2574
2575 opt_class:      any_name        { $$ = $1; }
2576                 | USING any_name        { $$ = cat2_str(make_str("using"), $2); }
2577                 | /*EMPTY*/             { $$ = EMPTY; }
2578                 ;
2579
2580 opt_asc_desc:   ASC             { $$ = make_str("asc"); }
2581                 | DESC          { $$ = make_str("desc"); } 
2582                 | /*EMPTY*/     { $$ = EMPTY; }
2583                 ;
2584
2585 opt_nulls_order:        NULLS_FIRST             { $$ = make_str("nulls first"); }
2586                         | NULLS_LAST            { $$ = make_str("nulls last"); } 
2587                         | /*EMPTY*/     { $$ = EMPTY; }
2588                         ;
2589
2590 CreateFunctionStmt:     CREATE opt_or_replace FUNCTION func_name func_args
2591                                         RETURNS func_return createfunc_opt_list opt_definition
2592                         { $$ = cat_str(8, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, $8); }
2593                 | CREATE opt_or_replace FUNCTION func_name func_args
2594                                         createfunc_opt_list opt_definition
2595                         { $$ = cat_str(6, make_str("create"), $2, make_str("function"), $4, $5, $6, $7); }
2596                 ;
2597
2598 opt_or_replace:  OR REPLACE             { $$ = make_str("or replace"); }
2599                 | /*EMPTY*/                             { $$ = EMPTY; }
2600                 ;
2601
2602 func_args:      '(' func_args_list ')'
2603                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2604                 | '(' ')'
2605                         { $$ = make_str("()"); }
2606                 ;
2607
2608 func_args_list:  func_arg
2609                         { $$ = $1; }
2610                 | func_args_list ',' func_arg
2611                         { $$ = cat_str(3, $1, make_str(","), $3); }
2612                 ;
2613
2614 func_arg:  arg_class param_name func_type               { $$ = cat_str(3, $1, $2, $3); }
2615                 | param_name arg_class func_type        { $$ = cat_str(3, $1, $2, $3); }
2616                 | param_name func_type                  { $$ = cat2_str($1, $2); }
2617                 | arg_class func_type                   { $$ = cat2_str($1, $2); }
2618                 | func_type                             { $$ = $1; }
2619                 ;
2620
2621 arg_class:  IN_P                { $$ = make_str("in"); }
2622                 | OUT_P         { $$ = make_str("out"); }
2623                 | INOUT         { $$ = make_str("inout"); }
2624                 | IN_P OUT_P    { $$ = make_str("in out"); }
2625                 ;
2626
2627 func_as: StringConst
2628                         { $$ = $1; }
2629                 | StringConst ',' StringConst
2630                         { $$ = cat_str(3, $1, make_str(","), $3); }
2631                 ;
2632
2633 param_name:    type_function_name       { $$ = $1; };
2634
2635 func_return:  func_type
2636                 {
2637                         /* We can catch over-specified arguments here if we want to,
2638                          * but for now better to silently swallow typmod, etc.
2639                          * - thomas 2000-03-22
2640                          */
2641                         $$ = $1;
2642                 }
2643                 ;
2644
2645 func_type:      Typename
2646                         { $$ = $1; }
2647                 | type_function_name attrs '%' TYPE_P
2648                         { $$ = cat_str(3, $1, $2, make_str("% type")); }
2649                 | SETOF type_function_name attrs '%' TYPE_P
2650                         { $$ = cat_str(4, make_str("setof"), $2, $3, make_str("% type")); }
2651                 ;
2652
2653
2654 createfunc_opt_list: createfunc_opt_item
2655                         { $$ = $1; }
2656                 | createfunc_opt_list createfunc_opt_item
2657                         { $$ = cat2_str($1, $2); }
2658                 ;
2659
2660 common_func_opt_item:
2661                 CALLED ON NULL_P INPUT_P
2662                                 { $$ = make_str("called on null input"); }
2663                 | RETURNS NULL_P ON NULL_P INPUT_P
2664                                 { $$ = make_str("returns null on null input"); }
2665                 | STRICT_P
2666                                 { $$ = make_str("strict"); }
2667                 | IMMUTABLE
2668                                 { $$ = make_str("immutable"); }
2669                 | STABLE
2670                                 { $$ = make_str("stable"); }
2671                 | VOLATILE
2672                                 { $$ = make_str("volatile"); }
2673                 | EXTERNAL SECURITY DEFINER
2674                                 { $$ = make_str("external security definer"); }
2675                 | EXTERNAL SECURITY INVOKER
2676                                 { $$ = make_str("external security invoker"); }
2677                 | SECURITY DEFINER
2678                                 { $$ = make_str("security definer"); }
2679                 | SECURITY INVOKER
2680                                 { $$ = make_str("security invoker"); }
2681                 | COST NumConst
2682                                 { $$ = cat2_str(make_str("cost"), $2); }
2683                 | ROWS NumConst
2684                                 { $$ = cat2_str(make_str("rows"), $2); }
2685                 | SetResetClause
2686                                 { $$ = $1; }
2687                 ;
2688
2689 createfunc_opt_item: AS func_as
2690                                 { $$ = cat2_str(make_str("as"), $2); }
2691                 | LANGUAGE ColId_or_Sconst
2692                                 { $$ = cat2_str(make_str("language"), $2); }
2693                 | common_func_opt_item
2694                                 { $$ = $1; }
2695                 ;
2696
2697 opt_definition: WITH definition { $$ = cat2_str(make_str("with"), $2); }
2698                 | /*EMPTY*/     { $$ = EMPTY; }
2699                 ;
2700
2701 AlterFunctionStmt:
2702                 ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
2703                         { $$ = cat_str(4, make_str("alter function"), $3, $4, $5); }
2704                 ;
2705
2706 alterfunc_opt_list: common_func_opt_item                        { $$ = $1; }
2707                 | alterfunc_opt_list common_func_opt_item       { $$ = cat2_str($1, $2);}
2708                 ;
2709
2710 opt_restrict:   RESTRICT        { $$ = make_str("restrict"); }
2711                 | /*EMPTY*/       { $$ = EMPTY; }
2712                 ;
2713
2714 /*****************************************************************************
2715  *
2716  *              QUERY:
2717  *
2718  *                         DROP FUNCTION funcname (arg1, arg2, ...)
2719  *                         DROP AGGREGATE (arg1, ...) [ RESTRICT | CASCADE ]
2720  *                         DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
2721  *
2722  *****************************************************************************/
2723
2724 RemoveFuncStmt:  DROP FUNCTION func_name func_args opt_drop_behavior
2725                         { $$ = cat_str(4, make_str("drop function"), $3, $4, $5); }
2726                 | DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
2727                         { $$ = cat_str(4, make_str("drop function if exists"), $5, $6, $7); }
2728                 ;
2729
2730 RemoveAggrStmt:  DROP AGGREGATE func_name aggr_args opt_drop_behavior
2731                         { $$ = cat_str(4, make_str("drop aggregate"), $3, $4, $5); }
2732                 | DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
2733                         { $$ = cat_str(4, make_str("drop aggregate if exists"), $5, $6, $7); }
2734                 ;
2735
2736 RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')' opt_drop_behavior
2737                         { $$ = cat_str(6, make_str("drop operator"), $3, make_str("("), $5, make_str(")"), $7); }
2738                 | DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
2739                         { $$ = cat_str(6, make_str("drop operator if exists"), $5, make_str("("), $7, make_str(")"), $9); }
2740                 ;
2741
2742 oper_argtypes:  Typename
2743                         { mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)"); }
2744                 | Typename ',' Typename
2745                         { $$ = cat_str(3, $1, make_str(","), $3); }
2746                 | NONE ',' Typename                     /* left unary */
2747                         { $$ = cat2_str(make_str("none,"), $3); }
2748                 | Typename ',' NONE                     /* right unary */
2749                         { $$ = cat2_str($1, make_str(", none")); }
2750                 ;
2751
2752 any_operator:
2753                 all_Op
2754                         { $$ = $1; }
2755                 | ColId '.' any_operator
2756                         { $$ = cat_str(3, $1, make_str("."), $3); }
2757                 ;
2758
2759 CreateCastStmt:         CREATE CAST '(' Typename AS Typename ')'
2760                                 WITH FUNCTION function_with_argtypes cast_context
2761                         { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") with function"), $10); }
2762                 | CREATE CAST '(' Typename AS Typename ')'
2763                                 WITHOUT FUNCTION cast_context
2764                         { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") without function"), $10); }
2765                 ;
2766
2767 cast_context: AS ASSIGNMENT   { $$ = make_str("as assignment"); }
2768                 | /*EMPTY*/     { $$ = EMPTY; }
2769                 ;
2770
2771
2772 DropCastStmt: DROP CAST opt_if_exists  '(' Typename AS Typename ')' opt_drop_behavior
2773                         { $$ = cat_str(8, make_str("drop cast"), $3, make_str("("), $5, make_str("as"), $7, make_str(")"), $9); }
2774                 ;
2775
2776 opt_if_exists: IF_P EXISTS      { $$ = make_str("if exists"); }
2777                 | /* EMPTY */   { $$ = EMPTY; }
2778                 ;
2779
2780 /*****************************************************************************
2781  *
2782  *                              QUERY:
2783  *
2784  *                              REINDEX type <typename> [FORCE] [ALL]
2785  *
2786  *****************************************************************************/
2787 ReindexStmt:  REINDEX reindex_type qualified_name opt_force
2788                         { $$ = cat_str(4, make_str("reindex"), $2, $3, $4); }
2789                 | REINDEX SYSTEM_P name opt_force
2790                         { $$ = cat_str(3, make_str("reindex system"), $3, $4); }
2791                 | REINDEX DATABASE name opt_force
2792                         { $$ = cat_str(3, make_str("reindex database"), $3, $4); }
2793                 ;
2794
2795 reindex_type:   INDEX           { $$ = make_str("index"); }
2796                 | TABLE         { $$ = make_str("table"); }
2797                 ;
2798
2799 opt_force: FORCE                        { $$ = make_str("force"); }
2800                 | /* EMPTY */           { $$ = EMPTY; }
2801                 ;
2802
2803 /*****************************************************************************
2804  *
2805  *              QUERY:
2806  *                              rename <attrname1> in <relname> [*] to <attrname2>
2807  *                              rename <relname1> to <relname2>
2808  *
2809  *****************************************************************************/
2810
2811 RenameStmt:  ALTER AGGREGATE func_name aggr_args RENAME TO name
2812                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("rename to"), $7); }
2813                 | ALTER CONVERSION_P any_name RENAME TO name
2814                         { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("rename to"), $6); }
2815                 | ALTER DATABASE database_name RENAME TO database_name
2816                         { $$ = cat_str(4, make_str("alter database"), $3, make_str("rename to"), $6); }
2817                 | ALTER FUNCTION function_with_argtypes RENAME TO name
2818                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("rename to"), $6); }
2819                 | ALTER GROUP_P RoleId RENAME TO RoleId
2820                         { $$ = cat_str(4, make_str("alter group"), $3, make_str("rename to"), $6); }
2821                 | ALTER opt_procedural LANGUAGE name RENAME TO name
2822                         { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("rename to"), $7); }
2823                 | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
2824                         { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
2825                 | ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name
2826                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("rename to"), $9); }
2827                 | ALTER SCHEMA name RENAME TO name
2828                         { $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
2829                 | ALTER TABLE relation_expr RENAME TO name
2830                         { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
2831                 | ALTER SEQUENCE relation_expr RENAME TO name
2832                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("rename to"), $6); }
2833                 | ALTER VIEW relation_expr RENAME TO name
2834                         { $$ = cat_str(4, make_str("alter view"), $3, make_str("rename to"), $6); }
2835                 | ALTER INDEX relation_expr RENAME TO name
2836                         { $$ = cat_str(4, make_str("alter index"), $3, make_str("rename to"), $6); }
2837                 | ALTER TABLE relation_expr RENAME opt_column name TO name
2838                         { $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
2839                 | ALTER TRIGGER name ON relation_expr RENAME TO name
2840                         { $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
2841                 | ALTER USER RoleId RENAME TO RoleId
2842                         { $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
2843                 | ALTER TABLESPACE name RENAME TO name
2844                         { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("rename to"), $6); }
2845                 | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
2846                         { $$ = cat_str(4, make_str("alter text search parser"), $5, make_str("rename to"), $8); }
2847                 | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name
2848                         { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("rename to"), $8); }
2849                 | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name
2850                         { $$ = cat_str(4, make_str("alter text search template"), $5, make_str("rename to"), $8); }
2851                 | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
2852                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("rename to"), $8); }
2853                 ;
2854
2855 opt_column:  COLUMN                     { $$ = make_str("column"); }
2856                 | /*EMPTY*/                     { $$ = EMPTY; }
2857                 ;
2858
2859 /*****************************************************************************
2860  *
2861  * ALTER THING name SET SCHEMA name
2862  *
2863  *****************************************************************************/
2864
2865 AlterObjectSchemaStmt:
2866                 ALTER AGGREGATE func_name aggr_args SET SCHEMA name
2867                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("set schema"), $7); }
2868                 | ALTER DOMAIN_P any_name SET SCHEMA name
2869                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("set schema"), $6); }
2870                 | ALTER FUNCTION function_with_argtypes SET SCHEMA name
2871                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("set schema"), $6); }
2872                 | ALTER SEQUENCE relation_expr SET SCHEMA name
2873                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
2874                 | ALTER TABLE relation_expr SET SCHEMA name
2875                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
2876                 | ALTER TYPE_P any_name SET SCHEMA name
2877                         { $$ = cat_str(4, make_str("alter type"), $3, make_str("set schema"), $6); }
2878                 ;
2879
2880 /*****************************************************************************
2881  *
2882  * ALTER THING name OWNER TO newname
2883  *
2884  *****************************************************************************/
2885
2886 AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
2887                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("owner to"), $7); }
2888                 | ALTER CONVERSION_P any_name OWNER TO RoleId
2889                         { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("owner to"), $6); }
2890                 | ALTER DATABASE database_name OWNER TO RoleId
2891                         { $$ = cat_str(4, make_str("alter database"), $3, make_str("owner to"), $6); }
2892                 | ALTER DOMAIN_P database_name OWNER TO RoleId
2893                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("owner to"), $6); }
2894                 | ALTER FUNCTION function_with_argtypes OWNER TO RoleId
2895                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("owner to"), $6); }
2896                 | ALTER opt_procedural LANGUAGE name OWNER TO RoleId
2897                         { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("owner to"), $7); }
2898                 | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
2899                         { $$ = cat_str(6, make_str("alter operator"), $3, make_str("("), $5, make_str(") owner to"), $9); }
2900                 | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
2901                         { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("owner to"), $9); }
2902                 | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId
2903                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("owner to"), $9); }
2904                 | ALTER SCHEMA name OWNER TO RoleId
2905                         { $$ = cat_str(4, make_str("alter schema"), $3, make_str("owner to"), $6); }
2906                 | ALTER TYPE_P any_name OWNER TO RoleId
2907                         { $$ = cat_str(4, make_str("alter type"), $3, make_str("owner to"), $6); }
2908                 | ALTER TABLESPACE name OWNER TO RoleId
2909                         { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("owner to"), $6); }
2910                 | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleId
2911                         { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("owner to"), $8); }
2912                 | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleId
2913                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("owner to"), $8); }
2914                 ;
2915
2916
2917 /*****************************************************************************
2918  *
2919  *              QUERY:  Define Rewrite Rule
2920  *
2921  *****************************************************************************/
2922
2923 RuleStmt:  CREATE opt_or_replace RULE name AS
2924                    { QueryIsRule=1; }
2925                    ON event TO qualified_name where_clause
2926                    DO opt_instead RuleActionList
2927                 {
2928                         QueryIsRule=0;
2929                         $$ = cat_str(12, make_str("create"), $2, make_str("rule"), $4, make_str("as on"), $8, make_str("to"), $10, $11, make_str("do"), $13, $14);
2930                 }
2931                 ;
2932
2933 RuleActionList:  NOTHING                                { $$ = make_str("nothing"); }
2934                 | RuleActionStmt                                { $$ = $1; }
2935                 | '(' RuleActionMulti ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2936                                 ;
2937
2938 /* the thrashing around here is to discard "empty" statements... */
2939 RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
2940                         {  $$ = cat_str(3, $1, make_str(";"), $3); }
2941                 | RuleActionStmtOrEmpty
2942                         { $$ = cat2_str($1, make_str(";")); }
2943                 ;
2944
2945 RuleActionStmt:   SelectStmt
2946                 | InsertStmt
2947                 | UpdateStmt
2948                 | DeleteStmt
2949                 | NotifyStmt
2950                 ;
2951
2952 RuleActionStmtOrEmpty: RuleActionStmt   { $$ = $1; }
2953                 | /*EMPTY*/                                             { $$ = EMPTY; }
2954                 ;
2955
2956 /* change me to select, update, etc. some day */
2957 event:  SELECT                          { $$ = make_str("select"); }
2958                 | UPDATE                        { $$ = make_str("update"); }
2959                 | DELETE_P                      { $$ = make_str("delete"); }
2960                 | INSERT                        { $$ = make_str("insert"); }
2961                 ;
2962
2963 opt_instead:  INSTEAD           { $$ = make_str("instead"); }
2964                 | ALSO          { $$ = make_str("also"); }
2965                 | /*EMPTY*/                     { $$ = EMPTY; }
2966                 ;
2967
2968 DropRuleStmt:  DROP RULE name ON qualified_name opt_drop_behavior
2969                         { $$ = cat_str(5, make_str("drop rule"), $3, make_str("on"), $5, $6);}
2970                 | DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
2971                         { $$ = cat_str(5, make_str("drop rule if exists"), $5, make_str("on"), $7, $8);}
2972                 ;
2973
2974 /*****************************************************************************
2975  *
2976  *              QUERY:
2977  *                              NOTIFY <qualified_name> can appear both in rule bodies and
2978  *                              as a query-level command
2979  *
2980  *****************************************************************************/
2981
2982 NotifyStmt:  NOTIFY ColId
2983                         { $$ = cat2_str(make_str("notify"), $2); }
2984                 ;
2985
2986 ListenStmt:  LISTEN ColId
2987                         { $$ = cat2_str(make_str("listen"), $2); }
2988                 ;
2989
2990 UnlistenStmt:  UNLISTEN ColId
2991                         { $$ = cat2_str(make_str("unlisten"), $2); }
2992                 | UNLISTEN '*'
2993                         { $$ = make_str("unlisten *"); }
2994                 ;
2995
2996
2997 /*****************************************************************************
2998  *
2999  *                              Transactions:
3000  *
3001  *        BEGIN / COMMIT / ROLLBACK
3002  *              (also older versions END / ABORT)
3003  *
3004  *****************************************************************************/
3005 TransactionStmt:  ABORT_P opt_transaction        { $$ = make_str("rollback"); }
3006                 | BEGIN_P opt_transaction transaction_mode_list_or_empty { $$ = cat2_str(make_str("begin transaction"), $3); }
3007                 | START TRANSACTION transaction_mode_list_or_empty       { $$ = cat2_str(make_str("start transaction"), $3); }
3008                 | COMMIT opt_transaction                         { $$ = make_str("commit"); }
3009                 | END_P opt_transaction                          { $$ = make_str("commit"); }
3010                 | ROLLBACK opt_transaction                       { $$ = make_str("rollback"); }
3011                 | SAVEPOINT ColId                                        { $$ = cat2_str(make_str("savepoint"), $2); }
3012                 | RELEASE SAVEPOINT ColId                        { $$ = cat2_str(make_str("release savepoint"), $3); }
3013                 | RELEASE ColId                                          { $$ = cat2_str(make_str("release"), $2); }
3014                 | ROLLBACK opt_transaction TO SAVEPOINT ColId            { $$ = cat_str(4, make_str("rollback"), $2, make_str("to savepoint"), $5); }
3015                 | ROLLBACK opt_transaction TO ColId      { $$ = cat_str(4, make_str("rollback"), $2, make_str("to"), $4); }
3016                 | PREPARE TRANSACTION StringConst        { $$ = cat2_str(make_str("prepare transaction"), $3); }
3017                 | COMMIT PREPARED StringConst            { $$ = cat2_str(make_str("commit prepared"), $3); }
3018                 | ROLLBACK PREPARED StringConst          { $$ = cat2_str(make_str("rollback prepared"), $3); }
3019                 ;
3020
3021 opt_transaction: WORK   { $$ = EMPTY; }
3022                 | TRANSACTION   { $$ = EMPTY; }
3023                 | /*EMPTY*/             { $$ = EMPTY; }
3024                 ;
3025
3026 transaction_mode_item:
3027                 ISOLATION LEVEL iso_level
3028                         { $$ = cat2_str(make_str("isolation level"), $3); }
3029                 | READ ONLY     { $$ = make_str("read only"); }
3030                 | READ WRITE    { $$ = make_str("read write"); }
3031                 ;
3032
3033 transaction_mode_list:
3034                 transaction_mode_item                                   { $$ = $1; }
3035                 | transaction_mode_list ',' transaction_mode_item       { $$ = cat_str(3, $1, make_str(","), $3); }
3036                 | transaction_mode_list transaction_mode_item           { $$ = cat_str(3, $1, make_str(" "), $2); }
3037                 ;
3038
3039 transaction_mode_list_or_empty:
3040                 transaction_mode_list   { $$ = $1; }
3041                 | /* EMPTY */           { $$ = EMPTY; }
3042                 ;
3043
3044 /*****************************************************************************
3045  *
3046  *      QUERY:
3047  *              CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
3048  *                     AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
3049  *
3050  *****************************************************************************/
3051
3052 ViewStmt:  CREATE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
3053                         { $$ = cat_str(8, make_str("create"), $2, make_str("view"), $4, $5, make_str("as"), $7, $8); }
3054                 | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
3055                         { $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); }
3056                 ;
3057
3058 /*
3059  * We use merged tokens here to avoid creating shift/reduce conflicts against
3060  * a whole lot of other uses of WITH.
3061  */
3062 opt_check_option:
3063                    WITH_CHECK OPTION
3064                    { 
3065                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3066                         $$ = EMPTY;
3067                    }
3068                    | WITH_CASCADED CHECK OPTION
3069                    { 
3070                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3071                         $$ = EMPTY;
3072                    }
3073                    | WITH_LOCAL CHECK OPTION
3074                    {
3075                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3076                         $$ = EMPTY;
3077                    }
3078                    | /* EMPTY */
3079                    { $$ = EMPTY; } 
3080                    ;
3081
3082 /*****************************************************************************
3083  *
3084  *              QUERY:
3085  *                              load make_str("filename")
3086  *
3087  *****************************************************************************/
3088
3089 LoadStmt:  LOAD file_name
3090                         { $$ = cat2_str(make_str("load"), $2); }
3091                 ;
3092
3093
3094 /*****************************************************************************
3095  *
3096  *              CREATE DATABASE
3097  *
3098  *
3099  *****************************************************************************/
3100
3101 CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
3102                         { $$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5); }
3103                 | CREATE DATABASE database_name
3104                         { $$ = cat2_str(make_str("create database"), $3); }
3105                 ;
3106
3107 createdb_opt_list:      createdb_opt_item
3108                         { $$ = $1; }
3109                 | createdb_opt_list createdb_opt_item
3110                         { $$ = cat2_str($1, $2); }
3111                 ;
3112
3113 createdb_opt_item:      TABLESPACE opt_equal name
3114                         { $$ = cat_str(3,make_str("tablespace"), $2, $3); }
3115                 | TABLESPACE opt_equal DEFAULT
3116                         { $$ = cat_str(3, make_str("tablespace"), $2, make_str("default")); }
3117                 | LOCATION opt_equal StringConst
3118                         { $$ = cat_str(3,make_str("location"), $2, $3); }
3119                 | LOCATION opt_equal DEFAULT
3120                         { $$ = cat_str(3, make_str("location"), $2, make_str("default")); }
3121                 | TEMPLATE opt_equal name
3122                         { $$ = cat_str(3, make_str("template"), $2, $3); }
3123                 | TEMPLATE opt_equal DEFAULT
3124                         { $$ = cat_str(3, make_str("template"), $2, make_str("default")); }
3125                 | ENCODING opt_equal PosIntStringConst
3126                         { $$ = cat_str(3, make_str("encoding"), $2, $3); }
3127                 | ENCODING opt_equal DEFAULT
3128                         { $$ = cat_str(3, make_str("encoding"), $2, make_str("default")); }
3129                 | CONNECTION LIMIT opt_equal PosIntConst
3130                         { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
3131                 | OWNER opt_equal name
3132                         { $$ = cat_str(3, make_str("owner"), $2, $3); }
3133                 | OWNER opt_equal DEFAULT
3134                         { $$ = cat_str(3, make_str("owner"), $2, make_str("default")); }
3135                 ;
3136
3137 opt_equal: '='                                  { $$ = make_str("="); }
3138                 | /* EMPTY */                   { $$ = EMPTY; }
3139                 ;
3140
3141
3142 /*****************************************************************************
3143  *
3144  *                              ALTER DATABASE
3145  *
3146  *
3147  *****************************************************************************/
3148
3149 AlterDatabaseStmt: ALTER DATABASE database_name opt_with alterdb_opt_list
3150                         { $$ = cat_str(4, make_str("alter database"), $3, $4, $5); }
3151                 ;
3152
3153 AlterDatabaseSetStmt: ALTER DATABASE database_name SetResetClause
3154                         { $$ = cat_str(3, make_str("alter database"), $3, $4); }
3155                 ;
3156
3157 alterdb_opt_list:
3158                 alterdb_opt_list alterdb_opt_item       { $$ = cat2_str($1, $2);}
3159                 | /* EMPTY */                           { $$ = EMPTY; }
3160                 ;
3161
3162 alterdb_opt_item:
3163                 CONNECTION LIMIT opt_equal PosIntConst { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
3164                 ;
3165
3166 /*****************************************************************************
3167  *
3168  *              DROP DATABASE [ IF EXISTS ]
3169  *
3170  *
3171  *****************************************************************************/
3172
3173 DropdbStmt: DROP DATABASE database_name
3174                         { $$ = cat2_str(make_str("drop database"), $3); }
3175                 | DROP DATABASE IF_P EXISTS database_name
3176                         { $$ = cat2_str(make_str("drop database if exists"), $5); }
3177                 ;
3178
3179
3180 /*****************************************************************************
3181  *
3182  * Manipulate a domain
3183  *
3184  *****************************************************************************/
3185
3186 CreateDomainStmt:  CREATE DOMAIN_P any_name opt_as Typename ColQualList
3187                 {
3188                         $$ = cat_str(5, make_str("create domain"), $3, $4, $5, $6);
3189                 }
3190                 ;
3191
3192 AlterDomainStmt:
3193                 ALTER DOMAIN_P any_name alter_column_default
3194                         { $$ = cat_str(3, make_str("alter domain"), $3, $4); }
3195                 | ALTER DOMAIN_P any_name DROP NOT NULL_P
3196                         { $$ = cat_str(3, make_str("alter domain"), $3, make_str("drop not null")); }
3197                 | ALTER DOMAIN_P any_name SET NOT NULL_P
3198                         { $$ = cat_str(3, make_str("alter domain"), $3, make_str("set not null")); }
3199                 | ALTER DOMAIN_P any_name ADD_P TableConstraint
3200                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("add"), $5); }
3201                 | ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
3202                         { $$ = cat_str(5, make_str("alter domain"), $3, make_str("drop constraint"), $6, $7); }
3203                 ;
3204
3205 opt_as: AS      {$$ = make_str("as"); }
3206                 | /* EMPTY */   {$$ = EMPTY; }
3207                 ;
3208
3209 AlterTSDictionaryStmt:
3210                 ALTER TEXT_P SEARCH DICTIONARY any_name definition
3211                         { $$ = cat_str(3, make_str("alter text search dictionary"), $5, $6); }
3212                 ;
3213
3214 AlterTSConfigurationStmt:
3215                 ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list WITH any_name_list
3216                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("add mapping for"), $9, make_str("with"), $11); }
3217                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list WITH any_name_list
3218                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("with"), $11); }
3219                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name WITH any_name
3220                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping replace"), $9, make_str("with"), $11); }
3221                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name WITH any_name
3222                         { $$ = cat_str(8, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("replace"), $11, make_str("with"), $13); }
3223                 | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
3224                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping for"), $9); }
3225                 | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
3226                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping if exists for"), $11); }
3227                 ;
3228
3229 CreateConversionStmt:
3230            CREATE opt_default CONVERSION_P any_name FOR StringConst
3231            TO StringConst FROM any_name
3232                    { $$ = cat_str(10, make_str("create"), $2, make_str("conversion"), $4, make_str("for"), $6, make_str("to"), $8, make_str("from"), $10); }
3233            ;
3234
3235 /*****************************************************************************
3236  *
3237  *              QUERY:
3238  *                             cluster <index_name> on <qualified_name>
3239  *                             cluster <qualified_name>
3240  *                             cluster
3241  *
3242  *****************************************************************************/
3243
3244 ClusterStmt:  CLUSTER qualified_name cluster_index_specification
3245                                 { $$ = cat_str(3,make_str("cluster"), $2, $3); }
3246                 | CLUSTER
3247                                 { $$ = make_str("cluster"); }
3248                 | CLUSTER qualified_name ON qualified_name
3249                                 { $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4); }
3250                 ;
3251
3252 cluster_index_specification:
3253                 USING index_name        { $$ = cat2_str(make_str("using"), $2); }
3254                 | /*EMPTY*/             { $$ = EMPTY; }
3255                 ;
3256
3257 /*****************************************************************************
3258  *
3259  *              QUERY:
3260  *                              vacuum
3261  *                              analyze
3262  *
3263  *****************************************************************************/
3264
3265 VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
3266                         { $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); }
3267                 | VACUUM opt_full opt_freeze opt_verbose qualified_name
3268                         { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
3269                 | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
3270                         { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
3271                 ;
3272
3273 AnalyzeStmt:  analyze_keyword opt_verbose
3274                         { $$ = cat_str(2, $1, $2); }
3275                 | analyze_keyword opt_verbose qualified_name opt_name_list
3276                         { $$ = cat_str(4, $1, $2, $3, $4); }
3277                 ;
3278
3279 analyze_keyword:  ANALYZE               { $$ = make_str("analyze"); }
3280                 | ANALYSE               { $$ = make_str("analyse"); }
3281                 ;
3282
3283 opt_verbose:  VERBOSE                   { $$ = make_str("verbose"); }
3284                 | /*EMPTY*/                             { $$ = EMPTY; }
3285                 ;
3286
3287 opt_full:  FULL                                 { $$ = make_str("full"); }
3288                 | /*EMPTY*/                             { $$ = EMPTY; }
3289                 ;
3290
3291 opt_freeze:  FREEZE                             { $$ = make_str("freeze"); }
3292                 | /*EMPTY*/                             { $$ = EMPTY; }
3293                 ;
3294
3295 opt_name_list:  '(' name_list ')'
3296                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3297                 | /*EMPTY*/
3298                         { $$ = EMPTY; }
3299                 ;
3300
3301
3302 /*****************************************************************************
3303  *
3304  *              QUERY:
3305  *                              EXPLAIN query
3306  *
3307  *****************************************************************************/
3308
3309 ExplainStmt:  EXPLAIN opt_analyze opt_verbose ExplainableStmt
3310                         { $$ = cat_str(4, make_str("explain"), $2, $3, $4); }
3311                 ;
3312
3313 ExplainableStmt:
3314                 SelectStmt
3315                 | InsertStmt
3316                 | UpdateStmt
3317                 | DeleteStmt
3318                 | DeclareCursorStmt
3319                 | ExecuteStmt
3320                 ;
3321 opt_analyze:
3322                 analyze_keyword                 { $$ = $1; }
3323                 | /* EMPTY */                   { $$ = EMPTY; }
3324                 ;
3325
3326 PrepareStmt: PREPARE prepared_name prep_type_clause AS PreparableStmt
3327                 {
3328                         $$.name = $2;
3329                         $$.type = $3;
3330                         $$.stmt = cat_str(3, make_str("\""), $5, make_str("\""));
3331                 }
3332                 | PREPARE prepared_name FROM execstring /* ECPG addon */
3333                 {
3334                         $$.name = $2;
3335                         $$.type = NULL;
3336                         $$.stmt = $4;
3337                 }
3338                 ;
3339
3340 PreparableStmt:
3341                 SelectStmt
3342                 | InsertStmt
3343                 | UpdateStmt
3344                 | DeleteStmt
3345                 ;
3346
3347 prep_type_clause: '(' type_list ')'     { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3348                 | /* EMPTY */           { $$ = EMPTY; }
3349                         ;
3350
3351 ExecuteStmt: EXECUTE prepared_name execute_param_clause execute_rest /* execute_rest is an ecpg addon */
3352                         {
3353                                 /* $$ = cat_str(3, make_str("ECPGprepared_statement("), connection, $2, make_str("__LINE__)"));*/
3354                                 $$ = $2;
3355                         }
3356                 | CREATE OptTemp TABLE create_as_target AS
3357                         EXECUTE prepared_name execute_param_clause
3358                         { $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4,  make_str("as execute"), $7, $8); }
3359                 ;
3360
3361 execute_param_clause: '(' expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3362                 | /* EMPTY */           { $$ = EMPTY; }
3363                 ;
3364
3365 DeallocateStmt: DEALLOCATE prepared_name                { $$ = $2; }
3366                 | DEALLOCATE PREPARE prepared_name      { $$ = $3; }
3367                 | DEALLOCATE ALL                        { $$ = make_str("all"); }
3368                 | DEALLOCATE PREPARE ALL                { $$ = make_str("all"); }
3369                 ;
3370
3371 /*****************************************************************************
3372  *
3373  *              QUERY:
3374  *                              INSERT STATEMENTS
3375  *
3376  *****************************************************************************/
3377
3378 InsertStmt:  INSERT INTO qualified_name insert_rest returning_clause
3379                         { $$ = cat_str(4, make_str("insert into"), $3, $4, $5); }
3380                 ;
3381
3382 insert_rest:  
3383                 SelectStmt
3384                         { $$ = $1; }
3385                 | '(' insert_column_list ')' SelectStmt
3386                         { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
3387                 | DEFAULT VALUES
3388                         { $$ = make_str("default values"); }
3389                 ;
3390
3391 insert_column_list: insert_column_list ',' insert_column_item
3392                         { $$ = cat_str(3, $1, make_str(","), $3); }
3393                 | insert_column_item
3394                         { $$ = $1; }
3395                 ;
3396
3397 insert_column_item:  ColId opt_indirection
3398                         { $$ = cat2_str($1, $2); }
3399                 ;
3400
3401 returning_clause:  RETURNING target_list        { $$ = cat2_str(make_str("returning"), $2); }
3402                 | /* EMPTY */                   { $$ = EMPTY; }
3403                 ;
3404
3405 /*****************************************************************************
3406  *
3407  *              QUERY:
3408  *                              DELETE STATEMENTS
3409  *
3410  *****************************************************************************/
3411
3412 DeleteStmt:  DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause
3413                         { $$ = cat_str(5, make_str("delete from"), $3, $4, $5, $6); }
3414                 ;
3415
3416 using_clause: USING from_list   { cat2_str(make_str("using"), $2); }
3417                         | /* EMPTY */           { $$ = EMPTY; }
3418                 ;
3419
3420 LockStmt:  LOCK_P opt_table qualified_name_list opt_lock opt_nowait
3421                         { $$ = cat_str(5, make_str("lock"), $2, $3, $4, $5); }
3422                 ;
3423
3424 opt_lock:  IN_P lock_type MODE
3425                         { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
3426                 | /*EMPTY*/
3427                         { $$ = EMPTY;}
3428                 ;
3429
3430 lock_type:      ACCESS SHARE            { $$ = make_str("access share"); }
3431                 | ROW SHARE                             { $$ = make_str("access share"); }
3432                 | ROW EXCLUSIVE                 { $$ = make_str("row exclusive"); }
3433                 | SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); }
3434                 | SHARE                                 { $$ = make_str("share"); }
3435                 | SHARE ROW EXCLUSIVE   { $$ = make_str("share row exclusive"); }
3436                 | EXCLUSIVE                             { $$ = make_str("exclusive"); }
3437                 | ACCESS EXCLUSIVE              { $$ = make_str("access exclusive"); }
3438                 ;
3439
3440 opt_nowait:    NOWAIT                   { $$ = make_str("nowait"); }
3441                 | /* EMPTY */           { $$ = EMPTY; }
3442                 ;
3443
3444 /*****************************************************************************
3445  *
3446  *              QUERY:
3447  *                              UpdateStmt (UPDATE)
3448  *
3449  *****************************************************************************/
3450
3451 UpdateStmt:  UPDATE relation_expr_opt_alias
3452                                 SET set_clause_list
3453                                 from_clause
3454                                 where_or_current_clause
3455                                 returning_clause
3456                         {$$ = cat_str(7, make_str("update"), $2, make_str("set"), $4, $5, $6, $7); }
3457                 ;
3458
3459 set_clause_list:
3460                 set_clause                              { $$ = $1; }
3461                 | set_clause_list ',' set_clause        { $$ = cat_str(3, $1, make_str(","), $3); }
3462                 ;
3463
3464 set_clause:
3465                 single_set_clause               { $$ = $1; }
3466                 | multiple_set_clause           { $$ = $1; }
3467                 ;
3468
3469 single_set_clause:
3470                 set_target '=' ctext_expr       { $$ = cat_str(3, $1, make_str("="), $3); };
3471
3472 multiple_set_clause:
3473                 '(' set_target_list ')' '=' ctext_row   { $$ = cat_str(4, make_str("("), $2, make_str(")="), $5); };
3474
3475 set_target:
3476                 ColId opt_indirection           { $$ = cat2_str($1, $2); };
3477
3478 set_target_list:
3479                 set_target                              { $$ = $1; }
3480                 | set_target_list ',' set_target        { $$ = cat_str(3, $1, make_str(","), $3); }
3481                 ;
3482
3483 /*****************************************************************************
3484  *
3485  *              QUERY:
3486  *                              CURSOR STATEMENTS
3487  *
3488  *****************************************************************************/
3489 DeclareCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
3490                 {
3491                         struct cursor *ptr, *this;
3492
3493                         for (ptr = cur; ptr != NULL; ptr = ptr->next)
3494                         {
3495                                 if (strcmp($2, ptr->name) == 0)
3496                                         /* re-definition is a bug */
3497                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
3498                         }
3499
3500                         this = (struct cursor *) mm_alloc(sizeof(struct cursor));
3501
3502                         /* initial definition */
3503                         this->next = cur;
3504                         this->name = $2;
3505                         this->connection = connection;
3506                         this->opened = false;
3507                         this->command =  cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
3508                         this->argsinsert = argsinsert;
3509                         this->argsresult = argsresult;
3510                         argsinsert = argsresult = NULL;
3511                         cur = this;
3512
3513                         if (INFORMIX_MODE)
3514                                 $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
3515                         else
3516                                 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
3517                 }
3518                 ;
3519
3520 cursor_options:  /* EMPTY */            { $$ = EMPTY; }
3521                 | cursor_options BINARY         { $$ = cat2_str($1, make_str("binary")); }
3522                 | cursor_options INSENSITIVE    { $$ = cat2_str($1, make_str("insensitive")); }
3523                 | cursor_options SCROLL         { $$ = cat2_str($1, make_str("scroll")); }
3524                 | cursor_options NO SCROLL      { $$ = cat2_str($1, make_str("no scroll")); }
3525                 ;
3526
3527 opt_hold:       /* EMPTY */
3528                 {
3529                         if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit == true)
3530                                 $$ = make_str("with hold");
3531                         else
3532                                  $$ = EMPTY;
3533                 }
3534                 | WITH HOLD                     { $$ = make_str("with hold"); }
3535                 | WITHOUT HOLD                  { $$ = make_str("without hold"); }
3536                 ;
3537
3538 /*****************************************************************************
3539  *
3540  *              QUERY:
3541  *                              SELECT STATEMENTS
3542  *
3543  *****************************************************************************/
3544
3545 SelectStmt: select_no_parens            %prec UMINUS
3546                         { $$ = $1; }
3547                 |       select_with_parens              %prec UMINUS
3548                         { $$ = $1; }
3549                 ;
3550
3551 select_with_parens: '(' select_no_parens ')'
3552                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3553                 | '(' select_with_parens ')'
3554                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3555                 ;
3556
3557 select_no_parens:          simple_select
3558                         { $$ = $1; }
3559                 | select_clause sort_clause
3560                         { $$ = cat2_str($1, $2); }
3561                 | select_clause opt_sort_clause for_locking_clause opt_select_limit
3562                         { $$ = cat_str(4, $1, $2, $3, $4); }
3563                 | select_clause opt_sort_clause select_limit opt_for_locking_clause
3564                         { $$ = cat_str(4, $1, $2, $3, $4); }
3565                 ;
3566
3567 select_clause: simple_select            { $$ = $1; }
3568                 | select_with_parens            { $$ = $1; }
3569                 ;
3570
3571 simple_select:  SELECT opt_distinct target_list
3572                                         into_clause from_clause where_clause
3573                                         group_clause having_clause
3574                         { $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8); }
3575                 | values_clause
3576                         { $$ = $1; }
3577                 | select_clause UNION opt_all select_clause
3578                         { $$ = cat_str(4, $1, make_str("union"), $3, $4); }
3579                 | select_clause INTERSECT opt_all select_clause
3580                         { $$ = cat_str(4, $1, make_str("intersect"), $3, $4); }
3581                 | select_clause EXCEPT opt_all select_clause
3582                         { $$ = cat_str(4, $1, make_str("except"), $3, $4); }
3583                 ;
3584
3585 into_clause:  INTO OptTempTableName
3586                 {
3587                         FoundInto = 1;
3588                         $$= cat2_str(make_str("into"), $2);
3589                 }
3590                 | ecpg_into                     { $$ = EMPTY; }
3591                 | /*EMPTY*/                     { $$ = EMPTY; }
3592                 ;
3593
3594 /*
3595  * Redundancy here is needed to avoid shift/reduce conflicts,
3596  * since TEMP is not a reserved word.  See also OptTemp.
3597  *
3598  * The result is a cons cell (not a true list!) containing
3599  * a boolean and a table name.
3600  */
3601 OptTempTableName:  TEMPORARY opt_table qualified_name
3602                         { $$ = cat_str(3, make_str("temporary"), $2, $3); }
3603                 | TEMP opt_table qualified_name
3604                         { $$ = cat_str(3, make_str("temp"), $2, $3); }
3605                 | LOCAL TEMPORARY opt_table qualified_name
3606                         { $$ = cat_str(3, make_str("local temporary"), $3, $4); }
3607                 | LOCAL TEMP opt_table qualified_name
3608                         { $$ = cat_str(3, make_str("local temp"), $3, $4); }
3609                 | GLOBAL TEMPORARY opt_table qualified_name
3610                         { $$ = cat_str(3, make_str("global temporary"), $3, $4); }
3611                 | GLOBAL TEMP opt_table qualified_name
3612                         { $$ = cat_str(3, make_str("global temp"), $3, $4); }
3613                 | TABLE qualified_name
3614                         { $$ = cat2_str(make_str("table"), $2); }
3615                 | qualified_name
3616                         { $$ = $1; }
3617                 ;
3618
3619 opt_table:      TABLE                           { $$ = make_str("table"); }
3620                 | /*EMPTY*/                             { $$ = EMPTY; }
3621                 ;
3622
3623 opt_all:  ALL                                   { $$ = make_str("all"); }
3624                 | /*EMPTY*/                             { $$ = EMPTY; }
3625                 ;
3626
3627 opt_distinct:  DISTINCT
3628                         { $$ = make_str("distinct"); }
3629                 | DISTINCT ON '(' expr_list ')'
3630                         { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
3631                 | ALL
3632                         { $$ = make_str("all"); }
3633                 | /*EMPTY*/
3634                         { $$ = EMPTY; }
3635                 ;
3636
3637 opt_sort_clause:        sort_clause     { $$ = $1; }
3638                 | /* EMPTY */           { $$ = EMPTY; }
3639                 ;
3640
3641 sort_clause:  ORDER BY sortby_list
3642                         { $$ = cat2_str(make_str("order by"), $3); }
3643                 ;
3644
3645 sortby_list:  sortby                                    { $$ = $1; }
3646                 | sortby_list ',' sortby                { $$ = cat_str(3, $1, make_str(","), $3); }
3647                 ;
3648
3649 sortby: a_expr USING qual_all_Op opt_nulls_order
3650                         { $$ = cat_str(4, $1, make_str("using"), $3, $4); }
3651                 | a_expr opt_asc_desc opt_nulls_order
3652                         { $$ = cat_str(3, $1, $2, $3); }
3653                 ;
3654
3655 select_limit:   LIMIT select_limit_value OFFSET select_offset_value
3656                    { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
3657                 | OFFSET select_offset_value LIMIT select_limit_value
3658                    { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
3659                 | LIMIT select_limit_value
3660                    { $$ = cat2_str(make_str("limit"), $2); }
3661                 | OFFSET select_offset_value
3662                    { $$ = cat2_str(make_str("offset"), $2); }
3663                 | LIMIT select_limit_value ',' select_offset_value
3664                    { mmerror(PARSE_ERROR, ET_WARNING, "No longer supported LIMIT #,# syntax passed to backend."); }
3665                 ;
3666
3667 opt_select_limit:       select_limit    { $$ = $1; }
3668                 | /*EMPTY*/                                     { $$ = EMPTY; }
3669                 ;
3670
3671 select_limit_value: a_expr      { $$ = $1; }
3672                 | ALL           { $$ = make_str("all"); }
3673                 ;
3674
3675 select_offset_value: a_expr { $$ = $1; }
3676                 ;
3677
3678 /*
3679  *      jimmy bell-style recursive queries aren't supported in the
3680  *      current system.
3681  *
3682  *      ...however, recursive addattr and rename supported.  make special
3683  *      cases for these.
3684  */
3685 group_clause:  GROUP_P BY expr_list
3686                         { $$ = cat2_str(make_str("group by"), $3); }
3687                 | /*EMPTY*/
3688                         { $$ = EMPTY; }
3689                 ;
3690
3691 having_clause:  HAVING a_expr
3692                         { $$ = cat2_str(make_str("having"), $2); }
3693                 | /*EMPTY*/
3694                         { $$ = EMPTY; }
3695                 ;
3696
3697 for_locking_clause:
3698                 for_locking_items       { $$ = $1; }
3699                 | FOR READ ONLY         { $$ = make_str("for read only");}
3700                 ;
3701
3702 opt_for_locking_clause: 
3703                 for_locking_clause      { $$ = $1; }
3704                 | /* EMPTY */           { $$ = EMPTY; }
3705                 ;
3706
3707 for_locking_items:
3708                 for_locking_item                        { $$ = $1; }
3709                 | for_locking_items for_locking_item    { $$ = cat2_str($1, $2); }
3710                 ;
3711
3712 for_locking_item:
3713                 FOR UPDATE locked_rels_list opt_nowait
3714                         { $$ = cat_str(3, make_str("for update"), $3, $4); }
3715                 | FOR SHARE locked_rels_list opt_nowait
3716                         { $$ = cat_str(3, make_str("for share"), $3, $4); }
3717                 ;
3718
3719 locked_rels_list:
3720                 OF name_list            { $$ = cat2_str(make_str("of"), $2); }
3721                 | /* EMPTY */           { $$ = EMPTY; }
3722                 ;
3723
3724 values_clause:  VALUES ctext_row
3725                         { $$ = cat2_str(make_str("values"), $2); }
3726                 | values_clause ',' ctext_row
3727                         { $$ = cat_str(3, $1, make_str(","), $3); }
3728                 ;
3729
3730 /*****************************************************************************
3731  *
3732  *      clauses common to all Optimizable Stmts:
3733  *              from_clause - allow list of both JOIN expressions and table names
3734  *              where_clause    - qualifications for joins or restrictions
3735  *
3736  *****************************************************************************/
3737
3738 from_clause:    FROM from_list          { $$ = cat2_str(make_str("from"), $2); }
3739                 | /* EMPTY */                           { $$ = EMPTY; }
3740                 ;
3741
3742 from_list:      from_list ',' table_ref { $$ = cat_str(3, $1, make_str(","), $3); }
3743                 | table_ref                                     { $$ = $1; }
3744                 ;
3745
3746 /*
3747  * table_ref is where an alias clause can be attached.  Note we cannot make
3748  * alias_clause have an empty production because that causes parse conflicts
3749  * between table_ref := '(' joined_table ')' alias_clause
3750  * and joined_table := '(' joined_table ')'.  So, we must have the
3751  * redundant-looking productions here instead.
3752  */
3753 table_ref:      relation_expr
3754                         { $$ = $1; }
3755                 | relation_expr alias_clause
3756                         { $$= cat2_str($1, $2); }
3757                 | func_table
3758                         { $$ = $1; }
3759                 | func_table alias_clause
3760                 { $$= cat2_str($1, $2); }
3761                 | func_table AS '(' TableFuncElementList ')'
3762                         { $$=cat_str(4, $1, make_str("as ("), $4, make_str(")")); }
3763                 | func_table AS ColId '(' TableFuncElementList ')'
3764                         { $$=cat_str(6, $1, make_str("as"), $3, make_str("("), $5, make_str(")"));}
3765                 | func_table ColId '(' TableFuncElementList ')'
3766                         { $$=cat_str(5, $1, $2, make_str("("), $4, make_str(")")); }
3767                 | select_with_parens
3768                         {mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");}
3769                 | select_with_parens alias_clause
3770                         { $$=cat2_str($1, $2); }
3771                 | joined_table
3772                         { $$ = $1; }
3773                 | '(' joined_table ')' alias_clause
3774                         { $$=cat_str(4, make_str("("), $2, make_str(")"), $4); }
3775                 ;
3776
3777 /*
3778  * It may seem silly to separate joined_table from table_ref, but there is
3779  * method in SQL92's madness: if you don't do it this way you get reduce-
3780  * reduce conflicts, because it's not clear to the parser generator whether
3781  * to expect alias_clause after ')' or not.  For the same reason we must
3782  * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
3783  * join_type to expand to empty; if we try it, the parser generator can't
3784  * figure out when to reduce an empty join_type right after table_ref.
3785  *
3786  * Note that a CROSS JOIN is the same as an unqualified
3787  * INNER JOIN, and an INNER JOIN/ON has the same shape
3788  * but a qualification expression to limit membership.
3789  * A NATURAL JOIN implicitly matches column names between
3790  * tables and the shape is determined by which columns are
3791  * in common. We'll collect columns during the later transformations.
3792  */
3793
3794 joined_table:  '(' joined_table ')'
3795                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3796                 | table_ref CROSS JOIN table_ref
3797                         { $$ = cat_str(3, $1, make_str("cross join"), $4); }
3798                 | table_ref join_type JOIN table_ref join_qual
3799                         { $$ = cat_str(5, $1, $2, make_str("join"), $4, $5); }
3800                 | table_ref JOIN table_ref join_qual
3801                         { $$ = cat_str(4, $1, make_str("join"), $3, $4); }
3802                 | table_ref NATURAL join_type JOIN table_ref
3803                         { $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5); }
3804                 | table_ref NATURAL JOIN table_ref
3805                         { $$ = cat_str(3, $1, make_str("natural join"), $4); }
3806                 ;
3807
3808 alias_clause:  AS ColId '(' name_list ')'
3809                         { $$ = cat_str(5, make_str("as"), $2, make_str("("), $4, make_str(")")); }
3810                 | AS ColId
3811                         { $$ = cat2_str(make_str("as"), $2); }
3812                 | ColId '(' name_list ')'
3813                         { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
3814                 | ColId
3815                         { $$ = $1; }
3816                 ;
3817
3818 join_type:      FULL join_outer         { $$ = cat2_str(make_str("full"), $2); }
3819                 | LEFT join_outer               { $$ = cat2_str(make_str("left"), $2); }
3820                 | RIGHT join_outer              { $$ = cat2_str(make_str("right"), $2); }
3821                 | INNER_P                               { $$ = make_str("inner"); }
3822                 ;
3823
3824 /* OUTER is just noise... */
3825 join_outer:  OUTER_P                    { $$ = make_str("outer"); }
3826                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3827                 ;
3828
3829 /* JOIN qualification clauses
3830  * Possibilities are:
3831  *      USING ( column list ) allows only unqualified column names,
3832  *                                                which must match between tables.
3833  *      ON expr allows more general qualifications.
3834  */
3835
3836 join_qual:      USING '(' name_list ')'
3837                         { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
3838                 | ON a_expr
3839                         { $$ = cat2_str(make_str("on"), $2); }
3840                 ;
3841
3842 relation_expr:  qualified_name
3843                         { /* normal relations */ $$ = $1; }
3844                 | qualified_name '*'
3845                         { /* inheritance query */ $$ = cat2_str($1, make_str("*")); }
3846                 | ONLY qualified_name
3847                         { /* inheritance query */ $$ = cat2_str(make_str("only "), $2); }
3848                 | ONLY '(' qualified_name ')'
3849                         { /* inheritance query */ $$ = cat_str(3, make_str("only ("), $3, make_str(")")); }
3850                 ;
3851
3852 relation_expr_opt_alias: relation_expr                                 %prec UMINUS
3853                 { $$ = $1; }
3854                 | relation_expr ColId
3855                 { $$ = cat2_str($1, $2); }
3856                 | relation_expr AS ColId
3857                 { $$ = cat_str(3, $1, make_str("as"), $3); }
3858                 ;
3859
3860 func_table:  func_expr  { $$ = $1; }
3861                 ;
3862
3863 where_clause:  WHERE a_expr             { $$ = cat2_str(make_str("where"), $2); }
3864                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3865                 ;
3866
3867 where_or_current_clause:  WHERE a_expr                  { $$ = cat2_str(make_str("where"), $2); }
3868                 | WHERE CURRENT_P OF name               { $$ = cat2_str(make_str("where current of"), $4); }
3869                 | WHERE CURRENT_P OF PARAM              { $$ = make_str("where current of param"); }
3870                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3871                 ;
3872
3873 TableFuncElementList: TableFuncElement
3874                         { $$ = $1; }
3875                 | TableFuncElementList ',' TableFuncElement
3876                         { $$ = cat_str(3, $1, make_str(","), $3); }
3877                 ;
3878
3879 TableFuncElement:       ColId Typename  { $$ = cat2_str($1, $2); }
3880                 ;
3881
3882 /*****************************************************************************
3883  *
3884  *      Type syntax
3885  *              SQL92 introduces a large amount of type-specific syntax.
3886  *              Define individual clauses to handle these cases, and use
3887  *               the generic case to handle regular type-extensible Postgres syntax.
3888  *              - thomas 1997-10-10
3889  *
3890  *****************************************************************************/
3891
3892 Typename:  SimpleTypename opt_array_bounds
3893                         { $$ = cat2_str($1, $2.str); }
3894                 | SETOF SimpleTypename opt_array_bounds
3895                         { $$ = cat_str(3, make_str("setof"), $2, $3); }
3896                 | SimpleTypename ARRAY '[' PosIntConst ']'
3897                         { $$ = cat_str(4, $1, make_str("array ["), $4, make_str("]")); }
3898                 | SETOF SimpleTypename ARRAY '[' PosIntConst ']'
3899                         { $$ = cat_str(5, make_str("setof"), $2, make_str("array ["), $5, make_str("]")); }
3900                 ;
3901
3902
3903 opt_array_bounds:  '[' ']' opt_array_bounds
3904                 {
3905                         $$.index1 = make_str("0");
3906                         $$.index2 = $3.index1;
3907                         $$.str = cat2_str(make_str("[]"), $3.str);
3908                 }
3909                 | '[' Iresult ']' opt_array_bounds
3910                 {
3911                         $$.index1 = strdup($2);
3912                         $$.index2 = $4.index1;
3913                         $$.str = cat_str(4, make_str("["), $2, make_str("]"), $4.str);
3914                 }
3915                 | /* EMPTY */
3916                 {
3917                         $$.index1 = make_str("-1");
3918                         $$.index2 = make_str("-1");
3919                         $$.str= EMPTY;
3920                 }
3921                 ;
3922
3923 Iresult:        PosIntConst             { $$ = $1; }
3924                 | '(' Iresult ')'       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3925                 | Iresult '+' Iresult   { $$ = cat_str(3, $1, make_str("+"), $3); }
3926                 | Iresult '-' Iresult   { $$ = cat_str(3, $1, make_str("-"), $3); }
3927                 | Iresult '*' Iresult   { $$ = cat_str(3, $1, make_str("*"), $3); }
3928                 | Iresult '/' Iresult   { $$ = cat_str(3, $1, make_str("/"), $3); }
3929                 | Iresult '%' Iresult   { $$ = cat_str(3, $1, make_str("%"), $3); }
3930                 | Sconst                { $$ = $1; }
3931                 | ColId                 { $$ = $1; }
3932                 ;
3933
3934 SimpleTypename:  GenericType            { $$ = $1; }
3935                 | ConstDatetime         { $$ = $1; }
3936                 | Numeric               { $$ = $1; }
3937                 | Bit                   { $$ = $1; }
3938                 | Character             { $$ = $1; }
3939                 | ConstInterval opt_interval
3940                         { $$ = cat2_str($1, $2); }
3941                 | ConstInterval '(' PosIntConst ')' opt_interval
3942                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
3943                 ;
3944
3945 ConstTypename:  Numeric                 { $$ = $1; }
3946                 | ConstBit              { $$ = $1; }
3947                 | ConstCharacter        { $$ = $1; }
3948                 | ConstDatetime         { $$ = $1; }
3949                 ;
3950
3951 GenericType:    type_function_name opt_type_modifiers           { $$ = cat2_str($1, $2); }
3952                 | type_function_name attrs opt_type_modifiers   { $$ = cat_str(3, $1, $2, $3); }
3953                 ;
3954
3955 opt_type_modifiers: '(' expr_list ')'   { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3956                 | /* EMPTY */           { $$ = EMPTY; }
3957                 ;
3958                 
3959 /* SQL92 numeric data types
3960  * Check FLOAT() precision limits assuming IEEE floating types.
3961  * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3962  * - thomas 1997-09-18
3963  */
3964 Numeric:  INT_P
3965                         { $$ = make_str("int"); }
3966                 | INTEGER
3967                         { $$ = make_str("integer"); }
3968                 | SMALLINT
3969                         { $$ = make_str("smallint"); }
3970                 | BIGINT
3971                         { $$ = make_str("bigint"); }
3972                 | REAL
3973                         { $$ = make_str("real"); }
3974                 | FLOAT_P opt_float
3975                         { $$ = cat2_str(make_str("float"), $2); }
3976                 | DOUBLE_P PRECISION
3977                         { $$ = make_str("double precision"); }
3978                 | DECIMAL_P opt_type_modifiers
3979                         { $$ = cat2_str(make_str("decimal"), $2); }
3980                 | DEC opt_type_modifiers
3981                         { $$ = cat2_str(make_str("dec"), $2); }
3982                 | NUMERIC opt_type_modifiers
3983                         { $$ = cat2_str(make_str("numeric"), $2); }
3984                 | BOOLEAN_P
3985                         { $$ = make_str("boolean"); }
3986                 ;
3987
3988 opt_float:      '(' PosIntConst ')'
3989                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3990                 | /*EMPTY*/
3991                         { $$ = EMPTY; }
3992                 ;
3993
3994 /*
3995  * SQL92 bit-field data types
3996  * The following implements BIT() and BIT VARYING().
3997  */
3998
3999 Bit:    BitWithLength           { $$ = $1; }
4000                 | BitWithoutLength      { $$ = $1; }
4001                 ;
4002
4003 ConstBit:       BitWithLength   { $$ = $1; }
4004                 | BitWithoutLength      { $$ = $1; }
4005                 ;
4006
4007 BitWithLength:  BIT opt_varying '(' expr_list ')'
4008                         { $$ = cat_str(5, make_str("bit"), $2, make_str("("), $4, make_str(")")); }
4009                 ;
4010
4011 BitWithoutLength: BIT opt_varying
4012                         { $$ = cat2_str(make_str("bit"), $2); }
4013                 ;
4014
4015 /*
4016  * SQL92 character data types
4017  * The following implements CHAR() and VARCHAR().
4018  *                                                              - ay 6/95
4019  */
4020 Character:      CharacterWithLength             { $$ = $1; }
4021                 | CharacterWithoutLength        { $$ = $1; }
4022                 ;
4023
4024 ConstCharacter: CharacterWithLength     { $$ = $1; }
4025                 | CharacterWithoutLength        { $$ = $1; }
4026                 ;
4027
4028 CharacterWithLength: character '(' PosIntConst ')' opt_charset
4029                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
4030                 ;
4031
4032 CharacterWithoutLength: character opt_charset
4033                         { $$ = cat2_str($1, $2); }
4034                 ;
4035
4036 character:      CHARACTER opt_varying
4037                         { $$ = cat2_str(make_str("character"), $2); }
4038                 | CHAR_P opt_varying
4039                         { $$ = cat2_str(make_str("char"), $2); }
4040                 | VARCHAR
4041                         { $$ = make_str("varchar"); }
4042                 | NATIONAL CHARACTER opt_varying
4043                         { $$ = cat2_str(make_str("national character"), $3); }
4044                 | NATIONAL CHAR_P opt_varying
4045                         { $$ = cat2_str(make_str("national char"), $3); }
4046                 | NCHAR opt_varying
4047                         { $$ = cat2_str(make_str("nchar"), $2); }
4048                 ;
4049
4050 opt_varying:  VARYING
4051                         { $$ = make_str("varying"); }
4052                 | /*EMPTY*/
4053                         { $$ = EMPTY; }
4054                 ;
4055
4056 opt_charset:  CHARACTER SET ColId
4057                         { $$ = cat2_str(make_str("character set"), $3); }
4058                 | /*EMPTY*/
4059                         { $$ = EMPTY; }
4060                 ;
4061
4062 ConstDatetime:  TIMESTAMP '(' PosIntConst ')' opt_timezone
4063                         { $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5); }
4064                 | TIMESTAMP opt_timezone
4065                         { $$ = cat2_str(make_str("timestamp"), $2); }
4066                 | TIME '(' PosIntConst ')' opt_timezone
4067                         { $$ = cat_str(4, make_str("time("), $3, make_str(")"), $5); }
4068                 | TIME opt_timezone
4069                         { $$ = cat2_str(make_str("time"), $2); }
4070                 ;
4071
4072 ConstInterval:  INTERVAL
4073                         { $$ = make_str("interval"); }
4074                 ;
4075
4076 opt_timezone:  WITH TIME ZONE
4077                         { $$ = make_str("with time zone"); }
4078                 | WITHOUT TIME ZONE
4079                         { $$ = make_str("without time zone"); }
4080                 | /*EMPTY*/
4081                         { $$ = EMPTY; }
4082                 ;
4083
4084 opt_interval:  YEAR_P                   { $$ = make_str("year"); }
4085                 | MONTH_P                               { $$ = make_str("month"); }
4086                 | DAY_P                                 { $$ = make_str("day"); }
4087                 | HOUR_P                                { $$ = make_str("hour"); }
4088                 | MINUTE_P                              { $$ = make_str("minute"); }
4089                 | SECOND_P                              { $$ = make_str("second"); }
4090                 | YEAR_P TO MONTH_P             { $$ = make_str("year to month"); }
4091                 | DAY_P TO HOUR_P               { $$ = make_str("day to hour"); }
4092                 | DAY_P TO MINUTE_P             { $$ = make_str("day to minute"); }
4093                 | DAY_P TO SECOND_P             { $$ = make_str("day to second"); }
4094                 | HOUR_P TO MINUTE_P    { $$ = make_str("hour to minute"); }
4095                 | MINUTE_P TO SECOND_P  { $$ = make_str("minute to second"); }
4096                 | HOUR_P TO SECOND_P    { $$ = make_str("hour to second"); }
4097                 | /*EMPTY*/                             { $$ = EMPTY; }
4098                 ;
4099
4100
4101 /*****************************************************************************
4102  *
4103  *      expression grammar
4104  *
4105  *****************************************************************************/
4106
4107 /* General expressions
4108  * This is the heart of the expression syntax.
4109  *
4110  * We have two expression types: a_expr is the unrestricted kind, and
4111  * b_expr is a subset that must be used in some places to avoid shift/reduce
4112  * conflicts.  For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
4113  * because that use of AND conflicts with AND as a boolean operator.  So,
4114  * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
4115  *
4116  * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
4117  * always be used by surrounding it with parens.
4118  *
4119  * c_expr is all the productions that are common to a_expr and b_expr;
4120  * it's factored out just to eliminate redundant coding.
4121  */
4122
4123 a_expr:  c_expr
4124                         { $$ = $1; }
4125                 | a_expr TYPECAST Typename
4126                         { $$ = cat_str(3, $1, make_str("::"), $3); }
4127                 | a_expr AT TIME ZONE a_expr
4128                         { $$ = cat_str(3, $1, make_str("at time zone"), $5); }
4129                 /*
4130                  * These operators must be called out explicitly in order to make use
4131                  * of yacc/bison's automatic operator-precedence handling.  All other
4132                  * operator names are handled by the generic productions using "Op",
4133                  * below; and all those operators will have the same precedence.
4134                  *
4135                  * If you add more explicitly-known operators, be sure to add them
4136                  * also to b_expr and to the MathOp list above.
4137                  */
4138                 | '+' a_expr %prec UMINUS
4139                         { $$ = cat2_str(make_str("+"), $2); }
4140                 | '-' a_expr %prec UMINUS
4141                         { $$ = cat2_str(make_str("-"), $2); }
4142                 | a_expr '+' a_expr
4143                         { $$ = cat_str(3, $1, make_str("+"), $3); }
4144                 | a_expr '-' a_expr
4145                         { $$ = cat_str(3, $1, make_str("-"), $3); }
4146                 | a_expr '*' a_expr
4147                         { $$ = cat_str(3, $1, make_str("*"), $3); }
4148                 | a_expr '/' a_expr
4149                         { $$ = cat_str(3, $1, make_str("/"), $3); }
4150                 | a_expr '%' a_expr
4151                         { $$ = cat_str(3, $1, make_str("%"), $3); }
4152                 | a_expr '^' a_expr
4153                         { $$ = cat_str(3, $1, make_str("^"), $3); }
4154                 | a_expr '<' a_expr
4155                         { $$ = cat_str(3, $1, make_str("<"), $3); }
4156                 | a_expr '>' a_expr
4157                         { $$ = cat_str(3, $1, make_str(">"), $3); }
4158                 | a_expr '=' a_expr
4159                         { $$ = cat_str(3, $1, make_str("="), $3); }
4160                 | a_expr qual_Op a_expr         %prec Op
4161                         { $$ = cat_str(3, $1, $2, $3); }
4162                 | qual_Op a_expr                %prec Op
4163                         { $$ = cat2_str($1, $2); }
4164                 | a_expr qual_Op                %prec POSTFIXOP
4165                         { $$ = cat2_str($1, $2); }
4166                 | a_expr AND a_expr
4167                         { $$ = cat_str(3, $1, make_str("and"), $3); }
4168                 | a_expr OR a_expr
4169                         { $$ = cat_str(3, $1, make_str("or"), $3); }
4170                 | NOT a_expr
4171                         { $$ = cat2_str(make_str("not"), $2); }
4172                 | a_expr LIKE a_expr
4173                         { $$ = cat_str(3, $1, make_str("like"), $3); }
4174                 | a_expr LIKE a_expr ESCAPE a_expr
4175                         { $$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
4176                 | a_expr NOT LIKE a_expr
4177                         { $$ = cat_str(3, $1, make_str("not like"), $4); }
4178                 | a_expr NOT LIKE a_expr ESCAPE a_expr
4179                         { $$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
4180                 | a_expr ILIKE a_expr
4181                         { $$ = cat_str(3, $1, make_str("ilike"), $3); }
4182                 | a_expr ILIKE a_expr ESCAPE a_expr
4183                         { $$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
4184                 | a_expr NOT ILIKE a_expr
4185                         { $$ = cat_str(3, $1, make_str("not ilike"), $4); }
4186                 | a_expr NOT ILIKE a_expr ESCAPE a_expr
4187                         { $$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
4188                 | a_expr SIMILAR TO a_expr      %prec SIMILAR
4189                         { $$ = cat_str(3, $1, make_str("similar to"), $4); }
4190                 | a_expr SIMILAR TO a_expr ESCAPE a_expr
4191                         { $$ = cat_str(5, $1, make_str("similar to"), $4, make_str("escape"), $6); }
4192                 | a_expr NOT SIMILAR TO a_expr  %prec SIMILAR
4193                         { $$ = cat_str(3, $1, make_str("not similar to"), $5); }
4194                 | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
4195                         { $$ = cat_str(5, $1, make_str("not similar to"), $5, make_str("escape"), $7); }
4196                 | a_expr ISNULL
4197                         { $$ = cat2_str($1, make_str("isnull")); }
4198                 | a_expr IS NULL_P
4199                         { $$ = cat2_str($1, make_str("is null")); }
4200                 | a_expr NOTNULL
4201                         { $$ = cat2_str($1, make_str("notnull")); }
4202                 | a_expr IS NOT NULL_P
4203                         { $$ = cat2_str($1, make_str("is not null")); }
4204                 | row OVERLAPS row
4205                         { $$ = cat_str(3, $1, make_str("overlaps"), $3); }
4206                 /* IS TRUE, IS FALSE, etc used to be function calls
4207                  *      but let's make them expressions to allow the optimizer
4208                  *      a chance to eliminate them if a_expr is a constant string.
4209                  * - thomas 1997-12-22
4210                  *
4211                  *      Created BooleanTest Node type, and changed handling
4212                  *      for NULL inputs
4213                  * - jec 2001-06-18
4214                  */
4215                 | a_expr IS TRUE_P
4216                         { $$ = cat2_str($1, make_str("is true")); }
4217                 | a_expr IS NOT TRUE_P
4218                         { $$ = cat2_str($1, make_str("is not true")); }
4219                 | a_expr IS FALSE_P
4220                         { $$ = cat2_str($1, make_str("is false")); }
4221                 | a_expr IS NOT FALSE_P
4222                         { $$ = cat2_str($1, make_str("is not false")); }
4223                 | a_expr IS UNKNOWN
4224                         { $$ = cat2_str($1, make_str("is unknown")); }
4225                 | a_expr IS NOT UNKNOWN
4226                         { $$ = cat2_str($1, make_str("is not unknown")); }
4227                 | a_expr IS DISTINCT FROM a_expr %prec IS
4228                         { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
4229                 | a_expr IS NOT DISTINCT FROM a_expr %prec IS
4230                         { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
4231                 | a_expr IS OF '(' type_list ')' %prec IS
4232                         { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
4233                 | a_expr IS NOT OF '(' type_list ')' %prec IS
4234                         { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
4235                 | a_expr BETWEEN opt_asymmetric b_expr AND b_expr       %prec BETWEEN
4236                         { $$ = cat_str(6, $1, make_str("between"), $3, $4, make_str("and"), $6); }
4237                 | a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr   %prec BETWEEN
4238                         { $$ = cat_str(6, $1, make_str("not between"), $4, $5, make_str("and"), $7); }
4239                 | a_expr BETWEEN SYMMETRIC b_expr AND b_expr    %prec BETWEEN
4240                         { $$ = cat_str(5, $1, make_str("between symmetric"), $4, make_str("and"), $6); }
4241                 | a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr        %prec BETWEEN
4242                         { $$ = cat_str(5, $1, make_str("not between symmetric"), $5, make_str("and"), $7); }
4243                 | a_expr IN_P in_expr
4244                         { $$ = cat_str(3, $1, make_str("in"), $3); }
4245                 | a_expr NOT IN_P in_expr
4246                         { $$ = cat_str(3, $1, make_str("not in"), $4); }
4247                 | a_expr subquery_Op sub_type select_with_parens %prec Op
4248                         { $$ = cat_str(4, $1, $2, $3, $4); }
4249                 | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
4250                         { $$ = cat_str(6, $1, $2, $3, make_str("("), $5, make_str(")")); }
4251                 | UNIQUE select_with_parens 
4252                         { $$ = cat2_str(make_str("unique"), $2); }
4253                 | a_expr IS DOCUMENT_P
4254                         { $$ = cat2_str($1, make_str("is document")); }
4255                 | a_expr IS NOT DOCUMENT_P
4256                         { $$ = cat2_str($1, make_str("is not document")); }
4257                 ;
4258
4259 /* Restricted expressions
4260  *
4261  * b_expr is a subset of the complete expression syntax
4262  *
4263  * Presently, AND, NOT, IS and IN are the a_expr keywords that would
4264  * cause trouble in the places where b_expr is used.  For simplicity, we
4265  * just eliminate all the boolean-keyword-operator productions from b_expr.
4266  */
4267 b_expr:  c_expr
4268                         { $$ = $1; }
4269                 | b_expr TYPECAST Typename
4270                         { $$ = cat_str(3, $1, make_str("::"), $3); }
4271                 | '-' b_expr %prec UMINUS
4272                         { $$ = cat2_str(make_str("-"), $2); }
4273                 | b_expr '+' b_expr
4274                         { $$ = cat_str(3, $1, make_str("+"), $3); }
4275                 | b_expr '-' b_expr
4276                         { $$ = cat_str(3, $1, make_str("-"), $3); }
4277                 | b_expr '*' b_expr
4278                         { $$ = cat_str(3, $1, make_str("*"), $3); }
4279                 | b_expr '/' b_expr
4280                         { $$ = cat_str(3, $1, make_str("/"), $3); }
4281                 | b_expr '%' b_expr
4282                         { $$ = cat_str(3, $1, make_str("%"), $3); }
4283                 | b_expr '^' b_expr
4284                         { $$ = cat_str(3, $1, make_str("^"), $3); }
4285                 | b_expr '<' b_expr
4286                         { $$ = cat_str(3, $1, make_str("<"), $3); }
4287                 | b_expr '>' b_expr
4288                         { $$ = cat_str(3, $1, make_str(">"), $3); }
4289                 | b_expr '=' b_expr
4290                         { $$ = cat_str(3, $1, make_str("="), $3); }
4291                 | b_expr Op b_expr
4292                         { $$ = cat_str(3, $1, $2, $3); }
4293                 | qual_Op b_expr                %prec Op
4294                         { $$ = cat2_str($1, $2); }
4295                 | b_expr qual_Op                %prec POSTFIXOP
4296                         { $$ = cat2_str($1, $2); }
4297                 | b_expr IS DISTINCT FROM b_expr %prec IS
4298                         { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
4299                 | b_expr IS NOT DISTINCT FROM b_expr %prec IS
4300                         { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
4301                 | b_expr IS OF '(' b_expr ')' %prec IS
4302                         { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
4303                 | b_expr IS NOT OF '(' b_expr ')' %prec IS
4304                         { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
4305                 | b_expr IS DOCUMENT_P
4306                         { $$ = cat2_str($1, make_str("is document")); }
4307                 | b_expr IS NOT DOCUMENT_P
4308                         { $$ = cat2_str($1, make_str("is not document")); }
4309                 ;
4310
4311 /*
4312  * Productions that can be used in both a_expr and b_expr.
4313  *
4314  * Note: productions that refer recursively to a_expr or b_expr mostly
4315  * cannot appear here.  However, it's OK to refer to a_exprs that occur
4316  * inside parentheses, such as function arguments; that cannot introduce
4317  * ambiguity to the b_expr syntax.
4318  */
4319 c_expr: columnref
4320                         { $$ = $1;      }
4321                 | AexprConst
4322                         { $$ = $1;      }
4323                 | PARAM opt_indirection
4324                         { $$ = cat2_str(make_str("param"), $2); }
4325                 | '(' a_expr ')' opt_indirection
4326                         { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
4327                 | case_expr
4328                         { $$ = $1; }
4329                 | func_expr
4330                         { $$ = $1; }
4331                 | select_with_parens    %prec UMINUS
4332                         { $$ = $1; }
4333                 | EXISTS select_with_parens
4334                         { $$ = cat2_str(make_str("exists"), $2); }
4335                 | ARRAY select_with_parens
4336                         { $$ = cat2_str(make_str("array"), $2); }
4337                 | ARRAY array_expr
4338                         { $$ = cat2_str(make_str("array"), $2); }
4339                 | row
4340                         { $$ = $1; }
4341                 ;
4342
4343 /*
4344  * func_expr is split out from c_expr just so that we have a classification
4345  * for "everything that is a function call or looks like one".  This isn't
4346  * very important, but it saves us having to document which variants are
4347  * legal in the backwards-compatible functional-index syntax for CREATE INDEX.
4348  * (Note that many of the special SQL functions wouldn't actually make any
4349  * sense as functional index entries, but we ignore that consideration here.)
4350  */
4351 func_expr:      func_name '(' ')'
4352                         { $$ = cat2_str($1, make_str("()"));    }
4353                 | func_name '(' expr_list ')'
4354                         { $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));        }
4355                 | func_name '(' ALL expr_list ')'
4356                         { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")"));    }
4357                 | func_name '(' DISTINCT expr_list ')'
4358                         { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")"));  }
4359                 | func_name '(' '*' ')'
4360                         { $$ = cat2_str($1, make_str("(*)")); }
4361                 | CURRENT_DATE
4362                         { $$ = make_str("current_date"); }
4363                 | CURRENT_TIME
4364                         { $$ = make_str("current_time"); }
4365                 | CURRENT_TIME '(' PosIntConst ')'
4366                         { $$ = cat_str(3, make_str("current_time ("), $3, make_str(")")); }
4367                 | CURRENT_TIMESTAMP
4368                         { $$ = make_str("current_timestamp"); }
4369                 | CURRENT_TIMESTAMP '(' PosIntConst ')'
4370                         { $$ = cat_str(3, make_str("current_timestamp ("), $3, make_str(")")); }
4371                 | LOCALTIME
4372                         { $$ = make_str("localtime"); }
4373                 | LOCALTIME '(' PosIntConst ')'
4374                         { $$ = cat_str(3, make_str("localtime ("), $3, make_str(")")); }
4375                 | LOCALTIMESTAMP
4376                         { $$ = make_str("local_timestamp"); }
4377                 | LOCALTIMESTAMP '(' PosIntConst ')'
4378                         { $$ = cat_str(3, make_str("locale_timestamp ("), $3, make_str(")")); }
4379                 | CURRENT_ROLE
4380                         { $$ = make_str("current_role"); }
4381                 | CURRENT_USER
4382                         { $$ = make_str("current_user"); }
4383                 | SESSION_USER
4384                         { $$ = make_str("session_user"); }
4385                 | USER
4386                         { $$ = make_str("user"); }
4387                 | CAST '(' a_expr AS Typename ')'
4388                         { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
4389                 | EXTRACT '(' extract_list ')'
4390                         { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
4391                 | OVERLAY '(' overlay_list ')'
4392                         { $$ = cat_str(3, make_str("overlay("), $3, make_str(")")); }
4393                 | POSITION '(' position_list ')'
4394                         { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
4395                 | SUBSTRING '(' substr_list ')'
4396                         { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
4397                 | TREAT '(' a_expr AS Typename ')'
4398                         { $$ = cat_str(5, make_str("treat("), $3, make_str("as"), $5, make_str(")")); }
4399                 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4400                 | TRIM '(' BOTH trim_list ')'
4401                         { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
4402                 | TRIM '(' LEADING trim_list ')'
4403                         { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
4404                 | TRIM '(' TRAILING trim_list ')'
4405                         { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
4406                 | TRIM '(' trim_list ')'
4407                         { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
4408                 | NULLIF '(' a_expr ',' a_expr ')'
4409                         { $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")")); }
4410                 | COALESCE '(' expr_list ')'
4411                         { $$ = cat_str(3, make_str("coalesce("), $3, make_str(")")); }
4412                 | GREATEST '(' expr_list ')'
4413                         { $$ = cat_str(3, make_str("greatest("), $3, make_str(")")); }
4414                 | LEAST '(' expr_list ')'
4415                         { $$ = cat_str(3, make_str("least("), $3, make_str(")")); }
4416                 | XMLCONCAT '(' expr_list ')'
4417                         { $$ = cat_str(3, make_str("xmlconcat("), $3, make_str(")")); }
4418                 | XMLELEMENT '(' NAME_P ColLabel ')'
4419                         { $$ = cat_str(3, make_str("xmlelement( name"), $4, make_str(")")); }
4420                 | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
4421                         { $$ = cat_str(5, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(")")); }
4422                 | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
4423                         { $$ = cat_str(5, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(")")); }
4424                 | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
4425                         { $$ = cat_str(7, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(","), $8, make_str(")")); }
4426                 | XMLFOREST '(' xml_attribute_list ')'
4427                         { $$ = cat_str(3, make_str("xmlforest("), $3, make_str(")")); }
4428                 | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
4429                         { $$ = cat_str(5, make_str("xmlparse("), $3, $4, $5, make_str(")")); }
4430                 | XMLPI '(' NAME_P ColLabel ')'
4431                         { $$ = cat_str(3, make_str("xmlpi( name"), $4, make_str(")")); }
4432                 | XMLPI '(' NAME_P ColLabel ',' a_expr ')'
4433                         { $$ = cat_str(5, make_str("xmlpi( name"), $4, make_str(","), $6, make_str(")")); }
4434                 | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone  ')'
4435                         { $$ = cat_str(6, make_str("xmlroot("), $3, make_str(","), $5, $6, make_str(")")); }
4436                 ;
4437
4438 /*
4439  * SQL/XML support
4440  */
4441
4442 xml_root_version: VERSION_P a_expr
4443                         { $$ = cat2_str(make_str("version"), $2); }
4444                 | VERSION_P NO VALUE_P
4445                         { $$ = make_str("version no value"); }
4446                 ;
4447
4448 opt_xml_root_standalone: ',' STANDALONE_P YES_P
4449                                 { $$ = make_str(", standalone yes"); }
4450                         | ',' STANDALONE_P NO
4451                                 { $$ = make_str(", standalone no"); }
4452                         | ',' STANDALONE_P NO VALUE_P
4453                                 { $$ = make_str(", standalone no value"); }
4454                         | /*EMPTY*/
4455                                 { $$ = EMPTY; }
4456                         ;
4457
4458 xml_attributes:         XMLATTRIBUTES '(' xml_attribute_list ')'
4459                                 { $$ = cat_str(3, make_str("xmlattributes("), $3, make_str(")")); }
4460                         ;
4461
4462 xml_attribute_list:     xml_attribute_el
4463                                 { $$ = $1; }
4464                         | xml_attribute_list ',' xml_attribute_el
4465                                 { $$ = cat_str(3, $1, make_str(","), $3); }
4466                         ;
4467
4468 xml_attribute_el: a_expr AS ColLabel
4469                         { $$ = cat_str(3, $1, make_str("as"), $3); }
4470                 | a_expr
4471                         { $$ = $1; }
4472                 ;
4473
4474 document_or_content: DOCUMENT_P         { $$ = make_str("document"); }
4475                         | CONTENT_P     { $$ = make_str("content"); }
4476                         ;
4477
4478 xml_whitespace_option: PRESERVE WHITESPACE_P    { $$ = make_str("preserve whitespace"); }
4479                         | STRIP_P WHITESPACE_P  { $$ = make_str("strip whitespace"); }
4480                         | /*EMPTY*/             { $$ = EMPTY; }
4481                         ;
4482
4483 row: ROW '(' expr_list ')'
4484                         { $$ = cat_str(3, make_str("row ("), $3, make_str(")")); }
4485                 | ROW '(' ')'
4486                         { $$ = make_str("row()"); }
4487                 | '(' expr_list ',' a_expr ')'
4488                         { $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")")); }
4489                 ;
4490
4491 sub_type:  ANY          { $$ = make_str("ANY"); }
4492                 | SOME          { $$ = make_str("SOME"); }
4493                 | ALL           { $$ = make_str("ALL"); }
4494                 ;
4495
4496 all_Op:  Op                             { $$ = $1; }
4497                 | MathOp                        { $$ = $1; }
4498                 ;
4499
4500 MathOp: '+'                             { $$ = make_str("+"); }
4501                 | '-'                   { $$ = make_str("-"); }
4502                 | '*'                   { $$ = make_str("*"); }
4503                 | '%'                   { $$ = make_str("%"); }
4504                 | '^'                   { $$ = make_str("^"); }
4505                 | '/'                   { $$ = make_str("/"); }
4506                 | '<'                   { $$ = make_str("<"); }
4507                 | '>'                   { $$ = make_str(">"); }
4508                 | '='                   { $$ = make_str("="); }
4509                 ;
4510
4511 qual_Op:  Op                            { $$ = $1; }
4512                 | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
4513                 ;
4514
4515 qual_all_Op:  all_Op                            { $$ = $1; }
4516                 | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
4517                 ;
4518
4519 subquery_Op:  all_Op                            { $$ = $1; }
4520                 | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
4521                 | LIKE                          { $$ = make_str("like"); }
4522                 | NOT LIKE                      { $$ = make_str("not like"); }
4523                 | ILIKE                         { $$ = make_str("ilike"); }
4524                 | NOT ILIKE                     { $$ = make_str("not ilike"); }
4525                 ;
4526
4527 expr_list:      a_expr
4528                         { $$ = $1; }
4529                 | expr_list ',' a_expr
4530                         { $$ = cat_str(3, $1, make_str(","), $3); }
4531                 ;
4532
4533 extract_list:  extract_arg FROM a_expr
4534                         { $$ = cat_str(3, $1, make_str("from"), $3); }
4535                 | /* EMPTY */
4536                         { $$ = EMPTY; }
4537                 ;
4538
4539 type_list:       Typename
4540                         { $$ = $1; }
4541                 | type_list ',' Typename
4542                         { $$ = cat_str(3, $1, ',', $3); }
4543                 ;
4544
4545 array_expr_list: array_expr                             { $$ = $1; }
4546                 | array_expr_list ',' array_expr        { $$ = cat_str(3, $1, make_str(","), $3); }
4547                 ;
4548
4549
4550 array_expr: '[' expr_list ']'                   { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
4551                 | '[' array_expr_list ']'       { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
4552                 ;
4553 /* Allow delimited string SCONST in extract_arg as an SQL extension.
4554  * - thomas 2001-04-12
4555  */
4556
4557 extract_arg:  ident                             { $$ = $1; }
4558                 | YEAR_P                                { $$ = make_str("year"); }
4559                 | MONTH_P                               { $$ = make_str("month"); }
4560                 | DAY_P                                 { $$ = make_str("day"); }
4561                 | HOUR_P                                { $$ = make_str("hour"); }
4562                 | MINUTE_P                              { $$ = make_str("minute"); }
4563                 | SECOND_P                              { $$ = make_str("second"); }
4564                 | StringConst                   { $$ = $1; }
4565                 ;
4566
4567 overlay_list:
4568                 a_expr overlay_placing substr_from substr_for
4569                         { $$ = cat_str(4, $1, 42, $3, $4); }
4570                 | a_expr overlay_placing substr_from
4571                         { $$ = cat_str(3, $1, $2, $3); }
4572                 ;
4573
4574 overlay_placing:
4575                 PLACING a_expr          { $$ = cat2_str(make_str("placing"), $2); }
4576                 ;
4577
4578 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
4579 position_list:  b_expr IN_P b_expr
4580                         { $$ = cat_str(3, $1, make_str("in"), $3); }
4581                 | /* EMPTY */
4582                         { $$ = EMPTY; }
4583                 ;
4584
4585 substr_list:  a_expr substr_from substr_for
4586                         { $$ = cat_str(3, $1, $2, $3); }
4587                 | a_expr substr_for substr_from
4588                         { $$ = cat_str(3, $1, $2, $3); }
4589                 | a_expr substr_from
4590                         { $$ = cat2_str($1, $2); }
4591                 | a_expr substr_for
4592                         { $$ = cat2_str($1, $2); }
4593                 | expr_list
4594                         { $$ = $1; }
4595                 | /* EMPTY */
4596                         { $$ = EMPTY; }
4597                 ;
4598
4599 substr_from:  FROM a_expr
4600                         { $$ = cat2_str(make_str("from"), $2); }
4601                 ;
4602
4603 substr_for:  FOR a_expr
4604                         { $$ = cat2_str(make_str("for"), $2); }
4605                 ;
4606
4607 trim_list:      a_expr FROM expr_list
4608                         { $$ = cat_str(3, $1, make_str("from"), $3); }
4609                 | FROM expr_list
4610                         { $$ = cat2_str(make_str("from"), $2); }
4611                 | expr_list
4612                         { $$ = $1; }
4613                 ;
4614
4615 in_expr:  select_with_parens
4616                         { $$ = $1; }
4617                 | '(' expr_list ')'
4618                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
4619                 ;
4620
4621 /* Case clause
4622  * Define SQL92-style case clause.
4623  */
4624 case_expr:      CASE case_arg when_clause_list case_default END_P
4625                         { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
4626                 ;
4627
4628 when_clause_list:  when_clause_list when_clause
4629                         { $$ = cat2_str($1, $2); }
4630                 | when_clause
4631                         { $$ = $1; }
4632                 ;
4633
4634 when_clause:  WHEN a_expr THEN a_expr
4635                         { $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4); }
4636                 ;
4637
4638 case_default:  ELSE a_expr
4639                         { $$ = cat2_str(make_str("else"), $2); }
4640                 | /*EMPTY*/
4641                         { $$ = EMPTY; }
4642                 ;
4643
4644 case_arg:  a_expr                       { $$ = $1; }
4645                 | /*EMPTY*/             { $$ = EMPTY; }
4646                 ;
4647
4648 columnref: relation_name                { $$ = $1; }
4649                 | relation_name indirection     { $$ = cat2_str($1, $2); }
4650                 ;
4651
4652 indirection_el:
4653                 '.' attr_name                   { $$ = cat2_str(make_str("."), $2); }
4654                 | '.' '*'                       { $$ = make_str(".*"); }
4655                 | '[' a_expr ']'                { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
4656                 | '[' a_expr ':' a_expr ']'     { $$ = cat_str(5, make_str("["), $2, make_str(":"), $4, make_str("]")); }
4657                 ;
4658
4659 indirection:    indirection_el          { $$ = $1; }
4660                 | indirection indirection_el    { $$ = cat2_str($1, $2); }
4661                 ;
4662
4663 opt_indirection:
4664                 /*EMPTY*/                               { $$ = EMPTY; }
4665                 | opt_indirection indirection_el        { $$ = cat2_str($1, $2);}
4666                 ;
4667
4668 opt_asymmetric: ASYMMETRIC      { $$ = make_str("asymmetric"); }
4669                 | /*EMPTY*/             { $$ = EMPTY; }
4670                 ;
4671
4672 ctext_expr:
4673                 a_expr          { $$ = $1; }
4674                 | DEFAULT       { $$ = make_str("default"); }
4675                 ;
4676
4677 ctext_expr_list:
4678                  ctext_expr                             { $$ = $1; }
4679                  |  ctext_expr_list ',' ctext_expr      { $$ = cat_str(3, $1, make_str(","), $3); }
4680                  ;
4681
4682 ctext_row: '(' ctext_expr_list ')'      { $$ = cat_str(3, make_str("("), $2, make_str(")"));};
4683
4684 /*****************************************************************************
4685  *
4686  *      target lists for SELECT
4687  *
4688  *****************************************************************************/
4689
4690 target_list:  target_list ',' target_el
4691                         { $$ = cat_str(3, $1, make_str(","), $3);  }
4692                 | target_el
4693                         { $$ = $1;      }
4694                 ;
4695
4696 /* AS is not optional because shift/red conflict with unary ops */
4697 target_el:      a_expr AS ColLabel
4698                         { $$ = cat_str(3, $1, make_str("as"), $3); }
4699                 | a_expr
4700                         { $$ = $1; }
4701                 | '*'
4702                         { $$ = make_str("*"); }
4703                 ;
4704
4705 /* INFORMIX workaround, no longer needed
4706 update_target_list:  '(' inf_col_list ')' '=' '(' inf_val_list ')'
4707                 {
4708                         struct inf_compat_col *ptrc;
4709                         struct inf_compat_val *ptrv;
4710                         char *cols = make_str( "(" );
4711                         char *vals = make_str( "(" );
4712
4713                         for (ptrc = informix_col, ptrv = informix_val; ptrc != NULL && ptrv != NULL; ptrc = ptrc->next, ptrv = ptrv->next)
4714                         {
4715                                 if ( ptrc->next != NULL )
4716                                 {
4717                                         cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(",") );
4718                                 }
4719                                 else
4720                                 {
4721                                         cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(")") );
4722                                 }
4723                                 if (ptrv->next != NULL )
4724                                         vals = cat_str(3, vals, ptrv->val, make_str("," ) );
4725                                 else
4726                                         vals = cat_str( 3, vals, ptrv->val, make_str(")") );
4727                         }
4728                         $$ = cat_str( 3, cols, make_str("="), vals );
4729                 } 
4730                 ;
4731
4732 inf_col_list: ColId opt_indirection
4733                 {
4734                         struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
4735
4736                         ptr->name = $1;
4737                         ptr->indirection = $2;
4738                         ptr->next = NULL;
4739                         informix_col = ptr;
4740                 }
4741                 | ColId opt_indirection ',' inf_col_list
4742                 {
4743                         struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
4744
4745                         ptr->name = $1;
4746                         ptr->indirection = $2;
4747                         ptr->next = informix_col;
4748                         informix_col = ptr;
4749                 }
4750                 ;
4751
4752 inf_val_list: a_expr
4753                 {
4754                         struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
4755
4756                         ptr->val = $1;
4757                         ptr->next = NULL;
4758                         informix_val = ptr;
4759                 }
4760                 | a_expr ',' inf_val_list
4761                 {
4762                         struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
4763
4764                         ptr->val = $1;
4765                         ptr->next = informix_val;
4766                         informix_val = ptr;
4767                 }
4768                 ;
4769 */
4770
4771 /*****************************************************************************
4772  *
4773  *         Names and constants
4774  *
4775  *****************************************************************************/
4776
4777 relation_name:  SpecialRuleRelation     { $$ = $1; }
4778                 | ColId                 { $$ = $1; }
4779                 ;
4780
4781 qualified_name_list:  qualified_name
4782                                 { $$ = $1; }
4783                 | qualified_name_list ',' qualified_name
4784                                 { $$ = cat_str(3, $1, make_str(","), $3); }
4785                 ;
4786
4787 qualified_name: relation_name
4788                 { $$ = $1; }
4789                 | relation_name indirection
4790                 { $$ = cat2_str($1, $2); }
4791                 ;
4792
4793 name_list:  name
4794                         { $$ = $1; }
4795                 | name_list ',' name
4796                         { $$ = cat_str(3, $1, make_str(","), $3); }
4797                 ;
4798
4799
4800 name:                           ColId                   { $$ = $1; };
4801 database_name:          ColId                   { $$ = $1; };
4802 access_method:          ColId                   { $$ = $1; };
4803 attr_name:                      ColLabel                { $$ = $1; };
4804 index_name:                     ColId                   { $$ = $1; };
4805
4806 file_name:                      StringConst             { $$ = $1; };
4807
4808 func_name: type_function_name
4809                         { $$ = $1; }
4810                 | relation_name indirection
4811                         { $$ = cat2_str($1, $2); }
4812                 ;
4813
4814
4815 /* Constants
4816  * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4817  */
4818 AexprConst:  PosAllConst
4819                         { $$ = $1; }
4820                 | ConstTypename StringConst
4821                         { $$ = cat2_str($1, $2); }
4822                 | ConstInterval StringConst opt_interval
4823                         { $$ = cat_str(3, $1, $2, $3); }
4824                 | ConstInterval  '(' PosIntConst ')' StringConst opt_interval
4825                         { $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
4826                 | TRUE_P
4827                         { $$ = make_str("true"); }
4828                 | FALSE_P
4829                         { $$ = make_str("false"); }
4830                 | NULL_P
4831                         { $$ = make_str("null"); }
4832                 | civarind
4833                         { $$ = $1; }
4834                 ;
4835
4836 Iconst:  ICONST                         { $$ = make_name();};
4837 Fconst:  FCONST                         { $$ = make_name();};
4838 Bconst:  BCONST                         { $$ = make_name();};
4839 Xconst:  XCONST                         { $$ = make_name();};
4840 Sconst:  SCONST
4841                 {
4842                         /* could have been input as '' or $$ */
4843                         $$ = (char *)mm_alloc(strlen($1) + 3);
4844                         $$[0]='\'';
4845                         strcpy($$+1, $1);
4846                         $$[strlen($1)+1]='\'';
4847                         $$[strlen($1)+2]='\0';
4848                         free($1);
4849                 }
4850         | ECONST
4851                 {
4852                         /* escaped quote starting with E */
4853                         $$ = (char *)mm_alloc(strlen($1) + 4);
4854                         $$[0]='E';
4855                         $$[1]='\'';
4856                         strcpy($$+2, $1);
4857                         $$[strlen($1)+2]='\'';
4858                         $$[strlen($1)+3]='\0';
4859                         free($1);
4860                 }
4861         | NCONST
4862                 {
4863                         /* escaped quote starting with rNE */
4864                         $$ = (char *)mm_alloc(strlen($1) + 4);
4865                         $$[0]='N';
4866                         $$[1]='\'';
4867                         strcpy($$+2, $1);
4868                         $$[strlen($1)+2]='\'';
4869                         $$[strlen($1)+3]='\0';
4870                         free($1);
4871                 }
4872         | DOLCONST
4873                 {
4874                         $$ = $1; 
4875                 }
4876         ;
4877
4878 PosIntConst:    Iconst          { $$ = $1; }
4879                 | civar         { $$ = $1; }
4880                 ;
4881
4882 IntConst:       PosIntConst             { $$ = $1; }
4883                 | '-' PosIntConst       { $$ = cat2_str(make_str("-"), $2); }
4884                 ;
4885
4886 IntConstVar:    Iconst
4887                 {
4888                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4889
4890                         sprintf(length, "%d", (int) strlen($1));
4891                         new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4892                         $$ = $1;
4893                 }
4894                 | cvariable     { $$ = $1; }
4895                 ;
4896
4897 AllConstVar:    Fconst
4898                 {
4899                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4900
4901                         sprintf(length, "%d", (int) strlen($1));
4902                         new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4903                         $$ = $1;
4904                 }
4905                 | IntConstVar           { $$ = $1; }
4906                 | '-' Fconst
4907                 {
4908                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4909                         char *var = cat2_str(make_str("-"), $2);
4910
4911                         sprintf(length, "%d", (int) strlen(var));
4912                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4913                         $$ = var;
4914                 }
4915                 | '-' Iconst
4916                 {
4917                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4918                         char *var = cat2_str(make_str("-"), $2);
4919
4920                         sprintf(length, "%d", (int) strlen(var));
4921                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4922                         $$ = var;
4923                 }
4924                 | Sconst
4925                 {
4926                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4927                         char *var = $1 + 1;
4928
4929                         var[strlen(var) - 1] = '\0';
4930                         sprintf(length, "%d", (int) strlen(var));
4931                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4932                         $$ = var;
4933                 }
4934                 ;
4935
4936 StringConst:    Sconst          { $$ = $1; }
4937                 | civar         { $$ = $1; }
4938                 ;
4939
4940 PosIntStringConst:      Iconst  { $$ = $1; }
4941                 | Sconst        { $$ = $1; }
4942                 | civar         { $$ = $1; }
4943                 ;
4944
4945 NumConst:       Fconst                  { $$ = $1; }
4946                 | Iconst                { $$ = $1; }
4947                 | '-' Fconst            { $$ = cat2_str(make_str("-"), $2); }
4948                 | '-' Iconst            { $$ = cat2_str(make_str("-"), $2); }
4949                 | civar                 { $$ = $1; }
4950                 ;
4951
4952 AllConst:       Sconst                  { $$ = $1; }
4953                 | NumConst              { $$ = $1; }
4954                 ;
4955
4956 PosAllConst:    Sconst                  { $$ = $1; }
4957                 | Fconst                { $$ = $1; }
4958                 | Iconst                { $$ = $1; }
4959                 | Bconst                { $$ = $1; }
4960                 | Xconst                { $$ = $1; }
4961                 | func_name Sconst      { $$ = cat2_str($1, $2); }
4962                 | func_name '(' expr_list ')' Sconst
4963                                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
4964                 | civar                 { $$ = $1; }
4965                 ;
4966
4967 RoleId:  ColId          { $$ = $1;};
4968
4969 SpecialRuleRelation:  OLD
4970                 {
4971                         if (!QueryIsRule)
4972                                 mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query");
4973
4974                         $$ = make_str("old");
4975                 }
4976                 | NEW
4977                 {
4978                         if (!QueryIsRule)
4979                                 mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query");
4980
4981                         $$ = make_str("new");
4982                 }
4983                 ;
4984
4985 /*
4986  * and now special embedded SQL stuff
4987  */
4988
4989 /*
4990  * the exec sql connect statement: connect to the given database
4991  */
4992 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
4993                         { $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4); }
4994                 | SQL_CONNECT TO DEFAULT
4995                         { $$ = make_str("NULL, NULL, NULL, \"DEFAULT\""); }
4996                   /* also allow ORACLE syntax */
4997                 | SQL_CONNECT ora_user
4998                         { $$ = cat_str(3, make_str("NULL,"), $2, make_str(", NULL")); }
4999                 | DATABASE connection_target
5000                         { $$ = cat2_str($2, make_str(", NULL, NULL, NULL")); }
5001                 ;
5002
5003 connection_target: opt_database_name opt_server opt_port
5004                 {
5005                         /* old style: dbname[@server][:port] */
5006                         if (strlen($2) > 0 && *($2) != '@')
5007                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected '@', found '%s'", $2);
5008                         
5009                         /* C strings need to be handled differently */
5010                         if ($1[0] == '\"')
5011                                 $$ = $1;
5012                         else
5013                                 $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
5014                 }
5015                 |  db_prefix ':' server opt_port '/' opt_database_name opt_options
5016                 {
5017                         /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
5018                         if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
5019                                 mmerror(PARSE_ERROR, ET_ERROR, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
5020
5021                         if (strncmp($3, "//", strlen("//")) != 0)
5022                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected '://', found '%s'", $3);
5023
5024                         if (strncmp($1, "unix", strlen("unix")) == 0 &&
5025                                 strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
5026                                 strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
5027                                 mmerror(PARSE_ERROR, ET_ERROR, "unix domain sockets only work on 'localhost' but not on '%s'", $3 + strlen("//"));
5028
5029                         $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6),    $7, make_str("\"")));
5030                 }
5031                 | char_variable
5032                 {
5033                         $$ = $1;
5034                 }
5035                 | Sconst
5036                 {
5037                         /* We can only process double quoted strings not single quotes ones,
5038                          * so we change the quotes.
5039                          * Note, that the rule for Sconst adds these single quotes. */
5040                         $1[0] = '\"';
5041                         $1[strlen($1)-1] = '\"';
5042                         $$ = $1;
5043                 }
5044                 ;
5045
5046 opt_database_name: database_name                { $$ = $1; }
5047                 | /*EMPTY*/                     { $$ = EMPTY; }
5048                 ;
5049
5050 db_prefix: ident cvariable
5051                 {
5052                         if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
5053                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected 'postgresql', found '%s'", $2);
5054
5055                         if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
5056                                 mmerror(PARSE_ERROR, ET_ERROR, "Illegal connection type %s", $1);
5057
5058                         $$ = make3_str($1, make_str(":"), $2);
5059                 }
5060                 ;
5061
5062 server: Op server_name
5063                 {
5064                         if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
5065                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected '@' or '://', found '%s'", $1);
5066
5067                         $$ = make2_str($1, $2);
5068                 }
5069                 ;
5070
5071 opt_server: server                      { $$ = $1; }
5072                 | /*EMPTY*/                     { $$ = EMPTY; }
5073                 ;
5074
5075 server_name: ColId                                      { $$ = $1; }
5076                 | ColId '.' server_name         { $$ = make3_str($1, make_str("."), $3); }
5077                 | IP                                            { $$ = make_name(); }
5078                 ;
5079
5080 opt_port: ':' PosIntConst       { $$ = make2_str(make_str(":"), $2); }
5081                 | /*EMPTY*/     { $$ = EMPTY; }
5082                 ;
5083
5084 opt_connection_name: AS connection_object       { $$ = $2; }
5085                 | /*EMPTY*/                     { $$ = make_str("NULL"); }
5086                 ;
5087
5088 opt_user: USER ora_user         { $$ = $2; }
5089                 | /*EMPTY*/                     { $$ = make_str("NULL, NULL"); }
5090                 ;
5091
5092 ora_user: user_name
5093                         { $$ = cat2_str($1, make_str(", NULL")); }
5094                 | user_name '/' user_name
5095                         { $$ = cat_str(3, $1, make_str(","), $3); }
5096                 | user_name SQL_IDENTIFIED BY user_name
5097                         { $$ = cat_str(3, $1, make_str(","), $4); }
5098                 | user_name USING user_name
5099                         { $$ = cat_str(3, $1, make_str(","), $3); }
5100                 ;
5101
5102 user_name: RoleId
5103                 {
5104                         if ($1[0] == '\"')
5105                                 $$ = $1;
5106                         else
5107                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
5108                 }
5109                 | StringConst
5110                 {
5111                         if ($1[0] == '\"')
5112                                 $$ = $1;
5113                         else if (strcmp($1, " ?") == 0) /* variable */
5114                         {
5115                                 enum ECPGttype type = argsinsert->variable->type->type;
5116
5117                                 /* if array see what's inside */
5118                                 if (type == ECPGt_array)
5119                                         type = argsinsert->variable->type->u.element->type;
5120
5121                                 /* handle varchars */
5122                                 if (type == ECPGt_varchar)
5123                                         $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
5124                                 else
5125                                         $$ = mm_strdup(argsinsert->variable->name);
5126                         }
5127                         else
5128                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
5129                 }
5130                 ;
5131
5132 char_variable: cvariable
5133                 {
5134                         /* check if we have a string variable */
5135                         struct variable *p = find_variable($1);
5136                         enum ECPGttype type = p->type->type;
5137
5138                         /* If we have just one character this is not a string */
5139                         if (atol(p->type->size) == 1)
5140                                         mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
5141                         else
5142                         {
5143                                 /* if array see what's inside */
5144                                 if (type == ECPGt_array)
5145                                         type = p->type->u.element->type;
5146
5147                                 switch (type)
5148                                 {
5149                                         case ECPGt_char:
5150                                         case ECPGt_unsigned_char:
5151                                                 $$ = $1;
5152                                                 break;
5153                                         case ECPGt_varchar:
5154                                                 $$ = make2_str($1, make_str(".arr"));
5155                                                 break;
5156                                         default:
5157                                                 mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
5158                                                 break;
5159                                 }
5160                         }
5161                 }
5162                 ;
5163
5164 opt_options: Op ColId
5165                 {
5166                         if (strlen($1) == 0)
5167                                 mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
5168
5169                         if (strcmp($1, "?") != 0)
5170                                 mmerror(PARSE_ERROR, ET_ERROR, "unrecognised token '%s'", $1);
5171
5172                         $$ = make2_str(make_str("?"), $2);
5173                 }
5174                 | /*EMPTY*/     { $$ = EMPTY; }
5175                 ;
5176
5177 /*
5178  * Declare a prepared cursor. The syntax is different from the standard
5179  * declare statement, so we create a new rule.
5180  */
5181 ECPGCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR prepared_name
5182                 {
5183                         struct cursor *ptr, *this;
5184                         struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
5185                         const char *con = connection ? connection : "NULL";
5186
5187                         for (ptr = cur; ptr != NULL; ptr = ptr->next)
5188                         {
5189                                 if (strcmp($2, ptr->name) == 0)
5190                                         /* re-definition is a bug */
5191                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
5192                         }
5193
5194                         this = (struct cursor *) mm_alloc(sizeof(struct cursor));
5195
5196                         /* initial definition */
5197                         this->next = cur;
5198                         this->name = $2;
5199                         this->connection = connection;
5200                         this->command =  cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for $1"));
5201                         this->argsresult = NULL;
5202
5203                         thisquery->type = &ecpg_query;
5204                         thisquery->brace_level = 0;
5205                         thisquery->next = NULL;
5206                         thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
5207                         sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
5208
5209                         this->argsinsert = NULL;
5210                         add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
5211
5212                         cur = this;
5213
5214                         $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
5215                 }
5216                 ;
5217
5218 ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
5219                         { 
5220                           /* execute immediate means prepare the statement and
5221                            * immediately execute it */
5222                           $$ = $3;
5223                         };
5224 /*
5225  * variable decalartion outside exec sql declare block
5226  */
5227 ECPGVarDeclaration: single_vt_declaration;
5228
5229 single_vt_declaration: type_declaration         { $$ = $1; }
5230                 | var_declaration               { $$ = $1; }
5231                 ;
5232
5233 precision:      NumConst        { $$ = $1; };
5234
5235 opt_scale:      ',' NumConst    { $$ = $2; }
5236                 | /* EMPTY */   { $$ = EMPTY; }
5237                 ;
5238
5239 ecpg_interval:  opt_interval    { $$ = $1; }
5240                 | YEAR_P TO MINUTE_P    { $$ = make_str("year to minute"); }
5241                 | YEAR_P TO SECOND_P    { $$ = make_str("year to second"); }
5242                 | DAY_P TO DAY_P                { $$ = make_str("day to day"); }
5243                 | MONTH_P TO MONTH_P    { $$ = make_str("month to month"); }
5244                 ;
5245
5246 /*
5247  * variable declaration inside exec sql declare block
5248  */
5249 ECPGDeclaration: sql_startdeclare
5250                 { fputs("/* exec sql begin declare section */", yyout); }
5251                 var_type_declarations sql_enddeclare
5252                 {
5253                         fprintf(yyout, "%s/* exec sql end declare section */", $3);
5254                         free($3);
5255                         output_line_number();
5256                 }
5257                 ;
5258
5259 sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {};
5260
5261 sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {};
5262
5263 var_type_declarations:  /*EMPTY*/                       { $$ = EMPTY; }
5264                 | vt_declarations                       { $$ = $1; }
5265                 | CPP_LINE                              { $$ = $1; }
5266                 ;
5267
5268 vt_declarations:  var_declaration                       { $$ = $1; }
5269                 | type_declaration                      { $$ = $1; }
5270                 | vt_declarations var_declaration       { $$ = cat2_str($1, $2); }
5271                 | vt_declarations type_declaration      { $$ = cat2_str($1, $2); }
5272                 | vt_declarations CPP_LINE              { $$ = cat2_str($1, $2); }
5273                 ;
5274
5275 variable_declarations:  var_declaration         { $$ = $1; }
5276                 | variable_declarations var_declaration         { $$ = cat2_str($1, $2); }
5277                 ;
5278
5279 type_declaration: S_TYPEDEF
5280         {
5281                 /* reset this variable so we see if there was */
5282                 /* an initializer specified */
5283                 initializer = 0;
5284         }
5285         var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
5286         {
5287                 add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
5288
5289                 fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
5290                 output_line_number();
5291                 $$ = make_str("");
5292         };
5293
5294 var_declaration: storage_declaration
5295                 var_type
5296                 {
5297                         actual_type[struct_level].type_enum = $2.type_enum;
5298                         actual_type[struct_level].type_dimension = $2.type_dimension;
5299                         actual_type[struct_level].type_index = $2.type_index;
5300                         actual_type[struct_level].type_sizeof = $2.type_sizeof;
5301
5302                         actual_startline[struct_level] = hashline_number();
5303                 }
5304                 variable_list ';'
5305                 {
5306                         $$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
5307                 }
5308                 | var_type
5309                 {
5310                         actual_type[struct_level].type_enum = $1.type_enum;
5311                         actual_type[struct_level].type_dimension = $1.type_dimension;
5312                         actual_type[struct_level].type_index = $1.type_index;
5313                         actual_type[struct_level].type_sizeof = $1.type_sizeof;
5314
5315                         actual_startline[struct_level] = hashline_number();
5316                 }
5317                 variable_list ';'
5318                 {
5319                         $$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
5320                 }
5321                 | struct_union_type_with_symbol ';'
5322                 {
5323                         $$ = cat2_str($1, make_str(";"));
5324                 }
5325                 ;
5326
5327 opt_bit_field:  ':' Iconst      { $$ =cat2_str(make_str(":"), $2); }
5328                 | /* EMPTY */   { $$ = EMPTY; }
5329                 ;
5330
5331 storage_declaration: storage_clause storage_modifier
5332                         {$$ = cat2_str ($1, $2); }
5333                 | storage_clause                {$$ = $1; }
5334                 | storage_modifier              {$$ = $1; }
5335                 ;
5336
5337 storage_clause : S_EXTERN       { $$ = make_str("extern"); }
5338                 | S_STATIC                      { $$ = make_str("static"); }
5339                 | S_REGISTER            { $$ = make_str("register"); }
5340                 | S_AUTO                        { $$ = make_str("auto"); }
5341                 ;
5342
5343 storage_modifier : S_CONST      { $$ = make_str("const"); }
5344                 | S_VOLATILE            { $$ = make_str("volatile"); }
5345                 ;
5346
5347 var_type:       simple_type
5348                 {
5349                         $$.type_enum = $1;
5350                         $$.type_str = mm_strdup(ecpg_type_name($1));
5351                         $$.type_dimension = make_str("-1");
5352                         $$.type_index = make_str("-1");
5353                         $$.type_sizeof = NULL;
5354                 }
5355                 | struct_union_type
5356                 {
5357                         $$.type_str = $1;
5358                         $$.type_dimension = make_str("-1");
5359                         $$.type_index = make_str("-1");
5360
5361                         if (strncmp($1, "struct", sizeof("struct")-1) == 0)
5362                         {
5363                                 $$.type_enum = ECPGt_struct;
5364                                 $$.type_sizeof = ECPGstruct_sizeof;
5365                         }
5366                         else
5367                         {
5368                                 $$.type_enum = ECPGt_union;
5369                                 $$.type_sizeof = NULL;
5370                         }
5371                 }
5372                 | enum_type
5373                 {
5374                         $$.type_str = $1;
5375                         $$.type_enum = ECPGt_int;
5376                         $$.type_dimension = make_str("-1");
5377                         $$.type_index = make_str("-1");
5378                         $$.type_sizeof = NULL;
5379                 }
5380                 | ECPGColLabelCommon '(' precision opt_scale ')'
5381                 {
5382                         if (strcmp($1, "numeric") == 0)
5383                         {
5384                                 $$.type_enum = ECPGt_numeric;
5385                                 $$.type_str = make_str("numeric");
5386                         }
5387                         else if (strcmp($1, "decimal") == 0)
5388                         {
5389                                 $$.type_enum = ECPGt_decimal;
5390                                 $$.type_str = make_str("decimal");
5391                         }
5392                         else
5393                         {
5394                                 mmerror(PARSE_ERROR, ET_ERROR, "Only numeric/decimal have precision/scale argument");
5395                                 $$.type_enum = ECPGt_numeric;
5396                                 $$.type_str = make_str("numeric");
5397                         }
5398
5399                         $$.type_dimension = make_str("-1");
5400                         $$.type_index = make_str("-1");
5401                         $$.type_sizeof = NULL;
5402                 }
5403                 | ECPGColLabelCommon ecpg_interval
5404                 {
5405                         if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
5406                                 mmerror (PARSE_ERROR, ET_ERROR, "Interval specification not allowed here ");
5407
5408                         /*
5409                          * Check for type names that the SQL grammar treats as
5410                          * unreserved keywords
5411                          */
5412                         if (strcmp($1, "varchar") == 0)
5413                         {
5414                                 $$.type_enum = ECPGt_varchar;
5415                                 $$.type_str = EMPTY; /*make_str("varchar");*/
5416                                 $$.type_dimension = make_str("-1");
5417                                 $$.type_index = make_str("-1");
5418                                 $$.type_sizeof = NULL;
5419                         }
5420                         else if (strcmp($1, "float") == 0)
5421                         {
5422                                 $$.type_enum = ECPGt_float;
5423                                 $$.type_str = make_str("float");
5424                                 $$.type_dimension = make_str("-1");
5425                                 $$.type_index = make_str("-1");
5426                                 $$.type_sizeof = NULL;
5427                         }
5428                         else if (strcmp($1, "double") == 0)
5429                         {
5430                                 $$.type_enum = ECPGt_double;
5431                                 $$.type_str = make_str("double");
5432                                 $$.type_dimension = make_str("-1");
5433                                 $$.type_index = make_str("-1");
5434                                 $$.type_sizeof = NULL;
5435                         }
5436                         else if (strcmp($1, "numeric") == 0)
5437                         {
5438                                 $$.type_enum = ECPGt_numeric;
5439                                 $$.type_str = make_str("numeric");
5440                                 $$.type_dimension = make_str("-1");
5441                                 $$.type_index = make_str("-1");
5442                                 $$.type_sizeof = NULL;
5443                         }
5444                         else if (strcmp($1, "decimal") == 0)
5445                         {
5446                                 $$.type_enum = ECPGt_decimal;
5447                                 $$.type_str = make_str("decimal");
5448                                 $$.type_dimension = make_str("-1");
5449                                 $$.type_index = make_str("-1");
5450                                 $$.type_sizeof = NULL;
5451                         }
5452                         else if (strcmp($1, "date") == 0)
5453                         {
5454                                 $$.type_enum = ECPGt_date;
5455                                 $$.type_str = make_str("date");
5456                                 $$.type_dimension = make_str("-1");
5457                                 $$.type_index = make_str("-1");
5458                                 $$.type_sizeof = NULL;
5459                         }
5460                         else if (strcmp($1, "timestamp") == 0)
5461                         {
5462                                 $$.type_enum = ECPGt_timestamp;
5463                                 $$.type_str = make_str("timestamp");
5464                                 $$.type_dimension = make_str("-1");
5465                                 $$.type_index = make_str("-1");
5466                                 $$.type_sizeof = NULL;
5467                         }
5468                         else if (strcmp($1, "interval") == 0)
5469                         {
5470                                 $$.type_enum = ECPGt_interval;
5471                                 $$.type_str = make_str("interval");
5472                                 $$.type_dimension = make_str("-1");
5473                                 $$.type_index = make_str("-1");
5474                                 $$.type_sizeof = NULL;
5475                         }
5476                         else if (strcmp($1, "datetime") == 0)
5477                         {
5478                                 $$.type_enum = ECPGt_timestamp;
5479                                 $$.type_str = make_str("timestamp");
5480                                 $$.type_dimension = make_str("-1");
5481                                 $$.type_index = make_str("-1");
5482                                 $$.type_sizeof = NULL;
5483                         }
5484                         else
5485                         {
5486                                 /* this is for typedef'ed types */
5487                                 struct typedefs *this = get_typedef($1);
5488
5489                                 $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
5490                                 $$.type_enum = this->type->type_enum;
5491                                 $$.type_dimension = this->type->type_dimension;
5492                                 $$.type_index = this->type->type_index;
5493                                 if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
5494                                         $$.type_sizeof = this->type->type_sizeof;
5495                                 else 
5496                                         $$.type_sizeof = cat_str(3, make_str("sizeof("), mm_strdup(this->name), make_str(")"));
5497
5498                                 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
5499                         }
5500                 }
5501                 | s_struct_union_symbol
5502                 {
5503                         /* this is for named structs/unions */
5504                         char *name;
5505                         struct typedefs *this;
5506                         bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
5507
5508                         name = cat2_str($1.su, $1.symbol);
5509                         /* Do we have a forward definition? */
5510                         if (!forward)
5511                         {
5512                                 /* No */
5513
5514                                 this = get_typedef(name);
5515                                 $$.type_str = mm_strdup(this->name);
5516                                 $$.type_enum = this->type->type_enum;
5517                                 $$.type_dimension = this->type->type_dimension;
5518                                 $$.type_index = this->type->type_index;
5519                                 $$.type_sizeof = this->type->type_sizeof;
5520                                 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
5521                                 free(name);
5522                         }
5523                         else
5524                         {
5525                                 $$.type_str = name;
5526                                 $$.type_enum = ECPGt_long;
5527                                 $$.type_dimension = make_str("-1");
5528                                 $$.type_index = make_str("-1");
5529                                 $$.type_sizeof = make_str("");
5530                                 struct_member_list[struct_level] = NULL;
5531                         }
5532                 }
5533                 ;
5534
5535 enum_type: ENUM_P symbol enum_definition
5536                         { $$ = cat_str(3, make_str("enum"), $2, $3); }
5537                 | ENUM_P enum_definition
5538                         { $$ = cat2_str(make_str("enum"), $2); }
5539                 | ENUM_P symbol
5540                         { $$ = cat2_str(make_str("enum"), $2); }
5541                 ;
5542
5543 enum_definition: '{' c_list '}'
5544                         { $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
5545
5546 struct_union_type_with_symbol: s_struct_union_symbol
5547                 {
5548                         struct_member_list[struct_level++] = NULL;
5549                         if (struct_level >= STRUCT_DEPTH)
5550                                  mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
5551                         forward_name = mm_strdup($1.symbol);
5552                 }
5553                 '{' variable_declarations '}'
5554                 {
5555                         struct typedefs *ptr, *this;
5556                         struct this_type su_type;
5557
5558                         ECPGfree_struct_member(struct_member_list[struct_level]);
5559                         struct_member_list[struct_level] = NULL;
5560                         struct_level--;
5561                         if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
5562                                 su_type.type_enum = ECPGt_struct;
5563                         else
5564                                 su_type.type_enum = ECPGt_union;
5565                         su_type.type_str = cat2_str($1.su, $1.symbol);
5566                         free(forward_name);
5567                         forward_name = NULL;
5568
5569                         /* This is essantially a typedef but needs the keyword struct/union as well.
5570                          * So we create the typedef for each struct definition with symbol */
5571                         for (ptr = types; ptr != NULL; ptr = ptr->next)
5572                         {
5573                                         if (strcmp(su_type.type_str, ptr->name) == 0)
5574                                                         /* re-definition is a bug */
5575                                                         mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", su_type.type_str);
5576                         }
5577
5578                         this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
5579
5580                         /* initial definition */
5581                         this->next = types;
5582                         this->name = mm_strdup(su_type.type_str);
5583                         this->brace_level = braces_open;
5584                         this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
5585                         this->type->type_enum = su_type.type_enum;
5586                         this->type->type_str = mm_strdup(su_type.type_str);
5587                         this->type->type_dimension = make_str("-1"); /* dimension of array */
5588                         this->type->type_index = make_str("-1");        /* length of string */
5589                         this->type->type_sizeof = ECPGstruct_sizeof;
5590                         this->struct_member_list = struct_member_list[struct_level];
5591
5592                         types = this;
5593                         $$ = cat_str(4, su_type.type_str, make_str("{"), $4, make_str("}"));
5594                 }
5595                 ;
5596
5597 struct_union_type: struct_union_type_with_symbol        { $$ = $1; }
5598                 | s_struct_union
5599                 {
5600                         struct_member_list[struct_level++] = NULL;
5601                         if (struct_level >= STRUCT_DEPTH)
5602                                  mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
5603                 }
5604                 '{' variable_declarations '}'
5605                 {
5606                         ECPGfree_struct_member(struct_member_list[struct_level]);
5607                         struct_member_list[struct_level] = NULL;
5608                         struct_level--;
5609                         $$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
5610                 }
5611                 ;
5612
5613 s_struct_union_symbol: SQL_STRUCT symbol
5614                 {
5615                         $$.su = make_str("struct");
5616                         $$.symbol = $2;
5617                         ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), make_str(")"));
5618                 }
5619                 | UNION symbol
5620                 {
5621                         $$.su = make_str("union");
5622                         $$.symbol = $2;
5623                 }
5624                 ;
5625
5626 s_struct_union: SQL_STRUCT
5627                 {
5628                         ECPGstruct_sizeof = make_str(""); /* This must not be NULL to distinguish from simple types. */
5629                         $$ = make_str("struct");
5630                 }
5631                 | UNION         { $$ = make_str("union"); }
5632                 ;
5633
5634 simple_type: unsigned_type                                      { $$=$1; }
5635                 |       opt_signed signed_type                  { $$=$2; }
5636                 ;
5637
5638 unsigned_type: SQL_UNSIGNED SQL_SHORT           { $$ = ECPGt_unsigned_short; }
5639                 | SQL_UNSIGNED SQL_SHORT INT_P  { $$ = ECPGt_unsigned_short; }
5640                 | SQL_UNSIGNED                                          { $$ = ECPGt_unsigned_int; }
5641                 | SQL_UNSIGNED INT_P                            { $$ = ECPGt_unsigned_int; }
5642                 | SQL_UNSIGNED SQL_LONG                         { $$ = ECPGt_unsigned_long; }
5643                 | SQL_UNSIGNED SQL_LONG INT_P           { $$ = ECPGt_unsigned_long; }
5644                 | SQL_UNSIGNED SQL_LONG SQL_LONG
5645                 {
5646 #ifdef HAVE_LONG_LONG_INT_64
5647                         $$ = ECPGt_unsigned_long_long;
5648 #else
5649                         $$ = ECPGt_unsigned_long;
5650 #endif
5651                 }
5652                 | SQL_UNSIGNED SQL_LONG SQL_LONG INT_P
5653                 {
5654 #ifdef HAVE_LONG_LONG_INT_64
5655                         $$ = ECPGt_unsigned_long_long;
5656 #else
5657                         $$ = ECPGt_unsigned_long;
5658 #endif
5659                 }
5660                 | SQL_UNSIGNED CHAR_P                   { $$ = ECPGt_unsigned_char; }
5661                 ;
5662
5663 signed_type: SQL_SHORT                          { $$ = ECPGt_short; }
5664                 | SQL_SHORT INT_P                       { $$ = ECPGt_short; }
5665                 | INT_P                                         { $$ = ECPGt_int; }
5666                 | SQL_LONG                                      { $$ = ECPGt_long; }
5667                 | SQL_LONG INT_P                        { $$ = ECPGt_long; }
5668                 | SQL_LONG SQL_LONG
5669                 {
5670 #ifdef HAVE_LONG_LONG_INT_64
5671                         $$ = ECPGt_long_long;
5672 #else
5673                         $$ = ECPGt_long;
5674 #endif
5675                 }
5676                 | SQL_LONG SQL_LONG INT_P
5677                 {
5678 #ifdef HAVE_LONG_LONG_INT_64
5679                         $$ = ECPGt_long_long;
5680 #else
5681                         $$ = ECPGt_long;
5682 #endif
5683                 }
5684                 | SQL_BOOL                                      { $$ = ECPGt_bool; }
5685                 | CHAR_P                                        { $$ = ECPGt_char; }
5686                 | DOUBLE_P                                      { $$ = ECPGt_double; }
5687                 ;
5688
5689 opt_signed: SQL_SIGNED
5690                 |       /* EMPTY */
5691                 ;
5692
5693 variable_list: variable
5694                         { $$ = $1; }
5695                 | variable_list ',' variable
5696                         { $$ = cat_str(3, $1, make_str(","), $3); }
5697                 ;
5698
5699 variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
5700                 {
5701                         struct ECPGtype * type;
5702                         char *dimension = $3.index1; /* dimension of array */
5703                         char *length = $3.index2;    /* length of string */
5704                         char dim[14L];
5705                         char *vcn;
5706
5707                         adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false);
5708
5709                         switch (actual_type[struct_level].type_enum)
5710                         {
5711                                 case ECPGt_struct:
5712                                 case ECPGt_union:
5713                                         if (atoi(dimension) < 0)
5714                                                 type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof);
5715                                         else
5716                                                 type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof), dimension);
5717
5718                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
5719                                         break;
5720
5721                                 case ECPGt_varchar:
5722                                         if (atoi(dimension) < 0)
5723                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno);
5724                                         else
5725                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno), dimension);
5726                                         
5727                                         if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1)
5728                                                         *dim = '\0';
5729                                         else
5730                                                         sprintf(dim, "[%s]", dimension);
5731                                         /* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
5732                                         if (atoi(length) < 0 || strcmp(length, "0") == 0)
5733                                                 mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
5734
5735                                         /* make sure varchar struct name is unique by adding linenumer of its definition */
5736                                         vcn = (char *) mm_alloc(strlen($2) + sizeof(int) * CHAR_BIT * 10 / 3);
5737                                         sprintf(vcn, "%s_%d", $2, yylineno);
5738                                         if (strcmp(dimension, "0") == 0)
5739                                                 $$ = cat_str(7, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } *"), mm_strdup($2), $4, $5);
5740                                         else
5741                                                 $$ = cat_str(8, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4, $5);
5742                                         break;
5743
5744                                 case ECPGt_char:
5745                                 case ECPGt_unsigned_char:
5746                                         if (atoi(dimension) == -1)
5747                                         {
5748                                                 int i = strlen($5);
5749
5750                                                 if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
5751                                                 {
5752                                                         /* if we have an initializer but no string size set, let's use the initializer's length */
5753                                                         free(length);
5754                                                         length = mm_alloc(i+sizeof("sizeof()"));
5755                                                         sprintf(length, "sizeof(%s)", $5+2);
5756                                                 }
5757                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
5758                                         }
5759                                         else
5760                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
5761
5762                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
5763                                         break;
5764
5765                                 default:
5766                                         if (atoi(dimension) < 0)
5767                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0);
5768                                         else
5769                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0), dimension);
5770
5771                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
5772                                         break;
5773                         }
5774
5775                         if (struct_level == 0)
5776                                 new_variable($2, type, braces_open);
5777                         else
5778                                 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
5779
5780                         free($2);
5781                 }
5782                 ;
5783
5784 opt_initializer: /*EMPTY*/
5785                         { $$ = EMPTY; }
5786                 | '=' c_term
5787                 {
5788                         initializer = 1;
5789                         $$ = cat2_str(make_str("="), $2);
5790                 }
5791                 ;
5792
5793 opt_pointer: /*EMPTY*/                          { $$ = EMPTY; }
5794                 | '*'                                           { $$ = make_str("*"); }
5795                 | '*' '*'                                       { $$ = make_str("**"); }
5796                 ;
5797
5798 /*
5799  * We try to simulate the correct DECLARE syntax here so we get dynamic SQL
5800  */
5801 ECPGDeclare: DECLARE STATEMENT ident
5802                 {
5803                         /* this is only supported for compatibility */
5804                         $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
5805                 }
5806                 ;
5807 /*
5808  * the exec sql disconnect statement: disconnect from the given database
5809  */
5810 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
5811                 ;
5812
5813 dis_name: connection_object                     { $$ = $1; }
5814                 | CURRENT_P                     { $$ = make_str("\"CURRENT\""); }
5815                 | ALL                           { $$ = make_str("\"ALL\""); }
5816                 | /* EMPTY */                   { $$ = make_str("\"CURRENT\""); }
5817                 ;
5818
5819 connection_object: database_name                { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5820                 | DEFAULT                       { $$ = make_str("\"DEFAULT\""); }
5821                 | char_variable                 { $$ = $1; }
5822                 ;
5823
5824 execute_rest:   ecpg_using ecpg_into    { $$ = EMPTY; }
5825                 | ecpg_into ecpg_using  { $$ = EMPTY; }
5826                 | ecpg_using            { $$ = EMPTY; }
5827                 | ecpg_into             { $$ = EMPTY; }
5828                 | /* EMPTY */           { $$ = EMPTY; }
5829                 ;
5830
5831 execstring: char_variable
5832                         { $$ = $1; }
5833                 |       CSTRING
5834                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5835                 ;
5836
5837 prepared_name: name             { 
5838                                         if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */
5839                                                 $$ = $1;
5840                                         else /* not quoted => convert to lowercase */
5841                                         {
5842                                                 int i;
5843
5844                                                 for (i = 0; i< strlen($1); i++)
5845                                                         $1[i] = tolower($1[i]);
5846
5847                                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
5848                                         }
5849                                 }
5850                 | char_variable { $$ = $1; }
5851                 ;
5852
5853 /*
5854  * the exec sql free command to deallocate a previously
5855  * prepared statement
5856  */
5857 ECPGFree:       SQL_FREE name   { $$ = $2; }
5858                 | SQL_FREE ALL  { $$ = make_str("all"); }
5859                 ;
5860
5861 /*
5862  * open is an open cursor, at the moment this has to be removed
5863  */
5864 ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; };
5865
5866 opt_ecpg_using: /*EMPTY*/       { $$ = EMPTY; }
5867                 | ecpg_using            { $$ = $1; }
5868                 ;
5869
5870 ecpg_using:     USING using_list        { $$ = EMPTY; }
5871                 | using_descriptor      { $$ = $1; }
5872                 ;
5873
5874 using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
5875                 {
5876                         add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
5877                         $$ = EMPTY;
5878                 }
5879                 ;
5880
5881 into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
5882                 {
5883                         add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
5884                         $$ = EMPTY;
5885                 }
5886                 ;
5887
5888 opt_sql: /*EMPTY*/ | SQL_SQL;
5889
5890 ecpg_into: INTO into_list               { $$ = EMPTY; }
5891                 | into_descriptor       { $$ = $1; }
5892                 ;
5893
5894 using_list: UsingConst | UsingConst ',' using_list;
5895
5896 UsingConst: AllConst
5897                 {
5898                         if ($1[1] != '$') /* found a constant */
5899                         {
5900                                 char *length = mm_alloc(32);
5901
5902                                 sprintf(length, "%d", (int) strlen($1));
5903                                 add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
5904                         }
5905                 }
5906                 | civarind { $$ = EMPTY; }
5907                 ;
5908
5909
5910 /*
5911  * We accept descibe but do nothing with it so far.
5912  */
5913 ECPGDescribe: SQL_DESCRIBE INPUT_P name using_descriptor
5914         {
5915                 const char *con = connection ? connection : "NULL";
5916                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement.\n");
5917                 $$ = (char *) mm_alloc(sizeof("1, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
5918                 sprintf($$, "1, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
5919         }
5920         | SQL_DESCRIBE opt_output name using_descriptor
5921         {
5922                 const char *con = connection ? connection : "NULL";
5923                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement.\n");
5924                 $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
5925                 sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
5926         }
5927         | SQL_DESCRIBE opt_output name into_descriptor
5928         {
5929                 const char *con = connection ? connection : "NULL";
5930                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement.\n");
5931                 $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
5932                 sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
5933         }
5934         ;
5935
5936 opt_output:     SQL_OUTPUT      { $$ = make_str("output"); }
5937         |       /* EMPTY */     { $$ = EMPTY; }
5938         ;
5939
5940 /*
5941  * dynamic SQL: descriptor based access
5942  *      originall written by Christof Petig <christof.petig@wtal.de>
5943  *                      and Peter Eisentraut <peter.eisentraut@credativ.de>
5944  */
5945
5946 /*
5947  * allocate a descriptor
5948  */
5949 ECPGAllocateDescr:     SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
5950                 {
5951                         add_descriptor($3,connection);
5952                         $$ = $3;
5953                 }
5954                 ;
5955
5956
5957 /*
5958  * deallocate a descriptor
5959  */
5960 ECPGDeallocateDescr:    DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
5961                 {
5962                         drop_descriptor($3,connection);
5963                         $$ = $3;
5964                 }
5965                 ;
5966
5967 /*
5968  * manipulate a descriptor header
5969  */
5970
5971 ECPGGetDescriptorHeader: GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
5972                         {  $$ = $3; }
5973                 ;
5974
5975 ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
5976                 | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
5977                 ;
5978
5979 ECPGGetDescHeaderItem: cvariable '=' desc_header_item
5980                         { push_assignment($1, $3); }
5981                 ;
5982
5983
5984 ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
5985                         { $$ = $3; }
5986                 ;
5987
5988 ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
5989                 | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
5990                 ;
5991
5992 ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
5993                 {
5994                         push_assignment($3, $1);
5995                 }
5996                 ;
5997
5998
5999 desc_header_item:       SQL_COUNT                       { $$ = ECPGd_count; }
6000                 ;
6001
6002 /*
6003  * manipulate a descriptor
6004  */
6005
6006 ECPGGetDescriptor:      GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
6007                         {  $$.str = $5; $$.name = $3; }
6008                 ;
6009
6010 ECPGGetDescItems: ECPGGetDescItem
6011                 | ECPGGetDescItems ',' ECPGGetDescItem
6012                 ;
6013
6014 ECPGGetDescItem: cvariable '=' descriptor_item  { push_assignment($1, $3); };
6015
6016
6017 ECPGSetDescriptor:      SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems
6018                         {  $$.str = $5; $$.name = $3; }
6019                 ;
6020
6021 ECPGSetDescItems: ECPGSetDescItem
6022                 | ECPGSetDescItems ',' ECPGSetDescItem
6023                 ;
6024
6025 ECPGSetDescItem: descriptor_item '=' AllConstVar
6026                 {
6027                         push_assignment($3, $1);
6028                 }
6029                 ;
6030
6031
6032 descriptor_item:        SQL_CARDINALITY                 { $$ = ECPGd_cardinality; }
6033                 | SQL_DATA                              { $$ = ECPGd_data; }
6034                 | SQL_DATETIME_INTERVAL_CODE            { $$ = ECPGd_di_code; }
6035                 | SQL_DATETIME_INTERVAL_PRECISION       { $$ = ECPGd_di_precision; }
6036                 | SQL_INDICATOR                         { $$ = ECPGd_indicator; }
6037                 | SQL_KEY_MEMBER                        { $$ = ECPGd_key_member; }
6038                 | SQL_LENGTH                            { $$ = ECPGd_length; }
6039                 | NAME_P                                { $$ = ECPGd_name; }
6040                 | SQL_NULLABLE                          { $$ = ECPGd_nullable; }
6041                 | SQL_OCTET_LENGTH                      { $$ = ECPGd_octet; }
6042                 | PRECISION                             { $$ = ECPGd_precision; }
6043                 | SQL_RETURNED_LENGTH                   { $$ = ECPGd_length; }
6044                 | SQL_RETURNED_OCTET_LENGTH             { $$ = ECPGd_ret_octet; }
6045                 | SQL_SCALE                             { $$ = ECPGd_scale; }
6046                 | TYPE_P                                { $$ = ECPGd_type; }
6047                 ;
6048
6049 /*
6050  * set/reset the automatic transaction mode, this needs a differnet handling
6051  * as the other set commands
6052  */
6053 ECPGSetAutocommit:      SET SQL_AUTOCOMMIT '=' on_off   { $$ = $4; }
6054                 |  SET SQL_AUTOCOMMIT TO on_off   { $$ = $4; }
6055                 ;
6056
6057 on_off: ON                              { $$ = make_str("on"); }
6058                 | OFF                   { $$ = make_str("off"); }
6059                 ;
6060
6061 /*
6062  * set the actual connection, this needs a differnet handling as the other
6063  * set commands
6064  */
6065 ECPGSetConnection:      SET CONNECTION TO connection_object { $$ = $4; }
6066                 | SET CONNECTION '=' connection_object { $$ = $4; }
6067                 | SET CONNECTION  connection_object { $$ = $3; }
6068                 ;
6069
6070 /*
6071  * define a new type for embedded SQL
6072  */
6073 ECPGTypedef: TYPE_P
6074                 {
6075                         /* reset this variable so we see if there was */
6076                         /* an initializer specified */
6077                         initializer = 0;
6078                 }
6079                 ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
6080                 {
6081                         add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
6082
6083                         if (auto_create_c == false)
6084                                 $$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
6085                         else
6086                                 $$ = cat_str(6, make_str("typedef "), mm_strdup($5.type_str), *$7?make_str("*"):make_str(""), mm_strdup($6.str), mm_strdup($3), make_str(";"));
6087                 }
6088                 ;
6089
6090 opt_reference: SQL_REFERENCE            { $$ = make_str("reference"); }
6091                 | /*EMPTY*/                                     { $$ = EMPTY; }
6092                 ;
6093
6094 /*
6095  * define the type of one variable for embedded SQL
6096  */
6097 ECPGVar: SQL_VAR
6098                 {
6099                         /* reset this variable so we see if there was */
6100                         /* an initializer specified */
6101                         initializer = 0;
6102                 }
6103                 ColLabel IS var_type opt_array_bounds opt_reference
6104                 {
6105                         struct variable *p = find_variable($3);
6106                         char *dimension = $6.index1;
6107                         char *length = $6.index2;
6108                         struct ECPGtype * type;
6109
6110                         if (($5.type_enum == ECPGt_struct ||
6111                                  $5.type_enum == ECPGt_union) &&
6112                                 initializer == 1)
6113                                 mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
6114                         else
6115                         {
6116                                 adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
6117
6118                                 switch ($5.type_enum)
6119                                 {
6120                                         case ECPGt_struct:
6121                                         case ECPGt_union:
6122                                                 if (atoi(dimension) < 0)
6123                                                         type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_sizeof);
6124                                                 else
6125                                                         type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,$5.type_sizeof), dimension);
6126                                                 break;
6127
6128                                         case ECPGt_varchar:
6129                                                 if (atoi(dimension) == -1)
6130                                                         type = ECPGmake_simple_type($5.type_enum, length, 0);
6131                                                 else
6132                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
6133                                                 break;
6134
6135                                         case ECPGt_char:
6136                                         case ECPGt_unsigned_char:
6137                                                 if (atoi(dimension) == -1)
6138                                                         type = ECPGmake_simple_type($5.type_enum, length, 0);
6139                                                 else
6140                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
6141                                                 break;
6142
6143                                         default:
6144                                                 if (atoi(length) >= 0)
6145                                                         mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
6146
6147                                                 if (atoi(dimension) < 0)
6148                                                         type = ECPGmake_simple_type($5.type_enum, make_str("1"), 0);
6149                                                 else
6150                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, make_str("1"), 0), dimension);
6151                                                 break;
6152                                 }
6153
6154                                 ECPGfree_type(p->type);
6155                                 p->type = type;
6156                         }
6157
6158                         $$ = cat_str(7, make_str("/* exec sql var"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
6159                 }
6160                 ;
6161
6162 /*
6163  * whenever statement: decide what to do in case of error/no data found
6164  * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
6165  */
6166 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
6167                 {
6168                         when_error.code = $<action>3.code;
6169                         when_error.command = $<action>3.command;
6170                         $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */"));
6171                 }
6172                 | SQL_WHENEVER NOT SQL_FOUND action
6173                 {
6174                         when_nf.code = $<action>4.code;
6175                         when_nf.command = $<action>4.command;
6176                         $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */"));
6177                 }
6178                 | SQL_WHENEVER SQL_SQLWARNING action
6179                 {
6180                         when_warn.code = $<action>3.code;
6181                         when_warn.command = $<action>3.command;
6182                         $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */"));
6183                 }
6184                 ;
6185
6186 action : SQL_CONTINUE
6187                 {
6188                         $<action>$.code = W_NOTHING;
6189                         $<action>$.command = NULL;
6190                         $<action>$.str = make_str("continue");
6191                 }
6192                 | SQL_SQLPRINT
6193                 {
6194                         $<action>$.code = W_SQLPRINT;
6195                         $<action>$.command = NULL;
6196                         $<action>$.str = make_str("sqlprint");
6197                 }
6198                 | SQL_STOP
6199                 {
6200                         $<action>$.code = W_STOP;
6201                         $<action>$.command = NULL;
6202                         $<action>$.str = make_str("stop");
6203                 }
6204                 | SQL_GOTO name
6205                 {
6206                         $<action>$.code = W_GOTO;
6207                         $<action>$.command = strdup($2);
6208                         $<action>$.str = cat2_str(make_str("goto "), $2);
6209                 }
6210                 | SQL_GO TO name
6211                 {
6212                         $<action>$.code = W_GOTO;
6213                         $<action>$.command = strdup($3);
6214                         $<action>$.str = cat2_str(make_str("goto "), $3);
6215                 }
6216                 | DO name '(' c_args ')'
6217                 {
6218                         $<action>$.code = W_DO;
6219                         $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
6220                         $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
6221                 }
6222                 | DO SQL_BREAK
6223                 {
6224                         $<action>$.code = W_BREAK;
6225                         $<action>$.command = NULL;
6226                         $<action>$.str = make_str("break");
6227                 }
6228                 | SQL_CALL name '(' c_args ')'
6229                 {
6230                         $<action>$.code = W_DO;
6231                         $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
6232                         $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
6233                 }
6234                 | SQL_CALL name
6235                 {
6236                         $<action>$.code = W_DO;
6237                         $<action>$.command = cat2_str($2, make_str("()"));
6238                         $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
6239                 }
6240                 ;
6241
6242 /* some other stuff for ecpg */
6243
6244 /* additional unreserved keywords */
6245 ECPGKeywords: ECPGKeywords_vanames      { $$ = $1; }
6246                 | ECPGKeywords_rest     { $$ = $1; }
6247                 ;
6248
6249 ECPGKeywords_vanames:  SQL_BREAK                { $$ = make_str("break"); }
6250                 | SQL_CALL                                              { $$ = make_str("call"); }
6251                 | SQL_CARDINALITY                               { $$ = make_str("cardinality"); }
6252                 | SQL_CONTINUE                                  { $$ = make_str("continue"); }
6253                 | SQL_COUNT                                             { $$ = make_str("count"); }
6254                 | SQL_DATA                                              { $$ = make_str("data"); }
6255                 | SQL_DATETIME_INTERVAL_CODE    { $$ = make_str("datetime_interval_code"); }
6256                 | SQL_DATETIME_INTERVAL_PRECISION       { $$ = make_str("datetime_interval_precision"); }
6257                 | SQL_FOUND                                             { $$ = make_str("found"); }
6258                 | SQL_GO                                                { $$ = make_str("go"); }
6259                 | SQL_GOTO                                              { $$ = make_str("goto"); }
6260                 | SQL_IDENTIFIED                                { $$ = make_str("identified"); }
6261                 | SQL_INDICATOR                         { $$ = make_str("indicator"); }
6262                 | SQL_KEY_MEMBER                        { $$ = make_str("key_member"); }
6263                 | SQL_LENGTH                            { $$ = make_str("length"); }
6264                 | SQL_NULLABLE                          { $$ = make_str("nullable"); }
6265                 | SQL_OCTET_LENGTH                      { $$ = make_str("octet_length"); }
6266                 | SQL_RETURNED_LENGTH           { $$ = make_str("returned_length"); }
6267                 | SQL_RETURNED_OCTET_LENGTH     { $$ = make_str("returned_octet_length"); }
6268                 | SQL_SCALE                                     { $$ = make_str("scale"); }
6269                 | SQL_SECTION                           { $$ = make_str("section"); }
6270                 | SQL_SQLERROR                          { $$ = make_str("sqlerror"); }
6271                 | SQL_SQLPRINT                          { $$ = make_str("sqlprint"); }
6272                 | SQL_SQLWARNING                        { $$ = make_str("sqlwarning"); }
6273                 | SQL_STOP                                      { $$ = make_str("stop"); }
6274                 ;
6275
6276 ECPGKeywords_rest:  SQL_CONNECT         { $$ = make_str("connect"); }
6277                 | SQL_DESCRIBE                          { $$ = make_str("describe"); }
6278                 | SQL_DISCONNECT                        { $$ = make_str("disconnect"); }
6279                 | SQL_OPEN                                      { $$ = make_str("open"); }
6280                 | SQL_VAR                                       { $$ = make_str("var"); }
6281                 | SQL_WHENEVER                          { $$ = make_str("whenever"); }
6282                 ;
6283
6284 /* additional keywords that can be SQL type names (but not ECPGColLabels) */
6285 ECPGTypeName:  SQL_BOOL                         { $$ = make_str("bool"); }
6286                 | SQL_LONG                                      { $$ = make_str("long"); }
6287                 | SQL_OUTPUT                            { $$ = make_str("output"); }
6288                 | SQL_SHORT                                     { $$ = make_str("short"); }
6289                 | SQL_STRUCT                            { $$ = make_str("struct"); }
6290                 | SQL_SIGNED                            { $$ = make_str("signed"); }
6291                 | SQL_UNSIGNED                          { $$ = make_str("unsigned"); }
6292                 ;
6293
6294 symbol: ColLabel                                        { $$ = $1; }
6295                 ;
6296
6297 /*
6298  * Name classification hierarchy.
6299  *
6300  * IDENT is the lexeme returned by the lexer for identifiers that match
6301  * no known keyword.  In most cases, we can accept certain keywords as
6302  * names, not only IDENTs.      We prefer to accept as many such keywords
6303  * as possible to minimize the impact of "reserved words" on programmers.
6304  * So, we divide names into several possible classes.  The classification
6305  * is chosen in part to make keywords acceptable as names wherever possible.
6306  */
6307
6308 ECPGColId:ident                                 { $$ = $1; }
6309                 | ECPGunreserved_interval       { $$ = $1; }
6310                 | ECPGunreserved_con            { $$ = $1; }
6311                 | col_name_keyword              { $$ = $1; }
6312                 | ECPGKeywords                  { $$ = $1; }
6313                 | ECPGCKeywords                 { $$ = $1; }
6314                 | CHAR_P                        { $$ = make_str("char"); }
6315                 | VALUES                        { $$ = make_str("values"); }
6316                 ;
6317 /* Column identifier --- names that can be column, table, etc names.
6318  */
6319 ColId:  ident                                   { $$ = $1; }
6320                 | unreserved_keyword            { $$ = $1; }
6321                 | col_name_keyword              { $$ = $1; }
6322                 | ECPGKeywords                  { $$ = $1; }
6323                 | ECPGCKeywords                 { $$ = $1; }
6324                 | CHAR_P                        { $$ = make_str("char"); }
6325                 | VALUES                        { $$ = make_str("values"); }
6326                 ;
6327 /* Type/function identifier --- names that can be type names.
6328  */
6329 type_function_name:     ident                                   { $$ = $1; }
6330                 | unreserved_keyword            { $$ = $1; }
6331                 | type_func_name_keyword                { $$ = $1; }
6332                 | ECPGKeywords                          { $$ = $1; }
6333                 | ECPGTypeName                          { $$ = $1; }
6334                 | ECPGCKeywords                         { $$ = $1; }
6335                 ;
6336
6337 /* Column label --- allowed labels in "AS" clauses.
6338  * This presently includes *all* Postgres keywords.
6339  */
6340 ColLabel:  ECPGColLabel                         { $$ = $1; }
6341                 | ECPGTypeName                  { $$ = $1; }
6342                 | CHAR_P                        { $$ = make_str("char"); }
6343                 | INPUT_P                       { $$ = make_str("input"); }
6344                 | INT_P                         { $$ = make_str("int"); }
6345                 | UNION                         { $$ = make_str("union"); }
6346                 | TO                            { $$ = make_str("to"); }
6347                 | ECPGCKeywords                 { $$ = $1; }
6348                 | ECPGunreserved_interval       { $$ = $1; }
6349                 ;
6350
6351 ECPGColLabelCommon:  ident                      { $$ = $1; }
6352                 | col_name_keyword              { $$ = $1; }
6353                 | type_func_name_keyword        { $$ = $1; }
6354                 | ECPGKeywords_vanames          { $$ = $1; }
6355                 ;
6356
6357 ECPGColLabel:  ECPGColLabelCommon       { $$ = $1; }
6358                 | reserved_keyword              { $$ = $1; }
6359                 | ECPGunreserved                { $$ = $1; }
6360                 | ECPGKeywords_rest             { $$ = $1; }
6361                 ;
6362
6363 ECPGCKeywords: S_AUTO                   { $$ = make_str("auto"); }
6364                 | S_CONST                               { $$ = make_str("const"); }
6365                 | S_EXTERN                              { $$ = make_str("extern"); }
6366                 | S_REGISTER                    { $$ = make_str("register"); }
6367                 | S_STATIC                              { $$ = make_str("static"); }
6368                 | S_TYPEDEF                             { $$ = make_str("typedef"); }
6369                 | S_VOLATILE                    { $$ = make_str("volatile"); }
6370                 ;
6371
6372 /*
6373  * Keyword classification lists.  Generally, every keyword present in
6374  * the Postgres grammar should appear in exactly one of these lists.
6375  *
6376  * Put a new keyword into the first list that it can go into without causing
6377  * shift or reduce conflicts.  The earlier lists define "less reserved"
6378  * categories of keywords.
6379  */
6380
6381 /* "Unreserved" keywords --- available for use as any kind of name.
6382  */
6383 /* The following symbols must be excluded from ECPGColLabel and directly included into ColLabel
6384    to enable C variables to get names from ECPGColLabel:
6385    DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P
6386  */
6387 unreserved_keyword: ECPGunreserved_interval | ECPGunreserved;
6388
6389 ECPGunreserved_interval: DAY_P                  { $$ = make_str("day"); }
6390                 | HOUR_P                        { $$ = make_str("hour"); }
6391                 | MINUTE_P                      { $$ = make_str("minute"); }
6392                 | MONTH_P                       { $$ = make_str("month"); }
6393                 | SECOND_P                      { $$ = make_str("second"); }
6394                 | YEAR_P                        { $$ = make_str("year"); }
6395                 ;
6396
6397 /* The following symbol must be excluded from var_name but still included in ColId
6398    to enable ecpg special postgresql variables with this name:  CONNECTION
6399  */
6400 ECPGunreserved: ECPGunreserved_con              { $$ = $1; }
6401                 | CONNECTION                    { $$ = make_str("connection"); }
6402                 ;
6403
6404 ECPGunreserved_con:       ABORT_P                       { $$ = make_str("abort"); }
6405                 | ABSOLUTE_P            { $$ = make_str("absolute"); }
6406                 | ACCESS                        { $$ = make_str("access"); }
6407                 | ACTION                        { $$ = make_str("action"); }
6408                 | ADD_P                         { $$ = make_str("add"); }
6409                 | ADMIN                         { $$ = make_str("admin"); }
6410                 | AFTER                         { $$ = make_str("after"); }
6411                 | AGGREGATE                     { $$ = make_str("aggregate"); }
6412                 | ALSO                          { $$ = make_str("also"); }
6413                 | ALTER                         { $$ = make_str("alter"); }
6414                 | ALWAYS                        { $$ = make_str("always"); }
6415                 | ASSERTION                     { $$ = make_str("assertion"); }
6416                 | ASSIGNMENT            { $$ = make_str("assignment"); }
6417                 | AT                            { $$ = make_str("at"); }
6418                 | BACKWARD                      { $$ = make_str("backward"); }
6419                 | BEFORE                        { $$ = make_str("before"); }
6420                 | BEGIN_P                       { $$ = make_str("begin"); }
6421                 | BY                            { $$ = make_str("by"); }
6422                 | CACHE                         { $$ = make_str("cache"); }
6423                 | CASCADE                       { $$ = make_str("cascade"); }
6424                 | CASCADED                      { $$ = make_str("cascaded"); }
6425                 | CHAIN                         { $$ = make_str("chain"); }
6426                 | CHARACTERISTICS       { $$ = make_str("characteristics"); }
6427                 | CHECKPOINT            { $$ = make_str("checkpoint"); }
6428                 | CLASS                         { $$ = make_str("class"); }
6429                 | CLOSE                         { $$ = make_str("close"); }
6430                 | CLUSTER                       { $$ = make_str("cluster"); }
6431                 | COMMENT                       { $$ = make_str("comment"); }
6432                 | COMMIT                        { $$ = make_str("commit"); }
6433                 | COMMITTED                     { $$ = make_str("committed"); }
6434                 | CONCURRENTLY          { $$ = make_str("concurrently"); }
6435                 | CONFIGURATION         { $$ = make_str("configuration"); }
6436 /*              | CONNECTION            { $$ = make_str("connection"); }*/
6437                 | CONSTRAINTS           { $$ = make_str("constraints"); }
6438                 | CONTENT_P             { $$ = make_str("content"); }
6439                 | CONVERSION_P          { $$ = make_str("conversion"); }
6440                 | COPY                          { $$ = make_str("copy"); }
6441                 | COST                          { $$ = make_str("cost"); }
6442                 | CREATEDB                      { $$ = make_str("createdb"); }
6443                 | CREATEROLE            { $$ = make_str("createrole"); }
6444                 | CREATEUSER            { $$ = make_str("createuser"); }
6445                 | CSV                           { $$ = make_str("csv"); }
6446                 | CURSOR                        { $$ = make_str("cursor"); }
6447                 | CYCLE                         { $$ = make_str("cycle"); }
6448                 | DATABASE                      { $$ = make_str("database"); }
6449 /*              | DAY_P                         { $$ = make_str("day"); }*/
6450                 | DEALLOCATE            { $$ = make_str("deallocate"); }
6451                 | DECLARE                       { $$ = make_str("declare"); }
6452                 | DEFAULTS                      { $$ = make_str("defaults"); }
6453                 | DEFERRED                      { $$ = make_str("deferred"); }
6454                 | DELETE_P                      { $$ = make_str("delete"); }
6455                 | DELIMITER                     { $$ = make_str("delimiter"); }
6456                 | DELIMITERS            { $$ = make_str("delimiters"); }
6457                 | DICTIONARY            { $$ = make_str("dictionary"); }
6458                 | DISABLE_P                     { $$ = make_str("disable"); }
6459                 | DISCARD                       { $$ = make_str("discard"); }
6460                 | DOCUMENT_P                    { $$ = make_str("document"); }
6461                 | DOMAIN_P                      { $$ = make_str("domain"); }
6462                 | DOUBLE_P                      { $$ = make_str("double"); }
6463                 | DROP                          { $$ = make_str("drop"); }
6464                 | EACH                          { $$ = make_str("each"); }
6465                 | ENABLE_P                      { $$ = make_str("enable"); }
6466                 | ENCODING                      { $$ = make_str("encoding"); }
6467                 | ENCRYPTED                     { $$ = make_str("encrypted"); }
6468 /*              | ENUM_P                        { $$ = make_str("enum"); }*/
6469                 | ESCAPE                        { $$ = make_str("escape"); }
6470                 | EXCLUDING                     { $$ = make_str("excluding"); }
6471                 | EXCLUSIVE                     { $$ = make_str("exclusive"); }
6472                 | EXECUTE                       { $$ = make_str("execute"); }
6473                 | EXPLAIN                       { $$ = make_str("explain"); }
6474                 | EXTERNAL                      { $$ = make_str("external"); }
6475                 | FAMILY                        { $$ = make_str("family"); }
6476                 | FETCH                         { $$ = make_str("fetch"); }
6477                 | FIRST_P                       { $$ = make_str("first"); }
6478                 | FORCE                         { $$ = make_str("force"); }
6479                 | FORWARD                       { $$ = make_str("forward"); }
6480                 | FUNCTION                      { $$ = make_str("function"); }
6481                 | GLOBAL                        { $$ = make_str("global"); }
6482                 | GRANTED                       { $$ = make_str("granted"); }
6483                 | HANDLER                       { $$ = make_str("handler"); }
6484                 | HEADER_P                      { $$ = make_str("header"); }
6485                 | HOLD                          { $$ = make_str("hold"); }
6486 /*              | HOUR_P                        { $$ = make_str("hour"); }*/
6487                 | IF_P                          { $$ = make_str("if"); }
6488                 | IMMEDIATE                     { $$ = make_str("immediate"); }
6489                 | IMMUTABLE                     { $$ = make_str("immutable"); }
6490                 | IMPLICIT_P            { $$ = make_str("implicit"); }
6491                 | INCLUDING                     { $$ = make_str("including"); }
6492                 | INCREMENT                     { $$ = make_str("increment"); }
6493                 | INDEX                         { $$ = make_str("index"); }
6494                 | INDEXES                       { $$ = make_str("indexes"); }
6495                 | INHERIT                       { $$ = make_str("inherit"); }
6496                 | INHERITS                      { $$ = make_str("inherits"); }
6497                 | INSENSITIVE           { $$ = make_str("insensitive"); }
6498                 | INSERT                        { $$ = make_str("insert"); }
6499                 | INSTEAD                       { $$ = make_str("instead"); }
6500                 | ISOLATION                     { $$ = make_str("isolation"); }
6501                 | KEY                           { $$ = make_str("key"); }
6502                 | LANCOMPILER           { $$ = make_str("lancompiler"); }
6503                 | LANGUAGE                      { $$ = make_str("language"); }
6504                 | LARGE_P                       { $$ = make_str("large"); }
6505                 | LAST_P                        { $$ = make_str("last"); }
6506                 | LEVEL                         { $$ = make_str("level"); }
6507                 | LISTEN                        { $$ = make_str("listen"); }
6508                 | LOAD                          { $$ = make_str("load"); }
6509                 | LOCAL                         { $$ = make_str("local"); }
6510                 | LOCATION                      { $$ = make_str("location"); }
6511                 | LOCK_P                        { $$ = make_str("lock"); }
6512                 | LOGIN_P                       { $$ = make_str("login"); }
6513                 | MAPPING                       { $$ = make_str("mapping"); }
6514                 | MATCH                         { $$ = make_str("match"); }
6515                 | MAXVALUE                      { $$ = make_str("maxvalue"); }
6516 /*              | MINUTE_P                      { $$ = make_str("minute"); }*/
6517                 | MINVALUE                      { $$ = make_str("minvalue"); }
6518                 | MODE                          { $$ = make_str("mode"); }
6519 /*              | MONTH_P                       { $$ = make_str("month"); }*/
6520                 | MOVE                          { $$ = make_str("move"); }
6521                 | NAME_P                        { $$ = make_str("name"); }
6522                 | NAMES                         { $$ = make_str("names"); }
6523                 | NEXT                          { $$ = make_str("next"); }
6524                 | NO                            { $$ = make_str("no"); }
6525                 | NOCREATEDB            { $$ = make_str("nocreatedb"); }
6526                 | NOCREATEROLE          { $$ = make_str("nocreaterole"); }
6527                 | NOCREATEUSER          { $$ = make_str("nocreateuser"); }
6528                 | NOINHERIT                     { $$ = make_str("noinherit"); }
6529                 | NOLOGIN_P             { $$ = make_str("nologin"); }
6530                 | NOSUPERUSER           { $$ = make_str("nosuperuser"); }
6531                 | NOTHING                       { $$ = make_str("nothing"); }
6532                 | NOTIFY                        { $$ = make_str("notify"); }
6533                 | NOWAIT                        { $$ = make_str("nowait"); }
6534                 | NULLS_P                       { $$ = make_str("nulls"); }
6535                 | OBJECT_P                      { $$ = make_str("object"); }
6536                 | OF                            { $$ = make_str("of"); }
6537                 | OIDS                          { $$ = make_str("oids"); }
6538                 | OPERATOR                      { $$ = make_str("operator"); }
6539                 | OPTION                        { $$ = make_str("option"); }
6540                 | OWNED                         { $$ = make_str("owned"); }
6541                 | OWNER                         { $$ = make_str("owner"); }
6542                 | PARSER                        { $$ = make_str("parser"); }
6543                 | PARTIAL                       { $$ = make_str("partial"); }
6544                 | PASSWORD                      { $$ = make_str("password"); }
6545                 | PLANS                         { $$ = make_str("plans"); }
6546                 | PREPARE                       { $$ = make_str("prepare"); }
6547                 | PREPARED                      { $$ = make_str("prepared"); }
6548                 | PRESERVE                      { $$ = make_str("preserver"); }
6549                 | PRIOR                         { $$ = make_str("prior"); }
6550                 | PRIVILEGES            { $$ = make_str("privileges"); }
6551                 | PROCEDURAL            { $$ = make_str("procedural"); }
6552                 | PROCEDURE                     { $$ = make_str("procedure"); }
6553                 | QUOTE                         { $$ = make_str("quote"); }
6554                 | READ                          { $$ = make_str("read"); }
6555                 | REASSIGN                      { $$ = make_str("reassign"); }
6556                 | RECHECK                       { $$ = make_str("recheck"); }
6557                 | REINDEX                       { $$ = make_str("reindex"); }
6558                 | RELATIVE_P            { $$ = make_str("relative"); }
6559                 | RELEASE                       { $$ = make_str("release"); }
6560                 | RENAME                        { $$ = make_str("rename"); }
6561                 | REPEATABLE            { $$ = make_str("repeatable"); }
6562                 | REPLACE                       { $$ = make_str("replace"); }
6563                 | REPLICA                       { $$ = make_str("replica"); }
6564                 | RESET                         { $$ = make_str("reset"); }
6565                 | RESTART                       { $$ = make_str("restart"); }
6566                 | RESTRICT                      { $$ = make_str("restrict"); }
6567                 | RETURNS                       { $$ = make_str("returns"); }
6568                 | REVOKE                        { $$ = make_str("revoke"); }
6569                 | ROLE                          { $$ = make_str("role"); }
6570                 | ROLLBACK                      { $$ = make_str("rollback"); }
6571                 | ROWS                          { $$ = make_str("rows"); }
6572                 | RULE                          { $$ = make_str("rule"); }
6573                 | SAVEPOINT                     { $$ = make_str("savepoint"); }
6574                 | SCHEMA                        { $$ = make_str("schema"); }
6575                 | SCROLL                        { $$ = make_str("scroll"); }
6576                 | SEARCH                        { $$ = make_str("search"); }
6577 /*              | SECOND_P                      { $$ = make_str("second"); }*/
6578                 | SEQUENCE                      { $$ = make_str("sequence"); }
6579                 | SERIALIZABLE          { $$ = make_str("serializable"); }
6580                 | SESSION                       { $$ = make_str("session"); }
6581                 | SET                           { $$ = make_str("set"); }
6582                 | SHARE                         { $$ = make_str("share"); }
6583                 | SHOW                          { $$ = make_str("show"); }
6584                 | SIMPLE                        { $$ = make_str("simple"); }
6585                 | STABLE                        { $$ = make_str("stable"); }
6586                 | STANDALONE_P                  { $$ = make_str("standalone"); }
6587                 | START                         { $$ = make_str("start"); }
6588                 | STATEMENT                     { $$ = make_str("statement"); }
6589                 | STATISTICS            { $$ = make_str("statistics"); }
6590                 | STDIN                         { $$ = make_str("stdin"); }
6591                 | STDOUT                        { $$ = make_str("stdout"); }
6592                 | STORAGE                       { $$ = make_str("storage"); }
6593                 | STRICT_P                      { $$ = make_str("strict"); }
6594                 | STRIP_P                       { $$ = make_str("strip"); }
6595                 | SUPERUSER_P           { $$ = make_str("superuser"); }
6596                 | SYSTEM_P                      { $$ = make_str("system"); }
6597                 | SYSID                         { $$ = make_str("sysid"); }
6598                 | TABLESPACE            { $$ = make_str("tablespace"); }
6599                 | TEMP                          { $$ = make_str("temp"); }
6600                 | TEMPLATE                      { $$ = make_str("template"); }
6601                 | TEMPORARY                     { $$ = make_str("temporary"); }
6602                 | TEXT_P                        { $$ = make_str("text"); }
6603                 | TRANSACTION           { $$ = make_str("transaction"); }
6604                 | TRIGGER                       { $$ = make_str("trigger"); }
6605                 | TRUNCATE                      { $$ = make_str("truncate"); }
6606                 | TRUSTED                       { $$ = make_str("trusted"); }
6607                 | TYPE_P                        { $$ = make_str("type"); }
6608                 | UNCOMMITTED           { $$ = make_str("uncommitted"); }
6609                 | UNENCRYPTED           { $$ = make_str("unencrypted"); }
6610                 | UNKNOWN                       { $$ = make_str("unknown"); }
6611                 | UNLISTEN                      { $$ = make_str("unlisten"); }
6612                 | UNTIL                         { $$ = make_str("until"); }
6613                 | UPDATE                        { $$ = make_str("update"); }
6614                 | VACUUM                        { $$ = make_str("vacuum"); }
6615                 | VALID                         { $$ = make_str("valid"); }
6616                 | VALIDATOR                     { $$ = make_str("validator"); }
6617                 | VALUE_P                       { $$ = make_str("value"); }
6618                 | VARYING                       { $$ = make_str("varying"); }
6619                 | VERSION_P                     { $$ = make_str("version"); }
6620                 | VIEW                          { $$ = make_str("view"); }
6621                 | VOLATILE                      { $$ = make_str("volatile"); }
6622                 | WHITESPACE_P                  { $$ = make_str("whitespace"); }
6623                 | WITH                          { $$ = make_str("with"); }
6624                 | WITHOUT                       { $$ = make_str("without"); }
6625                 | WORK                          { $$ = make_str("work"); }
6626                 | WRITE                         { $$ = make_str("write"); }
6627                 | XML_P                         { $$ = make_str("xml"); }
6628                 | YES_P                         { $$ = make_str("yes"); }
6629 /*              | YEAR_P                        { $$ = make_str("year"); }*/
6630                 | ZONE                          { $$ = make_str("zone"); }
6631                 ;
6632
6633 /* Column identifier --- keywords that can be column, table, etc names.
6634  *
6635  * Many of these keywords will in fact be recognized as type or function
6636  * names too; but they have special productions for the purpose, and so
6637  * can't be treated as "generic" type or function names.
6638  *
6639  * The type names appearing here are not usable as function names
6640  * because they can be followed by '(' in typename productions, which
6641  * looks too much like a function call for an LR(1) parser.
6642  */
6643 col_name_keyword:
6644                 BIGINT                  { $$ = make_str("bigint");}
6645                 | BIT                   { $$ = make_str("bit"); }
6646 /* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED
6647                 | CHAR_P                { $$ = make_str("char"); }
6648  */
6649                 | CHARACTER             { $$ = make_str("character"); }
6650                 | COALESCE              { $$ = make_str("coalesce"); }
6651                 | DEC                   { $$ = make_str("dec"); }
6652                 | DECIMAL_P             { $$ = make_str("decimal"); }
6653                 | EXISTS                { $$ = make_str("exists"); }
6654                 | EXTRACT               { $$ = make_str("extract"); }
6655                 | FLOAT_P               { $$ = make_str("float"); }
6656                 | GREATEST              { $$ = make_str("greatest"); }
6657                 | INOUT                 { $$ = make_str("inout"); }
6658 /* INT must be excluded from ECPGColLabel because of conflict
6659                 | INT_P                 { $$ = make_str("int"); }
6660  */
6661                 | INTEGER               { $$ = make_str("integer"); }
6662                 | INTERVAL              { $$ = make_str("interval"); }
6663                 | LEAST                 { $$ = make_str("least"); }
6664                 | NATIONAL              { $$ = make_str("national"); }
6665                 | NCHAR                 { $$ = make_str("nchar"); }
6666                 | NONE                  { $$ = make_str("none"); }
6667                 | NULLIF                { $$ = make_str("nullif"); }
6668                 | NUMERIC               { $$ = make_str("numeric"); }
6669                 | OUT_P                 { $$ = make_str("out"); }
6670                 | OVERLAY               { $$ = make_str("overlay"); }
6671                 | POSITION              { $$ = make_str("position"); }
6672                 | PRECISION             { $$ = make_str("precision"); }
6673                 | REAL                  { $$ = make_str("real"); }
6674                 | ROW                   { $$ = make_str("row"); }
6675                 | SETOF                 { $$ = make_str("setof"); }
6676                 | SMALLINT              { $$ = make_str("smallint"); }
6677                 | SUBSTRING             { $$ = make_str("substring"); }
6678                 | TIME                  { $$ = make_str("time"); }
6679                 | TIMESTAMP             { $$ = make_str("timestamp"); }
6680                 | TREAT                 { $$ = make_str("treat"); }
6681                 | TRIM                  { $$ = make_str("trim"); }
6682                 /* VALUES creates a shift/reduce problem if listed here
6683                 | VALUES                { $$ = make_str("values"); } */
6684                 | VARCHAR               { $$ = make_str("varchar"); }
6685                 | XMLATTRIBUTES         { $$ = make_str("xmlattributes"); }
6686                 | XMLCONCAT             { $$ = make_str("xmlconcat"); }
6687                 | XMLELEMENT            { $$ = make_str("xmlelement"); }
6688                 | XMLFOREST             { $$ = make_str("xmlforest"); }
6689                 | XMLPARSE              { $$ = make_str("xmlparse"); }
6690                 | XMLPI                 { $$ = make_str("xmlpi"); }
6691                 | XMLROOT               { $$ = make_str("xmlroot"); }
6692                 | XMLSERIALIZE          { $$ = make_str("xmlserialize"); }
6693                 ;
6694
6695 /* Function identifier --- keywords that can be function names.
6696  *
6697  * Most of these are keywords that are used as operators in expressions;
6698  * in general such keywords can't be column names because they would be
6699  * ambiguous with variables, but they are unambiguous as function identifiers.
6700  *
6701  * Do not include POSITION, SUBSTRING, etc here since they have explicit
6702  * productions in a_expr to support the goofy SQL9x argument syntax.
6703  *      - thomas 2000-11-28
6704  */
6705 type_func_name_keyword:
6706                   AUTHORIZATION         { $$ = make_str("authorization"); }
6707                 | BETWEEN               { $$ = make_str("between"); }
6708                 | BINARY                { $$ = make_str("binary"); }
6709                 | CROSS                 { $$ = make_str("cross"); }
6710                 | FREEZE                { $$ = make_str("freeze"); }
6711                 | FULL                  { $$ = make_str("full"); }
6712                 | ILIKE                 { $$ = make_str("ilike"); }
6713                 | INNER_P               { $$ = make_str("inner"); }
6714                 | IS                    { $$ = make_str("is"); }
6715                 | ISNULL                { $$ = make_str("isnull"); }
6716                 | JOIN                  { $$ = make_str("join"); }
6717                 | LEFT                  { $$ = make_str("left"); }
6718                 | LIKE                  { $$ = make_str("like"); }
6719                 | NATURAL               { $$ = make_str("natural"); }
6720                 | NOTNULL               { $$ = make_str("notnull"); }
6721                 | OUTER_P               { $$ = make_str("outer"); }
6722                 | OVERLAPS              { $$ = make_str("overlaps"); }
6723                 | RIGHT                 { $$ = make_str("right"); }
6724                 | SIMILAR               { $$ = make_str("similar"); }
6725                 | VERBOSE               { $$ = make_str("verbose"); }
6726                 ;
6727
6728 /* Reserved keyword --- these keywords are usable only as a ColLabel.
6729  *
6730  * Keywords appear here if they could not be distinguished from variable,
6731  * type, or function names in some contexts.  Don't put things here unless
6732  * forced to.
6733  */
6734 reserved_keyword:
6735                   ALL                           { $$ = make_str("all"); }
6736                 | ANALYSE                       { $$ = make_str("analyse"); } /* British */
6737                 | ANALYZE                       { $$ = make_str("analyze"); }
6738                 | AND                           { $$ = make_str("and"); }
6739                 | ANY                           { $$ = make_str("any"); }
6740                 | ARRAY                         { $$ = make_str("array"); }
6741                 | AS                            { $$ = make_str("as"); }
6742                 | ASC                           { $$ = make_str("asc"); }
6743                 | ASYMMETRIC            { $$ = make_str("asymmetric"); }
6744                 | BOTH                          { $$ = make_str("both"); }
6745                 | CASE                          { $$ = make_str("case"); }
6746                 | CAST                          { $$ = make_str("cast"); }
6747                 | CHECK                         { $$ = make_str("check"); }
6748                 | COLLATE                       { $$ = make_str("collate"); }
6749                 | COLUMN                        { $$ = make_str("column"); }
6750                 | CONSTRAINT            { $$ = make_str("constraint"); }
6751                 | CREATE                        { $$ = make_str("create"); }
6752                 | CURRENT_P                     { $$ = make_str("current"); }
6753                 | CURRENT_DATE          { $$ = make_str("current_date"); }
6754                 | CURRENT_TIME          { $$ = make_str("current_time"); }
6755                 | CURRENT_TIMESTAMP     { $$ = make_str("current_timestamp"); }
6756                 | CURRENT_ROLE          { $$ = make_str("current_role"); }
6757                 | CURRENT_USER          { $$ = make_str("current_user"); }
6758                 | DEFAULT                       { $$ = make_str("default"); }
6759                 | DEFERRABLE            { $$ = make_str("deferrable"); }
6760                 | DESC                          { $$ = make_str("desc"); }
6761                 | DISTINCT                      { $$ = make_str("distinct"); }
6762                 | DO                            { $$ = make_str("do"); }
6763                 | ELSE                          { $$ = make_str("else"); }
6764                 | END_P                         { $$ = make_str("end"); }
6765                 | EXCEPT                        { $$ = make_str("except"); }
6766                 | FALSE_P                       { $$ = make_str("false"); }
6767                 | FOR                           { $$ = make_str("for"); }
6768                 | FOREIGN                       { $$ = make_str("foreign"); }
6769                 | FROM                          { $$ = make_str("from"); }
6770                 | GRANT                         { $$ = make_str("grant"); }
6771                 | GROUP_P                       { $$ = make_str("group"); }
6772                 | HAVING                        { $$ = make_str("having"); }
6773                 | IN_P                          { $$ = make_str("in"); }
6774                 | INITIALLY                     { $$ = make_str("initially"); }
6775                 | INTERSECT                     { $$ = make_str("intersect"); }
6776                 | INTO                          { $$ = make_str("into"); }
6777                 | LEADING                       { $$ = make_str("leading"); }
6778                 | LIMIT                         { $$ = make_str("limit"); }
6779                 | NEW                           { $$ = make_str("new"); }
6780                 | NOT                           { $$ = make_str("not"); }
6781                 | NULL_P                        { $$ = make_str("null"); }
6782                 | OFF                           { $$ = make_str("off"); }
6783                 | OFFSET                        { $$ = make_str("offset"); }
6784                 | OLD                           { $$ = make_str("old"); }
6785                 | ON                            { $$ = make_str("on"); }
6786                 | ONLY                          { $$ = make_str("only"); }
6787                 | OR                            { $$ = make_str("or"); }
6788                 | ORDER                         { $$ = make_str("order"); }
6789                 | PRIMARY                       { $$ = make_str("primary"); }
6790                 | REFERENCES                    { $$ = make_str("references"); }
6791                 | RETURNING                     { $$ = make_str("returning"); }
6792                 | SELECT                        { $$ = make_str("select"); }
6793                 | SESSION_USER                  { $$ = make_str("session_user"); }
6794                 | SOME                          { $$ = make_str("some"); }
6795                 | SYMMETRIC                     { $$ = make_str("symmetric"); }
6796                 | TABLE                         { $$ = make_str("table"); }
6797                 | THEN                          { $$ = make_str("then"); }
6798 /* TO must be excluded from ECPGColLabel because of a conflict in variable name parsing
6799                 | TO                            { $$ = make_str("to"); }
6800  */
6801                 | TRAILING                      { $$ = make_str("trailing"); }
6802                 | TRUE_P                        { $$ = make_str("true"); }
6803 /* UNION must be excluded from ECPGColLabel because of conflict with s_union
6804                 | UNION                         { $$ = make_str("union"); }
6805  */
6806                 | UNIQUE                        { $$ = make_str("unique"); }
6807                 | USER                          { $$ = make_str("user"); }
6808                 | USING                         { $$ = make_str("using"); }
6809                 | WHEN                          { $$ = make_str("when"); }
6810                 | WHERE                         { $$ = make_str("where"); }
6811                 ;
6812
6813
6814 into_list : coutputvariable | into_list ',' coutputvariable
6815                 ;
6816
6817 ecpgstart: SQL_START    {
6818                                 reset_variables();
6819                                 pacounter = 1;
6820                         }
6821                 ;
6822
6823 c_args: /*EMPTY*/               { $$ = EMPTY; }
6824                 | c_list                { $$ = $1; }
6825                 ;
6826
6827 coutputvariable: cvariable indicator
6828                         { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
6829                 | cvariable
6830                         { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
6831                 ;
6832
6833
6834 civarind: cvariable indicator
6835                 {
6836                         if (find_variable($2)->type->type == ECPGt_array)
6837                                 mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
6838
6839                         add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
6840                         $$ = create_questionmarks($1, false);
6841                 }
6842                 ;
6843
6844 civar: cvariable
6845                 {
6846                         add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
6847                         $$ = create_questionmarks($1, false);
6848                 }
6849                 ;
6850
6851 indicator: cvariable                            { check_indicator((find_variable($1))->type); $$ = $1; }
6852                 | SQL_INDICATOR cvariable       { check_indicator((find_variable($2))->type); $$ = $2; }
6853                 | SQL_INDICATOR name            { check_indicator((find_variable($2))->type); $$ = $2; }
6854                 ;
6855
6856 cvariable:      CVARIABLE
6857                 {
6858                         /* As long as multidimensional arrays are not implemented we have to check for those here */
6859                         char *ptr = $1;
6860                         int brace_open=0, brace = false;
6861
6862                         for (; *ptr; ptr++)
6863                         {
6864                                 switch (*ptr)
6865                                 {
6866                                         case '[':
6867                                                         if (brace)
6868                                                                 mmerror(PARSE_ERROR, ET_FATAL, "No multidimensional array support for simple data types");
6869                                                         brace_open++;
6870                                                         break;
6871                                         case ']':
6872                                                         brace_open--;
6873                                                         if (brace_open == 0)
6874                                                                 brace = true;
6875                                                         break;
6876                                         case '\t':
6877                                         case ' ':
6878                                                         break;
6879                                         default:
6880                                                         if (brace_open == 0)
6881                                                                 brace = false;
6882                                                         break;
6883                                 }
6884                         }
6885                         $$ = $1;
6886                 }
6887                 ;
6888 ident: IDENT                            { $$ = $1; }
6889                 | CSTRING               { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6890                 ;
6891
6892 quoted_ident_stringvar: name
6893                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6894                 | char_variable
6895                         { $$ = make3_str(make_str("("), $1, make_str(")")); }
6896                 ;
6897
6898 /*
6899  * C stuff
6900  */
6901
6902 c_stuff_item: c_anything                        { $$ = $1; }
6903                 | '(' ')'                       { $$ = make_str("()"); }
6904                 | '(' c_stuff ')'
6905                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
6906                 ;
6907
6908 c_stuff: c_stuff_item                   { $$ = $1; }
6909                 | c_stuff c_stuff_item
6910                         { $$ = cat2_str($1, $2); }
6911                 ;
6912
6913 c_list: c_term                          { $$ = $1; }
6914                 | c_list ',' c_term     { $$ = cat_str(3, $1, make_str(","), $3); }
6915                 ;
6916
6917 c_term:  c_stuff                        { $$ = $1; }
6918                 | '{' c_list '}'        { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
6919                 ;
6920
6921 c_thing:        c_anything              { $$ = $1; }
6922                 |       '('             { $$ = make_str("("); }
6923                 |       ')'             { $$ = make_str(")"); }
6924                 |       ','             { $$ = make_str(","); }
6925                 |       ';'             { $$ = make_str(";"); }
6926                 ;
6927
6928 c_anything:  IDENT                              { $$ = $1; }
6929                 | CSTRING                       { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6930                 | Iconst                        { $$ = $1; }
6931                 | Fconst                        { $$ = $1; }
6932                 | Sconst                        { $$ = $1; }
6933                 | '*'                           { $$ = make_str("*"); }
6934                 | '+'                           { $$ = make_str("+"); }
6935                 | '-'                           { $$ = make_str("-"); }
6936                 | '/'                           { $$ = make_str("/"); }
6937                 | '%'                           { $$ = make_str("%"); }
6938                 | NULL_P                        { $$ = make_str("NULL"); }
6939                 | S_ADD                         { $$ = make_str("+="); }
6940                 | S_AND                         { $$ = make_str("&&"); }
6941                 | S_ANYTHING                    { $$ = make_name(); }
6942                 | S_AUTO                        { $$ = make_str("auto"); }
6943                 | S_CONST                       { $$ = make_str("const"); }
6944                 | S_DEC                         { $$ = make_str("--"); }
6945                 | S_DIV                         { $$ = make_str("/="); }
6946                 | S_DOTPOINT                    { $$ = make_str(".*"); }
6947                 | S_EQUAL                       { $$ = make_str("=="); }
6948                 | S_EXTERN                      { $$ = make_str("extern"); }
6949                 | S_INC                         { $$ = make_str("++"); }
6950                 | S_LSHIFT                      { $$ = make_str("<<"); }
6951                 | S_MEMBER                      { $$ = make_str("->"); }
6952                 | S_MEMPOINT                    { $$ = make_str("->*"); }
6953                 | S_MOD                         { $$ = make_str("%="); }
6954                 | S_MUL                         { $$ = make_str("*="); }
6955                 | S_NEQUAL                      { $$ = make_str("!="); }
6956                 | S_OR                          { $$ = make_str("||"); }
6957                 | S_REGISTER                    { $$ = make_str("register"); }
6958                 | S_RSHIFT                      { $$ = make_str(">>"); }
6959                 | S_STATIC                      { $$ = make_str("static"); }
6960                 | S_SUB                         { $$ = make_str("-="); }
6961                 | S_TYPEDEF                     { $$ = make_str("typedef"); }
6962                 | S_VOLATILE                    { $$ = make_str("volatile"); }
6963                 | SQL_BOOL                      { $$ = make_str("bool"); }
6964                 | ENUM_P                        { $$ = make_str("enum"); }
6965                 | HOUR_P                        { $$ = make_str("hour"); }
6966                 | INT_P                         { $$ = make_str("int"); }
6967                 | SQL_LONG                      { $$ = make_str("long"); }
6968                 | MINUTE_P                      { $$ = make_str("minute"); }
6969                 | MONTH_P                       { $$ = make_str("month"); }
6970                 | SECOND_P                      { $$ = make_str("second"); }
6971                 | SQL_SHORT                     { $$ = make_str("short"); }
6972                 | SQL_SIGNED                    { $$ = make_str("signed"); }
6973                 | SQL_STRUCT                    { $$ = make_str("struct"); }
6974                 | SQL_UNSIGNED                  { $$ = make_str("unsigned"); }
6975                 | YEAR_P                        { $$ = make_str("year"); }
6976                 | CHAR_P                        { $$ = make_str("char"); }
6977                 | FLOAT_P                       { $$ = make_str("float"); }
6978                 | TO                            { $$ = make_str("to"); }
6979                 | UNION                         { $$ = make_str("union"); }
6980                 | VARCHAR                       { $$ = make_str("varchar"); }
6981                 | '['                           { $$ = make_str("["); }
6982                 | ']'                           { $$ = make_str("]"); }
6983                 | '='                           { $$ = make_str("="); }
6984                 | ':'                           { $$ = make_str(":"); }
6985                 ;
6986
6987 %%
6988
6989 void base_yyerror(const char * error)
6990 {
6991         char buf[1024];
6992
6993         snprintf(buf,sizeof buf,"%s at or near \"%s\"", error, token_start ? token_start : yytext);
6994         buf[sizeof(buf)-1]=0;
6995         mmerror(PARSE_ERROR, ET_ERROR, buf);
6996 }
6997
6998 void parser_init(void)
6999 {
7000  /* This function is empty. It only exists for compatibility with the backend parser right now. */
7001 }
7002
7003 /*
7004  * Must undefine base_yylex before including pgc.c, since we want it
7005  * to create the function base_yylex not filtered_base_yylex.
7006  */
7007 #undef base_yylex
7008
7009 #include "pgc.c"