]> granicus.if.org Git - postgresql/blob - src/interfaces/ecpg/preproc/preproc.y
*** empty log message ***
[postgresql] / src / interfaces / ecpg / preproc / preproc.y
1 /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.357 2007/12/28 11:25:21 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, NULL, NULL, {NULL}, 0};
51 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
52
53 struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, {NULL}, 0};
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                 | /* EMPTY */
2028                 {
2029                         $$ = EMPTY;
2030                 }
2031                 ;
2032
2033 ConstraintDeferrabilitySpec: NOT DEFERRABLE
2034                         { $$ = make_str("not deferrable"); }
2035                 | DEFERRABLE
2036                         { $$ = make_str("deferrable"); }
2037                 ;
2038
2039 ConstraintTimeSpec: INITIALLY IMMEDIATE
2040                         { $$ = make_str("initially immediate"); }
2041                 | INITIALLY DEFERRED
2042                         { $$ = make_str("initially deferred"); }
2043                 ;
2044
2045 DropTrigStmt:  DROP TRIGGER name ON qualified_name opt_drop_behavior
2046                         { $$ = cat_str(5, make_str("drop trigger"), $3, make_str("on"), $5, $6); }
2047                 | DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
2048                         { $$ = cat_str(5, make_str("drop trigger if exists"), $5, make_str("on"), $7, $8); }
2049                 ;
2050
2051 /*****************************************************************************
2052  *
2053  *             QUERIES :
2054  *                             CREATE ASSERTION ...
2055  *                             DROP ASSERTION ...
2056  *
2057  *****************************************************************************/
2058 CreateAssertStmt:  CREATE ASSERTION name
2059                 CHECK '(' a_expr ')' ConstraintAttributeSpec
2060                 {
2061                         mmerror(PARSE_ERROR, ET_ERROR, "CREATE ASSERTION is not yet supported");
2062                         $$ = cat_str(6, make_str("create assertion"), $3, make_str("check ("), $6, make_str(")"), $8);
2063                 }
2064                 ;
2065
2066 DropAssertStmt:  DROP ASSERTION name
2067                 {
2068                         mmerror(PARSE_ERROR, ET_ERROR, "DROP ASSERTION is not yet supported");
2069                         $$ = cat2_str(make_str("drop assertion"), $3);
2070                 }
2071                 ;
2072
2073
2074 /*****************************************************************************
2075  *
2076  *              QUERY :
2077  *                              define (type,operator,aggregate)
2078  *
2079  *****************************************************************************/
2080
2081 DefineStmt:  CREATE AGGREGATE func_name aggr_args definition
2082                         { $$ = cat_str(4, make_str("create aggregate"), $3, $4, $5); }
2083                 | CREATE AGGREGATE func_name old_aggr_definition
2084                         { $$ = cat_str(3, make_str("create aggregate"), $3, $4); }
2085                 | CREATE OPERATOR all_Op definition
2086                         { $$ = cat_str(3, make_str("create operator"), $3, $4); }
2087                 | CREATE TYPE_P any_name definition
2088                         { $$ = cat_str(3, make_str("create type"), $3, $4); }
2089                 | CREATE TYPE_P any_name
2090                         { $$ = cat2_str(make_str("create type"), $3); }
2091                 | CREATE TYPE_P any_name AS '(' TableFuncElementList ')'
2092                         { $$ = cat_str(5, make_str("create type"), $3, make_str("as ("), $6, make_str(")")); }
2093                 | CREATE TYPE_P any_name AS ENUM_P '(' enum_val_list ')'
2094                         { $$ = cat_str(5, make_str("create type"), $3, make_str("as enum ("), $7, make_str(")")); }
2095                 | CREATE TEXT_P SEARCH PARSER any_name definition
2096                         { $$ = cat_str(3, make_str("create text search parser"), $5, $6); }
2097                 | CREATE TEXT_P SEARCH DICTIONARY any_name definition
2098                         { $$ = cat_str(3, make_str("create text search dictionary"), $5, $6); }
2099                 | CREATE TEXT_P SEARCH TEMPLATE any_name definition
2100                         { $$ = cat_str(3, make_str("create text search template"), $5, $6); }
2101                 | CREATE TEXT_P SEARCH CONFIGURATION any_name definition
2102                         { $$ = cat_str(3, make_str("create text search configuration"), $5, $6); }
2103                 ;
2104
2105 definition:  '(' def_list ')'
2106                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2107                 ;
2108
2109 def_list:  def_elem                                     { $$ = $1; }
2110                 | def_list ',' def_elem         { $$ = cat_str(3, $1, make_str(","), $3); }
2111                 ;
2112
2113 def_elem:  ColLabel '=' def_arg         { $$ = cat_str(3, $1, make_str("="), $3); }
2114                 | ColLabel                                      { $$ = $1; }
2115                 ;
2116
2117 /* Note: any simple identifier will be returned as a type name! */
2118 def_arg:  func_type                             { $$ = $1; }
2119                 | reserved_keyword              { $$ = $1; }
2120                 | qual_all_Op                   { $$ = $1; }
2121                 | AllConst                      { $$ = $1; }
2122                 ;
2123
2124 aggr_args:      '(' type_list ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2125                 | '(' '*' ')'                   { $$ = make_str("(*)"); }
2126                 ;
2127
2128 old_aggr_definition: '(' old_aggr_list ')'      { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2129                 ;
2130
2131 old_aggr_list: old_aggr_elem                            { $$ = $1; }
2132                  | old_aggr_list ',' old_aggr_elem      { $$ = cat_str(3, $1, make_str(","), $3); }
2133                  ;
2134
2135 old_aggr_elem:  ident '=' def_arg       { $$ = cat_str(3, $1, make_str("="), $3); }
2136                 ;
2137
2138 enum_val_list:  StringConst                     { $$ = $1; }
2139                 | enum_val_list ',' StringConst { $$ = cat_str(3, $1, make_str(","), $3);}
2140                 ;
2141
2142 CreateOpClassStmt:      CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
2143                                                 USING access_method opt_opfamily AS opclass_item_list
2144                 {
2145                         $$ = cat_str(10, make_str("create operator class"), $4, $5, make_str("for type"), $8, make_str("using"), $10, $11, make_str("as"), $13);
2146                 }
2147                 ;
2148
2149 opclass_item_list:      opclass_item            { $$ = $1; }
2150                 | opclass_item_list ',' opclass_item    { $$ = cat_str(3, $1, make_str(","), $3); }
2151                 ;
2152
2153 opclass_item:   OPERATOR PosIntConst any_operator opt_recheck
2154                         { $$ = cat_str(4, make_str("operator"), $2, $3, $4); }
2155                 | OPERATOR PosIntConst any_operator '(' oper_argtypes ')' opt_recheck
2156                         { $$ =  cat_str(7, make_str("operator"), $2, $3, make_str("("), $5, make_str(")"), $7); }
2157                 | FUNCTION PosIntConst func_name func_args
2158                         { $$ = cat_str(4, make_str("function"), $2, $3, $4); }
2159                 | FUNCTION PosIntConst '(' type_list ')' func_name func_args
2160                         { $$ = cat_str(7, make_str("function"), $2, make_str("("), $4, make_str(")"), $6, $7); }
2161                 | STORAGE Typename
2162                         { $$ = cat2_str(make_str("storage"), $2); }
2163                 ;
2164
2165 opt_default:   DEFAULT  { $$ = make_str("default"); }
2166                 |  /*EMPTY*/    { $$ = EMPTY; }
2167                 ;
2168
2169 opt_opfamily:  FAMILY any_name          { $$ = cat2_str(make_str("family"), $2); }
2170                        | /*EMPTY*/      { $$ = EMPTY; }
2171                ;
2172
2173 opt_recheck:   RECHECK  { $$ = make_str("recheck"); }
2174                 |  /*EMPTY*/    { $$ = EMPTY; }
2175                 ;
2176
2177 CreateOpFamilyStmt: CREATE OPERATOR FAMILY any_name USING access_method
2178                 { $$ = cat_str(4, make_str("create operator family"), $4, make_str("using"), $6); }
2179                 ;
2180
2181 AlterOpFamilyStmt: ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list
2182                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("add"), $8); }
2183                  | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list
2184                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("drop"), $8); }
2185                  ;
2186
2187 opclass_drop_list: opclass_drop                         { $$ = $1; }
2188                 | opclass_drop_list ',' opclass_drop    { $$ = cat_str(3, $1, make_str(","), $3); }
2189                 ;
2190
2191 opclass_drop:
2192                 OPERATOR PosIntConst '(' type_list ')'
2193                         { $$ = cat_str(5, make_str("operator"), $2, make_str("("), $4, make_str(")")); }
2194                 | FUNCTION PosIntConst '(' type_list ')'
2195                         { $$ = cat_str(5, make_str("function"), $2, make_str("("), $4, make_str(")")); }
2196                 ;
2197
2198 DropOpClassStmt: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
2199                         { $$ = cat_str(5,make_str("drop operator class"), $4, make_str("using"), $6, $7); }
2200                 | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
2201                         { $$ = cat_str(5,make_str("drop operator class if exists"), $6, make_str("using"), $8, $9); }
2202                 ;
2203
2204 DropOpFamilyStmt: DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
2205                         { $$ = cat_str(5,make_str("drop operator family"), $4, make_str("using"), $6, $7); }
2206                 | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
2207                         { $$ = cat_str(5,make_str("drop operator family if exists"), $6, make_str("using"), $8, $9); }
2208                 ;
2209
2210 /*****************************************************************************
2211  *
2212  *              QUERY:
2213  *
2214  *              DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ]
2215  *              REASSIGN OWNED BY username [, username ...] TO username
2216  *
2217  *****************************************************************************/
2218 DropOwnedStmt:
2219         DROP OWNED BY name_list opt_drop_behavior
2220                         {$$ = cat_str(3, make_str("drop owned by"), $4, $5); }
2221                 ;
2222
2223 ReassignOwnedStmt:
2224         REASSIGN OWNED BY name_list TO name
2225                         {$$ = cat_str(4, make_str("reassign owned by"), $4, make_str("to"), $6); }
2226                 ;
2227
2228 /*****************************************************************************
2229  *
2230  *              QUERY:
2231  *
2232  *                         DROP itemtype [ IF EXISTS ] itemname [, itemname ...] [ RESTRICT | CASCADE ]
2233  *
2234  *****************************************************************************/
2235
2236 DropStmt:  DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
2237                         { $$ = cat_str(5, make_str("drop"), $2, make_str("if exists"), $5, $6); }
2238                 | DROP drop_type any_name_list opt_drop_behavior
2239                         { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
2240                 ;
2241
2242 drop_type:      TABLE                           { $$ = make_str("table"); }
2243                 | SEQUENCE                      { $$ = make_str("sequence"); }
2244                 | VIEW                          { $$ = make_str("view"); }
2245                 | INDEX                         { $$ = make_str("index"); }
2246                 | TYPE_P                        { $$ = make_str("type"); }
2247                 | DOMAIN_P                      { $$ = make_str("domain"); }
2248                 | CONVERSION_P                  { $$ = make_str("conversion"); }
2249                 | SCHEMA                        { $$ = make_str("schema"); }
2250                 | TEXT_P SEARCH PARSER          { $$ = make_str("text search parser"); }
2251                 | TEXT_P SEARCH DICTIONARY      { $$ = make_str("text search dictionary"); }
2252                 | TEXT_P SEARCH TEMPLATE        { $$ = make_str("text search template"); }
2253                 | TEXT_P SEARCH CONFIGURATION   { $$ = make_str("text search configuration"); }
2254                 ;
2255
2256 any_name_list:  any_name
2257                         { $$ = $1; }
2258                 | any_name_list ',' any_name
2259                         { $$ = cat_str(3, $1, make_str(","), $3); }
2260                 ;
2261
2262 any_name: ColId        { $$ = $1; }
2263                 | ColId attrs  { $$ = cat2_str($1, $2); }
2264                 ;
2265
2266 attrs: '.' attr_name            { $$ = cat2_str(make_str("."), $2); }
2267                 | attrs '.' attr_name   { $$ = cat_str(3, $1, make_str("."), $3); }
2268                 ;
2269
2270 /*****************************************************************************
2271  *
2272  *                         QUERY:
2273  *                                 truncate table relname1, relname2, ....
2274  *
2275  *****************************************************************************/
2276 TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_drop_behavior
2277                         { $$ = cat_str(4, make_str("truncate table"), $2, $3, $4); }
2278                 ;
2279
2280 /*****************************************************************************
2281  *
2282  *              QUERY:
2283  *                      fetch/move
2284  *
2285  *****************************************************************************/
2286
2287 /* This is different from the backend as we try to be compatible with many other
2288  * embedded SQL implementations. So we accept their syntax as well and
2289  * translate it to the PGSQL syntax. */
2290
2291 FetchStmt: FETCH fetch_direction from_in name ecpg_into
2292                         {
2293                                 add_additional_variables($4, false);
2294                                 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
2295                         }
2296                 | FETCH fetch_direction name ecpg_into
2297                         {
2298                                 add_additional_variables($3, false);
2299                                 $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
2300                         }
2301                 | FETCH from_in name ecpg_into
2302                         {
2303                         add_additional_variables($3, false);
2304                                 $$ = cat_str(3, make_str("fetch"), $2, $3);
2305                         }
2306                 | FETCH name ecpg_into
2307                         {
2308                         add_additional_variables($2, false);
2309                                 $$ = cat2_str(make_str("fetch"), $2);
2310                         }
2311                 | FETCH fetch_direction from_in name
2312                         {
2313                         add_additional_variables($4, false);
2314                                 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
2315                         }
2316                 | FETCH fetch_direction name
2317                         {
2318                         add_additional_variables($3, false);
2319                                 $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
2320                         }
2321                 | FETCH from_in name
2322                         {
2323                                 add_additional_variables($3, false);
2324                                 $$ = cat_str(3, make_str("fetch"), $2, $3);
2325                         }
2326                 | FETCH name
2327                         {
2328                         add_additional_variables($2, false);
2329                                 $$ = cat2_str(make_str("fetch"), $2);
2330                         }
2331                 | MOVE fetch_direction from_in name
2332                         { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
2333                 | MOVE name
2334                         { $$ = cat2_str(make_str("move"), $2); }
2335                 ;
2336
2337 fetch_direction:  NEXT                  { $$ = make_str("next"); }
2338                 | PRIOR                 { $$ = make_str("prior"); }
2339                 | FIRST_P               { $$ = make_str("first"); }
2340                 | LAST_P                { $$ = make_str("last"); }
2341                 | ABSOLUTE_P IntConst   { 
2342                                           if ($2[1] == '$')
2343                                                  mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2344                                           else
2345                                                 $$ = cat2_str(make_str("absolute"), $2);
2346                                         }
2347                 | RELATIVE_P IntConst   { 
2348                                           if ($2[1] == '$')
2349                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2350                                           else
2351                                                 $$ = cat2_str(make_str("relative"), $2);
2352                                         }
2353                 | IntConst              {  
2354                                           if ($1[1] == '$')
2355                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2356                                           else
2357                                                 $$ = $1;
2358                                         }
2359                 | ALL                   { $$ = make_str("all"); }
2360                 | FORWARD               { $$ = make_str("forward"); }
2361                 | FORWARD IntConst      {  
2362                                           if ($2[1] == '$')
2363                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2364                                           else
2365                                                 $$ = cat2_str(make_str("forward"), $2);
2366                                         }
2367                 | FORWARD ALL           { $$ = make_str("forward all"); }
2368                 | BACKWARD              { $$ = make_str("backward"); }
2369                 | BACKWARD IntConst     {  
2370                                           if ($2[1] == '$')
2371                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2372                                           else
2373                                                 $$ = cat2_str(make_str("backward"), $2);
2374                                         }
2375                 | BACKWARD ALL          { $$ = make_str("backward all"); }
2376                 ;
2377
2378 from_in: IN_P                   { $$ = make_str("in"); }
2379                 | FROM                  { $$ = make_str("from"); }
2380                 ;
2381
2382 CommentStmt:   COMMENT ON comment_type name IS comment_text
2383                         { $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6); }
2384                 | COMMENT ON AGGREGATE func_name aggr_args IS comment_text
2385                         { $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7); }
2386                 | COMMENT ON FUNCTION func_name func_args IS comment_text
2387                         { $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7); }
2388                 | COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
2389                         { $$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9); }
2390                 | COMMENT ON TRIGGER name ON any_name IS comment_text
2391                         { $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8); }
2392                 | COMMENT ON RULE name ON any_name IS comment_text
2393                         { $$ = cat_str(6, make_str("comment on rule"), $4, make_str("on"), $6, make_str("is"), $8); }
2394                 | COMMENT ON RULE name IS comment_text
2395                         { $$ = cat_str(4, make_str("comment on rule"), $4, make_str("is"), $6); }
2396                 | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text
2397                         { $$ = cat_str(6, make_str("comment on operator class"), $5, make_str("using"), $7, make_str("is"), $9); }
2398                 | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text
2399                         { $$ = cat_str(6, make_str("comment on operator family"), $5, make_str("using"), $7, make_str("is"), $9); }
2400                 | COMMENT ON LARGE_P OBJECT_P NumConst IS comment_text
2401                         { $$ = cat_str(4, make_str("comment on large object"), $5, make_str("is"), $7); }
2402                 | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text
2403                         { $$ = cat_str(6, make_str("comment on cast ("), $5, make_str("as"), $7, make_str(") is"), $10); }
2404                 | COMMENT ON opt_procedural LANGUAGE any_name IS comment_text
2405                         { $$ = cat_str(6, make_str("comment on"), $3, make_str("language"), $5, make_str("is"), $7); }
2406                 | COMMENT ON TEXT_P SEARCH PARSER any_name IS comment_text
2407                         { $$ = cat_str(4, make_str("comment on test search parser"), $6, make_str("is"), $8); }
2408                 | COMMENT ON TEXT_P SEARCH DICTIONARY any_name IS comment_text
2409                         { $$ = cat_str(4, make_str("comment on test search dictionary"), $6, make_str("is"), $8); }
2410                 | COMMENT ON TEXT_P SEARCH TEMPLATE any_name IS comment_text
2411                         { $$ = cat_str(4, make_str("comment on test search template"), $6, make_str("is"), $8); }
2412                 | COMMENT ON TEXT_P SEARCH CONFIGURATION any_name IS comment_text
2413                         { $$ = cat_str(4, make_str("comment on test search configuration"), $6, make_str("is"), $8); }
2414                 ;
2415
2416 comment_type:  COLUMN           { $$ = make_str("column"); }
2417                 | DATABASE                      { $$ = make_str("database"); }
2418                 | SCHEMA                        { $$ = make_str("schema"); }
2419                 | INDEX                         { $$ = make_str("idnex"); }
2420                 | SEQUENCE                      { $$ = make_str("sequence"); }
2421                 | TABLE                         { $$ = make_str("table"); }
2422                 | DOMAIN_P                      { $$ = make_str("domain"); }
2423                 | TYPE_P                        { $$ = make_str("type"); }
2424                 | VIEW                          { $$ = make_str("view"); }
2425                 | CONVERSION_P                  { $$ = make_str("conversion"); }
2426                 | TABLESPACE                    { $$ = make_str("tablespace"); }
2427                 | ROLE                          { $$ = make_str("role"); }
2428                 ;
2429
2430 comment_text:   StringConst { $$ = $1; }
2431                 | NULL_P                        { $$ = make_str("null"); }
2432                 ;
2433
2434 /*****************************************************************************
2435  *
2436  *              QUERY:
2437  * GRANT and REVOKE statements
2438  *
2439  *****************************************************************************/
2440
2441 GrantStmt:      GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
2442                         { $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6, $7); }
2443                 ;
2444
2445 RevokeStmt:  REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior
2446                         {$$ = cat_str(7, make_str("revoke"), $2, make_str("on"), $4, make_str("from"), $6, $7); }
2447                 | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior
2448                         {$$ = cat_str(7, make_str("revoke grant option for"), $5, make_str("on"), $7, make_str("from"), $9, $10); }
2449                 ;
2450
2451 privileges:  ALL PRIVILEGES             { $$ = make_str("all privileges"); }
2452                 | ALL                                   { $$ = make_str("all"); }
2453                 | privilege_list                { $$ = $1; }
2454                 ;
2455
2456 privilege_list:  privilege
2457                         { $$ = $1; }
2458                 | privilege_list ',' privilege
2459                         { $$ = cat_str(3, $1, make_str(","), $3); }
2460                 ;
2461
2462 privilege:      SELECT                  { $$ = make_str("select"); }
2463                 | REFERENCES            { $$ = make_str("references"); }
2464                 | CREATE                        { $$ = make_str("create"); }
2465                 | ColId                         { $$ = $1; }
2466                 ;
2467
2468 privilege_target: qualified_name_list
2469                         { $$ = $1; }
2470                 | TABLE qualified_name_list
2471                         { $$ = cat2_str(make_str("table"), $2); }
2472                 | SEQUENCE qualified_name_list
2473                         { $$ = cat2_str(make_str("sequence"), $2); }
2474                 | FUNCTION function_with_argtypes_list
2475                         { $$ = cat2_str(make_str("function"), $2); }
2476                 | DATABASE name_list
2477                         { $$ = cat2_str(make_str("database"), $2); }
2478                 | LANGUAGE name_list
2479                         { $$ = cat2_str(make_str("language") , $2); }
2480                 | SCHEMA name_list
2481                         { $$ = cat2_str(make_str("schema") , $2); }
2482                 | TABLESPACE name_list
2483                         { $$ = cat2_str(make_str("tablespace") , $2); }
2484                 ;
2485
2486 grantee_list: grantee
2487                         { $$ = $1; }
2488                 | grantee_list ',' grantee
2489                         { $$ = cat_str(3, $1, make_str(","), $3); }
2490                 ;
2491
2492 grantee:  RoleId                        { $$ = $1; }
2493                 | GROUP_P RoleId        { $$ = cat2_str(make_str("group"), $2); }
2494                 ;
2495
2496 opt_grant_grant_option:  WITH GRANT OPTION
2497                 {
2498                         mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
2499                         $$ = make_str("with grant option");
2500                 }
2501                 | /*EMPTY*/             { $$ = EMPTY; }
2502                 ;
2503
2504 function_with_argtypes_list: function_with_argtypes
2505                         { $$ = $1; }
2506                 | function_with_argtypes_list ',' function_with_argtypes
2507                         { $$ = cat_str(3, $1, make_str(","), $3); }
2508                 ;
2509
2510 function_with_argtypes: func_name func_args { $$ = cat2_str($1, $2); };
2511
2512 /*****************************************************************************
2513  *
2514  * GRANT and REVOKE ROLE statements
2515  *
2516  *****************************************************************************/
2517
2518 GrantRoleStmt:
2519                 GRANT privilege_list TO name_list opt_grant_admin_option opt_granted_by
2520                         { $$ = cat_str(6, make_str("grant"), $2, make_str("to"), $4, $5, $6); }
2521                 ;
2522
2523 RevokeRoleStmt:
2524                 REVOKE privilege_list FROM name_list opt_granted_by opt_drop_behavior
2525                         { $$ = cat_str(6, make_str("revoke"), $2, make_str("from"), $4, $5, $6); }
2526                 ;
2527
2528 opt_grant_admin_option: WITH ADMIN OPTION       { $$ = make_str("with admin option"); }
2529                 | /*EMPTY*/                     { $$ = EMPTY; }
2530                 ;
2531
2532 opt_granted_by: GRANTED BY RoleId        { $$ = cat2_str(make_str("granted by"), $3); }
2533                 | /*EMPTY*/              { $$ = EMPTY; }
2534                 ;
2535
2536 /*****************************************************************************
2537  *
2538  *              QUERY:
2539  *             QUERY: CREATE INDEX
2540  *
2541  * Note: we can't factor CONCURRENTLY into a separate production without
2542  * making it a reserved word.
2543  *
2544  * Note: we cannot put TABLESPACE clause after WHERE clause unless we are
2545  * willing to make TABLESPACE a fully reserved word.
2546  *
2547  *****************************************************************************/
2548
2549 IndexStmt:      CREATE index_opt_unique INDEX index_name ON qualified_name
2550                                 access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
2551                         { $$ = cat_str(13, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12, $13); }
2552                 | CREATE index_opt_unique INDEX CONCURRENTLY index_name ON qualified_name
2553                                 access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
2554                         { $$ = 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); }
2555                 ;
2556
2557 index_opt_unique:  UNIQUE       { $$ = make_str("unique"); }
2558                 | /*EMPTY*/             { $$ = EMPTY; }
2559                 ;
2560
2561 access_method_clause:  USING access_method
2562                         { $$ = cat2_str(make_str("using"), $2); }
2563                 | /*EMPTY*/
2564                         { $$ = EMPTY; }
2565                 ;
2566
2567 index_params:  index_elem                       { $$ = $1; }
2568                 | index_params ',' index_elem   { $$ = cat_str(3, $1, make_str(","), $3); }
2569                 ;
2570
2571 index_elem:  ColId opt_class opt_asc_desc opt_nulls_order
2572                         { $$ = cat_str(4, $1, $2, $3, $4); }
2573                 | func_expr opt_class opt_asc_desc opt_nulls_order
2574                         { $$ = cat_str(4, $1, $2, $3, $4); }
2575                 | '(' a_expr ')' opt_class opt_asc_desc opt_nulls_order
2576                         { $$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6); }
2577                 ;
2578
2579 opt_class:      any_name        { $$ = $1; }
2580                 | USING any_name        { $$ = cat2_str(make_str("using"), $2); }
2581                 | /*EMPTY*/             { $$ = EMPTY; }
2582                 ;
2583
2584 opt_asc_desc:   ASC             { $$ = make_str("asc"); }
2585                 | DESC          { $$ = make_str("desc"); } 
2586                 | /*EMPTY*/     { $$ = EMPTY; }
2587                 ;
2588
2589 opt_nulls_order:        NULLS_FIRST             { $$ = make_str("nulls first"); }
2590                         | NULLS_LAST            { $$ = make_str("nulls last"); } 
2591                         | /*EMPTY*/     { $$ = EMPTY; }
2592                         ;
2593
2594 CreateFunctionStmt:     CREATE opt_or_replace FUNCTION func_name func_args
2595                                         RETURNS func_return createfunc_opt_list opt_definition
2596                         { $$ = cat_str(8, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, $8); }
2597                 | CREATE opt_or_replace FUNCTION func_name func_args
2598                                         createfunc_opt_list opt_definition
2599                         { $$ = cat_str(6, make_str("create"), $2, make_str("function"), $4, $5, $6, $7); }
2600                 ;
2601
2602 opt_or_replace:  OR REPLACE             { $$ = make_str("or replace"); }
2603                 | /*EMPTY*/                             { $$ = EMPTY; }
2604                 ;
2605
2606 func_args:      '(' func_args_list ')'
2607                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2608                 | '(' ')'
2609                         { $$ = make_str("()"); }
2610                 ;
2611
2612 func_args_list:  func_arg
2613                         { $$ = $1; }
2614                 | func_args_list ',' func_arg
2615                         { $$ = cat_str(3, $1, make_str(","), $3); }
2616                 ;
2617
2618 func_arg:  arg_class param_name func_type               { $$ = cat_str(3, $1, $2, $3); }
2619                 | param_name arg_class func_type        { $$ = cat_str(3, $1, $2, $3); }
2620                 | param_name func_type                  { $$ = cat2_str($1, $2); }
2621                 | arg_class func_type                   { $$ = cat2_str($1, $2); }
2622                 | func_type                             { $$ = $1; }
2623                 ;
2624
2625 arg_class:  IN_P                { $$ = make_str("in"); }
2626                 | OUT_P         { $$ = make_str("out"); }
2627                 | INOUT         { $$ = make_str("inout"); }
2628                 | IN_P OUT_P    { $$ = make_str("in out"); }
2629                 ;
2630
2631 func_as: StringConst
2632                         { $$ = $1; }
2633                 | StringConst ',' StringConst
2634                         { $$ = cat_str(3, $1, make_str(","), $3); }
2635                 ;
2636
2637 param_name:    type_function_name       { $$ = $1; };
2638
2639 func_return:  func_type
2640                 {
2641                         /* We can catch over-specified arguments here if we want to,
2642                          * but for now better to silently swallow typmod, etc.
2643                          * - thomas 2000-03-22
2644                          */
2645                         $$ = $1;
2646                 }
2647                 ;
2648
2649 func_type:      Typename
2650                         { $$ = $1; }
2651                 | type_function_name attrs '%' TYPE_P
2652                         { $$ = cat_str(3, $1, $2, make_str("% type")); }
2653                 | SETOF type_function_name attrs '%' TYPE_P
2654                         { $$ = cat_str(4, make_str("setof"), $2, $3, make_str("% type")); }
2655                 ;
2656
2657
2658 createfunc_opt_list: createfunc_opt_item
2659                         { $$ = $1; }
2660                 | createfunc_opt_list createfunc_opt_item
2661                         { $$ = cat2_str($1, $2); }
2662                 ;
2663
2664 common_func_opt_item:
2665                 CALLED ON NULL_P INPUT_P
2666                                 { $$ = make_str("called on null input"); }
2667                 | RETURNS NULL_P ON NULL_P INPUT_P
2668                                 { $$ = make_str("returns null on null input"); }
2669                 | STRICT_P
2670                                 { $$ = make_str("strict"); }
2671                 | IMMUTABLE
2672                                 { $$ = make_str("immutable"); }
2673                 | STABLE
2674                                 { $$ = make_str("stable"); }
2675                 | VOLATILE
2676                                 { $$ = make_str("volatile"); }
2677                 | EXTERNAL SECURITY DEFINER
2678                                 { $$ = make_str("external security definer"); }
2679                 | EXTERNAL SECURITY INVOKER
2680                                 { $$ = make_str("external security invoker"); }
2681                 | SECURITY DEFINER
2682                                 { $$ = make_str("security definer"); }
2683                 | SECURITY INVOKER
2684                                 { $$ = make_str("security invoker"); }
2685                 | COST NumConst
2686                                 { $$ = cat2_str(make_str("cost"), $2); }
2687                 | ROWS NumConst
2688                                 { $$ = cat2_str(make_str("rows"), $2); }
2689                 | SetResetClause
2690                                 { $$ = $1; }
2691                 ;
2692
2693 createfunc_opt_item: AS func_as
2694                                 { $$ = cat2_str(make_str("as"), $2); }
2695                 | LANGUAGE ColId_or_Sconst
2696                                 { $$ = cat2_str(make_str("language"), $2); }
2697                 | common_func_opt_item
2698                                 { $$ = $1; }
2699                 ;
2700
2701 opt_definition: WITH definition { $$ = cat2_str(make_str("with"), $2); }
2702                 | /*EMPTY*/     { $$ = EMPTY; }
2703                 ;
2704
2705 AlterFunctionStmt:
2706                 ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
2707                         { $$ = cat_str(4, make_str("alter function"), $3, $4, $5); }
2708                 ;
2709
2710 alterfunc_opt_list: common_func_opt_item                        { $$ = $1; }
2711                 | alterfunc_opt_list common_func_opt_item       { $$ = cat2_str($1, $2);}
2712                 ;
2713
2714 opt_restrict:   RESTRICT        { $$ = make_str("restrict"); }
2715                 | /*EMPTY*/       { $$ = EMPTY; }
2716                 ;
2717
2718 /*****************************************************************************
2719  *
2720  *              QUERY:
2721  *
2722  *                         DROP FUNCTION funcname (arg1, arg2, ...)
2723  *                         DROP AGGREGATE (arg1, ...) [ RESTRICT | CASCADE ]
2724  *                         DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
2725  *
2726  *****************************************************************************/
2727
2728 RemoveFuncStmt:  DROP FUNCTION func_name func_args opt_drop_behavior
2729                         { $$ = cat_str(4, make_str("drop function"), $3, $4, $5); }
2730                 | DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
2731                         { $$ = cat_str(4, make_str("drop function if exists"), $5, $6, $7); }
2732                 ;
2733
2734 RemoveAggrStmt:  DROP AGGREGATE func_name aggr_args opt_drop_behavior
2735                         { $$ = cat_str(4, make_str("drop aggregate"), $3, $4, $5); }
2736                 | DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
2737                         { $$ = cat_str(4, make_str("drop aggregate if exists"), $5, $6, $7); }
2738                 ;
2739
2740 RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')' opt_drop_behavior
2741                         { $$ = cat_str(6, make_str("drop operator"), $3, make_str("("), $5, make_str(")"), $7); }
2742                 | DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
2743                         { $$ = cat_str(6, make_str("drop operator if exists"), $5, make_str("("), $7, make_str(")"), $9); }
2744                 ;
2745
2746 oper_argtypes:  Typename
2747                         { mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)"); }
2748                 | Typename ',' Typename
2749                         { $$ = cat_str(3, $1, make_str(","), $3); }
2750                 | NONE ',' Typename                     /* left unary */
2751                         { $$ = cat2_str(make_str("none,"), $3); }
2752                 | Typename ',' NONE                     /* right unary */
2753                         { $$ = cat2_str($1, make_str(", none")); }
2754                 ;
2755
2756 any_operator:
2757                 all_Op
2758                         { $$ = $1; }
2759                 | ColId '.' any_operator
2760                         { $$ = cat_str(3, $1, make_str("."), $3); }
2761                 ;
2762
2763 CreateCastStmt:         CREATE CAST '(' Typename AS Typename ')'
2764                                 WITH FUNCTION function_with_argtypes cast_context
2765                         { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") with function"), $10); }
2766                 | CREATE CAST '(' Typename AS Typename ')'
2767                                 WITHOUT FUNCTION cast_context
2768                         { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") without function"), $10); }
2769                 ;
2770
2771 cast_context: AS ASSIGNMENT   { $$ = make_str("as assignment"); }
2772                 | /*EMPTY*/     { $$ = EMPTY; }
2773                 ;
2774
2775
2776 DropCastStmt: DROP CAST opt_if_exists  '(' Typename AS Typename ')' opt_drop_behavior
2777                         { $$ = cat_str(8, make_str("drop cast"), $3, make_str("("), $5, make_str("as"), $7, make_str(")"), $9); }
2778                 ;
2779
2780 opt_if_exists: IF_P EXISTS      { $$ = make_str("if exists"); }
2781                 | /* EMPTY */   { $$ = EMPTY; }
2782                 ;
2783
2784 /*****************************************************************************
2785  *
2786  *                              QUERY:
2787  *
2788  *                              REINDEX type <typename> [FORCE] [ALL]
2789  *
2790  *****************************************************************************/
2791 ReindexStmt:  REINDEX reindex_type qualified_name opt_force
2792                         { $$ = cat_str(4, make_str("reindex"), $2, $3, $4); }
2793                 | REINDEX SYSTEM_P name opt_force
2794                         { $$ = cat_str(3, make_str("reindex system"), $3, $4); }
2795                 | REINDEX DATABASE name opt_force
2796                         { $$ = cat_str(3, make_str("reindex database"), $3, $4); }
2797                 ;
2798
2799 reindex_type:   INDEX           { $$ = make_str("index"); }
2800                 | TABLE         { $$ = make_str("table"); }
2801                 ;
2802
2803 opt_force: FORCE                        { $$ = make_str("force"); }
2804                 | /* EMPTY */           { $$ = EMPTY; }
2805                 ;
2806
2807 /*****************************************************************************
2808  *
2809  *              QUERY:
2810  *                              rename <attrname1> in <relname> [*] to <attrname2>
2811  *                              rename <relname1> to <relname2>
2812  *
2813  *****************************************************************************/
2814
2815 RenameStmt:  ALTER AGGREGATE func_name aggr_args RENAME TO name
2816                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("rename to"), $7); }
2817                 | ALTER CONVERSION_P any_name RENAME TO name
2818                         { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("rename to"), $6); }
2819                 | ALTER DATABASE database_name RENAME TO database_name
2820                         { $$ = cat_str(4, make_str("alter database"), $3, make_str("rename to"), $6); }
2821                 | ALTER FUNCTION function_with_argtypes RENAME TO name
2822                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("rename to"), $6); }
2823                 | ALTER GROUP_P RoleId RENAME TO RoleId
2824                         { $$ = cat_str(4, make_str("alter group"), $3, make_str("rename to"), $6); }
2825                 | ALTER opt_procedural LANGUAGE name RENAME TO name
2826                         { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("rename to"), $7); }
2827                 | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
2828                         { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
2829                 | ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name
2830                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("rename to"), $9); }
2831                 | ALTER SCHEMA name RENAME TO name
2832                         { $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
2833                 | ALTER TABLE relation_expr RENAME TO name
2834                         { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
2835                 | ALTER SEQUENCE relation_expr RENAME TO name
2836                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("rename to"), $6); }
2837                 | ALTER VIEW relation_expr RENAME TO name
2838                         { $$ = cat_str(4, make_str("alter view"), $3, make_str("rename to"), $6); }
2839                 | ALTER INDEX relation_expr RENAME TO name
2840                         { $$ = cat_str(4, make_str("alter index"), $3, make_str("rename to"), $6); }
2841                 | ALTER TABLE relation_expr RENAME opt_column name TO name
2842                         { $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
2843                 | ALTER TRIGGER name ON relation_expr RENAME TO name
2844                         { $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
2845                 | ALTER USER RoleId RENAME TO RoleId
2846                         { $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
2847                 | ALTER TABLESPACE name RENAME TO name
2848                         { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("rename to"), $6); }
2849                 | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
2850                         { $$ = cat_str(4, make_str("alter text search parser"), $5, make_str("rename to"), $8); }
2851                 | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name
2852                         { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("rename to"), $8); }
2853                 | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name
2854                         { $$ = cat_str(4, make_str("alter text search template"), $5, make_str("rename to"), $8); }
2855                 | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
2856                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("rename to"), $8); }
2857                 ;
2858
2859 opt_column:  COLUMN                     { $$ = make_str("column"); }
2860                 | /*EMPTY*/                     { $$ = EMPTY; }
2861                 ;
2862
2863 /*****************************************************************************
2864  *
2865  * ALTER THING name SET SCHEMA name
2866  *
2867  *****************************************************************************/
2868
2869 AlterObjectSchemaStmt:
2870                 ALTER AGGREGATE func_name aggr_args SET SCHEMA name
2871                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("set schema"), $7); }
2872                 | ALTER DOMAIN_P any_name SET SCHEMA name
2873                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("set schema"), $6); }
2874                 | ALTER FUNCTION function_with_argtypes SET SCHEMA name
2875                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("set schema"), $6); }
2876                 | ALTER SEQUENCE relation_expr SET SCHEMA name
2877                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
2878                 | ALTER TABLE relation_expr SET SCHEMA name
2879                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
2880                 | ALTER TYPE_P any_name SET SCHEMA name
2881                         { $$ = cat_str(4, make_str("alter type"), $3, make_str("set schema"), $6); }
2882                 ;
2883
2884 /*****************************************************************************
2885  *
2886  * ALTER THING name OWNER TO newname
2887  *
2888  *****************************************************************************/
2889
2890 AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
2891                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("owner to"), $7); }
2892                 | ALTER CONVERSION_P any_name OWNER TO RoleId
2893                         { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("owner to"), $6); }
2894                 | ALTER DATABASE database_name OWNER TO RoleId
2895                         { $$ = cat_str(4, make_str("alter database"), $3, make_str("owner to"), $6); }
2896                 | ALTER DOMAIN_P database_name OWNER TO RoleId
2897                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("owner to"), $6); }
2898                 | ALTER FUNCTION function_with_argtypes OWNER TO RoleId
2899                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("owner to"), $6); }
2900                 | ALTER opt_procedural LANGUAGE name OWNER TO RoleId
2901                         { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("owner to"), $7); }
2902                 | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
2903                         { $$ = cat_str(6, make_str("alter operator"), $3, make_str("("), $5, make_str(") owner to"), $9); }
2904                 | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
2905                         { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("owner to"), $9); }
2906                 | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId
2907                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("owner to"), $9); }
2908                 | ALTER SCHEMA name OWNER TO RoleId
2909                         { $$ = cat_str(4, make_str("alter schema"), $3, make_str("owner to"), $6); }
2910                 | ALTER TYPE_P any_name OWNER TO RoleId
2911                         { $$ = cat_str(4, make_str("alter type"), $3, make_str("owner to"), $6); }
2912                 | ALTER TABLESPACE name OWNER TO RoleId
2913                         { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("owner to"), $6); }
2914                 | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleId
2915                         { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("owner to"), $8); }
2916                 | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleId
2917                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("owner to"), $8); }
2918                 ;
2919
2920
2921 /*****************************************************************************
2922  *
2923  *              QUERY:  Define Rewrite Rule
2924  *
2925  *****************************************************************************/
2926
2927 RuleStmt:  CREATE opt_or_replace RULE name AS
2928                    { QueryIsRule=1; }
2929                    ON event TO qualified_name where_clause
2930                    DO opt_instead RuleActionList
2931                 {
2932                         QueryIsRule=0;
2933                         $$ = 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);
2934                 }
2935                 ;
2936
2937 RuleActionList:  NOTHING                                { $$ = make_str("nothing"); }
2938                 | RuleActionStmt                                { $$ = $1; }
2939                 | '(' RuleActionMulti ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2940                                 ;
2941
2942 /* the thrashing around here is to discard "empty" statements... */
2943 RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
2944                         {  $$ = cat_str(3, $1, make_str(";"), $3); }
2945                 | RuleActionStmtOrEmpty
2946                         { $$ = cat2_str($1, make_str(";")); }
2947                 ;
2948
2949 RuleActionStmt:   SelectStmt
2950                 | InsertStmt
2951                 | UpdateStmt
2952                 | DeleteStmt
2953                 | NotifyStmt
2954                 ;
2955
2956 RuleActionStmtOrEmpty: RuleActionStmt   { $$ = $1; }
2957                 | /*EMPTY*/                                             { $$ = EMPTY; }
2958                 ;
2959
2960 /* change me to select, update, etc. some day */
2961 event:  SELECT                          { $$ = make_str("select"); }
2962                 | UPDATE                        { $$ = make_str("update"); }
2963                 | DELETE_P                      { $$ = make_str("delete"); }
2964                 | INSERT                        { $$ = make_str("insert"); }
2965                 ;
2966
2967 opt_instead:  INSTEAD           { $$ = make_str("instead"); }
2968                 | ALSO          { $$ = make_str("also"); }
2969                 | /*EMPTY*/                     { $$ = EMPTY; }
2970                 ;
2971
2972 DropRuleStmt:  DROP RULE name ON qualified_name opt_drop_behavior
2973                         { $$ = cat_str(5, make_str("drop rule"), $3, make_str("on"), $5, $6);}
2974                 | DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
2975                         { $$ = cat_str(5, make_str("drop rule if exists"), $5, make_str("on"), $7, $8);}
2976                 ;
2977
2978 /*****************************************************************************
2979  *
2980  *              QUERY:
2981  *                              NOTIFY <qualified_name> can appear both in rule bodies and
2982  *                              as a query-level command
2983  *
2984  *****************************************************************************/
2985
2986 NotifyStmt:  NOTIFY ColId
2987                         { $$ = cat2_str(make_str("notify"), $2); }
2988                 ;
2989
2990 ListenStmt:  LISTEN ColId
2991                         { $$ = cat2_str(make_str("listen"), $2); }
2992                 ;
2993
2994 UnlistenStmt:  UNLISTEN ColId
2995                         { $$ = cat2_str(make_str("unlisten"), $2); }
2996                 | UNLISTEN '*'
2997                         { $$ = make_str("unlisten *"); }
2998                 ;
2999
3000
3001 /*****************************************************************************
3002  *
3003  *                              Transactions:
3004  *
3005  *        BEGIN / COMMIT / ROLLBACK
3006  *              (also older versions END / ABORT)
3007  *
3008  *****************************************************************************/
3009 TransactionStmt:  ABORT_P opt_transaction        { $$ = make_str("rollback"); }
3010                 | BEGIN_P opt_transaction transaction_mode_list_or_empty { $$ = cat2_str(make_str("begin transaction"), $3); }
3011                 | START TRANSACTION transaction_mode_list_or_empty       { $$ = cat2_str(make_str("start transaction"), $3); }
3012                 | COMMIT opt_transaction                         { $$ = make_str("commit"); }
3013                 | END_P opt_transaction                          { $$ = make_str("commit"); }
3014                 | ROLLBACK opt_transaction                       { $$ = make_str("rollback"); }
3015                 | SAVEPOINT ColId                                        { $$ = cat2_str(make_str("savepoint"), $2); }
3016                 | RELEASE SAVEPOINT ColId                        { $$ = cat2_str(make_str("release savepoint"), $3); }
3017                 | RELEASE ColId                                          { $$ = cat2_str(make_str("release"), $2); }
3018                 | ROLLBACK opt_transaction TO SAVEPOINT ColId            { $$ = cat_str(4, make_str("rollback"), $2, make_str("to savepoint"), $5); }
3019                 | ROLLBACK opt_transaction TO ColId      { $$ = cat_str(4, make_str("rollback"), $2, make_str("to"), $4); }
3020                 | PREPARE TRANSACTION StringConst        { $$ = cat2_str(make_str("prepare transaction"), $3); }
3021                 | COMMIT PREPARED StringConst            { $$ = cat2_str(make_str("commit prepared"), $3); }
3022                 | ROLLBACK PREPARED StringConst          { $$ = cat2_str(make_str("rollback prepared"), $3); }
3023                 ;
3024
3025 opt_transaction: WORK   { $$ = EMPTY; }
3026                 | TRANSACTION   { $$ = EMPTY; }
3027                 | /*EMPTY*/             { $$ = EMPTY; }
3028                 ;
3029
3030 transaction_mode_item:
3031                 ISOLATION LEVEL iso_level
3032                         { $$ = cat2_str(make_str("isolation level"), $3); }
3033                 | READ ONLY     { $$ = make_str("read only"); }
3034                 | READ WRITE    { $$ = make_str("read write"); }
3035                 ;
3036
3037 transaction_mode_list:
3038                 transaction_mode_item                                   { $$ = $1; }
3039                 | transaction_mode_list ',' transaction_mode_item       { $$ = cat_str(3, $1, make_str(","), $3); }
3040                 | transaction_mode_list transaction_mode_item           { $$ = cat_str(3, $1, make_str(" "), $2); }
3041                 ;
3042
3043 transaction_mode_list_or_empty:
3044                 transaction_mode_list   { $$ = $1; }
3045                 | /* EMPTY */           { $$ = EMPTY; }
3046                 ;
3047
3048 /*****************************************************************************
3049  *
3050  *      QUERY:
3051  *              CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
3052  *                     AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
3053  *
3054  *****************************************************************************/
3055
3056 ViewStmt:  CREATE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
3057                         { $$ = cat_str(8, make_str("create"), $2, make_str("view"), $4, $5, make_str("as"), $7, $8); }
3058                 | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
3059                         { $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); }
3060                 ;
3061
3062 /*
3063  * We use merged tokens here to avoid creating shift/reduce conflicts against
3064  * a whole lot of other uses of WITH.
3065  */
3066 opt_check_option:
3067                    WITH_CHECK OPTION
3068                    { 
3069                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3070                         $$ = EMPTY;
3071                    }
3072                    | WITH_CASCADED CHECK OPTION
3073                    { 
3074                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3075                         $$ = EMPTY;
3076                    }
3077                    | WITH_LOCAL CHECK OPTION
3078                    {
3079                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3080                         $$ = EMPTY;
3081                    }
3082                    | /* EMPTY */
3083                    { $$ = EMPTY; } 
3084                    ;
3085
3086 /*****************************************************************************
3087  *
3088  *              QUERY:
3089  *                              load make_str("filename")
3090  *
3091  *****************************************************************************/
3092
3093 LoadStmt:  LOAD file_name
3094                         { $$ = cat2_str(make_str("load"), $2); }
3095                 ;
3096
3097
3098 /*****************************************************************************
3099  *
3100  *              CREATE DATABASE
3101  *
3102  *
3103  *****************************************************************************/
3104
3105 CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
3106                         { $$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5); }
3107                 | CREATE DATABASE database_name
3108                         { $$ = cat2_str(make_str("create database"), $3); }
3109                 ;
3110
3111 createdb_opt_list:      createdb_opt_item
3112                         { $$ = $1; }
3113                 | createdb_opt_list createdb_opt_item
3114                         { $$ = cat2_str($1, $2); }
3115                 ;
3116
3117 createdb_opt_item:      TABLESPACE opt_equal name
3118                         { $$ = cat_str(3,make_str("tablespace"), $2, $3); }
3119                 | TABLESPACE opt_equal DEFAULT
3120                         { $$ = cat_str(3, make_str("tablespace"), $2, make_str("default")); }
3121                 | LOCATION opt_equal StringConst
3122                         { $$ = cat_str(3,make_str("location"), $2, $3); }
3123                 | LOCATION opt_equal DEFAULT
3124                         { $$ = cat_str(3, make_str("location"), $2, make_str("default")); }
3125                 | TEMPLATE opt_equal name
3126                         { $$ = cat_str(3, make_str("template"), $2, $3); }
3127                 | TEMPLATE opt_equal DEFAULT
3128                         { $$ = cat_str(3, make_str("template"), $2, make_str("default")); }
3129                 | ENCODING opt_equal PosIntStringConst
3130                         { $$ = cat_str(3, make_str("encoding"), $2, $3); }
3131                 | ENCODING opt_equal DEFAULT
3132                         { $$ = cat_str(3, make_str("encoding"), $2, make_str("default")); }
3133                 | CONNECTION LIMIT opt_equal PosIntConst
3134                         { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
3135                 | OWNER opt_equal name
3136                         { $$ = cat_str(3, make_str("owner"), $2, $3); }
3137                 | OWNER opt_equal DEFAULT
3138                         { $$ = cat_str(3, make_str("owner"), $2, make_str("default")); }
3139                 ;
3140
3141 opt_equal: '='                                  { $$ = make_str("="); }
3142                 | /* EMPTY */                   { $$ = EMPTY; }
3143                 ;
3144
3145
3146 /*****************************************************************************
3147  *
3148  *                              ALTER DATABASE
3149  *
3150  *
3151  *****************************************************************************/
3152
3153 AlterDatabaseStmt: ALTER DATABASE database_name opt_with alterdb_opt_list
3154                         { $$ = cat_str(4, make_str("alter database"), $3, $4, $5); }
3155                 ;
3156
3157 AlterDatabaseSetStmt: ALTER DATABASE database_name SetResetClause
3158                         { $$ = cat_str(3, make_str("alter database"), $3, $4); }
3159                 ;
3160
3161 alterdb_opt_list:
3162                 alterdb_opt_list alterdb_opt_item       { $$ = cat2_str($1, $2);}
3163                 | /* EMPTY */                           { $$ = EMPTY; }
3164                 ;
3165
3166 alterdb_opt_item:
3167                 CONNECTION LIMIT opt_equal PosIntConst { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
3168                 ;
3169
3170 /*****************************************************************************
3171  *
3172  *              DROP DATABASE [ IF EXISTS ]
3173  *
3174  *
3175  *****************************************************************************/
3176
3177 DropdbStmt: DROP DATABASE database_name
3178                         { $$ = cat2_str(make_str("drop database"), $3); }
3179                 | DROP DATABASE IF_P EXISTS database_name
3180                         { $$ = cat2_str(make_str("drop database if exists"), $5); }
3181                 ;
3182
3183
3184 /*****************************************************************************
3185  *
3186  * Manipulate a domain
3187  *
3188  *****************************************************************************/
3189
3190 CreateDomainStmt:  CREATE DOMAIN_P any_name opt_as Typename ColQualList
3191                 {
3192                         $$ = cat_str(5, make_str("create domain"), $3, $4, $5, $6);
3193                 }
3194                 ;
3195
3196 AlterDomainStmt:
3197                 ALTER DOMAIN_P any_name alter_column_default
3198                         { $$ = cat_str(3, make_str("alter domain"), $3, $4); }
3199                 | ALTER DOMAIN_P any_name DROP NOT NULL_P
3200                         { $$ = cat_str(3, make_str("alter domain"), $3, make_str("drop not null")); }
3201                 | ALTER DOMAIN_P any_name SET NOT NULL_P
3202                         { $$ = cat_str(3, make_str("alter domain"), $3, make_str("set not null")); }
3203                 | ALTER DOMAIN_P any_name ADD_P TableConstraint
3204                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("add"), $5); }
3205                 | ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
3206                         { $$ = cat_str(5, make_str("alter domain"), $3, make_str("drop constraint"), $6, $7); }
3207                 ;
3208
3209 opt_as: AS      {$$ = make_str("as"); }
3210                 | /* EMPTY */   {$$ = EMPTY; }
3211                 ;
3212
3213 AlterTSDictionaryStmt:
3214                 ALTER TEXT_P SEARCH DICTIONARY any_name definition
3215                         { $$ = cat_str(3, make_str("alter text search dictionary"), $5, $6); }
3216                 ;
3217
3218 AlterTSConfigurationStmt:
3219                 ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list WITH any_name_list
3220                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("add mapping for"), $9, make_str("with"), $11); }
3221                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list WITH any_name_list
3222                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("with"), $11); }
3223                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name WITH any_name
3224                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping replace"), $9, make_str("with"), $11); }
3225                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name WITH any_name
3226                         { $$ = cat_str(8, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("replace"), $11, make_str("with"), $13); }
3227                 | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
3228                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping for"), $9); }
3229                 | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
3230                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping if exists for"), $11); }
3231                 ;
3232
3233 CreateConversionStmt:
3234            CREATE opt_default CONVERSION_P any_name FOR StringConst
3235            TO StringConst FROM any_name
3236                    { $$ = cat_str(10, make_str("create"), $2, make_str("conversion"), $4, make_str("for"), $6, make_str("to"), $8, make_str("from"), $10); }
3237            ;
3238
3239 /*****************************************************************************
3240  *
3241  *              QUERY:
3242  *                             cluster <index_name> on <qualified_name>
3243  *                             cluster <qualified_name>
3244  *                             cluster
3245  *
3246  *****************************************************************************/
3247
3248 ClusterStmt:  CLUSTER qualified_name cluster_index_specification
3249                                 { $$ = cat_str(3,make_str("cluster"), $2, $3); }
3250                 | CLUSTER
3251                                 { $$ = make_str("cluster"); }
3252                 | CLUSTER qualified_name ON qualified_name
3253                                 { $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4); }
3254                 ;
3255
3256 cluster_index_specification:
3257                 USING index_name        { $$ = cat2_str(make_str("using"), $2); }
3258                 | /*EMPTY*/             { $$ = EMPTY; }
3259                 ;
3260
3261 /*****************************************************************************
3262  *
3263  *              QUERY:
3264  *                              vacuum
3265  *                              analyze
3266  *
3267  *****************************************************************************/
3268
3269 VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
3270                         { $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); }
3271                 | VACUUM opt_full opt_freeze opt_verbose qualified_name
3272                         { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
3273                 | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
3274                         { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
3275                 ;
3276
3277 AnalyzeStmt:  analyze_keyword opt_verbose
3278                         { $$ = cat_str(2, $1, $2); }
3279                 | analyze_keyword opt_verbose qualified_name opt_name_list
3280                         { $$ = cat_str(4, $1, $2, $3, $4); }
3281                 ;
3282
3283 analyze_keyword:  ANALYZE               { $$ = make_str("analyze"); }
3284                 | ANALYSE               { $$ = make_str("analyse"); }
3285                 ;
3286
3287 opt_verbose:  VERBOSE                   { $$ = make_str("verbose"); }
3288                 | /*EMPTY*/                             { $$ = EMPTY; }
3289                 ;
3290
3291 opt_full:  FULL                                 { $$ = make_str("full"); }
3292                 | /*EMPTY*/                             { $$ = EMPTY; }
3293                 ;
3294
3295 opt_freeze:  FREEZE                             { $$ = make_str("freeze"); }
3296                 | /*EMPTY*/                             { $$ = EMPTY; }
3297                 ;
3298
3299 opt_name_list:  '(' name_list ')'
3300                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3301                 | /*EMPTY*/
3302                         { $$ = EMPTY; }
3303                 ;
3304
3305
3306 /*****************************************************************************
3307  *
3308  *              QUERY:
3309  *                              EXPLAIN query
3310  *
3311  *****************************************************************************/
3312
3313 ExplainStmt:  EXPLAIN opt_analyze opt_verbose ExplainableStmt
3314                         { $$ = cat_str(4, make_str("explain"), $2, $3, $4); }
3315                 ;
3316
3317 ExplainableStmt:
3318                 SelectStmt
3319                 | InsertStmt
3320                 | UpdateStmt
3321                 | DeleteStmt
3322                 | DeclareCursorStmt
3323                 | ExecuteStmt
3324                 ;
3325 opt_analyze:
3326                 analyze_keyword                 { $$ = $1; }
3327                 | /* EMPTY */                   { $$ = EMPTY; }
3328                 ;
3329
3330 PrepareStmt: PREPARE prepared_name prep_type_clause AS PreparableStmt
3331                 {
3332                         $$.name = $2;
3333                         $$.type = $3;
3334                         $$.stmt = cat_str(3, make_str("\""), $5, make_str("\""));
3335                 }
3336                 | PREPARE prepared_name FROM execstring /* ECPG addon */
3337                 {
3338                         $$.name = $2;
3339                         $$.type = NULL;
3340                         $$.stmt = $4;
3341                 }
3342                 ;
3343
3344 PreparableStmt:
3345                 SelectStmt
3346                 | InsertStmt
3347                 | UpdateStmt
3348                 | DeleteStmt
3349                 ;
3350
3351 prep_type_clause: '(' type_list ')'     { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3352                 | /* EMPTY */           { $$ = EMPTY; }
3353                         ;
3354
3355 ExecuteStmt: EXECUTE prepared_name execute_param_clause execute_rest /* execute_rest is an ecpg addon */
3356                         {
3357                                 /* $$ = cat_str(3, make_str("ECPGprepared_statement("), connection, $2, make_str("__LINE__)"));*/
3358                                 $$ = $2;
3359                         }
3360                 | CREATE OptTemp TABLE create_as_target AS
3361                         EXECUTE prepared_name execute_param_clause
3362                         { $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4,  make_str("as execute"), $7, $8); }
3363                 ;
3364
3365 execute_param_clause: '(' expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3366                 | /* EMPTY */           { $$ = EMPTY; }
3367                 ;
3368
3369 DeallocateStmt: DEALLOCATE prepared_name                { $$ = $2; }
3370                 | DEALLOCATE PREPARE prepared_name      { $$ = $3; }
3371                 | DEALLOCATE ALL                        { $$ = make_str("all"); }
3372                 | DEALLOCATE PREPARE ALL                { $$ = make_str("all"); }
3373                 ;
3374
3375 /*****************************************************************************
3376  *
3377  *              QUERY:
3378  *                              INSERT STATEMENTS
3379  *
3380  *****************************************************************************/
3381
3382 InsertStmt:  INSERT INTO qualified_name insert_rest returning_clause
3383                         { $$ = cat_str(4, make_str("insert into"), $3, $4, $5); }
3384                 ;
3385
3386 insert_rest:  
3387                 SelectStmt
3388                         { $$ = $1; }
3389                 | '(' insert_column_list ')' SelectStmt
3390                         { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
3391                 | DEFAULT VALUES
3392                         { $$ = make_str("default values"); }
3393                 ;
3394
3395 insert_column_list: insert_column_list ',' insert_column_item
3396                         { $$ = cat_str(3, $1, make_str(","), $3); }
3397                 | insert_column_item
3398                         { $$ = $1; }
3399                 ;
3400
3401 insert_column_item:  ColId opt_indirection
3402                         { $$ = cat2_str($1, $2); }
3403                 ;
3404
3405 returning_clause:  RETURNING target_list        { $$ = cat2_str(make_str("returning"), $2); }
3406                 | /* EMPTY */                   { $$ = EMPTY; }
3407                 ;
3408
3409 /*****************************************************************************
3410  *
3411  *              QUERY:
3412  *                              DELETE STATEMENTS
3413  *
3414  *****************************************************************************/
3415
3416 DeleteStmt:  DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause
3417                         { $$ = cat_str(5, make_str("delete from"), $3, $4, $5, $6); }
3418                 ;
3419
3420 using_clause: USING from_list   { $$ = cat2_str(make_str("using"), $2); }
3421                         | /* EMPTY */           { $$ = EMPTY; }
3422                 ;
3423
3424 LockStmt:  LOCK_P opt_table qualified_name_list opt_lock opt_nowait
3425                         { $$ = cat_str(5, make_str("lock"), $2, $3, $4, $5); }
3426                 ;
3427
3428 opt_lock:  IN_P lock_type MODE
3429                         { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
3430                 | /*EMPTY*/
3431                         { $$ = EMPTY;}
3432                 ;
3433
3434 lock_type:      ACCESS SHARE            { $$ = make_str("access share"); }
3435                 | ROW SHARE                             { $$ = make_str("access share"); }
3436                 | ROW EXCLUSIVE                 { $$ = make_str("row exclusive"); }
3437                 | SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); }
3438                 | SHARE                                 { $$ = make_str("share"); }
3439                 | SHARE ROW EXCLUSIVE   { $$ = make_str("share row exclusive"); }
3440                 | EXCLUSIVE                             { $$ = make_str("exclusive"); }
3441                 | ACCESS EXCLUSIVE              { $$ = make_str("access exclusive"); }
3442                 ;
3443
3444 opt_nowait:    NOWAIT                   { $$ = make_str("nowait"); }
3445                 | /* EMPTY */           { $$ = EMPTY; }
3446                 ;
3447
3448 /*****************************************************************************
3449  *
3450  *              QUERY:
3451  *                              UpdateStmt (UPDATE)
3452  *
3453  *****************************************************************************/
3454
3455 UpdateStmt:  UPDATE relation_expr_opt_alias
3456                                 SET set_clause_list
3457                                 from_clause
3458                                 where_or_current_clause
3459                                 returning_clause
3460                         {$$ = cat_str(7, make_str("update"), $2, make_str("set"), $4, $5, $6, $7); }
3461                 ;
3462
3463 set_clause_list:
3464                 set_clause                              { $$ = $1; }
3465                 | set_clause_list ',' set_clause        { $$ = cat_str(3, $1, make_str(","), $3); }
3466                 ;
3467
3468 set_clause:
3469                 single_set_clause               { $$ = $1; }
3470                 | multiple_set_clause           { $$ = $1; }
3471                 ;
3472
3473 single_set_clause:
3474                 set_target '=' ctext_expr       { $$ = cat_str(3, $1, make_str("="), $3); };
3475
3476 multiple_set_clause:
3477                 '(' set_target_list ')' '=' ctext_row   { $$ = cat_str(4, make_str("("), $2, make_str(")="), $5); };
3478
3479 set_target:
3480                 ColId opt_indirection           { $$ = cat2_str($1, $2); };
3481
3482 set_target_list:
3483                 set_target                              { $$ = $1; }
3484                 | set_target_list ',' set_target        { $$ = cat_str(3, $1, make_str(","), $3); }
3485                 ;
3486
3487 /*****************************************************************************
3488  *
3489  *              QUERY:
3490  *                              CURSOR STATEMENTS
3491  *
3492  *****************************************************************************/
3493 DeclareCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
3494                 {
3495                         struct cursor *ptr, *this;
3496
3497                         for (ptr = cur; ptr != NULL; ptr = ptr->next)
3498                         {
3499                                 if (strcmp($2, ptr->name) == 0)
3500                                         /* re-definition is a bug */
3501                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
3502                         }
3503
3504                         this = (struct cursor *) mm_alloc(sizeof(struct cursor));
3505
3506                         /* initial definition */
3507                         this->next = cur;
3508                         this->name = $2;
3509                         this->connection = connection;
3510                         this->opened = false;
3511                         this->command =  cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
3512                         this->argsinsert = argsinsert;
3513                         this->argsresult = argsresult;
3514                         argsinsert = argsresult = NULL;
3515                         cur = this;
3516
3517                         if (INFORMIX_MODE)
3518                                 $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
3519                         else
3520                                 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
3521                 }
3522                 ;
3523
3524 cursor_options:  /* EMPTY */            { $$ = EMPTY; }
3525                 | cursor_options BINARY         { $$ = cat2_str($1, make_str("binary")); }
3526                 | cursor_options INSENSITIVE    { $$ = cat2_str($1, make_str("insensitive")); }
3527                 | cursor_options SCROLL         { $$ = cat2_str($1, make_str("scroll")); }
3528                 | cursor_options NO SCROLL      { $$ = cat2_str($1, make_str("no scroll")); }
3529                 ;
3530
3531 opt_hold:       /* EMPTY */
3532                 {
3533                         if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit == true)
3534                                 $$ = make_str("with hold");
3535                         else
3536                                  $$ = EMPTY;
3537                 }
3538                 | WITH HOLD                     { $$ = make_str("with hold"); }
3539                 | WITHOUT HOLD                  { $$ = make_str("without hold"); }
3540                 ;
3541
3542 /*****************************************************************************
3543  *
3544  *              QUERY:
3545  *                              SELECT STATEMENTS
3546  *
3547  *****************************************************************************/
3548
3549 SelectStmt: select_no_parens            %prec UMINUS
3550                         { $$ = $1; }
3551                 |       select_with_parens              %prec UMINUS
3552                         { $$ = $1; }
3553                 ;
3554
3555 select_with_parens: '(' select_no_parens ')'
3556                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3557                 | '(' select_with_parens ')'
3558                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3559                 ;
3560
3561 select_no_parens:          simple_select
3562                         { $$ = $1; }
3563                 | select_clause sort_clause
3564                         { $$ = cat2_str($1, $2); }
3565                 | select_clause opt_sort_clause for_locking_clause opt_select_limit
3566                         { $$ = cat_str(4, $1, $2, $3, $4); }
3567                 | select_clause opt_sort_clause select_limit opt_for_locking_clause
3568                         { $$ = cat_str(4, $1, $2, $3, $4); }
3569                 ;
3570
3571 select_clause: simple_select            { $$ = $1; }
3572                 | select_with_parens            { $$ = $1; }
3573                 ;
3574
3575 simple_select:  SELECT opt_distinct target_list
3576                                         into_clause from_clause where_clause
3577                                         group_clause having_clause
3578                         { $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8); }
3579                 | values_clause
3580                         { $$ = $1; }
3581                 | select_clause UNION opt_all select_clause
3582                         { $$ = cat_str(4, $1, make_str("union"), $3, $4); }
3583                 | select_clause INTERSECT opt_all select_clause
3584                         { $$ = cat_str(4, $1, make_str("intersect"), $3, $4); }
3585                 | select_clause EXCEPT opt_all select_clause
3586                         { $$ = cat_str(4, $1, make_str("except"), $3, $4); }
3587                 ;
3588
3589 into_clause:  INTO OptTempTableName
3590                 {
3591                         FoundInto = 1;
3592                         $$= cat2_str(make_str("into"), $2);
3593                 }
3594                 | ecpg_into                     { $$ = EMPTY; }
3595                 | /*EMPTY*/                     { $$ = EMPTY; }
3596                 ;
3597
3598 /*
3599  * Redundancy here is needed to avoid shift/reduce conflicts,
3600  * since TEMP is not a reserved word.  See also OptTemp.
3601  *
3602  * The result is a cons cell (not a true list!) containing
3603  * a boolean and a table name.
3604  */
3605 OptTempTableName:  TEMPORARY opt_table qualified_name
3606                         { $$ = cat_str(3, make_str("temporary"), $2, $3); }
3607                 | TEMP opt_table qualified_name
3608                         { $$ = cat_str(3, make_str("temp"), $2, $3); }
3609                 | LOCAL TEMPORARY opt_table qualified_name
3610                         { $$ = cat_str(3, make_str("local temporary"), $3, $4); }
3611                 | LOCAL TEMP opt_table qualified_name
3612                         { $$ = cat_str(3, make_str("local temp"), $3, $4); }
3613                 | GLOBAL TEMPORARY opt_table qualified_name
3614                         { $$ = cat_str(3, make_str("global temporary"), $3, $4); }
3615                 | GLOBAL TEMP opt_table qualified_name
3616                         { $$ = cat_str(3, make_str("global temp"), $3, $4); }
3617                 | TABLE qualified_name
3618                         { $$ = cat2_str(make_str("table"), $2); }
3619                 | qualified_name
3620                         { $$ = $1; }
3621                 ;
3622
3623 opt_table:      TABLE                           { $$ = make_str("table"); }
3624                 | /*EMPTY*/                             { $$ = EMPTY; }
3625                 ;
3626
3627 opt_all:  ALL                                   { $$ = make_str("all"); }
3628                 | /*EMPTY*/                             { $$ = EMPTY; }
3629                 ;
3630
3631 opt_distinct:  DISTINCT
3632                         { $$ = make_str("distinct"); }
3633                 | DISTINCT ON '(' expr_list ')'
3634                         { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
3635                 | ALL
3636                         { $$ = make_str("all"); }
3637                 | /*EMPTY*/
3638                         { $$ = EMPTY; }
3639                 ;
3640
3641 opt_sort_clause:        sort_clause     { $$ = $1; }
3642                 | /* EMPTY */           { $$ = EMPTY; }
3643                 ;
3644
3645 sort_clause:  ORDER BY sortby_list
3646                         { $$ = cat2_str(make_str("order by"), $3); }
3647                 ;
3648
3649 sortby_list:  sortby                                    { $$ = $1; }
3650                 | sortby_list ',' sortby                { $$ = cat_str(3, $1, make_str(","), $3); }
3651                 ;
3652
3653 sortby: a_expr USING qual_all_Op opt_nulls_order
3654                         { $$ = cat_str(4, $1, make_str("using"), $3, $4); }
3655                 | a_expr opt_asc_desc opt_nulls_order
3656                         { $$ = cat_str(3, $1, $2, $3); }
3657                 ;
3658
3659 select_limit:   LIMIT select_limit_value OFFSET select_offset_value
3660                    { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
3661                 | OFFSET select_offset_value LIMIT select_limit_value
3662                    { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
3663                 | LIMIT select_limit_value
3664                    { $$ = cat2_str(make_str("limit"), $2); }
3665                 | OFFSET select_offset_value
3666                    { $$ = cat2_str(make_str("offset"), $2); }
3667                 | LIMIT select_limit_value ',' select_offset_value
3668                    { mmerror(PARSE_ERROR, ET_WARNING, "No longer supported LIMIT #,# syntax passed to backend."); }
3669                 ;
3670
3671 opt_select_limit:       select_limit    { $$ = $1; }
3672                 | /*EMPTY*/                                     { $$ = EMPTY; }
3673                 ;
3674
3675 select_limit_value: a_expr      { $$ = $1; }
3676                 | ALL           { $$ = make_str("all"); }
3677                 ;
3678
3679 select_offset_value: a_expr { $$ = $1; }
3680                 ;
3681
3682 /*
3683  *      jimmy bell-style recursive queries aren't supported in the
3684  *      current system.
3685  *
3686  *      ...however, recursive addattr and rename supported.  make special
3687  *      cases for these.
3688  */
3689 group_clause:  GROUP_P BY expr_list
3690                         { $$ = cat2_str(make_str("group by"), $3); }
3691                 | /*EMPTY*/
3692                         { $$ = EMPTY; }
3693                 ;
3694
3695 having_clause:  HAVING a_expr
3696                         { $$ = cat2_str(make_str("having"), $2); }
3697                 | /*EMPTY*/
3698                         { $$ = EMPTY; }
3699                 ;
3700
3701 for_locking_clause:
3702                 for_locking_items       { $$ = $1; }
3703                 | FOR READ ONLY         { $$ = make_str("for read only");}
3704                 ;
3705
3706 opt_for_locking_clause: 
3707                 for_locking_clause      { $$ = $1; }
3708                 | /* EMPTY */           { $$ = EMPTY; }
3709                 ;
3710
3711 for_locking_items:
3712                 for_locking_item                        { $$ = $1; }
3713                 | for_locking_items for_locking_item    { $$ = cat2_str($1, $2); }
3714                 ;
3715
3716 for_locking_item:
3717                 FOR UPDATE locked_rels_list opt_nowait
3718                         { $$ = cat_str(3, make_str("for update"), $3, $4); }
3719                 | FOR SHARE locked_rels_list opt_nowait
3720                         { $$ = cat_str(3, make_str("for share"), $3, $4); }
3721                 ;
3722
3723 locked_rels_list:
3724                 OF name_list            { $$ = cat2_str(make_str("of"), $2); }
3725                 | /* EMPTY */           { $$ = EMPTY; }
3726                 ;
3727
3728 values_clause:  VALUES ctext_row
3729                         { $$ = cat2_str(make_str("values"), $2); }
3730                 | values_clause ',' ctext_row
3731                         { $$ = cat_str(3, $1, make_str(","), $3); }
3732                 ;
3733
3734 /*****************************************************************************
3735  *
3736  *      clauses common to all Optimizable Stmts:
3737  *              from_clause - allow list of both JOIN expressions and table names
3738  *              where_clause    - qualifications for joins or restrictions
3739  *
3740  *****************************************************************************/
3741
3742 from_clause:    FROM from_list          { $$ = cat2_str(make_str("from"), $2); }
3743                 | /* EMPTY */                           { $$ = EMPTY; }
3744                 ;
3745
3746 from_list:      from_list ',' table_ref { $$ = cat_str(3, $1, make_str(","), $3); }
3747                 | table_ref                                     { $$ = $1; }
3748                 ;
3749
3750 /*
3751  * table_ref is where an alias clause can be attached.  Note we cannot make
3752  * alias_clause have an empty production because that causes parse conflicts
3753  * between table_ref := '(' joined_table ')' alias_clause
3754  * and joined_table := '(' joined_table ')'.  So, we must have the
3755  * redundant-looking productions here instead.
3756  */
3757 table_ref:      relation_expr
3758                         { $$ = $1; }
3759                 | relation_expr alias_clause
3760                         { $$= cat2_str($1, $2); }
3761                 | func_table
3762                         { $$ = $1; }
3763                 | func_table alias_clause
3764                         { $$= cat2_str($1, $2); }
3765                 | func_table AS '(' TableFuncElementList ')'
3766                         { $$=cat_str(4, $1, make_str("as ("), $4, make_str(")")); }
3767                 | func_table AS ColId '(' TableFuncElementList ')'
3768                         { $$=cat_str(6, $1, make_str("as"), $3, make_str("("), $5, make_str(")"));}
3769                 | func_table ColId '(' TableFuncElementList ')'
3770                         { $$=cat_str(5, $1, $2, make_str("("), $4, make_str(")")); }
3771                 | select_with_parens
3772                         {mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");}
3773                 | select_with_parens alias_clause
3774                         { $$=cat2_str($1, $2); }
3775                 | joined_table
3776                         { $$ = $1; }
3777                 | '(' joined_table ')' alias_clause
3778                         { $$=cat_str(4, make_str("("), $2, make_str(")"), $4); }
3779                 ;
3780
3781 /*
3782  * It may seem silly to separate joined_table from table_ref, but there is
3783  * method in SQL92's madness: if you don't do it this way you get reduce-
3784  * reduce conflicts, because it's not clear to the parser generator whether
3785  * to expect alias_clause after ')' or not.  For the same reason we must
3786  * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
3787  * join_type to expand to empty; if we try it, the parser generator can't
3788  * figure out when to reduce an empty join_type right after table_ref.
3789  *
3790  * Note that a CROSS JOIN is the same as an unqualified
3791  * INNER JOIN, and an INNER JOIN/ON has the same shape
3792  * but a qualification expression to limit membership.
3793  * A NATURAL JOIN implicitly matches column names between
3794  * tables and the shape is determined by which columns are
3795  * in common. We'll collect columns during the later transformations.
3796  */
3797
3798 joined_table:  '(' joined_table ')'
3799                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3800                 | table_ref CROSS JOIN table_ref
3801                         { $$ = cat_str(3, $1, make_str("cross join"), $4); }
3802                 | table_ref join_type JOIN table_ref join_qual
3803                         { $$ = cat_str(5, $1, $2, make_str("join"), $4, $5); }
3804                 | table_ref JOIN table_ref join_qual
3805                         { $$ = cat_str(4, $1, make_str("join"), $3, $4); }
3806                 | table_ref NATURAL join_type JOIN table_ref
3807                         { $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5); }
3808                 | table_ref NATURAL JOIN table_ref
3809                         { $$ = cat_str(3, $1, make_str("natural join"), $4); }
3810                 ;
3811
3812 alias_clause:  AS ColId '(' name_list ')'
3813                         { $$ = cat_str(5, make_str("as"), $2, make_str("("), $4, make_str(")")); }
3814                 | AS ColId
3815                         { $$ = cat2_str(make_str("as"), $2); }
3816                 | ColId '(' name_list ')'
3817                         { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
3818                 | ColId
3819                         { $$ = $1; }
3820                 ;
3821
3822 join_type:      FULL join_outer         { $$ = cat2_str(make_str("full"), $2); }
3823                 | LEFT join_outer               { $$ = cat2_str(make_str("left"), $2); }
3824                 | RIGHT join_outer              { $$ = cat2_str(make_str("right"), $2); }
3825                 | INNER_P                               { $$ = make_str("inner"); }
3826                 ;
3827
3828 /* OUTER is just noise... */
3829 join_outer:  OUTER_P                    { $$ = make_str("outer"); }
3830                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3831                 ;
3832
3833 /* JOIN qualification clauses
3834  * Possibilities are:
3835  *      USING ( column list ) allows only unqualified column names,
3836  *                                                which must match between tables.
3837  *      ON expr allows more general qualifications.
3838  */
3839
3840 join_qual:      USING '(' name_list ')'
3841                         { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
3842                 | ON a_expr
3843                         { $$ = cat2_str(make_str("on"), $2); }
3844                 ;
3845
3846 relation_expr:  qualified_name
3847                         { /* normal relations */ $$ = $1; }
3848                 | qualified_name '*'
3849                         { /* inheritance query */ $$ = cat2_str($1, make_str("*")); }
3850                 | ONLY qualified_name
3851                         { /* inheritance query */ $$ = cat2_str(make_str("only "), $2); }
3852                 | ONLY '(' qualified_name ')'
3853                         { /* inheritance query */ $$ = cat_str(3, make_str("only ("), $3, make_str(")")); }
3854                 ;
3855
3856 relation_expr_opt_alias: relation_expr                                 %prec UMINUS
3857                 { $$ = $1; }
3858                 | relation_expr ColId
3859                 { $$ = cat2_str($1, $2); }
3860                 | relation_expr AS ColId
3861                 { $$ = cat_str(3, $1, make_str("as"), $3); }
3862                 ;
3863
3864 func_table:  func_expr  { $$ = $1; }
3865                 ;
3866
3867 where_clause:  WHERE a_expr             { $$ = cat2_str(make_str("where"), $2); }
3868                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3869                 ;
3870
3871 where_or_current_clause:  WHERE a_expr                  { $$ = cat2_str(make_str("where"), $2); }
3872                 | WHERE CURRENT_P OF name               { $$ = cat2_str(make_str("where current of"), $4); }
3873                 | WHERE CURRENT_P OF PARAM              { $$ = make_str("where current of param"); }
3874                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3875                 ;
3876
3877 TableFuncElementList: TableFuncElement
3878                         { $$ = $1; }
3879                 | TableFuncElementList ',' TableFuncElement
3880                         { $$ = cat_str(3, $1, make_str(","), $3); }
3881                 ;
3882
3883 TableFuncElement:       ColId Typename  { $$ = cat2_str($1, $2); }
3884                 ;
3885
3886 /*****************************************************************************
3887  *
3888  *      Type syntax
3889  *              SQL92 introduces a large amount of type-specific syntax.
3890  *              Define individual clauses to handle these cases, and use
3891  *               the generic case to handle regular type-extensible Postgres syntax.
3892  *              - thomas 1997-10-10
3893  *
3894  *****************************************************************************/
3895
3896 Typename:  SimpleTypename opt_array_bounds
3897                         { $$ = cat2_str($1, $2.str); }
3898                 | SETOF SimpleTypename opt_array_bounds
3899                         { $$ = cat_str(3, make_str("setof"), $2, $3); }
3900                 | SimpleTypename ARRAY '[' PosIntConst ']'
3901                         { $$ = cat_str(4, $1, make_str("array ["), $4, make_str("]")); }
3902                 | SETOF SimpleTypename ARRAY '[' PosIntConst ']'
3903                         { $$ = cat_str(5, make_str("setof"), $2, make_str("array ["), $5, make_str("]")); }
3904                 ;
3905
3906
3907 opt_array_bounds:  '[' ']' opt_array_bounds
3908                 {
3909                         $$.index1 = make_str("0");
3910                         $$.index2 = $3.index1;
3911                         $$.str = cat2_str(make_str("[]"), $3.str);
3912                 }
3913                 | '[' Iresult ']' opt_array_bounds
3914                 {
3915                         $$.index1 = strdup($2);
3916                         $$.index2 = $4.index1;
3917                         $$.str = cat_str(4, make_str("["), $2, make_str("]"), $4.str);
3918                 }
3919                 | /* EMPTY */
3920                 {
3921                         $$.index1 = make_str("-1");
3922                         $$.index2 = make_str("-1");
3923                         $$.str= EMPTY;
3924                 }
3925                 ;
3926
3927 Iresult:        PosIntConst             { $$ = $1; }
3928                 | '(' Iresult ')'       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3929                 | Iresult '+' Iresult   { $$ = cat_str(3, $1, make_str("+"), $3); }
3930                 | Iresult '-' Iresult   { $$ = cat_str(3, $1, make_str("-"), $3); }
3931                 | Iresult '*' Iresult   { $$ = cat_str(3, $1, make_str("*"), $3); }
3932                 | Iresult '/' Iresult   { $$ = cat_str(3, $1, make_str("/"), $3); }
3933                 | Iresult '%' Iresult   { $$ = cat_str(3, $1, make_str("%"), $3); }
3934                 | Sconst                { $$ = $1; }
3935                 | ColId                 { $$ = $1; }
3936                 ;
3937
3938 SimpleTypename:  GenericType            { $$ = $1; }
3939                 | ConstDatetime         { $$ = $1; }
3940                 | Numeric               { $$ = $1; }
3941                 | Bit                   { $$ = $1; }
3942                 | Character             { $$ = $1; }
3943                 | ConstInterval opt_interval
3944                         { $$ = cat2_str($1, $2); }
3945                 | ConstInterval '(' PosIntConst ')' opt_interval
3946                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
3947                 ;
3948
3949 ConstTypename:  Numeric                 { $$ = $1; }
3950                 | ConstBit              { $$ = $1; }
3951                 | ConstCharacter        { $$ = $1; }
3952                 | ConstDatetime         { $$ = $1; }
3953                 ;
3954
3955 GenericType:    type_function_name opt_type_modifiers           { $$ = cat2_str($1, $2); }
3956                 | type_function_name attrs opt_type_modifiers   { $$ = cat_str(3, $1, $2, $3); }
3957                 ;
3958
3959 opt_type_modifiers: '(' expr_list ')'   { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3960                 | /* EMPTY */           { $$ = EMPTY; }
3961                 ;
3962                 
3963 /* SQL92 numeric data types
3964  * Check FLOAT() precision limits assuming IEEE floating types.
3965  * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3966  * - thomas 1997-09-18
3967  */
3968 Numeric:  INT_P
3969                         { $$ = make_str("int"); }
3970                 | INTEGER
3971                         { $$ = make_str("integer"); }
3972                 | SMALLINT
3973                         { $$ = make_str("smallint"); }
3974                 | BIGINT
3975                         { $$ = make_str("bigint"); }
3976                 | REAL
3977                         { $$ = make_str("real"); }
3978                 | FLOAT_P opt_float
3979                         { $$ = cat2_str(make_str("float"), $2); }
3980                 | DOUBLE_P PRECISION
3981                         { $$ = make_str("double precision"); }
3982                 | DECIMAL_P opt_type_modifiers
3983                         { $$ = cat2_str(make_str("decimal"), $2); }
3984                 | DEC opt_type_modifiers
3985                         { $$ = cat2_str(make_str("dec"), $2); }
3986                 | NUMERIC opt_type_modifiers
3987                         { $$ = cat2_str(make_str("numeric"), $2); }
3988                 | BOOLEAN_P
3989                         { $$ = make_str("boolean"); }
3990                 ;
3991
3992 opt_float:      '(' PosIntConst ')'
3993                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3994                 | /*EMPTY*/
3995                         { $$ = EMPTY; }
3996                 ;
3997
3998 /*
3999  * SQL92 bit-field data types
4000  * The following implements BIT() and BIT VARYING().
4001  */
4002
4003 Bit:    BitWithLength           { $$ = $1; }
4004                 | BitWithoutLength      { $$ = $1; }
4005                 ;
4006
4007 ConstBit:       BitWithLength   { $$ = $1; }
4008                 | BitWithoutLength      { $$ = $1; }
4009                 ;
4010
4011 BitWithLength:  BIT opt_varying '(' expr_list ')'
4012                         { $$ = cat_str(5, make_str("bit"), $2, make_str("("), $4, make_str(")")); }
4013                 ;
4014
4015 BitWithoutLength: BIT opt_varying
4016                         { $$ = cat2_str(make_str("bit"), $2); }
4017                 ;
4018
4019 /*
4020  * SQL92 character data types
4021  * The following implements CHAR() and VARCHAR().
4022  *                                                              - ay 6/95
4023  */
4024 Character:      CharacterWithLength             { $$ = $1; }
4025                 | CharacterWithoutLength        { $$ = $1; }
4026                 ;
4027
4028 ConstCharacter: CharacterWithLength     { $$ = $1; }
4029                 | CharacterWithoutLength        { $$ = $1; }
4030                 ;
4031
4032 CharacterWithLength: character '(' PosIntConst ')' opt_charset
4033                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
4034                 ;
4035
4036 CharacterWithoutLength: character opt_charset
4037                         { $$ = cat2_str($1, $2); }
4038                 ;
4039
4040 character:      CHARACTER opt_varying
4041                         { $$ = cat2_str(make_str("character"), $2); }
4042                 | CHAR_P opt_varying
4043                         { $$ = cat2_str(make_str("char"), $2); }
4044                 | VARCHAR
4045                         { $$ = make_str("varchar"); }
4046                 | NATIONAL CHARACTER opt_varying
4047                         { $$ = cat2_str(make_str("national character"), $3); }
4048                 | NATIONAL CHAR_P opt_varying
4049                         { $$ = cat2_str(make_str("national char"), $3); }
4050                 | NCHAR opt_varying
4051                         { $$ = cat2_str(make_str("nchar"), $2); }
4052                 ;
4053
4054 opt_varying:  VARYING
4055                         { $$ = make_str("varying"); }
4056                 | /*EMPTY*/
4057                         { $$ = EMPTY; }
4058                 ;
4059
4060 opt_charset:  CHARACTER SET ColId
4061                         { $$ = cat2_str(make_str("character set"), $3); }
4062                 | /*EMPTY*/
4063                         { $$ = EMPTY; }
4064                 ;
4065
4066 ConstDatetime:  TIMESTAMP '(' PosIntConst ')' opt_timezone
4067                         { $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5); }
4068                 | TIMESTAMP opt_timezone
4069                         { $$ = cat2_str(make_str("timestamp"), $2); }
4070                 | TIME '(' PosIntConst ')' opt_timezone
4071                         { $$ = cat_str(4, make_str("time("), $3, make_str(")"), $5); }
4072                 | TIME opt_timezone
4073                         { $$ = cat2_str(make_str("time"), $2); }
4074                 ;
4075
4076 ConstInterval:  INTERVAL
4077                         { $$ = make_str("interval"); }
4078                 ;
4079
4080 opt_timezone:  WITH TIME ZONE
4081                         { $$ = make_str("with time zone"); }
4082                 | WITHOUT TIME ZONE
4083                         { $$ = make_str("without time zone"); }
4084                 | /*EMPTY*/
4085                         { $$ = EMPTY; }
4086                 ;
4087
4088 opt_interval:  YEAR_P                   { $$ = make_str("year"); }
4089                 | MONTH_P                               { $$ = make_str("month"); }
4090                 | DAY_P                                 { $$ = make_str("day"); }
4091                 | HOUR_P                                { $$ = make_str("hour"); }
4092                 | MINUTE_P                              { $$ = make_str("minute"); }
4093                 | SECOND_P                              { $$ = make_str("second"); }
4094                 | YEAR_P TO MONTH_P             { $$ = make_str("year to month"); }
4095                 | DAY_P TO HOUR_P               { $$ = make_str("day to hour"); }
4096                 | DAY_P TO MINUTE_P             { $$ = make_str("day to minute"); }
4097                 | DAY_P TO SECOND_P             { $$ = make_str("day to second"); }
4098                 | HOUR_P TO MINUTE_P    { $$ = make_str("hour to minute"); }
4099                 | MINUTE_P TO SECOND_P  { $$ = make_str("minute to second"); }
4100                 | HOUR_P TO SECOND_P    { $$ = make_str("hour to second"); }
4101                 | /*EMPTY*/                             { $$ = EMPTY; }
4102                 ;
4103
4104
4105 /*****************************************************************************
4106  *
4107  *      expression grammar
4108  *
4109  *****************************************************************************/
4110
4111 /* General expressions
4112  * This is the heart of the expression syntax.
4113  *
4114  * We have two expression types: a_expr is the unrestricted kind, and
4115  * b_expr is a subset that must be used in some places to avoid shift/reduce
4116  * conflicts.  For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
4117  * because that use of AND conflicts with AND as a boolean operator.  So,
4118  * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
4119  *
4120  * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
4121  * always be used by surrounding it with parens.
4122  *
4123  * c_expr is all the productions that are common to a_expr and b_expr;
4124  * it's factored out just to eliminate redundant coding.
4125  */
4126
4127 a_expr:  c_expr
4128                         { $$ = $1; }
4129                 | a_expr TYPECAST Typename
4130                         { $$ = cat_str(3, $1, make_str("::"), $3); }
4131                 | a_expr AT TIME ZONE a_expr
4132                         { $$ = cat_str(3, $1, make_str("at time zone"), $5); }
4133                 /*
4134                  * These operators must be called out explicitly in order to make use
4135                  * of yacc/bison's automatic operator-precedence handling.  All other
4136                  * operator names are handled by the generic productions using "Op",
4137                  * below; and all those operators will have the same precedence.
4138                  *
4139                  * If you add more explicitly-known operators, be sure to add them
4140                  * also to b_expr and to the MathOp list above.
4141                  */
4142                 | '+' a_expr %prec UMINUS
4143                         { $$ = cat2_str(make_str("+"), $2); }
4144                 | '-' a_expr %prec UMINUS
4145                         { $$ = cat2_str(make_str("-"), $2); }
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 '>' a_expr
4161                         { $$ = cat_str(3, $1, make_str(">"), $3); }
4162                 | a_expr '=' a_expr
4163                         { $$ = cat_str(3, $1, make_str("="), $3); }
4164                 | a_expr qual_Op a_expr         %prec Op
4165                         { $$ = cat_str(3, $1, $2, $3); }
4166                 | qual_Op a_expr                %prec Op
4167                         { $$ = cat2_str($1, $2); }
4168                 | a_expr qual_Op                %prec POSTFIXOP
4169                         { $$ = cat2_str($1, $2); }
4170                 | a_expr AND a_expr
4171                         { $$ = cat_str(3, $1, make_str("and"), $3); }
4172                 | a_expr OR a_expr
4173                         { $$ = cat_str(3, $1, make_str("or"), $3); }
4174                 | NOT a_expr
4175                         { $$ = cat2_str(make_str("not"), $2); }
4176                 | a_expr LIKE a_expr
4177                         { $$ = cat_str(3, $1, make_str("like"), $3); }
4178                 | a_expr LIKE a_expr ESCAPE a_expr
4179                         { $$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
4180                 | a_expr NOT LIKE a_expr
4181                         { $$ = cat_str(3, $1, make_str("not like"), $4); }
4182                 | a_expr NOT LIKE a_expr ESCAPE a_expr
4183                         { $$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
4184                 | a_expr ILIKE a_expr
4185                         { $$ = cat_str(3, $1, make_str("ilike"), $3); }
4186                 | a_expr ILIKE a_expr ESCAPE a_expr
4187                         { $$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
4188                 | a_expr NOT ILIKE a_expr
4189                         { $$ = cat_str(3, $1, make_str("not ilike"), $4); }
4190                 | a_expr NOT ILIKE a_expr ESCAPE a_expr
4191                         { $$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
4192                 | a_expr SIMILAR TO a_expr      %prec SIMILAR
4193                         { $$ = cat_str(3, $1, make_str("similar to"), $4); }
4194                 | a_expr SIMILAR TO a_expr ESCAPE a_expr
4195                         { $$ = cat_str(5, $1, make_str("similar to"), $4, make_str("escape"), $6); }
4196                 | a_expr NOT SIMILAR TO a_expr  %prec SIMILAR
4197                         { $$ = cat_str(3, $1, make_str("not similar to"), $5); }
4198                 | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
4199                         { $$ = cat_str(5, $1, make_str("not similar to"), $5, make_str("escape"), $7); }
4200                 | a_expr ISNULL
4201                         { $$ = cat2_str($1, make_str("isnull")); }
4202                 | a_expr IS NULL_P
4203                         { $$ = cat2_str($1, make_str("is null")); }
4204                 | a_expr NOTNULL
4205                         { $$ = cat2_str($1, make_str("notnull")); }
4206                 | a_expr IS NOT NULL_P
4207                         { $$ = cat2_str($1, make_str("is not null")); }
4208                 | row OVERLAPS row
4209                         { $$ = cat_str(3, $1, make_str("overlaps"), $3); }
4210                 /* IS TRUE, IS FALSE, etc used to be function calls
4211                  *      but let's make them expressions to allow the optimizer
4212                  *      a chance to eliminate them if a_expr is a constant string.
4213                  * - thomas 1997-12-22
4214                  *
4215                  *      Created BooleanTest Node type, and changed handling
4216                  *      for NULL inputs
4217                  * - jec 2001-06-18
4218                  */
4219                 | a_expr IS TRUE_P
4220                         { $$ = cat2_str($1, make_str("is true")); }
4221                 | a_expr IS NOT TRUE_P
4222                         { $$ = cat2_str($1, make_str("is not true")); }
4223                 | a_expr IS FALSE_P
4224                         { $$ = cat2_str($1, make_str("is false")); }
4225                 | a_expr IS NOT FALSE_P
4226                         { $$ = cat2_str($1, make_str("is not false")); }
4227                 | a_expr IS UNKNOWN
4228                         { $$ = cat2_str($1, make_str("is unknown")); }
4229                 | a_expr IS NOT UNKNOWN
4230                         { $$ = cat2_str($1, make_str("is not unknown")); }
4231                 | a_expr IS DISTINCT FROM a_expr %prec IS
4232                         { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
4233                 | a_expr IS NOT DISTINCT FROM a_expr %prec IS
4234                         { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
4235                 | a_expr IS OF '(' type_list ')' %prec IS
4236                         { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
4237                 | a_expr IS NOT OF '(' type_list ')' %prec IS
4238                         { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
4239                 | a_expr BETWEEN opt_asymmetric b_expr AND b_expr       %prec BETWEEN
4240                         { $$ = cat_str(6, $1, make_str("between"), $3, $4, make_str("and"), $6); }
4241                 | a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr   %prec BETWEEN
4242                         { $$ = cat_str(6, $1, make_str("not between"), $4, $5, make_str("and"), $7); }
4243                 | a_expr BETWEEN SYMMETRIC b_expr AND b_expr    %prec BETWEEN
4244                         { $$ = cat_str(5, $1, make_str("between symmetric"), $4, make_str("and"), $6); }
4245                 | a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr        %prec BETWEEN
4246                         { $$ = cat_str(5, $1, make_str("not between symmetric"), $5, make_str("and"), $7); }
4247                 | a_expr IN_P in_expr
4248                         { $$ = cat_str(3, $1, make_str("in"), $3); }
4249                 | a_expr NOT IN_P in_expr
4250                         { $$ = cat_str(3, $1, make_str("not in"), $4); }
4251                 | a_expr subquery_Op sub_type select_with_parens %prec Op
4252                         { $$ = cat_str(4, $1, $2, $3, $4); }
4253                 | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
4254                         { $$ = cat_str(6, $1, $2, $3, make_str("("), $5, make_str(")")); }
4255                 | UNIQUE select_with_parens 
4256                         { $$ = cat2_str(make_str("unique"), $2); }
4257                 | a_expr IS DOCUMENT_P
4258                         { $$ = cat2_str($1, make_str("is document")); }
4259                 | a_expr IS NOT DOCUMENT_P
4260                         { $$ = cat2_str($1, make_str("is not document")); }
4261                 ;
4262
4263 /* Restricted expressions
4264  *
4265  * b_expr is a subset of the complete expression syntax
4266  *
4267  * Presently, AND, NOT, IS and IN are the a_expr keywords that would
4268  * cause trouble in the places where b_expr is used.  For simplicity, we
4269  * just eliminate all the boolean-keyword-operator productions from b_expr.
4270  */
4271 b_expr:  c_expr
4272                         { $$ = $1; }
4273                 | b_expr TYPECAST Typename
4274                         { $$ = cat_str(3, $1, make_str("::"), $3); }
4275                 | '-' b_expr %prec UMINUS
4276                         { $$ = cat2_str(make_str("-"), $2); }
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 '>' b_expr
4292                         { $$ = cat_str(3, $1, make_str(">"), $3); }
4293                 | b_expr '=' b_expr
4294                         { $$ = cat_str(3, $1, make_str("="), $3); }
4295                 | b_expr Op b_expr
4296                         { $$ = cat_str(3, $1, $2, $3); }
4297                 | qual_Op b_expr                %prec Op
4298                         { $$ = cat2_str($1, $2); }
4299                 | b_expr qual_Op                %prec POSTFIXOP
4300                         { $$ = cat2_str($1, $2); }
4301                 | b_expr IS DISTINCT FROM b_expr %prec IS
4302                         { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
4303                 | b_expr IS NOT DISTINCT FROM b_expr %prec IS
4304                         { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
4305                 | b_expr IS OF '(' b_expr ')' %prec IS
4306                         { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
4307                 | b_expr IS NOT OF '(' b_expr ')' %prec IS
4308                         { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
4309                 | b_expr IS DOCUMENT_P
4310                         { $$ = cat2_str($1, make_str("is document")); }
4311                 | b_expr IS NOT DOCUMENT_P
4312                         { $$ = cat2_str($1, make_str("is not document")); }
4313                 ;
4314
4315 /*
4316  * Productions that can be used in both a_expr and b_expr.
4317  *
4318  * Note: productions that refer recursively to a_expr or b_expr mostly
4319  * cannot appear here.  However, it's OK to refer to a_exprs that occur
4320  * inside parentheses, such as function arguments; that cannot introduce
4321  * ambiguity to the b_expr syntax.
4322  */
4323 c_expr: columnref
4324                         { $$ = $1;      }
4325                 | AexprConst
4326                         { $$ = $1;      }
4327                 | PARAM opt_indirection
4328                         { $$ = cat2_str(make_str("param"), $2); }
4329                 | '(' a_expr ')' opt_indirection
4330                         { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
4331                 | case_expr
4332                         { $$ = $1; }
4333                 | func_expr
4334                         { $$ = $1; }
4335                 | select_with_parens    %prec UMINUS
4336                         { $$ = $1; }
4337                 | EXISTS select_with_parens
4338                         { $$ = cat2_str(make_str("exists"), $2); }
4339                 | ARRAY select_with_parens
4340                         { $$ = cat2_str(make_str("array"), $2); }
4341                 | ARRAY array_expr
4342                         { $$ = cat2_str(make_str("array"), $2); }
4343                 | row
4344                         { $$ = $1; }
4345                 ;
4346
4347 /*
4348  * func_expr is split out from c_expr just so that we have a classification
4349  * for "everything that is a function call or looks like one".  This isn't
4350  * very important, but it saves us having to document which variants are
4351  * legal in the backwards-compatible functional-index syntax for CREATE INDEX.
4352  * (Note that many of the special SQL functions wouldn't actually make any
4353  * sense as functional index entries, but we ignore that consideration here.)
4354  */
4355 func_expr:      func_name '(' ')'
4356                         { $$ = cat2_str($1, make_str("()"));    }
4357                 | func_name '(' expr_list ')'
4358                         { $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));        }
4359                 | func_name '(' ALL expr_list ')'
4360                         { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")"));    }
4361                 | func_name '(' DISTINCT expr_list ')'
4362                         { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")"));  }
4363                 | func_name '(' '*' ')'
4364                         { $$ = cat2_str($1, make_str("(*)")); }
4365                 | CURRENT_DATE
4366                         { $$ = make_str("current_date"); }
4367                 | CURRENT_TIME
4368                         { $$ = make_str("current_time"); }
4369                 | CURRENT_TIME '(' PosIntConst ')'
4370                         { $$ = cat_str(3, make_str("current_time ("), $3, make_str(")")); }
4371                 | CURRENT_TIMESTAMP
4372                         { $$ = make_str("current_timestamp"); }
4373                 | CURRENT_TIMESTAMP '(' PosIntConst ')'
4374                         { $$ = cat_str(3, make_str("current_timestamp ("), $3, make_str(")")); }
4375                 | LOCALTIME
4376                         { $$ = make_str("localtime"); }
4377                 | LOCALTIME '(' PosIntConst ')'
4378                         { $$ = cat_str(3, make_str("localtime ("), $3, make_str(")")); }
4379                 | LOCALTIMESTAMP
4380                         { $$ = make_str("local_timestamp"); }
4381                 | LOCALTIMESTAMP '(' PosIntConst ')'
4382                         { $$ = cat_str(3, make_str("locale_timestamp ("), $3, make_str(")")); }
4383                 | CURRENT_ROLE
4384                         { $$ = make_str("current_role"); }
4385                 | CURRENT_USER
4386                         { $$ = make_str("current_user"); }
4387                 | SESSION_USER
4388                         { $$ = make_str("session_user"); }
4389                 | USER
4390                         { $$ = make_str("user"); }
4391                 | CAST '(' a_expr AS Typename ')'
4392                         { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
4393                 | EXTRACT '(' extract_list ')'
4394                         { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
4395                 | OVERLAY '(' overlay_list ')'
4396                         { $$ = cat_str(3, make_str("overlay("), $3, make_str(")")); }
4397                 | POSITION '(' position_list ')'
4398                         { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
4399                 | SUBSTRING '(' substr_list ')'
4400                         { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
4401                 | TREAT '(' a_expr AS Typename ')'
4402                         { $$ = cat_str(5, make_str("treat("), $3, make_str("as"), $5, make_str(")")); }
4403                 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4404                 | TRIM '(' BOTH trim_list ')'
4405                         { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
4406                 | TRIM '(' LEADING trim_list ')'
4407                         { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
4408                 | TRIM '(' TRAILING trim_list ')'
4409                         { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
4410                 | TRIM '(' trim_list ')'
4411                         { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
4412                 | NULLIF '(' a_expr ',' a_expr ')'
4413                         { $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")")); }
4414                 | COALESCE '(' expr_list ')'
4415                         { $$ = cat_str(3, make_str("coalesce("), $3, make_str(")")); }
4416                 | GREATEST '(' expr_list ')'
4417                         { $$ = cat_str(3, make_str("greatest("), $3, make_str(")")); }
4418                 | LEAST '(' expr_list ')'
4419                         { $$ = cat_str(3, make_str("least("), $3, make_str(")")); }
4420                 | XMLCONCAT '(' expr_list ')'
4421                         { $$ = cat_str(3, make_str("xmlconcat("), $3, make_str(")")); }
4422                 | XMLELEMENT '(' NAME_P ColLabel ')'
4423                         { $$ = cat_str(3, make_str("xmlelement( name"), $4, make_str(")")); }
4424                 | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ')'
4425                         { $$ = cat_str(5, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(")")); }
4426                 | XMLELEMENT '(' NAME_P ColLabel ',' expr_list ')'
4427                         { $$ = cat_str(5, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(")")); }
4428                 | XMLELEMENT '(' NAME_P ColLabel ',' xml_attributes ',' expr_list ')'
4429                         { $$ = cat_str(7, make_str("xmlelement( name"), $4, make_str(","), $6, make_str(","), $8, make_str(")")); }
4430                 | XMLFOREST '(' xml_attribute_list ')'
4431                         { $$ = cat_str(3, make_str("xmlforest("), $3, make_str(")")); }
4432                 | XMLPARSE '(' document_or_content a_expr xml_whitespace_option ')'
4433                         { $$ = cat_str(5, make_str("xmlparse("), $3, $4, $5, make_str(")")); }
4434                 | XMLPI '(' NAME_P ColLabel ')'
4435                         { $$ = cat_str(3, make_str("xmlpi( name"), $4, make_str(")")); }
4436                 | XMLPI '(' NAME_P ColLabel ',' a_expr ')'
4437                         { $$ = cat_str(5, make_str("xmlpi( name"), $4, make_str(","), $6, make_str(")")); }
4438                 | XMLROOT '(' a_expr ',' xml_root_version opt_xml_root_standalone  ')'
4439                         { $$ = cat_str(6, make_str("xmlroot("), $3, make_str(","), $5, $6, make_str(")")); }
4440                 ;
4441
4442 /*
4443  * SQL/XML support
4444  */
4445
4446 xml_root_version: VERSION_P a_expr
4447                         { $$ = cat2_str(make_str("version"), $2); }
4448                 | VERSION_P NO VALUE_P
4449                         { $$ = make_str("version no value"); }
4450                 ;
4451
4452 opt_xml_root_standalone: ',' STANDALONE_P YES_P
4453                                 { $$ = make_str(", standalone yes"); }
4454                         | ',' STANDALONE_P NO
4455                                 { $$ = make_str(", standalone no"); }
4456                         | ',' STANDALONE_P NO VALUE_P
4457                                 { $$ = make_str(", standalone no value"); }
4458                         | /*EMPTY*/
4459                                 { $$ = EMPTY; }
4460                         ;
4461
4462 xml_attributes:         XMLATTRIBUTES '(' xml_attribute_list ')'
4463                                 { $$ = cat_str(3, make_str("xmlattributes("), $3, make_str(")")); }
4464                         ;
4465
4466 xml_attribute_list:     xml_attribute_el
4467                                 { $$ = $1; }
4468                         | xml_attribute_list ',' xml_attribute_el
4469                                 { $$ = cat_str(3, $1, make_str(","), $3); }
4470                         ;
4471
4472 xml_attribute_el: a_expr AS ColLabel
4473                         { $$ = cat_str(3, $1, make_str("as"), $3); }
4474                 | a_expr
4475                         { $$ = $1; }
4476                 ;
4477
4478 document_or_content: DOCUMENT_P         { $$ = make_str("document"); }
4479                         | CONTENT_P     { $$ = make_str("content"); }
4480                         ;
4481
4482 xml_whitespace_option: PRESERVE WHITESPACE_P    { $$ = make_str("preserve whitespace"); }
4483                         | STRIP_P WHITESPACE_P  { $$ = make_str("strip whitespace"); }
4484                         | /*EMPTY*/             { $$ = EMPTY; }
4485                         ;
4486
4487 row: ROW '(' expr_list ')'
4488                         { $$ = cat_str(3, make_str("row ("), $3, make_str(")")); }
4489                 | ROW '(' ')'
4490                         { $$ = make_str("row()"); }
4491                 | '(' expr_list ',' a_expr ')'
4492                         { $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")")); }
4493                 ;
4494
4495 sub_type:  ANY          { $$ = make_str("ANY"); }
4496                 | SOME          { $$ = make_str("SOME"); }
4497                 | ALL           { $$ = make_str("ALL"); }
4498                 ;
4499
4500 all_Op:  Op                             { $$ = $1; }
4501                 | MathOp                        { $$ = $1; }
4502                 ;
4503
4504 MathOp: '+'                             { $$ = make_str("+"); }
4505                 | '-'                   { $$ = make_str("-"); }
4506                 | '*'                   { $$ = make_str("*"); }
4507                 | '%'                   { $$ = make_str("%"); }
4508                 | '^'                   { $$ = make_str("^"); }
4509                 | '/'                   { $$ = make_str("/"); }
4510                 | '<'                   { $$ = make_str("<"); }
4511                 | '>'                   { $$ = make_str(">"); }
4512                 | '='                   { $$ = make_str("="); }
4513                 ;
4514
4515 qual_Op:  Op                            { $$ = $1; }
4516                 | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
4517                 ;
4518
4519 qual_all_Op:  all_Op                            { $$ = $1; }
4520                 | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
4521                 ;
4522
4523 subquery_Op:  all_Op                            { $$ = $1; }
4524                 | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
4525                 | LIKE                          { $$ = make_str("like"); }
4526                 | NOT LIKE                      { $$ = make_str("not like"); }
4527                 | ILIKE                         { $$ = make_str("ilike"); }
4528                 | NOT ILIKE                     { $$ = make_str("not ilike"); }
4529                 ;
4530
4531 expr_list:      a_expr
4532                         { $$ = $1; }
4533                 | expr_list ',' a_expr
4534                         { $$ = cat_str(3, $1, make_str(","), $3); }
4535                 ;
4536
4537 extract_list:  extract_arg FROM a_expr
4538                         { $$ = cat_str(3, $1, make_str("from"), $3); }
4539                 | /* EMPTY */
4540                         { $$ = EMPTY; }
4541                 ;
4542
4543 type_list:       Typename
4544                         { $$ = $1; }
4545                 | type_list ',' Typename
4546                         { $$ = cat_str(3, $1, ',', $3); }
4547                 ;
4548
4549 array_expr_list: array_expr                             { $$ = $1; }
4550                 | array_expr_list ',' array_expr        { $$ = cat_str(3, $1, make_str(","), $3); }
4551                 ;
4552
4553
4554 array_expr: '[' expr_list ']'                   { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
4555                 | '[' array_expr_list ']'       { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
4556                 ;
4557 /* Allow delimited string SCONST in extract_arg as an SQL extension.
4558  * - thomas 2001-04-12
4559  */
4560
4561 extract_arg:  ident                             { $$ = $1; }
4562                 | YEAR_P                                { $$ = make_str("year"); }
4563                 | MONTH_P                               { $$ = make_str("month"); }
4564                 | DAY_P                                 { $$ = make_str("day"); }
4565                 | HOUR_P                                { $$ = make_str("hour"); }
4566                 | MINUTE_P                              { $$ = make_str("minute"); }
4567                 | SECOND_P                              { $$ = make_str("second"); }
4568                 | StringConst                   { $$ = $1; }
4569                 ;
4570
4571 overlay_list:
4572                 a_expr overlay_placing substr_from substr_for
4573                         { $$ = cat_str(4, $1, 42, $3, $4); }
4574                 | a_expr overlay_placing substr_from
4575                         { $$ = cat_str(3, $1, $2, $3); }
4576                 ;
4577
4578 overlay_placing:
4579                 PLACING a_expr          { $$ = cat2_str(make_str("placing"), $2); }
4580                 ;
4581
4582 /* position_list uses b_expr not a_expr to avoid conflict with general IN */
4583 position_list:  b_expr IN_P b_expr
4584                         { $$ = cat_str(3, $1, make_str("in"), $3); }
4585                 | /* EMPTY */
4586                         { $$ = EMPTY; }
4587                 ;
4588
4589 substr_list:  a_expr substr_from substr_for
4590                         { $$ = cat_str(3, $1, $2, $3); }
4591                 | a_expr substr_for substr_from
4592                         { $$ = cat_str(3, $1, $2, $3); }
4593                 | a_expr substr_from
4594                         { $$ = cat2_str($1, $2); }
4595                 | a_expr substr_for
4596                         { $$ = cat2_str($1, $2); }
4597                 | expr_list
4598                         { $$ = $1; }
4599                 | /* EMPTY */
4600                         { $$ = EMPTY; }
4601                 ;
4602
4603 substr_from:  FROM a_expr
4604                         { $$ = cat2_str(make_str("from"), $2); }
4605                 ;
4606
4607 substr_for:  FOR a_expr
4608                         { $$ = cat2_str(make_str("for"), $2); }
4609                 ;
4610
4611 trim_list:      a_expr FROM expr_list
4612                         { $$ = cat_str(3, $1, make_str("from"), $3); }
4613                 | FROM expr_list
4614                         { $$ = cat2_str(make_str("from"), $2); }
4615                 | expr_list
4616                         { $$ = $1; }
4617                 ;
4618
4619 in_expr:  select_with_parens
4620                         { $$ = $1; }
4621                 | '(' expr_list ')'
4622                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
4623                 ;
4624
4625 /* Case clause
4626  * Define SQL92-style case clause.
4627  */
4628 case_expr:      CASE case_arg when_clause_list case_default END_P
4629                         { $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
4630                 ;
4631
4632 when_clause_list:  when_clause_list when_clause
4633                         { $$ = cat2_str($1, $2); }
4634                 | when_clause
4635                         { $$ = $1; }
4636                 ;
4637
4638 when_clause:  WHEN a_expr THEN a_expr
4639                         { $$ = cat_str(4, make_str("when"), $2, make_str("then"), $4); }
4640                 ;
4641
4642 case_default:  ELSE a_expr
4643                         { $$ = cat2_str(make_str("else"), $2); }
4644                 | /*EMPTY*/
4645                         { $$ = EMPTY; }
4646                 ;
4647
4648 case_arg:  a_expr                       { $$ = $1; }
4649                 | /*EMPTY*/             { $$ = EMPTY; }
4650                 ;
4651
4652 columnref: relation_name                { $$ = $1; }
4653                 | relation_name indirection     { $$ = cat2_str($1, $2); }
4654                 ;
4655
4656 indirection_el:
4657                 '.' attr_name                   { $$ = cat2_str(make_str("."), $2); }
4658                 | '.' '*'                       { $$ = make_str(".*"); }
4659                 | '[' a_expr ']'                { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
4660                 | '[' a_expr ':' a_expr ']'     { $$ = cat_str(5, make_str("["), $2, make_str(":"), $4, make_str("]")); }
4661                 ;
4662
4663 indirection:    indirection_el          { $$ = $1; }
4664                 | indirection indirection_el    { $$ = cat2_str($1, $2); }
4665                 ;
4666
4667 opt_indirection:
4668                 /*EMPTY*/                               { $$ = EMPTY; }
4669                 | opt_indirection indirection_el        { $$ = cat2_str($1, $2);}
4670                 ;
4671
4672 opt_asymmetric: ASYMMETRIC      { $$ = make_str("asymmetric"); }
4673                 | /*EMPTY*/             { $$ = EMPTY; }
4674                 ;
4675
4676 ctext_expr:
4677                 a_expr          { $$ = $1; }
4678                 | DEFAULT       { $$ = make_str("default"); }
4679                 ;
4680
4681 ctext_expr_list:
4682                  ctext_expr                             { $$ = $1; }
4683                  |  ctext_expr_list ',' ctext_expr      { $$ = cat_str(3, $1, make_str(","), $3); }
4684                  ;
4685
4686 ctext_row: '(' ctext_expr_list ')'      { $$ = cat_str(3, make_str("("), $2, make_str(")"));};
4687
4688 /*****************************************************************************
4689  *
4690  *      target lists for SELECT
4691  *
4692  *****************************************************************************/
4693
4694 target_list:  target_list ',' target_el
4695                         { $$ = cat_str(3, $1, make_str(","), $3);  }
4696                 | target_el
4697                         { $$ = $1;      }
4698                 ;
4699
4700 /* AS is not optional because shift/red conflict with unary ops */
4701 target_el:      a_expr AS ColLabel
4702                         { $$ = cat_str(3, $1, make_str("as"), $3); }
4703                 | a_expr
4704                         { $$ = $1; }
4705                 | '*'
4706                         { $$ = make_str("*"); }
4707                 ;
4708
4709 /* INFORMIX workaround, no longer needed
4710 update_target_list:  '(' inf_col_list ')' '=' '(' inf_val_list ')'
4711                 {
4712                         struct inf_compat_col *ptrc;
4713                         struct inf_compat_val *ptrv;
4714                         char *cols = make_str( "(" );
4715                         char *vals = make_str( "(" );
4716
4717                         for (ptrc = informix_col, ptrv = informix_val; ptrc != NULL && ptrv != NULL; ptrc = ptrc->next, ptrv = ptrv->next)
4718                         {
4719                                 if ( ptrc->next != NULL )
4720                                 {
4721                                         cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(",") );
4722                                 }
4723                                 else
4724                                 {
4725                                         cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(")") );
4726                                 }
4727                                 if (ptrv->next != NULL )
4728                                         vals = cat_str(3, vals, ptrv->val, make_str("," ) );
4729                                 else
4730                                         vals = cat_str( 3, vals, ptrv->val, make_str(")") );
4731                         }
4732                         $$ = cat_str( 3, cols, make_str("="), vals );
4733                 } 
4734                 ;
4735
4736 inf_col_list: ColId opt_indirection
4737                 {
4738                         struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
4739
4740                         ptr->name = $1;
4741                         ptr->indirection = $2;
4742                         ptr->next = NULL;
4743                         informix_col = ptr;
4744                 }
4745                 | ColId opt_indirection ',' inf_col_list
4746                 {
4747                         struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
4748
4749                         ptr->name = $1;
4750                         ptr->indirection = $2;
4751                         ptr->next = informix_col;
4752                         informix_col = ptr;
4753                 }
4754                 ;
4755
4756 inf_val_list: a_expr
4757                 {
4758                         struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
4759
4760                         ptr->val = $1;
4761                         ptr->next = NULL;
4762                         informix_val = ptr;
4763                 }
4764                 | a_expr ',' inf_val_list
4765                 {
4766                         struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
4767
4768                         ptr->val = $1;
4769                         ptr->next = informix_val;
4770                         informix_val = ptr;
4771                 }
4772                 ;
4773 */
4774
4775 /*****************************************************************************
4776  *
4777  *         Names and constants
4778  *
4779  *****************************************************************************/
4780
4781 relation_name:  SpecialRuleRelation     { $$ = $1; }
4782                 | ColId                 { $$ = $1; }
4783                 ;
4784
4785 qualified_name_list:  qualified_name
4786                                 { $$ = $1; }
4787                 | qualified_name_list ',' qualified_name
4788                                 { $$ = cat_str(3, $1, make_str(","), $3); }
4789                 ;
4790
4791 qualified_name: relation_name
4792                 { $$ = $1; }
4793                 | relation_name indirection
4794                 { $$ = cat2_str($1, $2); }
4795                 ;
4796
4797 name_list:  name
4798                         { $$ = $1; }
4799                 | name_list ',' name
4800                         { $$ = cat_str(3, $1, make_str(","), $3); }
4801                 ;
4802
4803
4804 name:                           ColId                   { $$ = $1; };
4805 database_name:          ColId                   { $$ = $1; };
4806 access_method:          ColId                   { $$ = $1; };
4807 attr_name:                      ColLabel                { $$ = $1; };
4808 index_name:                     ColId                   { $$ = $1; };
4809
4810 file_name:                      StringConst             { $$ = $1; };
4811
4812 func_name: type_function_name
4813                         { $$ = $1; }
4814                 | relation_name indirection
4815                         { $$ = cat2_str($1, $2); }
4816                 ;
4817
4818
4819 /* Constants
4820  * Include TRUE/FALSE for SQL3 support. - thomas 1997-10-24
4821  */
4822 AexprConst:  PosAllConst
4823                         { $$ = $1; }
4824                 | ConstTypename StringConst
4825                         { $$ = cat2_str($1, $2); }
4826                 | ConstInterval StringConst opt_interval
4827                         { $$ = cat_str(3, $1, $2, $3); }
4828                 | ConstInterval  '(' PosIntConst ')' StringConst opt_interval
4829                         { $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
4830                 | TRUE_P
4831                         { $$ = make_str("true"); }
4832                 | FALSE_P
4833                         { $$ = make_str("false"); }
4834                 | NULL_P
4835                         { $$ = make_str("null"); }
4836                 | civarind
4837                         { $$ = $1; }
4838                 ;
4839
4840 Iconst:  ICONST                         { $$ = make_name();};
4841 Fconst:  FCONST                         { $$ = make_name();};
4842 Bconst:  BCONST                         { $$ = make_name();};
4843 Xconst:  XCONST                         { $$ = make_name();};
4844 Sconst:  SCONST
4845                 {
4846                         /* could have been input as '' or $$ */
4847                         $$ = (char *)mm_alloc(strlen($1) + 3);
4848                         $$[0]='\'';
4849                         strcpy($$+1, $1);
4850                         $$[strlen($1)+1]='\'';
4851                         $$[strlen($1)+2]='\0';
4852                         free($1);
4853                 }
4854         | ECONST
4855                 {
4856                         /* escaped quote starting with E */
4857                         $$ = (char *)mm_alloc(strlen($1) + 4);
4858                         $$[0]='E';
4859                         $$[1]='\'';
4860                         strcpy($$+2, $1);
4861                         $$[strlen($1)+2]='\'';
4862                         $$[strlen($1)+3]='\0';
4863                         free($1);
4864                 }
4865         | NCONST
4866                 {
4867                         /* escaped quote starting with rNE */
4868                         $$ = (char *)mm_alloc(strlen($1) + 4);
4869                         $$[0]='N';
4870                         $$[1]='\'';
4871                         strcpy($$+2, $1);
4872                         $$[strlen($1)+2]='\'';
4873                         $$[strlen($1)+3]='\0';
4874                         free($1);
4875                 }
4876         | DOLCONST
4877                 {
4878                         $$ = $1; 
4879                 }
4880         ;
4881
4882 PosIntConst:    Iconst          { $$ = $1; }
4883                 | civar         { $$ = $1; }
4884                 ;
4885
4886 IntConst:       PosIntConst             { $$ = $1; }
4887                 | '-' PosIntConst       { $$ = cat2_str(make_str("-"), $2); }
4888                 ;
4889
4890 IntConstVar:    Iconst
4891                 {
4892                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4893
4894                         sprintf(length, "%d", (int) strlen($1));
4895                         new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4896                         $$ = $1;
4897                 }
4898                 | cvariable     { $$ = $1; }
4899                 ;
4900
4901 AllConstVar:    Fconst
4902                 {
4903                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4904
4905                         sprintf(length, "%d", (int) strlen($1));
4906                         new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4907                         $$ = $1;
4908                 }
4909                 | IntConstVar           { $$ = $1; }
4910                 | '-' Fconst
4911                 {
4912                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4913                         char *var = cat2_str(make_str("-"), $2);
4914
4915                         sprintf(length, "%d", (int) strlen(var));
4916                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4917                         $$ = var;
4918                 }
4919                 | '-' Iconst
4920                 {
4921                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4922                         char *var = cat2_str(make_str("-"), $2);
4923
4924                         sprintf(length, "%d", (int) strlen(var));
4925                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4926                         $$ = var;
4927                 }
4928                 | Sconst
4929                 {
4930                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
4931                         char *var = $1 + 1;
4932
4933                         var[strlen(var) - 1] = '\0';
4934                         sprintf(length, "%d", (int) strlen(var));
4935                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
4936                         $$ = var;
4937                 }
4938                 ;
4939
4940 StringConst:    Sconst          { $$ = $1; }
4941                 | civar         { $$ = $1; }
4942                 ;
4943
4944 PosIntStringConst:      Iconst  { $$ = $1; }
4945                 | Sconst        { $$ = $1; }
4946                 | civar         { $$ = $1; }
4947                 ;
4948
4949 NumConst:       Fconst                  { $$ = $1; }
4950                 | Iconst                { $$ = $1; }
4951                 | '-' Fconst            { $$ = cat2_str(make_str("-"), $2); }
4952                 | '-' Iconst            { $$ = cat2_str(make_str("-"), $2); }
4953                 | civar                 { $$ = $1; }
4954                 ;
4955
4956 AllConst:       Sconst                  { $$ = $1; }
4957                 | NumConst              { $$ = $1; }
4958                 ;
4959
4960 PosAllConst:    Sconst                  { $$ = $1; }
4961                 | Fconst                { $$ = $1; }
4962                 | Iconst                { $$ = $1; }
4963                 | Bconst                { $$ = $1; }
4964                 | Xconst                { $$ = $1; }
4965                 | func_name Sconst      { $$ = cat2_str($1, $2); }
4966                 | func_name '(' expr_list ')' Sconst
4967                                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
4968                 | civar                 { $$ = $1; }
4969                 ;
4970
4971 RoleId:  ColId          { $$ = $1;};
4972
4973 SpecialRuleRelation:  OLD
4974                 {
4975                         if (!QueryIsRule)
4976                                 mmerror(PARSE_ERROR, ET_ERROR, "OLD used in non-rule query");
4977
4978                         $$ = make_str("old");
4979                 }
4980                 | NEW
4981                 {
4982                         if (!QueryIsRule)
4983                                 mmerror(PARSE_ERROR, ET_ERROR, "NEW used in non-rule query");
4984
4985                         $$ = make_str("new");
4986                 }
4987                 ;
4988
4989 /*
4990  * and now special embedded SQL stuff
4991  */
4992
4993 /*
4994  * the exec sql connect statement: connect to the given database
4995  */
4996 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
4997                         { $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4); }
4998                 | SQL_CONNECT TO DEFAULT
4999                         { $$ = make_str("NULL, NULL, NULL, \"DEFAULT\""); }
5000                   /* also allow ORACLE syntax */
5001                 | SQL_CONNECT ora_user
5002                         { $$ = cat_str(3, make_str("NULL,"), $2, make_str(", NULL")); }
5003                 | DATABASE connection_target
5004                         { $$ = cat2_str($2, make_str(", NULL, NULL, NULL")); }
5005                 ;
5006
5007 connection_target: opt_database_name opt_server opt_port
5008                 {
5009                         /* old style: dbname[@server][:port] */
5010                         if (strlen($2) > 0 && *($2) != '@')
5011                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected '@', found '%s'", $2);
5012                         
5013                         /* C strings need to be handled differently */
5014                         if ($1[0] == '\"')
5015                                 $$ = $1;
5016                         else
5017                                 $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
5018                 }
5019                 |  db_prefix ':' server opt_port '/' opt_database_name opt_options
5020                 {
5021                         /* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
5022                         if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
5023                                 mmerror(PARSE_ERROR, ET_ERROR, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
5024
5025                         if (strncmp($3, "//", strlen("//")) != 0)
5026                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected '://', found '%s'", $3);
5027
5028                         if (strncmp($1, "unix", strlen("unix")) == 0 &&
5029                                 strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
5030                                 strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
5031                                 mmerror(PARSE_ERROR, ET_ERROR, "unix domain sockets only work on 'localhost' but not on '%s'", $3 + strlen("//"));
5032
5033                         $$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6),    $7, make_str("\"")));
5034                 }
5035                 | char_variable
5036                 {
5037                         $$ = $1;
5038                 }
5039                 | Sconst
5040                 {
5041                         /* We can only process double quoted strings not single quotes ones,
5042                          * so we change the quotes.
5043                          * Note, that the rule for Sconst adds these single quotes. */
5044                         $1[0] = '\"';
5045                         $1[strlen($1)-1] = '\"';
5046                         $$ = $1;
5047                 }
5048                 ;
5049
5050 opt_database_name: database_name                { $$ = $1; }
5051                 | /*EMPTY*/                     { $$ = EMPTY; }
5052                 ;
5053
5054 db_prefix: ident cvariable
5055                 {
5056                         if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
5057                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected 'postgresql', found '%s'", $2);
5058
5059                         if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
5060                                 mmerror(PARSE_ERROR, ET_ERROR, "Illegal connection type %s", $1);
5061
5062                         $$ = make3_str($1, make_str(":"), $2);
5063                 }
5064                 ;
5065
5066 server: Op server_name
5067                 {
5068                         if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
5069                                 mmerror(PARSE_ERROR, ET_ERROR, "Expected '@' or '://', found '%s'", $1);
5070
5071                         $$ = make2_str($1, $2);
5072                 }
5073                 ;
5074
5075 opt_server: server                      { $$ = $1; }
5076                 | /*EMPTY*/                     { $$ = EMPTY; }
5077                 ;
5078
5079 server_name: ColId                                      { $$ = $1; }
5080                 | ColId '.' server_name         { $$ = make3_str($1, make_str("."), $3); }
5081                 | IP                                            { $$ = make_name(); }
5082                 ;
5083
5084 opt_port: ':' PosIntConst       { $$ = make2_str(make_str(":"), $2); }
5085                 | /*EMPTY*/     { $$ = EMPTY; }
5086                 ;
5087
5088 opt_connection_name: AS connection_object       { $$ = $2; }
5089                 | /*EMPTY*/                     { $$ = make_str("NULL"); }
5090                 ;
5091
5092 opt_user: USER ora_user         { $$ = $2; }
5093                 | /*EMPTY*/                     { $$ = make_str("NULL, NULL"); }
5094                 ;
5095
5096 ora_user: user_name
5097                         { $$ = cat2_str($1, make_str(", NULL")); }
5098                 | user_name '/' user_name
5099                         { $$ = cat_str(3, $1, make_str(","), $3); }
5100                 | user_name SQL_IDENTIFIED BY user_name
5101                         { $$ = cat_str(3, $1, make_str(","), $4); }
5102                 | user_name USING user_name
5103                         { $$ = cat_str(3, $1, make_str(","), $3); }
5104                 ;
5105
5106 user_name: RoleId
5107                 {
5108                         if ($1[0] == '\"')
5109                                 $$ = $1;
5110                         else
5111                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
5112                 }
5113                 | StringConst
5114                 {
5115                         if ($1[0] == '\"')
5116                                 $$ = $1;
5117                         else if ($1[1] == '$') /* variable */
5118                         {
5119                                 enum ECPGttype type = argsinsert->variable->type->type;
5120
5121                                 /* if array see what's inside */
5122                                 if (type == ECPGt_array)
5123                                         type = argsinsert->variable->type->u.element->type;
5124
5125                                 /* handle varchars */
5126                                 if (type == ECPGt_varchar)
5127                                         $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
5128                                 else
5129                                         $$ = mm_strdup(argsinsert->variable->name);
5130                         }
5131                         else
5132                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
5133                 }
5134                 ;
5135
5136 char_variable: cvariable
5137                 {
5138                         /* check if we have a string variable */
5139                         struct variable *p = find_variable($1);
5140                         enum ECPGttype type = p->type->type;
5141
5142                         /* If we have just one character this is not a string */
5143                         if (atol(p->type->size) == 1)
5144                                         mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
5145                         else
5146                         {
5147                                 /* if array see what's inside */
5148                                 if (type == ECPGt_array)
5149                                         type = p->type->u.element->type;
5150
5151                                 switch (type)
5152                                 {
5153                                         case ECPGt_char:
5154                                         case ECPGt_unsigned_char:
5155                                                 $$ = $1;
5156                                                 break;
5157                                         case ECPGt_varchar:
5158                                                 $$ = make2_str($1, make_str(".arr"));
5159                                                 break;
5160                                         default:
5161                                                 mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
5162                                                 break;
5163                                 }
5164                         }
5165                 }
5166                 ;
5167
5168 opt_options: Op ColId
5169                 {
5170                         if (strlen($1) == 0)
5171                                 mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
5172
5173                         if (strcmp($1, "?") != 0)
5174                                 mmerror(PARSE_ERROR, ET_ERROR, "unrecognised token '%s'", $1);
5175
5176                         $$ = make2_str(make_str("?"), $2);
5177                 }
5178                 | /*EMPTY*/     { $$ = EMPTY; }
5179                 ;
5180
5181 /*
5182  * Declare a prepared cursor. The syntax is different from the standard
5183  * declare statement, so we create a new rule.
5184  */
5185 ECPGCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR prepared_name
5186                 {
5187                         struct cursor *ptr, *this;
5188                         struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
5189                         const char *con = connection ? connection : "NULL";
5190
5191                         for (ptr = cur; ptr != NULL; ptr = ptr->next)
5192                         {
5193                                 if (strcmp($2, ptr->name) == 0)
5194                                         /* re-definition is a bug */
5195                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
5196                         }
5197
5198                         this = (struct cursor *) mm_alloc(sizeof(struct cursor));
5199
5200                         /* initial definition */
5201                         this->next = cur;
5202                         this->name = $2;
5203                         this->connection = connection;
5204                         this->command =  cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for $1"));
5205                         this->argsresult = NULL;
5206
5207                         thisquery->type = &ecpg_query;
5208                         thisquery->brace_level = 0;
5209                         thisquery->next = NULL;
5210                         thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
5211                         sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
5212
5213                         this->argsinsert = NULL;
5214                         add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
5215
5216                         cur = this;
5217
5218                         $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
5219                 }
5220                 ;
5221
5222 ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
5223                         { 
5224                           /* execute immediate means prepare the statement and
5225                            * immediately execute it */
5226                           $$ = $3;
5227                         };
5228 /*
5229  * variable decalartion outside exec sql declare block
5230  */
5231 ECPGVarDeclaration: single_vt_declaration;
5232
5233 single_vt_declaration: type_declaration         { $$ = $1; }
5234                 | var_declaration               { $$ = $1; }
5235                 ;
5236
5237 precision:      NumConst        { $$ = $1; };
5238
5239 opt_scale:      ',' NumConst    { $$ = $2; }
5240                 | /* EMPTY */   { $$ = EMPTY; }
5241                 ;
5242
5243 ecpg_interval:  opt_interval    { $$ = $1; }
5244                 | YEAR_P TO MINUTE_P    { $$ = make_str("year to minute"); }
5245                 | YEAR_P TO SECOND_P    { $$ = make_str("year to second"); }
5246                 | DAY_P TO DAY_P                { $$ = make_str("day to day"); }
5247                 | MONTH_P TO MONTH_P    { $$ = make_str("month to month"); }
5248                 ;
5249
5250 /*
5251  * variable declaration inside exec sql declare block
5252  */
5253 ECPGDeclaration: sql_startdeclare
5254                 { fputs("/* exec sql begin declare section */", yyout); }
5255                 var_type_declarations sql_enddeclare
5256                 {
5257                         fprintf(yyout, "%s/* exec sql end declare section */", $3);
5258                         free($3);
5259                         output_line_number();
5260                 }
5261                 ;
5262
5263 sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {};
5264
5265 sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {};
5266
5267 var_type_declarations:  /*EMPTY*/                       { $$ = EMPTY; }
5268                 | vt_declarations                       { $$ = $1; }
5269                 | CPP_LINE                              { $$ = $1; }
5270                 ;
5271
5272 vt_declarations:  var_declaration                       { $$ = $1; }
5273                 | type_declaration                      { $$ = $1; }
5274                 | vt_declarations var_declaration       { $$ = cat2_str($1, $2); }
5275                 | vt_declarations type_declaration      { $$ = cat2_str($1, $2); }
5276                 | vt_declarations CPP_LINE              { $$ = cat2_str($1, $2); }
5277                 ;
5278
5279 variable_declarations:  var_declaration         { $$ = $1; }
5280                 | variable_declarations var_declaration         { $$ = cat2_str($1, $2); }
5281                 ;
5282
5283 type_declaration: S_TYPEDEF
5284         {
5285                 /* reset this variable so we see if there was */
5286                 /* an initializer specified */
5287                 initializer = 0;
5288         }
5289         var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
5290         {
5291                 add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
5292
5293                 fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
5294                 output_line_number();
5295                 $$ = make_str("");
5296         };
5297
5298 var_declaration: storage_declaration
5299                 var_type
5300                 {
5301                         actual_type[struct_level].type_enum = $2.type_enum;
5302                         actual_type[struct_level].type_dimension = $2.type_dimension;
5303                         actual_type[struct_level].type_index = $2.type_index;
5304                         actual_type[struct_level].type_sizeof = $2.type_sizeof;
5305
5306                         actual_startline[struct_level] = hashline_number();
5307                 }
5308                 variable_list ';'
5309                 {
5310                         $$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
5311                 }
5312                 | var_type
5313                 {
5314                         actual_type[struct_level].type_enum = $1.type_enum;
5315                         actual_type[struct_level].type_dimension = $1.type_dimension;
5316                         actual_type[struct_level].type_index = $1.type_index;
5317                         actual_type[struct_level].type_sizeof = $1.type_sizeof;
5318
5319                         actual_startline[struct_level] = hashline_number();
5320                 }
5321                 variable_list ';'
5322                 {
5323                         $$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
5324                 }
5325                 | struct_union_type_with_symbol ';'
5326                 {
5327                         $$ = cat2_str($1, make_str(";"));
5328                 }
5329                 ;
5330
5331 opt_bit_field:  ':' Iconst      { $$ =cat2_str(make_str(":"), $2); }
5332                 | /* EMPTY */   { $$ = EMPTY; }
5333                 ;
5334
5335 storage_declaration: storage_clause storage_modifier
5336                         {$$ = cat2_str ($1, $2); }
5337                 | storage_clause                {$$ = $1; }
5338                 | storage_modifier              {$$ = $1; }
5339                 ;
5340
5341 storage_clause : S_EXTERN       { $$ = make_str("extern"); }
5342                 | S_STATIC                      { $$ = make_str("static"); }
5343                 | S_REGISTER            { $$ = make_str("register"); }
5344                 | S_AUTO                        { $$ = make_str("auto"); }
5345                 ;
5346
5347 storage_modifier : S_CONST      { $$ = make_str("const"); }
5348                 | S_VOLATILE            { $$ = make_str("volatile"); }
5349                 ;
5350
5351 var_type:       simple_type
5352                 {
5353                         $$.type_enum = $1;
5354                         $$.type_str = mm_strdup(ecpg_type_name($1));
5355                         $$.type_dimension = make_str("-1");
5356                         $$.type_index = make_str("-1");
5357                         $$.type_sizeof = NULL;
5358                 }
5359                 | struct_union_type
5360                 {
5361                         $$.type_str = $1;
5362                         $$.type_dimension = make_str("-1");
5363                         $$.type_index = make_str("-1");
5364
5365                         if (strncmp($1, "struct", sizeof("struct")-1) == 0)
5366                         {
5367                                 $$.type_enum = ECPGt_struct;
5368                                 $$.type_sizeof = ECPGstruct_sizeof;
5369                         }
5370                         else
5371                         {
5372                                 $$.type_enum = ECPGt_union;
5373                                 $$.type_sizeof = NULL;
5374                         }
5375                 }
5376                 | enum_type
5377                 {
5378                         $$.type_str = $1;
5379                         $$.type_enum = ECPGt_int;
5380                         $$.type_dimension = make_str("-1");
5381                         $$.type_index = make_str("-1");
5382                         $$.type_sizeof = NULL;
5383                 }
5384                 | ECPGColLabelCommon '(' precision opt_scale ')'
5385                 {
5386                         if (strcmp($1, "numeric") == 0)
5387                         {
5388                                 $$.type_enum = ECPGt_numeric;
5389                                 $$.type_str = make_str("numeric");
5390                         }
5391                         else if (strcmp($1, "decimal") == 0)
5392                         {
5393                                 $$.type_enum = ECPGt_decimal;
5394                                 $$.type_str = make_str("decimal");
5395                         }
5396                         else
5397                         {
5398                                 mmerror(PARSE_ERROR, ET_ERROR, "Only numeric/decimal have precision/scale argument");
5399                                 $$.type_enum = ECPGt_numeric;
5400                                 $$.type_str = make_str("numeric");
5401                         }
5402
5403                         $$.type_dimension = make_str("-1");
5404                         $$.type_index = make_str("-1");
5405                         $$.type_sizeof = NULL;
5406                 }
5407                 | ECPGColLabelCommon ecpg_interval
5408                 {
5409                         if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
5410                                 mmerror (PARSE_ERROR, ET_ERROR, "Interval specification not allowed here ");
5411
5412                         /*
5413                          * Check for type names that the SQL grammar treats as
5414                          * unreserved keywords
5415                          */
5416                         if (strcmp($1, "varchar") == 0)
5417                         {
5418                                 $$.type_enum = ECPGt_varchar;
5419                                 $$.type_str = EMPTY; /*make_str("varchar");*/
5420                                 $$.type_dimension = make_str("-1");
5421                                 $$.type_index = make_str("-1");
5422                                 $$.type_sizeof = NULL;
5423                         }
5424                         else if (strcmp($1, "float") == 0)
5425                         {
5426                                 $$.type_enum = ECPGt_float;
5427                                 $$.type_str = make_str("float");
5428                                 $$.type_dimension = make_str("-1");
5429                                 $$.type_index = make_str("-1");
5430                                 $$.type_sizeof = NULL;
5431                         }
5432                         else if (strcmp($1, "double") == 0)
5433                         {
5434                                 $$.type_enum = ECPGt_double;
5435                                 $$.type_str = make_str("double");
5436                                 $$.type_dimension = make_str("-1");
5437                                 $$.type_index = make_str("-1");
5438                                 $$.type_sizeof = NULL;
5439                         }
5440                         else if (strcmp($1, "numeric") == 0)
5441                         {
5442                                 $$.type_enum = ECPGt_numeric;
5443                                 $$.type_str = make_str("numeric");
5444                                 $$.type_dimension = make_str("-1");
5445                                 $$.type_index = make_str("-1");
5446                                 $$.type_sizeof = NULL;
5447                         }
5448                         else if (strcmp($1, "decimal") == 0)
5449                         {
5450                                 $$.type_enum = ECPGt_decimal;
5451                                 $$.type_str = make_str("decimal");
5452                                 $$.type_dimension = make_str("-1");
5453                                 $$.type_index = make_str("-1");
5454                                 $$.type_sizeof = NULL;
5455                         }
5456                         else if (strcmp($1, "date") == 0)
5457                         {
5458                                 $$.type_enum = ECPGt_date;
5459                                 $$.type_str = make_str("date");
5460                                 $$.type_dimension = make_str("-1");
5461                                 $$.type_index = make_str("-1");
5462                                 $$.type_sizeof = NULL;
5463                         }
5464                         else if (strcmp($1, "timestamp") == 0)
5465                         {
5466                                 $$.type_enum = ECPGt_timestamp;
5467                                 $$.type_str = make_str("timestamp");
5468                                 $$.type_dimension = make_str("-1");
5469                                 $$.type_index = make_str("-1");
5470                                 $$.type_sizeof = NULL;
5471                         }
5472                         else if (strcmp($1, "interval") == 0)
5473                         {
5474                                 $$.type_enum = ECPGt_interval;
5475                                 $$.type_str = make_str("interval");
5476                                 $$.type_dimension = make_str("-1");
5477                                 $$.type_index = make_str("-1");
5478                                 $$.type_sizeof = NULL;
5479                         }
5480                         else if (strcmp($1, "datetime") == 0)
5481                         {
5482                                 $$.type_enum = ECPGt_timestamp;
5483                                 $$.type_str = make_str("timestamp");
5484                                 $$.type_dimension = make_str("-1");
5485                                 $$.type_index = make_str("-1");
5486                                 $$.type_sizeof = NULL;
5487                         }
5488                         else
5489                         {
5490                                 /* this is for typedef'ed types */
5491                                 struct typedefs *this = get_typedef($1);
5492
5493                                 $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
5494                                 $$.type_enum = this->type->type_enum;
5495                                 $$.type_dimension = this->type->type_dimension;
5496                                 $$.type_index = this->type->type_index;
5497                                 if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
5498                                         $$.type_sizeof = this->type->type_sizeof;
5499                                 else 
5500                                         $$.type_sizeof = cat_str(3, make_str("sizeof("), mm_strdup(this->name), make_str(")"));
5501
5502                                 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
5503                         }
5504                 }
5505                 | s_struct_union_symbol
5506                 {
5507                         /* this is for named structs/unions */
5508                         char *name;
5509                         struct typedefs *this;
5510                         bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
5511
5512                         name = cat2_str($1.su, $1.symbol);
5513                         /* Do we have a forward definition? */
5514                         if (!forward)
5515                         {
5516                                 /* No */
5517
5518                                 this = get_typedef(name);
5519                                 $$.type_str = mm_strdup(this->name);
5520                                 $$.type_enum = this->type->type_enum;
5521                                 $$.type_dimension = this->type->type_dimension;
5522                                 $$.type_index = this->type->type_index;
5523                                 $$.type_sizeof = this->type->type_sizeof;
5524                                 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
5525                                 free(name);
5526                         }
5527                         else
5528                         {
5529                                 $$.type_str = name;
5530                                 $$.type_enum = ECPGt_long;
5531                                 $$.type_dimension = make_str("-1");
5532                                 $$.type_index = make_str("-1");
5533                                 $$.type_sizeof = make_str("");
5534                                 struct_member_list[struct_level] = NULL;
5535                         }
5536                 }
5537                 ;
5538
5539 enum_type: ENUM_P symbol enum_definition
5540                         { $$ = cat_str(3, make_str("enum"), $2, $3); }
5541                 | ENUM_P enum_definition
5542                         { $$ = cat2_str(make_str("enum"), $2); }
5543                 | ENUM_P symbol
5544                         { $$ = cat2_str(make_str("enum"), $2); }
5545                 ;
5546
5547 enum_definition: '{' c_list '}'
5548                         { $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
5549
5550 struct_union_type_with_symbol: s_struct_union_symbol
5551                 {
5552                         struct_member_list[struct_level++] = NULL;
5553                         if (struct_level >= STRUCT_DEPTH)
5554                                  mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
5555                         forward_name = mm_strdup($1.symbol);
5556                 }
5557                 '{' variable_declarations '}'
5558                 {
5559                         struct typedefs *ptr, *this;
5560                         struct this_type su_type;
5561
5562                         ECPGfree_struct_member(struct_member_list[struct_level]);
5563                         struct_member_list[struct_level] = NULL;
5564                         struct_level--;
5565                         if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
5566                                 su_type.type_enum = ECPGt_struct;
5567                         else
5568                                 su_type.type_enum = ECPGt_union;
5569                         su_type.type_str = cat2_str($1.su, $1.symbol);
5570                         free(forward_name);
5571                         forward_name = NULL;
5572
5573                         /* This is essantially a typedef but needs the keyword struct/union as well.
5574                          * So we create the typedef for each struct definition with symbol */
5575                         for (ptr = types; ptr != NULL; ptr = ptr->next)
5576                         {
5577                                         if (strcmp(su_type.type_str, ptr->name) == 0)
5578                                                         /* re-definition is a bug */
5579                                                         mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", su_type.type_str);
5580                         }
5581
5582                         this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
5583
5584                         /* initial definition */
5585                         this->next = types;
5586                         this->name = mm_strdup(su_type.type_str);
5587                         this->brace_level = braces_open;
5588                         this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
5589                         this->type->type_enum = su_type.type_enum;
5590                         this->type->type_str = mm_strdup(su_type.type_str);
5591                         this->type->type_dimension = make_str("-1"); /* dimension of array */
5592                         this->type->type_index = make_str("-1");        /* length of string */
5593                         this->type->type_sizeof = ECPGstruct_sizeof;
5594                         this->struct_member_list = struct_member_list[struct_level];
5595
5596                         types = this;
5597                         $$ = cat_str(4, su_type.type_str, make_str("{"), $4, make_str("}"));
5598                 }
5599                 ;
5600
5601 struct_union_type: struct_union_type_with_symbol        { $$ = $1; }
5602                 | s_struct_union
5603                 {
5604                         struct_member_list[struct_level++] = NULL;
5605                         if (struct_level >= STRUCT_DEPTH)
5606                                  mmerror(PARSE_ERROR, ET_ERROR, "Too many levels in nested structure/union definition");
5607                 }
5608                 '{' variable_declarations '}'
5609                 {
5610                         ECPGfree_struct_member(struct_member_list[struct_level]);
5611                         struct_member_list[struct_level] = NULL;
5612                         struct_level--;
5613                         $$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
5614                 }
5615                 ;
5616
5617 s_struct_union_symbol: SQL_STRUCT symbol
5618                 {
5619                         $$.su = make_str("struct");
5620                         $$.symbol = $2;
5621                         ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), make_str(")"));
5622                 }
5623                 | UNION symbol
5624                 {
5625                         $$.su = make_str("union");
5626                         $$.symbol = $2;
5627                 }
5628                 ;
5629
5630 s_struct_union: SQL_STRUCT
5631                 {
5632                         ECPGstruct_sizeof = make_str(""); /* This must not be NULL to distinguish from simple types. */
5633                         $$ = make_str("struct");
5634                 }
5635                 | UNION         { $$ = make_str("union"); }
5636                 ;
5637
5638 simple_type: unsigned_type                                      { $$=$1; }
5639                 |       opt_signed signed_type                  { $$=$2; }
5640                 ;
5641
5642 unsigned_type: SQL_UNSIGNED SQL_SHORT           { $$ = ECPGt_unsigned_short; }
5643                 | SQL_UNSIGNED SQL_SHORT INT_P  { $$ = ECPGt_unsigned_short; }
5644                 | SQL_UNSIGNED                                          { $$ = ECPGt_unsigned_int; }
5645                 | SQL_UNSIGNED INT_P                            { $$ = ECPGt_unsigned_int; }
5646                 | SQL_UNSIGNED SQL_LONG                         { $$ = ECPGt_unsigned_long; }
5647                 | SQL_UNSIGNED SQL_LONG INT_P           { $$ = ECPGt_unsigned_long; }
5648                 | SQL_UNSIGNED SQL_LONG SQL_LONG
5649                 {
5650 #ifdef HAVE_LONG_LONG_INT_64
5651                         $$ = ECPGt_unsigned_long_long;
5652 #else
5653                         $$ = ECPGt_unsigned_long;
5654 #endif
5655                 }
5656                 | SQL_UNSIGNED SQL_LONG SQL_LONG INT_P
5657                 {
5658 #ifdef HAVE_LONG_LONG_INT_64
5659                         $$ = ECPGt_unsigned_long_long;
5660 #else
5661                         $$ = ECPGt_unsigned_long;
5662 #endif
5663                 }
5664                 | SQL_UNSIGNED CHAR_P                   { $$ = ECPGt_unsigned_char; }
5665                 ;
5666
5667 signed_type: SQL_SHORT                          { $$ = ECPGt_short; }
5668                 | SQL_SHORT INT_P                       { $$ = ECPGt_short; }
5669                 | INT_P                                         { $$ = ECPGt_int; }
5670                 | SQL_LONG                                      { $$ = ECPGt_long; }
5671                 | SQL_LONG INT_P                        { $$ = ECPGt_long; }
5672                 | SQL_LONG SQL_LONG
5673                 {
5674 #ifdef HAVE_LONG_LONG_INT_64
5675                         $$ = ECPGt_long_long;
5676 #else
5677                         $$ = ECPGt_long;
5678 #endif
5679                 }
5680                 | SQL_LONG SQL_LONG INT_P
5681                 {
5682 #ifdef HAVE_LONG_LONG_INT_64
5683                         $$ = ECPGt_long_long;
5684 #else
5685                         $$ = ECPGt_long;
5686 #endif
5687                 }
5688                 | SQL_BOOL                                      { $$ = ECPGt_bool; }
5689                 | CHAR_P                                        { $$ = ECPGt_char; }
5690                 | DOUBLE_P                                      { $$ = ECPGt_double; }
5691                 ;
5692
5693 opt_signed: SQL_SIGNED
5694                 |       /* EMPTY */
5695                 ;
5696
5697 variable_list: variable
5698                         { $$ = $1; }
5699                 | variable_list ',' variable
5700                         { $$ = cat_str(3, $1, make_str(","), $3); }
5701                 ;
5702
5703 variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
5704                 {
5705                         struct ECPGtype * type;
5706                         char *dimension = $3.index1; /* dimension of array */
5707                         char *length = $3.index2;    /* length of string */
5708                         char dim[14L];
5709                         char *vcn;
5710
5711                         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);
5712
5713                         switch (actual_type[struct_level].type_enum)
5714                         {
5715                                 case ECPGt_struct:
5716                                 case ECPGt_union:
5717                                         if (atoi(dimension) < 0)
5718                                                 type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof);
5719                                         else
5720                                                 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);
5721
5722                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
5723                                         break;
5724
5725                                 case ECPGt_varchar:
5726                                         if (atoi(dimension) < 0)
5727                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno);
5728                                         else
5729                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno), dimension);
5730                                         
5731                                         if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1)
5732                                                         *dim = '\0';
5733                                         else
5734                                                         sprintf(dim, "[%s]", dimension);
5735                                         /* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
5736                                         if (atoi(length) < 0 || strcmp(length, "0") == 0)
5737                                                 mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
5738
5739                                         /* make sure varchar struct name is unique by adding linenumer of its definition */
5740                                         vcn = (char *) mm_alloc(strlen($2) + sizeof(int) * CHAR_BIT * 10 / 3);
5741                                         sprintf(vcn, "%s_%d", $2, yylineno);
5742                                         if (strcmp(dimension, "0") == 0)
5743                                                 $$ = 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);
5744                                         else
5745                                                 $$ = 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);
5746                                         break;
5747
5748                                 case ECPGt_char:
5749                                 case ECPGt_unsigned_char:
5750                                         if (atoi(dimension) == -1)
5751                                         {
5752                                                 int i = strlen($5);
5753
5754                                                 if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
5755                                                 {
5756                                                         /* if we have an initializer but no string size set, let's use the initializer's length */
5757                                                         free(length);
5758                                                         length = mm_alloc(i+sizeof("sizeof()"));
5759                                                         sprintf(length, "sizeof(%s)", $5+2);
5760                                                 }
5761                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
5762                                         }
5763                                         else
5764                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
5765
5766                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
5767                                         break;
5768
5769                                 default:
5770                                         if (atoi(dimension) < 0)
5771                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0);
5772                                         else
5773                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0), dimension);
5774
5775                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
5776                                         break;
5777                         }
5778
5779                         if (struct_level == 0)
5780                                 new_variable($2, type, braces_open);
5781                         else
5782                                 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
5783
5784                         free($2);
5785                 }
5786                 ;
5787
5788 opt_initializer: /*EMPTY*/
5789                         { $$ = EMPTY; }
5790                 | '=' c_term
5791                 {
5792                         initializer = 1;
5793                         $$ = cat2_str(make_str("="), $2);
5794                 }
5795                 ;
5796
5797 opt_pointer: /*EMPTY*/                          { $$ = EMPTY; }
5798                 | '*'                                           { $$ = make_str("*"); }
5799                 | '*' '*'                                       { $$ = make_str("**"); }
5800                 ;
5801
5802 /*
5803  * We try to simulate the correct DECLARE syntax here so we get dynamic SQL
5804  */
5805 ECPGDeclare: DECLARE STATEMENT ident
5806                 {
5807                         /* this is only supported for compatibility */
5808                         $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
5809                 }
5810                 ;
5811 /*
5812  * the exec sql disconnect statement: disconnect from the given database
5813  */
5814 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
5815                 ;
5816
5817 dis_name: connection_object                     { $$ = $1; }
5818                 | CURRENT_P                     { $$ = make_str("\"CURRENT\""); }
5819                 | ALL                           { $$ = make_str("\"ALL\""); }
5820                 | /* EMPTY */                   { $$ = make_str("\"CURRENT\""); }
5821                 ;
5822
5823 connection_object: database_name                { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5824                 | DEFAULT                       { $$ = make_str("\"DEFAULT\""); }
5825                 | char_variable                 { $$ = $1; }
5826                 ;
5827
5828 execute_rest:   ecpg_using ecpg_into    { $$ = EMPTY; }
5829                 | ecpg_into ecpg_using  { $$ = EMPTY; }
5830                 | ecpg_using            { $$ = EMPTY; }
5831                 | ecpg_into             { $$ = EMPTY; }
5832                 | /* EMPTY */           { $$ = EMPTY; }
5833                 ;
5834
5835 execstring: char_variable
5836                         { $$ = $1; }
5837                 |       CSTRING
5838                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
5839                 ;
5840
5841 prepared_name: name             { 
5842                                         if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */
5843                                                 $$ = $1;
5844                                         else /* not quoted => convert to lowercase */
5845                                         {
5846                                                 int i;
5847
5848                                                 for (i = 0; i< strlen($1); i++)
5849                                                         $1[i] = tolower($1[i]);
5850
5851                                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
5852                                         }
5853                                 }
5854                 | char_variable { $$ = $1; }
5855                 ;
5856
5857 /*
5858  * the exec sql free command to deallocate a previously
5859  * prepared statement
5860  */
5861 ECPGFree:       SQL_FREE name   { $$ = $2; }
5862                 | SQL_FREE ALL  { $$ = make_str("all"); }
5863                 ;
5864
5865 /*
5866  * open is an open cursor, at the moment this has to be removed
5867  */
5868 ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; };
5869
5870 opt_ecpg_using: /*EMPTY*/       { $$ = EMPTY; }
5871                 | ecpg_using            { $$ = $1; }
5872                 ;
5873
5874 ecpg_using:     USING using_list        { $$ = EMPTY; }
5875                 | using_descriptor      { $$ = $1; }
5876                 ;
5877
5878 using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
5879                 {
5880                         add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
5881                         $$ = EMPTY;
5882                 }
5883                 ;
5884
5885 into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
5886                 {
5887                         add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
5888                         $$ = EMPTY;
5889                 }
5890                 ;
5891
5892 opt_sql: /*EMPTY*/ | SQL_SQL;
5893
5894 ecpg_into: INTO into_list               { $$ = EMPTY; }
5895                 | into_descriptor       { $$ = $1; }
5896                 ;
5897
5898 using_list: UsingConst | UsingConst ',' using_list;
5899
5900 UsingConst: AllConst
5901                 {
5902                         if ($1[1] != '$') /* found a constant */
5903                         {
5904                                 char *length = mm_alloc(32);
5905
5906                                 sprintf(length, "%d", (int) strlen($1));
5907                                 add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
5908                         }
5909                 }
5910                 | civarind { $$ = EMPTY; }
5911                 ;
5912
5913
5914 /*
5915  * We accept descibe but do nothing with it so far.
5916  */
5917 ECPGDescribe: SQL_DESCRIBE INPUT_P name using_descriptor
5918         {
5919                 const char *con = connection ? connection : "NULL";
5920                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement.\n");
5921                 $$ = (char *) mm_alloc(sizeof("1, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
5922                 sprintf($$, "1, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
5923         }
5924         | SQL_DESCRIBE opt_output name using_descriptor
5925         {
5926                 const char *con = connection ? connection : "NULL";
5927                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement.\n");
5928                 $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
5929                 sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
5930         }
5931         | SQL_DESCRIBE opt_output name into_descriptor
5932         {
5933                 const char *con = connection ? connection : "NULL";
5934                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported describe statement.\n");
5935                 $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
5936                 sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
5937         }
5938         ;
5939
5940 opt_output:     SQL_OUTPUT      { $$ = make_str("output"); }
5941         |       /* EMPTY */     { $$ = EMPTY; }
5942         ;
5943
5944 /*
5945  * dynamic SQL: descriptor based access
5946  *      originall written by Christof Petig <christof.petig@wtal.de>
5947  *                      and Peter Eisentraut <peter.eisentraut@credativ.de>
5948  */
5949
5950 /*
5951  * allocate a descriptor
5952  */
5953 ECPGAllocateDescr:     SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
5954                 {
5955                         add_descriptor($3,connection);
5956                         $$ = $3;
5957                 }
5958                 ;
5959
5960
5961 /*
5962  * deallocate a descriptor
5963  */
5964 ECPGDeallocateDescr:    DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
5965                 {
5966                         drop_descriptor($3,connection);
5967                         $$ = $3;
5968                 }
5969                 ;
5970
5971 /*
5972  * manipulate a descriptor header
5973  */
5974
5975 ECPGGetDescriptorHeader: GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
5976                         {  $$ = $3; }
5977                 ;
5978
5979 ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
5980                 | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
5981                 ;
5982
5983 ECPGGetDescHeaderItem: cvariable '=' desc_header_item
5984                         { push_assignment($1, $3); }
5985                 ;
5986
5987
5988 ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
5989                         { $$ = $3; }
5990                 ;
5991
5992 ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
5993                 | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
5994                 ;
5995
5996 ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
5997                 {
5998                         push_assignment($3, $1);
5999                 }
6000                 ;
6001
6002
6003 desc_header_item:       SQL_COUNT                       { $$ = ECPGd_count; }
6004                 ;
6005
6006 /*
6007  * manipulate a descriptor
6008  */
6009
6010 ECPGGetDescriptor:      GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
6011                         {  $$.str = $5; $$.name = $3; }
6012                 ;
6013
6014 ECPGGetDescItems: ECPGGetDescItem
6015                 | ECPGGetDescItems ',' ECPGGetDescItem
6016                 ;
6017
6018 ECPGGetDescItem: cvariable '=' descriptor_item  { push_assignment($1, $3); };
6019
6020
6021 ECPGSetDescriptor:      SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems
6022                         {  $$.str = $5; $$.name = $3; }
6023                 ;
6024
6025 ECPGSetDescItems: ECPGSetDescItem
6026                 | ECPGSetDescItems ',' ECPGSetDescItem
6027                 ;
6028
6029 ECPGSetDescItem: descriptor_item '=' AllConstVar
6030                 {
6031                         push_assignment($3, $1);
6032                 }
6033                 ;
6034
6035
6036 descriptor_item:        SQL_CARDINALITY                 { $$ = ECPGd_cardinality; }
6037                 | SQL_DATA                              { $$ = ECPGd_data; }
6038                 | SQL_DATETIME_INTERVAL_CODE            { $$ = ECPGd_di_code; }
6039                 | SQL_DATETIME_INTERVAL_PRECISION       { $$ = ECPGd_di_precision; }
6040                 | SQL_INDICATOR                         { $$ = ECPGd_indicator; }
6041                 | SQL_KEY_MEMBER                        { $$ = ECPGd_key_member; }
6042                 | SQL_LENGTH                            { $$ = ECPGd_length; }
6043                 | NAME_P                                { $$ = ECPGd_name; }
6044                 | SQL_NULLABLE                          { $$ = ECPGd_nullable; }
6045                 | SQL_OCTET_LENGTH                      { $$ = ECPGd_octet; }
6046                 | PRECISION                             { $$ = ECPGd_precision; }
6047                 | SQL_RETURNED_LENGTH                   { $$ = ECPGd_length; }
6048                 | SQL_RETURNED_OCTET_LENGTH             { $$ = ECPGd_ret_octet; }
6049                 | SQL_SCALE                             { $$ = ECPGd_scale; }
6050                 | TYPE_P                                { $$ = ECPGd_type; }
6051                 ;
6052
6053 /*
6054  * set/reset the automatic transaction mode, this needs a differnet handling
6055  * as the other set commands
6056  */
6057 ECPGSetAutocommit:      SET SQL_AUTOCOMMIT '=' on_off   { $$ = $4; }
6058                 |  SET SQL_AUTOCOMMIT TO on_off   { $$ = $4; }
6059                 ;
6060
6061 on_off: ON                              { $$ = make_str("on"); }
6062                 | OFF                   { $$ = make_str("off"); }
6063                 ;
6064
6065 /*
6066  * set the actual connection, this needs a differnet handling as the other
6067  * set commands
6068  */
6069 ECPGSetConnection:      SET CONNECTION TO connection_object { $$ = $4; }
6070                 | SET CONNECTION '=' connection_object { $$ = $4; }
6071                 | SET CONNECTION  connection_object { $$ = $3; }
6072                 ;
6073
6074 /*
6075  * define a new type for embedded SQL
6076  */
6077 ECPGTypedef: TYPE_P
6078                 {
6079                         /* reset this variable so we see if there was */
6080                         /* an initializer specified */
6081                         initializer = 0;
6082                 }
6083                 ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
6084                 {
6085                         add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
6086
6087                         if (auto_create_c == false)
6088                                 $$ = 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("*/"));
6089                         else
6090                                 $$ = 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(";"));
6091                 }
6092                 ;
6093
6094 opt_reference: SQL_REFERENCE            { $$ = make_str("reference"); }
6095                 | /*EMPTY*/                                     { $$ = EMPTY; }
6096                 ;
6097
6098 /*
6099  * define the type of one variable for embedded SQL
6100  */
6101 ECPGVar: SQL_VAR
6102                 {
6103                         /* reset this variable so we see if there was */
6104                         /* an initializer specified */
6105                         initializer = 0;
6106                 }
6107                 ColLabel IS var_type opt_array_bounds opt_reference
6108                 {
6109                         struct variable *p = find_variable($3);
6110                         char *dimension = $6.index1;
6111                         char *length = $6.index2;
6112                         struct ECPGtype * type;
6113
6114                         if (($5.type_enum == ECPGt_struct ||
6115                                  $5.type_enum == ECPGt_union) &&
6116                                 initializer == 1)
6117                                 mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
6118                         else
6119                         {
6120                                 adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
6121
6122                                 switch ($5.type_enum)
6123                                 {
6124                                         case ECPGt_struct:
6125                                         case ECPGt_union:
6126                                                 if (atoi(dimension) < 0)
6127                                                         type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_sizeof);
6128                                                 else
6129                                                         type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,$5.type_sizeof), dimension);
6130                                                 break;
6131
6132                                         case ECPGt_varchar:
6133                                                 if (atoi(dimension) == -1)
6134                                                         type = ECPGmake_simple_type($5.type_enum, length, 0);
6135                                                 else
6136                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
6137                                                 break;
6138
6139                                         case ECPGt_char:
6140                                         case ECPGt_unsigned_char:
6141                                                 if (atoi(dimension) == -1)
6142                                                         type = ECPGmake_simple_type($5.type_enum, length, 0);
6143                                                 else
6144                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
6145                                                 break;
6146
6147                                         default:
6148                                                 if (atoi(length) >= 0)
6149                                                         mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
6150
6151                                                 if (atoi(dimension) < 0)
6152                                                         type = ECPGmake_simple_type($5.type_enum, make_str("1"), 0);
6153                                                 else
6154                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, make_str("1"), 0), dimension);
6155                                                 break;
6156                                 }
6157
6158                                 ECPGfree_type(p->type);
6159                                 p->type = type;
6160                         }
6161
6162                         $$ = 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("*/"));
6163                 }
6164                 ;
6165
6166 /*
6167  * whenever statement: decide what to do in case of error/no data found
6168  * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
6169  */
6170 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
6171                 {
6172                         when_error.code = $<action>3.code;
6173                         when_error.command = $<action>3.command;
6174                         $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */"));
6175                 }
6176                 | SQL_WHENEVER NOT SQL_FOUND action
6177                 {
6178                         when_nf.code = $<action>4.code;
6179                         when_nf.command = $<action>4.command;
6180                         $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */"));
6181                 }
6182                 | SQL_WHENEVER SQL_SQLWARNING action
6183                 {
6184                         when_warn.code = $<action>3.code;
6185                         when_warn.command = $<action>3.command;
6186                         $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */"));
6187                 }
6188                 ;
6189
6190 action : SQL_CONTINUE
6191                 {
6192                         $<action>$.code = W_NOTHING;
6193                         $<action>$.command = NULL;
6194                         $<action>$.str = make_str("continue");
6195                 }
6196                 | SQL_SQLPRINT
6197                 {
6198                         $<action>$.code = W_SQLPRINT;
6199                         $<action>$.command = NULL;
6200                         $<action>$.str = make_str("sqlprint");
6201                 }
6202                 | SQL_STOP
6203                 {
6204                         $<action>$.code = W_STOP;
6205                         $<action>$.command = NULL;
6206                         $<action>$.str = make_str("stop");
6207                 }
6208                 | SQL_GOTO name
6209                 {
6210                         $<action>$.code = W_GOTO;
6211                         $<action>$.command = strdup($2);
6212                         $<action>$.str = cat2_str(make_str("goto "), $2);
6213                 }
6214                 | SQL_GO TO name
6215                 {
6216                         $<action>$.code = W_GOTO;
6217                         $<action>$.command = strdup($3);
6218                         $<action>$.str = cat2_str(make_str("goto "), $3);
6219                 }
6220                 | DO name '(' c_args ')'
6221                 {
6222                         $<action>$.code = W_DO;
6223                         $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
6224                         $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
6225                 }
6226                 | DO SQL_BREAK
6227                 {
6228                         $<action>$.code = W_BREAK;
6229                         $<action>$.command = NULL;
6230                         $<action>$.str = make_str("break");
6231                 }
6232                 | SQL_CALL name '(' c_args ')'
6233                 {
6234                         $<action>$.code = W_DO;
6235                         $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
6236                         $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
6237                 }
6238                 | SQL_CALL name
6239                 {
6240                         $<action>$.code = W_DO;
6241                         $<action>$.command = cat2_str($2, make_str("()"));
6242                         $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
6243                 }
6244                 ;
6245
6246 /* some other stuff for ecpg */
6247
6248 /* additional unreserved keywords */
6249 ECPGKeywords: ECPGKeywords_vanames      { $$ = $1; }
6250                 | ECPGKeywords_rest     { $$ = $1; }
6251                 ;
6252
6253 ECPGKeywords_vanames:  SQL_BREAK                { $$ = make_str("break"); }
6254                 | SQL_CALL                                              { $$ = make_str("call"); }
6255                 | SQL_CARDINALITY                               { $$ = make_str("cardinality"); }
6256                 | SQL_CONTINUE                                  { $$ = make_str("continue"); }
6257                 | SQL_COUNT                                             { $$ = make_str("count"); }
6258                 | SQL_DATA                                              { $$ = make_str("data"); }
6259                 | SQL_DATETIME_INTERVAL_CODE    { $$ = make_str("datetime_interval_code"); }
6260                 | SQL_DATETIME_INTERVAL_PRECISION       { $$ = make_str("datetime_interval_precision"); }
6261                 | SQL_FOUND                                             { $$ = make_str("found"); }
6262                 | SQL_GO                                                { $$ = make_str("go"); }
6263                 | SQL_GOTO                                              { $$ = make_str("goto"); }
6264                 | SQL_IDENTIFIED                                { $$ = make_str("identified"); }
6265                 | SQL_INDICATOR                         { $$ = make_str("indicator"); }
6266                 | SQL_KEY_MEMBER                        { $$ = make_str("key_member"); }
6267                 | SQL_LENGTH                            { $$ = make_str("length"); }
6268                 | SQL_NULLABLE                          { $$ = make_str("nullable"); }
6269                 | SQL_OCTET_LENGTH                      { $$ = make_str("octet_length"); }
6270                 | SQL_RETURNED_LENGTH           { $$ = make_str("returned_length"); }
6271                 | SQL_RETURNED_OCTET_LENGTH     { $$ = make_str("returned_octet_length"); }
6272                 | SQL_SCALE                                     { $$ = make_str("scale"); }
6273                 | SQL_SECTION                           { $$ = make_str("section"); }
6274                 | SQL_SQLERROR                          { $$ = make_str("sqlerror"); }
6275                 | SQL_SQLPRINT                          { $$ = make_str("sqlprint"); }
6276                 | SQL_SQLWARNING                        { $$ = make_str("sqlwarning"); }
6277                 | SQL_STOP                                      { $$ = make_str("stop"); }
6278                 ;
6279
6280 ECPGKeywords_rest:  SQL_CONNECT         { $$ = make_str("connect"); }
6281                 | SQL_DESCRIBE                          { $$ = make_str("describe"); }
6282                 | SQL_DISCONNECT                        { $$ = make_str("disconnect"); }
6283                 | SQL_OPEN                                      { $$ = make_str("open"); }
6284                 | SQL_VAR                                       { $$ = make_str("var"); }
6285                 | SQL_WHENEVER                          { $$ = make_str("whenever"); }
6286                 ;
6287
6288 /* additional keywords that can be SQL type names (but not ECPGColLabels) */
6289 ECPGTypeName:  SQL_BOOL                         { $$ = make_str("bool"); }
6290                 | SQL_LONG                                      { $$ = make_str("long"); }
6291                 | SQL_OUTPUT                            { $$ = make_str("output"); }
6292                 | SQL_SHORT                                     { $$ = make_str("short"); }
6293                 | SQL_STRUCT                            { $$ = make_str("struct"); }
6294                 | SQL_SIGNED                            { $$ = make_str("signed"); }
6295                 | SQL_UNSIGNED                          { $$ = make_str("unsigned"); }
6296                 ;
6297
6298 symbol: ColLabel                                        { $$ = $1; }
6299                 ;
6300
6301 /*
6302  * Name classification hierarchy.
6303  *
6304  * IDENT is the lexeme returned by the lexer for identifiers that match
6305  * no known keyword.  In most cases, we can accept certain keywords as
6306  * names, not only IDENTs.      We prefer to accept as many such keywords
6307  * as possible to minimize the impact of "reserved words" on programmers.
6308  * So, we divide names into several possible classes.  The classification
6309  * is chosen in part to make keywords acceptable as names wherever possible.
6310  */
6311
6312 ECPGColId:ident                                 { $$ = $1; }
6313                 | ECPGunreserved_interval       { $$ = $1; }
6314                 | ECPGunreserved_con            { $$ = $1; }
6315                 | col_name_keyword              { $$ = $1; }
6316                 | ECPGKeywords                  { $$ = $1; }
6317                 | ECPGCKeywords                 { $$ = $1; }
6318                 | CHAR_P                        { $$ = make_str("char"); }
6319                 | VALUES                        { $$ = make_str("values"); }
6320                 ;
6321 /* Column identifier --- names that can be column, table, etc names.
6322  */
6323 ColId:  ident                                   { $$ = $1; }
6324                 | unreserved_keyword            { $$ = $1; }
6325                 | col_name_keyword              { $$ = $1; }
6326                 | ECPGKeywords                  { $$ = $1; }
6327                 | ECPGCKeywords                 { $$ = $1; }
6328                 | CHAR_P                        { $$ = make_str("char"); }
6329                 | VALUES                        { $$ = make_str("values"); }
6330                 ;
6331 /* Type/function identifier --- names that can be type names.
6332  */
6333 type_function_name:     ident                                   { $$ = $1; }
6334                 | unreserved_keyword            { $$ = $1; }
6335                 | type_func_name_keyword                { $$ = $1; }
6336                 | ECPGKeywords                          { $$ = $1; }
6337                 | ECPGTypeName                          { $$ = $1; }
6338                 | ECPGCKeywords                         { $$ = $1; }
6339                 ;
6340
6341 /* Column label --- allowed labels in "AS" clauses.
6342  * This presently includes *all* Postgres keywords.
6343  */
6344 ColLabel:  ECPGColLabel                         { $$ = $1; }
6345                 | ECPGTypeName                  { $$ = $1; }
6346                 | CHAR_P                        { $$ = make_str("char"); }
6347                 | INPUT_P                       { $$ = make_str("input"); }
6348                 | INT_P                         { $$ = make_str("int"); }
6349                 | UNION                         { $$ = make_str("union"); }
6350                 | TO                            { $$ = make_str("to"); }
6351                 | ECPGCKeywords                 { $$ = $1; }
6352                 | ECPGunreserved_interval       { $$ = $1; }
6353                 ;
6354
6355 ECPGColLabelCommon:  ident                      { $$ = $1; }
6356                 | col_name_keyword              { $$ = $1; }
6357                 | type_func_name_keyword        { $$ = $1; }
6358                 | ECPGKeywords_vanames          { $$ = $1; }
6359                 ;
6360
6361 ECPGColLabel:  ECPGColLabelCommon       { $$ = $1; }
6362                 | reserved_keyword              { $$ = $1; }
6363                 | ECPGunreserved                { $$ = $1; }
6364                 | ECPGKeywords_rest             { $$ = $1; }
6365                 ;
6366
6367 ECPGCKeywords: S_AUTO                   { $$ = make_str("auto"); }
6368                 | S_CONST                               { $$ = make_str("const"); }
6369                 | S_EXTERN                              { $$ = make_str("extern"); }
6370                 | S_REGISTER                    { $$ = make_str("register"); }
6371                 | S_STATIC                              { $$ = make_str("static"); }
6372                 | S_TYPEDEF                             { $$ = make_str("typedef"); }
6373                 | S_VOLATILE                    { $$ = make_str("volatile"); }
6374                 ;
6375
6376 /*
6377  * Keyword classification lists.  Generally, every keyword present in
6378  * the Postgres grammar should appear in exactly one of these lists.
6379  *
6380  * Put a new keyword into the first list that it can go into without causing
6381  * shift or reduce conflicts.  The earlier lists define "less reserved"
6382  * categories of keywords.
6383  */
6384
6385 /* "Unreserved" keywords --- available for use as any kind of name.
6386  */
6387 /* The following symbols must be excluded from ECPGColLabel and directly included into ColLabel
6388    to enable C variables to get names from ECPGColLabel:
6389    DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P
6390  */
6391 unreserved_keyword: ECPGunreserved_interval | ECPGunreserved;
6392
6393 ECPGunreserved_interval: DAY_P                  { $$ = make_str("day"); }
6394                 | HOUR_P                        { $$ = make_str("hour"); }
6395                 | MINUTE_P                      { $$ = make_str("minute"); }
6396                 | MONTH_P                       { $$ = make_str("month"); }
6397                 | SECOND_P                      { $$ = make_str("second"); }
6398                 | YEAR_P                        { $$ = make_str("year"); }
6399                 ;
6400
6401 /* The following symbol must be excluded from var_name but still included in ColId
6402    to enable ecpg special postgresql variables with this name:  CONNECTION
6403  */
6404 ECPGunreserved: ECPGunreserved_con              { $$ = $1; }
6405                 | CONNECTION                    { $$ = make_str("connection"); }
6406                 ;
6407
6408 ECPGunreserved_con:       ABORT_P                       { $$ = make_str("abort"); }
6409                 | ABSOLUTE_P            { $$ = make_str("absolute"); }
6410                 | ACCESS                        { $$ = make_str("access"); }
6411                 | ACTION                        { $$ = make_str("action"); }
6412                 | ADD_P                         { $$ = make_str("add"); }
6413                 | ADMIN                         { $$ = make_str("admin"); }
6414                 | AFTER                         { $$ = make_str("after"); }
6415                 | AGGREGATE                     { $$ = make_str("aggregate"); }
6416                 | ALSO                          { $$ = make_str("also"); }
6417                 | ALTER                         { $$ = make_str("alter"); }
6418                 | ALWAYS                        { $$ = make_str("always"); }
6419                 | ASSERTION                     { $$ = make_str("assertion"); }
6420                 | ASSIGNMENT            { $$ = make_str("assignment"); }
6421                 | AT                            { $$ = make_str("at"); }
6422                 | BACKWARD                      { $$ = make_str("backward"); }
6423                 | BEFORE                        { $$ = make_str("before"); }
6424                 | BEGIN_P                       { $$ = make_str("begin"); }
6425                 | BY                            { $$ = make_str("by"); }
6426                 | CACHE                         { $$ = make_str("cache"); }
6427                 | CASCADE                       { $$ = make_str("cascade"); }
6428                 | CASCADED                      { $$ = make_str("cascaded"); }
6429                 | CHAIN                         { $$ = make_str("chain"); }
6430                 | CHARACTERISTICS       { $$ = make_str("characteristics"); }
6431                 | CHECKPOINT            { $$ = make_str("checkpoint"); }
6432                 | CLASS                         { $$ = make_str("class"); }
6433                 | CLOSE                         { $$ = make_str("close"); }
6434                 | CLUSTER                       { $$ = make_str("cluster"); }
6435                 | COMMENT                       { $$ = make_str("comment"); }
6436                 | COMMIT                        { $$ = make_str("commit"); }
6437                 | COMMITTED                     { $$ = make_str("committed"); }
6438                 | CONCURRENTLY          { $$ = make_str("concurrently"); }
6439                 | CONFIGURATION         { $$ = make_str("configuration"); }
6440 /*              | CONNECTION            { $$ = make_str("connection"); }*/
6441                 | CONSTRAINTS           { $$ = make_str("constraints"); }
6442                 | CONTENT_P             { $$ = make_str("content"); }
6443                 | CONVERSION_P          { $$ = make_str("conversion"); }
6444                 | COPY                          { $$ = make_str("copy"); }
6445                 | COST                          { $$ = make_str("cost"); }
6446                 | CREATEDB                      { $$ = make_str("createdb"); }
6447                 | CREATEROLE            { $$ = make_str("createrole"); }
6448                 | CREATEUSER            { $$ = make_str("createuser"); }
6449                 | CSV                           { $$ = make_str("csv"); }
6450                 | CURSOR                        { $$ = make_str("cursor"); }
6451                 | CYCLE                         { $$ = make_str("cycle"); }
6452                 | DATABASE                      { $$ = make_str("database"); }
6453 /*              | DAY_P                         { $$ = make_str("day"); }*/
6454                 | DEALLOCATE            { $$ = make_str("deallocate"); }
6455                 | DECLARE                       { $$ = make_str("declare"); }
6456                 | DEFAULTS                      { $$ = make_str("defaults"); }
6457                 | DEFERRED                      { $$ = make_str("deferred"); }
6458                 | DELETE_P                      { $$ = make_str("delete"); }
6459                 | DELIMITER                     { $$ = make_str("delimiter"); }
6460                 | DELIMITERS            { $$ = make_str("delimiters"); }
6461                 | DICTIONARY            { $$ = make_str("dictionary"); }
6462                 | DISABLE_P                     { $$ = make_str("disable"); }
6463                 | DISCARD                       { $$ = make_str("discard"); }
6464                 | DOCUMENT_P                    { $$ = make_str("document"); }
6465                 | DOMAIN_P                      { $$ = make_str("domain"); }
6466                 | DOUBLE_P                      { $$ = make_str("double"); }
6467                 | DROP                          { $$ = make_str("drop"); }
6468                 | EACH                          { $$ = make_str("each"); }
6469                 | ENABLE_P                      { $$ = make_str("enable"); }
6470                 | ENCODING                      { $$ = make_str("encoding"); }
6471                 | ENCRYPTED                     { $$ = make_str("encrypted"); }
6472 /*              | ENUM_P                        { $$ = make_str("enum"); }*/
6473                 | ESCAPE                        { $$ = make_str("escape"); }
6474                 | EXCLUDING                     { $$ = make_str("excluding"); }
6475                 | EXCLUSIVE                     { $$ = make_str("exclusive"); }
6476                 | EXECUTE                       { $$ = make_str("execute"); }
6477                 | EXPLAIN                       { $$ = make_str("explain"); }
6478                 | EXTERNAL                      { $$ = make_str("external"); }
6479                 | FAMILY                        { $$ = make_str("family"); }
6480                 | FETCH                         { $$ = make_str("fetch"); }
6481                 | FIRST_P                       { $$ = make_str("first"); }
6482                 | FORCE                         { $$ = make_str("force"); }
6483                 | FORWARD                       { $$ = make_str("forward"); }
6484                 | FUNCTION                      { $$ = make_str("function"); }
6485                 | GLOBAL                        { $$ = make_str("global"); }
6486                 | GRANTED                       { $$ = make_str("granted"); }
6487                 | HANDLER                       { $$ = make_str("handler"); }
6488                 | HEADER_P                      { $$ = make_str("header"); }
6489                 | HOLD                          { $$ = make_str("hold"); }
6490 /*              | HOUR_P                        { $$ = make_str("hour"); }*/
6491                 | IF_P                          { $$ = make_str("if"); }
6492                 | IMMEDIATE                     { $$ = make_str("immediate"); }
6493                 | IMMUTABLE                     { $$ = make_str("immutable"); }
6494                 | IMPLICIT_P            { $$ = make_str("implicit"); }
6495                 | INCLUDING                     { $$ = make_str("including"); }
6496                 | INCREMENT                     { $$ = make_str("increment"); }
6497                 | INDEX                         { $$ = make_str("index"); }
6498                 | INDEXES                       { $$ = make_str("indexes"); }
6499                 | INHERIT                       { $$ = make_str("inherit"); }
6500                 | INHERITS                      { $$ = make_str("inherits"); }
6501                 | INSENSITIVE           { $$ = make_str("insensitive"); }
6502                 | INSERT                        { $$ = make_str("insert"); }
6503                 | INSTEAD                       { $$ = make_str("instead"); }
6504                 | ISOLATION                     { $$ = make_str("isolation"); }
6505                 | KEY                           { $$ = make_str("key"); }
6506                 | LANCOMPILER           { $$ = make_str("lancompiler"); }
6507                 | LANGUAGE                      { $$ = make_str("language"); }
6508                 | LARGE_P                       { $$ = make_str("large"); }
6509                 | LAST_P                        { $$ = make_str("last"); }
6510                 | LEVEL                         { $$ = make_str("level"); }
6511                 | LISTEN                        { $$ = make_str("listen"); }
6512                 | LOAD                          { $$ = make_str("load"); }
6513                 | LOCAL                         { $$ = make_str("local"); }
6514                 | LOCATION                      { $$ = make_str("location"); }
6515                 | LOCK_P                        { $$ = make_str("lock"); }
6516                 | LOGIN_P                       { $$ = make_str("login"); }
6517                 | MAPPING                       { $$ = make_str("mapping"); }
6518                 | MATCH                         { $$ = make_str("match"); }
6519                 | MAXVALUE                      { $$ = make_str("maxvalue"); }
6520 /*              | MINUTE_P                      { $$ = make_str("minute"); }*/
6521                 | MINVALUE                      { $$ = make_str("minvalue"); }
6522                 | MODE                          { $$ = make_str("mode"); }
6523 /*              | MONTH_P                       { $$ = make_str("month"); }*/
6524                 | MOVE                          { $$ = make_str("move"); }
6525                 | NAME_P                        { $$ = make_str("name"); }
6526                 | NAMES                         { $$ = make_str("names"); }
6527                 | NEXT                          { $$ = make_str("next"); }
6528                 | NO                            { $$ = make_str("no"); }
6529                 | NOCREATEDB            { $$ = make_str("nocreatedb"); }
6530                 | NOCREATEROLE          { $$ = make_str("nocreaterole"); }
6531                 | NOCREATEUSER          { $$ = make_str("nocreateuser"); }
6532                 | NOINHERIT                     { $$ = make_str("noinherit"); }
6533                 | NOLOGIN_P             { $$ = make_str("nologin"); }
6534                 | NOSUPERUSER           { $$ = make_str("nosuperuser"); }
6535                 | NOTHING                       { $$ = make_str("nothing"); }
6536                 | NOTIFY                        { $$ = make_str("notify"); }
6537                 | NOWAIT                        { $$ = make_str("nowait"); }
6538                 | NULLS_P                       { $$ = make_str("nulls"); }
6539                 | OBJECT_P                      { $$ = make_str("object"); }
6540                 | OF                            { $$ = make_str("of"); }
6541                 | OIDS                          { $$ = make_str("oids"); }
6542                 | OPERATOR                      { $$ = make_str("operator"); }
6543                 | OPTION                        { $$ = make_str("option"); }
6544                 | OWNED                         { $$ = make_str("owned"); }
6545                 | OWNER                         { $$ = make_str("owner"); }
6546                 | PARSER                        { $$ = make_str("parser"); }
6547                 | PARTIAL                       { $$ = make_str("partial"); }
6548                 | PASSWORD                      { $$ = make_str("password"); }
6549                 | PLANS                         { $$ = make_str("plans"); }
6550                 | PREPARE                       { $$ = make_str("prepare"); }
6551                 | PREPARED                      { $$ = make_str("prepared"); }
6552                 | PRESERVE                      { $$ = make_str("preserver"); }
6553                 | PRIOR                         { $$ = make_str("prior"); }
6554                 | PRIVILEGES            { $$ = make_str("privileges"); }
6555                 | PROCEDURAL            { $$ = make_str("procedural"); }
6556                 | PROCEDURE                     { $$ = make_str("procedure"); }
6557                 | QUOTE                         { $$ = make_str("quote"); }
6558                 | READ                          { $$ = make_str("read"); }
6559                 | REASSIGN                      { $$ = make_str("reassign"); }
6560                 | RECHECK                       { $$ = make_str("recheck"); }
6561                 | REINDEX                       { $$ = make_str("reindex"); }
6562                 | RELATIVE_P            { $$ = make_str("relative"); }
6563                 | RELEASE                       { $$ = make_str("release"); }
6564                 | RENAME                        { $$ = make_str("rename"); }
6565                 | REPEATABLE            { $$ = make_str("repeatable"); }
6566                 | REPLACE                       { $$ = make_str("replace"); }
6567                 | REPLICA                       { $$ = make_str("replica"); }
6568                 | RESET                         { $$ = make_str("reset"); }
6569                 | RESTART                       { $$ = make_str("restart"); }
6570                 | RESTRICT                      { $$ = make_str("restrict"); }
6571                 | RETURNS                       { $$ = make_str("returns"); }
6572                 | REVOKE                        { $$ = make_str("revoke"); }
6573                 | ROLE                          { $$ = make_str("role"); }
6574                 | ROLLBACK                      { $$ = make_str("rollback"); }
6575                 | ROWS                          { $$ = make_str("rows"); }
6576                 | RULE                          { $$ = make_str("rule"); }
6577                 | SAVEPOINT                     { $$ = make_str("savepoint"); }
6578                 | SCHEMA                        { $$ = make_str("schema"); }
6579                 | SCROLL                        { $$ = make_str("scroll"); }
6580                 | SEARCH                        { $$ = make_str("search"); }
6581 /*              | SECOND_P                      { $$ = make_str("second"); }*/
6582                 | SEQUENCE                      { $$ = make_str("sequence"); }
6583                 | SERIALIZABLE          { $$ = make_str("serializable"); }
6584                 | SESSION                       { $$ = make_str("session"); }
6585                 | SET                           { $$ = make_str("set"); }
6586                 | SHARE                         { $$ = make_str("share"); }
6587                 | SHOW                          { $$ = make_str("show"); }
6588                 | SIMPLE                        { $$ = make_str("simple"); }
6589                 | STABLE                        { $$ = make_str("stable"); }
6590                 | STANDALONE_P                  { $$ = make_str("standalone"); }
6591                 | START                         { $$ = make_str("start"); }
6592                 | STATEMENT                     { $$ = make_str("statement"); }
6593                 | STATISTICS            { $$ = make_str("statistics"); }
6594                 | STDIN                         { $$ = make_str("stdin"); }
6595                 | STDOUT                        { $$ = make_str("stdout"); }
6596                 | STORAGE                       { $$ = make_str("storage"); }
6597                 | STRICT_P                      { $$ = make_str("strict"); }
6598                 | STRIP_P                       { $$ = make_str("strip"); }
6599                 | SUPERUSER_P           { $$ = make_str("superuser"); }
6600                 | SYSTEM_P                      { $$ = make_str("system"); }
6601                 | SYSID                         { $$ = make_str("sysid"); }
6602                 | TABLESPACE            { $$ = make_str("tablespace"); }
6603                 | TEMP                          { $$ = make_str("temp"); }
6604                 | TEMPLATE                      { $$ = make_str("template"); }
6605                 | TEMPORARY                     { $$ = make_str("temporary"); }
6606                 | TEXT_P                        { $$ = make_str("text"); }
6607                 | TRANSACTION           { $$ = make_str("transaction"); }
6608                 | TRIGGER                       { $$ = make_str("trigger"); }
6609                 | TRUNCATE                      { $$ = make_str("truncate"); }
6610                 | TRUSTED                       { $$ = make_str("trusted"); }
6611                 | TYPE_P                        { $$ = make_str("type"); }
6612                 | UNCOMMITTED           { $$ = make_str("uncommitted"); }
6613                 | UNENCRYPTED           { $$ = make_str("unencrypted"); }
6614                 | UNKNOWN                       { $$ = make_str("unknown"); }
6615                 | UNLISTEN                      { $$ = make_str("unlisten"); }
6616                 | UNTIL                         { $$ = make_str("until"); }
6617                 | UPDATE                        { $$ = make_str("update"); }
6618                 | VACUUM                        { $$ = make_str("vacuum"); }
6619                 | VALID                         { $$ = make_str("valid"); }
6620                 | VALIDATOR                     { $$ = make_str("validator"); }
6621                 | VALUE_P                       { $$ = make_str("value"); }
6622                 | VARYING                       { $$ = make_str("varying"); }
6623                 | VERSION_P                     { $$ = make_str("version"); }
6624                 | VIEW                          { $$ = make_str("view"); }
6625                 | VOLATILE                      { $$ = make_str("volatile"); }
6626                 | WHITESPACE_P                  { $$ = make_str("whitespace"); }
6627                 | WITH                          { $$ = make_str("with"); }
6628                 | WITHOUT                       { $$ = make_str("without"); }
6629                 | WORK                          { $$ = make_str("work"); }
6630                 | WRITE                         { $$ = make_str("write"); }
6631                 | XML_P                         { $$ = make_str("xml"); }
6632                 | YES_P                         { $$ = make_str("yes"); }
6633 /*              | YEAR_P                        { $$ = make_str("year"); }*/
6634                 | ZONE                          { $$ = make_str("zone"); }
6635                 ;
6636
6637 /* Column identifier --- keywords that can be column, table, etc names.
6638  *
6639  * Many of these keywords will in fact be recognized as type or function
6640  * names too; but they have special productions for the purpose, and so
6641  * can't be treated as "generic" type or function names.
6642  *
6643  * The type names appearing here are not usable as function names
6644  * because they can be followed by '(' in typename productions, which
6645  * looks too much like a function call for an LR(1) parser.
6646  */
6647 col_name_keyword:
6648                 BIGINT                  { $$ = make_str("bigint");}
6649                 | BIT                   { $$ = make_str("bit"); }
6650 /* CHAR must be excluded from ECPGColLabel because of conflict with UNSIGNED
6651                 | CHAR_P                { $$ = make_str("char"); }
6652  */
6653                 | CHARACTER             { $$ = make_str("character"); }
6654                 | COALESCE              { $$ = make_str("coalesce"); }
6655                 | DEC                   { $$ = make_str("dec"); }
6656                 | DECIMAL_P             { $$ = make_str("decimal"); }
6657                 | EXISTS                { $$ = make_str("exists"); }
6658                 | EXTRACT               { $$ = make_str("extract"); }
6659                 | FLOAT_P               { $$ = make_str("float"); }
6660                 | GREATEST              { $$ = make_str("greatest"); }
6661                 | INOUT                 { $$ = make_str("inout"); }
6662 /* INT must be excluded from ECPGColLabel because of conflict
6663                 | INT_P                 { $$ = make_str("int"); }
6664  */
6665                 | INTEGER               { $$ = make_str("integer"); }
6666                 | INTERVAL              { $$ = make_str("interval"); }
6667                 | LEAST                 { $$ = make_str("least"); }
6668                 | NATIONAL              { $$ = make_str("national"); }
6669                 | NCHAR                 { $$ = make_str("nchar"); }
6670                 | NONE                  { $$ = make_str("none"); }
6671                 | NULLIF                { $$ = make_str("nullif"); }
6672                 | NUMERIC               { $$ = make_str("numeric"); }
6673                 | OUT_P                 { $$ = make_str("out"); }
6674                 | OVERLAY               { $$ = make_str("overlay"); }
6675                 | POSITION              { $$ = make_str("position"); }
6676                 | PRECISION             { $$ = make_str("precision"); }
6677                 | REAL                  { $$ = make_str("real"); }
6678                 | ROW                   { $$ = make_str("row"); }
6679                 | SETOF                 { $$ = make_str("setof"); }
6680                 | SMALLINT              { $$ = make_str("smallint"); }
6681                 | SUBSTRING             { $$ = make_str("substring"); }
6682                 | TIME                  { $$ = make_str("time"); }
6683                 | TIMESTAMP             { $$ = make_str("timestamp"); }
6684                 | TREAT                 { $$ = make_str("treat"); }
6685                 | TRIM                  { $$ = make_str("trim"); }
6686                 /* VALUES creates a shift/reduce problem if listed here
6687                 | VALUES                { $$ = make_str("values"); } */
6688                 | VARCHAR               { $$ = make_str("varchar"); }
6689                 | XMLATTRIBUTES         { $$ = make_str("xmlattributes"); }
6690                 | XMLCONCAT             { $$ = make_str("xmlconcat"); }
6691                 | XMLELEMENT            { $$ = make_str("xmlelement"); }
6692                 | XMLFOREST             { $$ = make_str("xmlforest"); }
6693                 | XMLPARSE              { $$ = make_str("xmlparse"); }
6694                 | XMLPI                 { $$ = make_str("xmlpi"); }
6695                 | XMLROOT               { $$ = make_str("xmlroot"); }
6696                 | XMLSERIALIZE          { $$ = make_str("xmlserialize"); }
6697                 ;
6698
6699 /* Function identifier --- keywords that can be function names.
6700  *
6701  * Most of these are keywords that are used as operators in expressions;
6702  * in general such keywords can't be column names because they would be
6703  * ambiguous with variables, but they are unambiguous as function identifiers.
6704  *
6705  * Do not include POSITION, SUBSTRING, etc here since they have explicit
6706  * productions in a_expr to support the goofy SQL9x argument syntax.
6707  *      - thomas 2000-11-28
6708  */
6709 type_func_name_keyword:
6710                   AUTHORIZATION         { $$ = make_str("authorization"); }
6711                 | BETWEEN               { $$ = make_str("between"); }
6712                 | BINARY                { $$ = make_str("binary"); }
6713                 | CROSS                 { $$ = make_str("cross"); }
6714                 | FREEZE                { $$ = make_str("freeze"); }
6715                 | FULL                  { $$ = make_str("full"); }
6716                 | ILIKE                 { $$ = make_str("ilike"); }
6717                 | INNER_P               { $$ = make_str("inner"); }
6718                 | IS                    { $$ = make_str("is"); }
6719                 | ISNULL                { $$ = make_str("isnull"); }
6720                 | JOIN                  { $$ = make_str("join"); }
6721                 | LEFT                  { $$ = make_str("left"); }
6722                 | LIKE                  { $$ = make_str("like"); }
6723                 | NATURAL               { $$ = make_str("natural"); }
6724                 | NOTNULL               { $$ = make_str("notnull"); }
6725                 | OUTER_P               { $$ = make_str("outer"); }
6726                 | OVERLAPS              { $$ = make_str("overlaps"); }
6727                 | RIGHT                 { $$ = make_str("right"); }
6728                 | SIMILAR               { $$ = make_str("similar"); }
6729                 | VERBOSE               { $$ = make_str("verbose"); }
6730                 ;
6731
6732 /* Reserved keyword --- these keywords are usable only as a ColLabel.
6733  *
6734  * Keywords appear here if they could not be distinguished from variable,
6735  * type, or function names in some contexts.  Don't put things here unless
6736  * forced to.
6737  */
6738 reserved_keyword:
6739                   ALL                           { $$ = make_str("all"); }
6740                 | ANALYSE                       { $$ = make_str("analyse"); } /* British */
6741                 | ANALYZE                       { $$ = make_str("analyze"); }
6742                 | AND                           { $$ = make_str("and"); }
6743                 | ANY                           { $$ = make_str("any"); }
6744                 | ARRAY                         { $$ = make_str("array"); }
6745                 | AS                            { $$ = make_str("as"); }
6746                 | ASC                           { $$ = make_str("asc"); }
6747                 | ASYMMETRIC            { $$ = make_str("asymmetric"); }
6748                 | BOTH                          { $$ = make_str("both"); }
6749                 | CASE                          { $$ = make_str("case"); }
6750                 | CAST                          { $$ = make_str("cast"); }
6751                 | CHECK                         { $$ = make_str("check"); }
6752                 | COLLATE                       { $$ = make_str("collate"); }
6753                 | COLUMN                        { $$ = make_str("column"); }
6754                 | CONSTRAINT            { $$ = make_str("constraint"); }
6755                 | CREATE                        { $$ = make_str("create"); }
6756                 | CURRENT_P                     { $$ = make_str("current"); }
6757                 | CURRENT_DATE          { $$ = make_str("current_date"); }
6758                 | CURRENT_TIME          { $$ = make_str("current_time"); }
6759                 | CURRENT_TIMESTAMP     { $$ = make_str("current_timestamp"); }
6760                 | CURRENT_ROLE          { $$ = make_str("current_role"); }
6761                 | CURRENT_USER          { $$ = make_str("current_user"); }
6762                 | DEFAULT                       { $$ = make_str("default"); }
6763                 | DEFERRABLE            { $$ = make_str("deferrable"); }
6764                 | DESC                          { $$ = make_str("desc"); }
6765                 | DISTINCT                      { $$ = make_str("distinct"); }
6766                 | DO                            { $$ = make_str("do"); }
6767                 | ELSE                          { $$ = make_str("else"); }
6768                 | END_P                         { $$ = make_str("end"); }
6769                 | EXCEPT                        { $$ = make_str("except"); }
6770                 | FALSE_P                       { $$ = make_str("false"); }
6771                 | FOR                           { $$ = make_str("for"); }
6772                 | FOREIGN                       { $$ = make_str("foreign"); }
6773                 | FROM                          { $$ = make_str("from"); }
6774                 | GRANT                         { $$ = make_str("grant"); }
6775                 | GROUP_P                       { $$ = make_str("group"); }
6776                 | HAVING                        { $$ = make_str("having"); }
6777                 | IN_P                          { $$ = make_str("in"); }
6778                 | INITIALLY                     { $$ = make_str("initially"); }
6779                 | INTERSECT                     { $$ = make_str("intersect"); }
6780                 | INTO                          { $$ = make_str("into"); }
6781                 | LEADING                       { $$ = make_str("leading"); }
6782                 | LIMIT                         { $$ = make_str("limit"); }
6783                 | NEW                           { $$ = make_str("new"); }
6784                 | NOT                           { $$ = make_str("not"); }
6785                 | NULL_P                        { $$ = make_str("null"); }
6786                 | OFF                           { $$ = make_str("off"); }
6787                 | OFFSET                        { $$ = make_str("offset"); }
6788                 | OLD                           { $$ = make_str("old"); }
6789                 | ON                            { $$ = make_str("on"); }
6790                 | ONLY                          { $$ = make_str("only"); }
6791                 | OR                            { $$ = make_str("or"); }
6792                 | ORDER                         { $$ = make_str("order"); }
6793                 | PRIMARY                       { $$ = make_str("primary"); }
6794                 | REFERENCES                    { $$ = make_str("references"); }
6795                 | RETURNING                     { $$ = make_str("returning"); }
6796                 | SELECT                        { $$ = make_str("select"); }
6797                 | SESSION_USER                  { $$ = make_str("session_user"); }
6798                 | SOME                          { $$ = make_str("some"); }
6799                 | SYMMETRIC                     { $$ = make_str("symmetric"); }
6800                 | TABLE                         { $$ = make_str("table"); }
6801                 | THEN                          { $$ = make_str("then"); }
6802 /* TO must be excluded from ECPGColLabel because of a conflict in variable name parsing
6803                 | TO                            { $$ = make_str("to"); }
6804  */
6805                 | TRAILING                      { $$ = make_str("trailing"); }
6806                 | TRUE_P                        { $$ = make_str("true"); }
6807 /* UNION must be excluded from ECPGColLabel because of conflict with s_union
6808                 | UNION                         { $$ = make_str("union"); }
6809  */
6810                 | UNIQUE                        { $$ = make_str("unique"); }
6811                 | USER                          { $$ = make_str("user"); }
6812                 | USING                         { $$ = make_str("using"); }
6813                 | WHEN                          { $$ = make_str("when"); }
6814                 | WHERE                         { $$ = make_str("where"); }
6815                 ;
6816
6817
6818 into_list : coutputvariable | into_list ',' coutputvariable
6819                 ;
6820
6821 ecpgstart: SQL_START    {
6822                                 reset_variables();
6823                                 pacounter = 1;
6824                         }
6825                 ;
6826
6827 c_args: /*EMPTY*/               { $$ = EMPTY; }
6828                 | c_list                { $$ = $1; }
6829                 ;
6830
6831 coutputvariable: cvariable indicator
6832                         { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
6833                 | cvariable
6834                         { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
6835                 ;
6836
6837
6838 civarind: cvariable indicator
6839                 {
6840                         if (find_variable($2)->type->type == ECPGt_array)
6841                                 mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
6842
6843                         add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
6844                         $$ = create_questionmarks($1, false);
6845                 }
6846                 ;
6847
6848 civar: cvariable
6849                 {
6850                         add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
6851                         $$ = create_questionmarks($1, false);
6852                 }
6853                 ;
6854
6855 indicator: cvariable                            { check_indicator((find_variable($1))->type); $$ = $1; }
6856                 | SQL_INDICATOR cvariable       { check_indicator((find_variable($2))->type); $$ = $2; }
6857                 | SQL_INDICATOR name            { check_indicator((find_variable($2))->type); $$ = $2; }
6858                 ;
6859
6860 cvariable:      CVARIABLE
6861                 {
6862                         /* As long as multidimensional arrays are not implemented we have to check for those here */
6863                         char *ptr = $1;
6864                         int brace_open=0, brace = false;
6865
6866                         for (; *ptr; ptr++)
6867                         {
6868                                 switch (*ptr)
6869                                 {
6870                                         case '[':
6871                                                         if (brace)
6872                                                                 mmerror(PARSE_ERROR, ET_FATAL, "No multidimensional array support for simple data types");
6873                                                         brace_open++;
6874                                                         break;
6875                                         case ']':
6876                                                         brace_open--;
6877                                                         if (brace_open == 0)
6878                                                                 brace = true;
6879                                                         break;
6880                                         case '\t':
6881                                         case ' ':
6882                                                         break;
6883                                         default:
6884                                                         if (brace_open == 0)
6885                                                                 brace = false;
6886                                                         break;
6887                                 }
6888                         }
6889                         $$ = $1;
6890                 }
6891                 ;
6892 ident: IDENT                            { $$ = $1; }
6893                 | CSTRING               { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6894                 ;
6895
6896 quoted_ident_stringvar: name
6897                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6898                 | char_variable
6899                         { $$ = make3_str(make_str("("), $1, make_str(")")); }
6900                 ;
6901
6902 /*
6903  * C stuff
6904  */
6905
6906 c_stuff_item: c_anything                        { $$ = $1; }
6907                 | '(' ')'                       { $$ = make_str("()"); }
6908                 | '(' c_stuff ')'
6909                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
6910                 ;
6911
6912 c_stuff: c_stuff_item                   { $$ = $1; }
6913                 | c_stuff c_stuff_item
6914                         { $$ = cat2_str($1, $2); }
6915                 ;
6916
6917 c_list: c_term                          { $$ = $1; }
6918                 | c_list ',' c_term     { $$ = cat_str(3, $1, make_str(","), $3); }
6919                 ;
6920
6921 c_term:  c_stuff                        { $$ = $1; }
6922                 | '{' c_list '}'        { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
6923                 ;
6924
6925 c_thing:        c_anything              { $$ = $1; }
6926                 |       '('             { $$ = make_str("("); }
6927                 |       ')'             { $$ = make_str(")"); }
6928                 |       ','             { $$ = make_str(","); }
6929                 |       ';'             { $$ = make_str(";"); }
6930                 ;
6931
6932 c_anything:  IDENT                              { $$ = $1; }
6933                 | CSTRING                       { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6934                 | Iconst                        { $$ = $1; }
6935                 | Fconst                        { $$ = $1; }
6936                 | Sconst                        { $$ = $1; }
6937                 | '*'                           { $$ = make_str("*"); }
6938                 | '+'                           { $$ = make_str("+"); }
6939                 | '-'                           { $$ = make_str("-"); }
6940                 | '/'                           { $$ = make_str("/"); }
6941                 | '%'                           { $$ = make_str("%"); }
6942                 | NULL_P                        { $$ = make_str("NULL"); }
6943                 | S_ADD                         { $$ = make_str("+="); }
6944                 | S_AND                         { $$ = make_str("&&"); }
6945                 | S_ANYTHING                    { $$ = make_name(); }
6946                 | S_AUTO                        { $$ = make_str("auto"); }
6947                 | S_CONST                       { $$ = make_str("const"); }
6948                 | S_DEC                         { $$ = make_str("--"); }
6949                 | S_DIV                         { $$ = make_str("/="); }
6950                 | S_DOTPOINT                    { $$ = make_str(".*"); }
6951                 | S_EQUAL                       { $$ = make_str("=="); }
6952                 | S_EXTERN                      { $$ = make_str("extern"); }
6953                 | S_INC                         { $$ = make_str("++"); }
6954                 | S_LSHIFT                      { $$ = make_str("<<"); }
6955                 | S_MEMBER                      { $$ = make_str("->"); }
6956                 | S_MEMPOINT                    { $$ = make_str("->*"); }
6957                 | S_MOD                         { $$ = make_str("%="); }
6958                 | S_MUL                         { $$ = make_str("*="); }
6959                 | S_NEQUAL                      { $$ = make_str("!="); }
6960                 | S_OR                          { $$ = make_str("||"); }
6961                 | S_REGISTER                    { $$ = make_str("register"); }
6962                 | S_RSHIFT                      { $$ = make_str(">>"); }
6963                 | S_STATIC                      { $$ = make_str("static"); }
6964                 | S_SUB                         { $$ = make_str("-="); }
6965                 | S_TYPEDEF                     { $$ = make_str("typedef"); }
6966                 | S_VOLATILE                    { $$ = make_str("volatile"); }
6967                 | SQL_BOOL                      { $$ = make_str("bool"); }
6968                 | ENUM_P                        { $$ = make_str("enum"); }
6969                 | HOUR_P                        { $$ = make_str("hour"); }
6970                 | INT_P                         { $$ = make_str("int"); }
6971                 | SQL_LONG                      { $$ = make_str("long"); }
6972                 | MINUTE_P                      { $$ = make_str("minute"); }
6973                 | MONTH_P                       { $$ = make_str("month"); }
6974                 | SECOND_P                      { $$ = make_str("second"); }
6975                 | SQL_SHORT                     { $$ = make_str("short"); }
6976                 | SQL_SIGNED                    { $$ = make_str("signed"); }
6977                 | SQL_STRUCT                    { $$ = make_str("struct"); }
6978                 | SQL_UNSIGNED                  { $$ = make_str("unsigned"); }
6979                 | YEAR_P                        { $$ = make_str("year"); }
6980                 | CHAR_P                        { $$ = make_str("char"); }
6981                 | FLOAT_P                       { $$ = make_str("float"); }
6982                 | TO                            { $$ = make_str("to"); }
6983                 | UNION                         { $$ = make_str("union"); }
6984                 | VARCHAR                       { $$ = make_str("varchar"); }
6985                 | '['                           { $$ = make_str("["); }
6986                 | ']'                           { $$ = make_str("]"); }
6987                 | '='                           { $$ = make_str("="); }
6988                 | ':'                           { $$ = make_str(":"); }
6989                 ;
6990
6991 %%
6992
6993 void base_yyerror(const char * error)
6994 {
6995         char buf[1024];
6996
6997         snprintf(buf,sizeof buf,"%s at or near \"%s\"", error, token_start ? token_start : yytext);
6998         buf[sizeof(buf)-1]=0;
6999         mmerror(PARSE_ERROR, ET_ERROR, buf);
7000 }
7001
7002 void parser_init(void)
7003 {
7004  /* This function is empty. It only exists for compatibility with the backend parser right now. */
7005 }
7006
7007 /*
7008  * Must undefine base_yylex before including pgc.c, since we want it
7009  * to create the function base_yylex not filtered_base_yylex.
7010  */
7011 #undef base_yylex
7012
7013 #include "pgc.c"