]> granicus.if.org Git - postgresql/blob - src/interfaces/ecpg/preproc/preproc.y
Cleaned up ecpglib and renamed functions that do not need to be exported.
[postgresql] / src / interfaces / ecpg / preproc / preproc.y
1 /* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.353 2007/10/03 11:11:12 meskes Exp $ */
2
3 /* Copyright comment */
4 %{
5 #include "postgres_fe.h"
6
7 #include "extern.h"
8 #include <unistd.h>
9
10 /* Location tracking support --- simpler than bison's default */
11 #define YYLLOC_DEFAULT(Current, Rhs, N) \
12         do { \
13                 if (N) \
14                         (Current) = (Rhs)[1]; \
15                 else \
16                         (Current) = (Rhs)[0]; \
17         } while (0)
18
19 /*
20  * The %name-prefix option below will make bison call base_yylex, but we
21  * really want it to call filtered_base_yylex (see parser.c).
22  */
23 #define base_yylex filtered_base_yylex
24
25 /*
26  * Variables containing simple states.
27  */
28 int struct_level = 0;
29 int braces_open; /* brace level counter */
30 int ecpg_informix_var = 0;
31 char    *connection = NULL;
32 char    *input_filename = NULL;
33
34 static int      QueryIsRule = 0, FoundInto = 0;
35 static int      initializer = 0;
36 static int      pacounter = 1;
37 static char     pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the size we need */
38 static struct this_type actual_type[STRUCT_DEPTH];
39 static char *actual_startline[STRUCT_DEPTH];
40
41 /* temporarily store struct members while creating the data structure */
42 struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
43
44 /* also store struct type so we can do a sizeof() later */
45 static char *ECPGstruct_sizeof = NULL;
46
47 /* for forward declarations we have to store some data as well */
48 static char *forward_name = NULL;
49
50 struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, NULL, {NULL}};
51 struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
52
53 struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
54
55 /*
56  * Handle parsing errors and warnings
57  */
58 void
59 mmerror(int error_code, enum errortype type, char * error, ...)
60 {
61         va_list ap;
62
63         fprintf(stderr, "%s:%d: ", input_filename, yylineno);
64
65         switch(type)
66         {
67                 case ET_WARNING:
68                         fprintf(stderr, "WARNING: ");
69                         break;
70                 case ET_ERROR:
71                 case ET_FATAL:
72                         fprintf(stderr, "ERROR: ");
73                         break;
74         }
75
76         va_start(ap, error);
77         vfprintf(stderr, error, ap);
78         va_end(ap);
79
80         fprintf(stderr, "\n");
81
82         switch(type)
83         {
84                 case ET_WARNING:
85                         break;
86                 case ET_ERROR:
87                         ret_value = error_code;
88                         break;
89                 case ET_FATAL:
90                         fclose(yyin);
91                         fclose(yyout);
92                         if (unlink(output_filename) != 0 && *output_filename != '-')
93                                 fprintf(stderr, "Could not remove output file %s!\n", output_filename);
94                         exit(error_code);
95         }
96 }
97
98 /*
99  * string concatenation
100  */
101
102 static char *
103 cat2_str(char *str1, char *str2)
104 {
105         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
106
107         strcpy(res_str, str1);
108         strcat(res_str, " ");
109         strcat(res_str, str2);
110         free(str1);
111         free(str2);
112         return(res_str);
113 }
114
115 static char *
116 cat_str(int count, ...)
117 {
118         va_list         args;
119         int                     i;
120         char            *res_str;
121
122         va_start(args, count);
123
124         res_str = va_arg(args, char *);
125
126         /* now add all other strings */
127         for (i = 1; i < count; i++)
128                 res_str = cat2_str(res_str, va_arg(args, char *));
129
130         va_end(args);
131
132         return(res_str);
133 }
134
135 char *
136 make_str(const char *str)
137 {
138         char * res_str = (char *)mm_alloc(strlen(str) + 1);
139
140         strcpy(res_str, str);
141         return res_str;
142 }
143
144 static char *
145 make2_str(char *str1, char *str2)
146 {
147         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
148
149         strcpy(res_str, str1);
150         strcat(res_str, str2);
151         free(str1);
152         free(str2);
153         return(res_str);
154 }
155
156 static char *
157 make3_str(char *str1, char *str2, char *str3)
158 {
159         char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
160
161         strcpy(res_str, str1);
162         strcat(res_str, str2);
163         strcat(res_str, str3);
164         free(str1);
165         free(str2);
166         free(str3);
167         return(res_str);
168 }
169
170 /* and the rest */
171 static char *
172 make_name(void)
173 {
174         char * name = (char *)mm_alloc(yyleng + 1);
175
176         strncpy(name, yytext, yyleng);
177         name[yyleng] = '\0';
178         return(name);
179 }
180
181 static char *
182 create_questionmarks(char *name, bool array)
183 {
184         struct variable *p = find_variable(name);
185         int count;
186         char *result = EMPTY;
187
188         /* In case we have a struct, we have to print as many "?" as there are attributes in the struct
189          * An array is only allowed together with an element argument
190          * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else
191          * so we don't have to worry here. */
192
193         if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
194         {
195                 struct ECPGstruct_member *m;
196
197                 if (p->type->type == ECPGt_struct)
198                         m = p->type->u.members;
199                 else
200                         m = p->type->u.element->u.members;
201
202                 for (count = 0; m != NULL; m=m->next, count++);
203         }
204         else
205                 count = 1;
206
207         for (; count > 0; count --)
208         {
209                 sprintf(pacounter_buffer, "$%d", pacounter++);
210                 result = cat_str(3, result, strdup(pacounter_buffer), make_str(" , "));
211         }
212
213         /* removed the trailing " ," */
214
215         result[strlen(result)-3] = '\0';
216         return(result);
217 }
218
219 static char *
220 adjust_informix(struct arguments *list)
221 {
222         /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
223          * for instance you can declare variables in a function, and then subsequently use them
224          * {
225          *      declare_vars();
226          *      exec sql ... which uses vars declared in the above function
227          *
228          * This breaks standard and leads to some very dangerous programming.
229          * Since they do, we have to work around and accept their syntax as well.
230          * But we will do so ONLY in Informix mode.
231          * We have to change the variables to our own struct and just store the pointer instead of the variable
232          */
233
234          struct arguments *ptr;
235          char *result = make_str("");
236
237          for (ptr = list; ptr != NULL; ptr = ptr->next)
238          {
239                 char temp[20]; /* this should be sufficient unless you have 8 byte integers */
240                 char *original_var;
241
242                 /* change variable name to "ECPG_informix_get_var(<counter>)" */
243                 original_var = ptr->variable->name;
244                 sprintf(temp, "%d))", ecpg_informix_var);
245
246                 if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
247                 {
248                         ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1"), ptr->variable->type->u.element->lineno), ptr->variable->type->size), 0);
249                         sprintf(temp, "%d, (", ecpg_informix_var++);
250                 }
251                 else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
252                 {
253                         ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
254                         sprintf(temp, "%d, (", ecpg_informix_var++);
255                 }
256                 else
257                 {
258                         ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->lineno), 0);
259                         sprintf(temp, "%d, &(", ecpg_informix_var++);
260                 }
261
262                 /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
263                 result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
264
265                 /* now the indicator if there is one */
266                 if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
267                 {
268                         /* change variable name to "ECPG_informix_get_var(<counter>)" */
269                         original_var = ptr->indicator->name;
270                         sprintf(temp, "%d))", ecpg_informix_var);
271
272                         /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
273                         if (atoi(ptr->indicator->type->size) > 1)
274                         {
275                                 ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
276                                 sprintf(temp, "%d, (", ecpg_informix_var++);
277                         }
278                         else
279                         {
280                                 ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->lineno), 0);
281                                 sprintf(temp, "%d, &(", ecpg_informix_var++);
282                         }
283                         result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
284                 }
285          }
286
287          return result;
288 }
289
290 static struct cursor *
291 add_additional_variables(char *name, bool insert)
292 {
293         struct cursor *ptr;
294         struct arguments *p;
295
296         for (ptr = cur; ptr != NULL; ptr=ptr->next)
297         {
298                 if (strcmp(ptr->name, name) == 0)
299                         break;
300         }
301
302         if (ptr == NULL)
303         {
304                 mmerror(PARSE_ERROR, ET_ERROR, "trying to access an undeclared cursor %s\n", name);
305                 return NULL;
306         }
307
308         if (insert)
309         {
310                 /* add all those input variables that were given earlier
311                  * note that we have to append here but have to keep the existing order */
312                 for (p = ptr->argsinsert; p; p = p->next)
313                         add_variable_to_tail(&argsinsert, p->variable, p->indicator);
314         }
315
316         /* add all those output variables that were given earlier */
317         for (p = ptr->argsresult; p; p = p->next)
318                 add_variable_to_tail(&argsresult, p->variable, p->indicator);
319
320         return ptr;
321 }
322
323 static void
324 add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
325 {
326         /* add entry to list */
327         struct typedefs *ptr, *this;
328
329         if ((type_enum == ECPGt_struct ||
330              type_enum == ECPGt_union) &&
331             initializer == 1)
332                 mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
333         else
334         {
335                 for (ptr = types; ptr != NULL; ptr = ptr->next)
336                 {
337                         if (strcmp(name, ptr->name) == 0)
338                                 /* re-definition is a bug */
339                                 mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", name);
340                 }
341                 adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
342
343                 this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
344
345                 /* initial definition */
346                 this->next = types;
347                 this->name = name;
348                 this->brace_level = braces_open;
349                 this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
350                 this->type->type_enum = type_enum;
351                 this->type->type_str = mm_strdup(name);
352                 this->type->type_dimension = dimension; /* dimension of array */
353                 this->type->type_index = length;        /* length of string */
354                 this->type->type_sizeof = ECPGstruct_sizeof;
355                 this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
356                 ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
357
358                 if (type_enum != ECPGt_varchar &&
359                         type_enum != ECPGt_char &&
360                         type_enum != ECPGt_unsigned_char &&
361                         atoi(this->type->type_index) >= 0)
362                         mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
363
364                 types = this;
365         }
366 }
367 %}
368
369 %name-prefix="base_yy"
370 %locations
371
372 %union {
373         double  dval;
374         char    *str;
375         int     ival;
376         struct  when            action;
377         struct  index           index;
378         int             tagname;
379         struct  this_type       type;
380         enum    ECPGttype       type_enum;
381         enum    ECPGdtype       dtype_enum;
382         struct  fetch_desc      descriptor;
383         struct  su_symbol       struct_union;
384         struct  prep            prep;
385 }
386
387 /* special embedded SQL token */
388 %token  SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
389                 SQL_CALL SQL_CARDINALITY SQL_CONNECT
390                 SQL_CONTINUE SQL_COUNT SQL_DATA
391                 SQL_DATETIME_INTERVAL_CODE
392                 SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
393                 SQL_DESCRIPTOR SQL_DISCONNECT SQL_FOUND
394                 SQL_FREE SQL_GO SQL_GOTO SQL_IDENTIFIED
395                 SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
396                 SQL_LONG SQL_NULLABLE SQL_OCTET_LENGTH
397                 SQL_OPEN SQL_OUTPUT SQL_REFERENCE
398                 SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
399                 SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
400                 SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
401                 SQL_STRUCT SQL_UNSIGNED SQL_VAR SQL_WHENEVER
402
403 /* C token */
404 %token  S_ADD S_AND S_ANYTHING S_AUTO S_CONST S_DEC S_DIV
405                 S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
406                 S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
407                 S_STATIC S_SUB S_VOLATILE
408                 S_TYPEDEF
409
410 /* I need this and don't know where it is defined inside the backend */
411 %token  TYPECAST
412
413 /* ordinary key words in alphabetical order */
414 %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
415         AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
416         ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
417
418         BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
419         BOOLEAN_P BOTH BY
420
421         CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
422         CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
423         CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
424         COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS 
425         CONTENT_P CONVERSION_P CONVERT COPY COST CREATE CREATEDB
426         CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
427         CURRENT_TIME CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
428
429         DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
430         DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS DESC
431         DICTIONARY DISABLE_P DISCARD DISTINCT DO DOCUMENT_P DOMAIN_P DOUBLE_P DROP
432
433         EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ENUM_P ESCAPE EXCEPT EXCLUSIVE EXCLUDING
434         EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
435
436         FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
437         FULL FUNCTION
438
439         GET GLOBAL GRANT GRANTED GREATEST GROUP_P
440
441         HANDLER HAVING HEADER_P HOLD HOUR_P
442
443         IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
444         INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
445         INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
446         INTERVAL INTO INVOKER IS ISNULL ISOLATION
447
448         JOIN
449
450         KEY
451
452         LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
453         LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
454         LOCK_P LOGIN_P
455
456         MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
457
458         NAME_P NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
459         NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
460         NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NULLS_P NUMERIC
461
462         OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
463         OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER
464
465         PARSER PARTIAL PASSWORD PLACING PLANS POSITION
466         PRECISION PRESERVE PREPARE PREPARED PRIMARY
467         PRIOR PRIVILEGES PROCEDURAL PROCEDURE
468
469         QUOTE
470
471         READ REAL REASSIGN RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
472         REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
473         RIGHT ROLE ROLLBACK ROW ROWS RULE
474
475         SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
476         SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
477         SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
478         STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
479         SYMMETRIC SYSID SYSTEM_P
480
481         TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO 
482         TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
483
484         UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
485         UPDATE USER USING
486
487         VACUUM VALID VALIDATOR VALUE_P VALUES VARCHAR VARYING
488         VERBOSE VERSION_P VIEW VOLATILE
489         WHEN WHERE WHITESPACE_P WITH WITHOUT WORK WRITE
490
491         XML_P XMLATTRIBUTES XMLCONCAT XMLELEMENT XMLFOREST XMLPARSE
492         XMLPI XMLROOT XMLSERIALIZE
493
494         YEAR_P YES_P
495
496         ZONE
497
498 /* The grammar thinks these are keywords, but they are not in the keywords.c
499  * list and so can never be entered directly.  The filter in parser.c
500  * creates these tokens when required.
501  */
502 %token           NULLS_FIRST NULLS_LAST WITH_CASCADED WITH_LOCAL WITH_CHECK
503
504 /* Special token types, not actually keywords - see the "lex" file */
505 %token <str>    IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST
506 %token <str>    XCONST DOLCONST ECONST NCONST
507 %token <ival>   ICONST PARAM
508 %token <dval>   FCONST
509
510 /* precedence: lowest to highest */
511 %nonassoc       SET                             /* see relation_expr_opt_alias */
512 %left           UNION EXCEPT
513 %left           INTERSECT
514 %left           OR
515 %left           AND
516 %right          NOT
517 %right          '='
518 %nonassoc       '<' '>'
519 %nonassoc       LIKE ILIKE SIMILAR
520 %nonassoc       ESCAPE
521 %nonassoc       OVERLAPS
522 %nonassoc       BETWEEN
523 %nonassoc       IN_P
524 %left           POSTFIXOP                                       /* dummy for postfix Op rules */
525 %left           Op OPERATOR                             /* multi-character ops and user-defined operators */
526 %nonassoc       NOTNULL
527 %nonassoc       ISNULL
528 %nonassoc       IS NULL_P TRUE_P FALSE_P UNKNOWN
529 %left           '+' '-'
530 %left           '*' '/' '%'
531 %left           '^'
532 /* Unary Operators */
533 %left           AT ZONE
534 %right          UMINUS
535 %left           '[' ']'
536 %left           '(' ')'
537 %left           TYPECAST
538 %left           '.'
539 %left           JOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
540 /* kluge to keep xml_whitespace_option from causing shift/reduce conflicts */
541 %right         PRESERVE STRIP_P
542
543 %type  <str>    Iconst Fconst Sconst TransactionStmt CreateStmt RoleId
544 %type  <str>    CreateAsElement OptCreateAs CreateAsList CreateAsStmt
545 %type  <str>    comment_text ConstraintDeferrabilitySpec TableElementList
546 %type  <str>    key_match ColLabel SpecialRuleRelation ColId columnDef
547 %type  <str>    ColConstraint ColConstraintElem drop_type Bconst Iresult
548 %type  <str>    TableConstraint OptTableElementList Xconst opt_transaction
549 %type  <str>    ConstraintElem key_actions ColQualList cluster_index_specification
550 %type  <str>    target_list target_el alias_clause type_func_name_keyword
551 %type  <str>    qualified_name database_name alter_using type_function_name
552 %type  <str>    access_method attr_name index_name name func_name
553 %type  <str>    file_name AexprConst c_expr ConstTypename var_list
554 %type  <str>    a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
555 %type  <str>    opt_indirection expr_list extract_list extract_arg
556 %type  <str>    position_list substr_list substr_from alter_column_default
557 %type  <str>    trim_list in_expr substr_for attrs TableFuncElement
558 %type  <str>    Typename SimpleTypename Numeric opt_float DiscardStmt
559 %type  <str>    Character character opt_varying opt_charset enum_val_list
560 %type  <str>    opt_timezone opt_interval table_ref fetch_direction
561 %type  <str>    ConstDatetime AlterDomainStmt AlterSeqStmt alter_rel_cmds
562 %type  <str>    SelectStmt into_clause OptTemp ConstraintAttributeSpec
563 %type  <str>    opt_table opt_all sort_clause sortby_list ConstraintAttr
564 %type  <str>    sortby qualified_name_list name_list ColId_or_Sconst
565 %type  <str>    group_clause having_clause from_clause opt_distinct opt_hold
566 %type  <str>    join_outer where_clause relation_expr sub_type arg_class
567 %type  <str>    opt_column_list insert_rest InsertStmt param_name
568 %type  <str>    columnList DeleteStmt UpdateStmt DeclareCursorStmt
569 %type  <str>    NotifyStmt columnElem UnlistenStmt TableElement
570 %type  <str>    copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
571 %type  <str>    FetchStmt from_in CreateOpClassStmt returning_clause
572 %type  <str>    ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
573 %type  <str>    opt_full func_arg OptWith opt_freeze alter_table_cmd
574 %type  <str>    analyze_keyword opt_name_list ExplainStmt index_params
575 %type  <str>    index_elem opt_class access_method_clause alter_table_cmds
576 %type  <str>    index_opt_unique IndexStmt func_return ConstInterval
577 %type  <str>    func_args_list func_args opt_with def_arg overlay_placing
578 %type  <str>    def_elem def_list definition DefineStmt select_with_parens
579 %type  <str>    opt_instead event RuleActionList opt_using CreateAssertStmt
580 %type  <str>    RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
581 %type  <str>    RuleStmt opt_column oper_argtypes NumConst var_name
582 %type  <str>    MathOp RemoveFuncStmt ECPGunreserved_con opt_database_name
583 %type  <str>    RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
584 %type  <str>    RemoveOperStmt RenameStmt all_Op opt_trusted opt_lancompiler
585 %type  <str>    VariableSetStmt var_value zone_value VariableShowStmt
586 %type  <str>    VariableResetStmt AlterTableStmt from_list overlay_list
587 %type  <str>    relation_name OptTableSpace LockStmt opt_lock 
588 %type  <str>    CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
589 %type  <str>    OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
590 %type  <str>    DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
591 %type  <str>    TriggerActionTime CreateTrigStmt DropPLangStmt DropCastStmt
592 %type  <str>    CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
593 %type  <str>    ViewStmt LoadStmt CreatedbStmt createdb_opt_item ExplainableStmt
594 %type  <str>    createdb_opt_list opt_encoding OptInherit opt_equal
595 %type  <str>    privilege_list privilege privilege_target opt_if_exists
596 %type  <str>    opt_grant_grant_option cursor_options DropOwnedStmt
597 %type  <str>    transaction_mode_list_or_empty transaction_mode_list
598 %type  <str>    function_with_argtypes_list function_with_argtypes IntConstVar
599 %type  <str>    DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
600 %type  <str>    GrantStmt privileges PosAllConst constraints_set_list
601 %type  <str>    ConstraintsSetStmt AllConst CreateDomainStmt opt_nowait
602 %type  <str>    case_expr when_clause_list case_default case_arg when_clause
603 %type  <str>    select_clause opt_select_limit select_limit_value opt_recheck
604 %type  <str>    ConstraintTimeSpec AlterDatabaseSetStmt DropAssertStmt
605 %type  <str>    select_offset_value ReindexStmt join_type opt_boolean
606 %type  <str>    join_qual joined_table opclass_item relation_expr_opt_alias
607 %type  <str>    lock_type array_expr_list ReassignOwnedStmt for_locking_item
608 %type  <str>    OptConstrFromTable OptTempTableName StringConst array_expr
609 %type  <str>    constraints_set_mode comment_type opt_check_option
610 %type  <str>    CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
611 %type  <str>    opt_force key_update CreateSchemaStmt PosIntStringConst
612 %type  <str>    IntConst PosIntConst grantee_list func_type opt_or_replace
613 %type  <str>    select_limit CheckPointStmt ECPGColId old_aggr_list
614 %type  <str>    OptSchemaName OptSchemaEltList schema_stmt opt_drop_behavior
615 %type  <str>    handler_name any_name_list any_name opt_as insert_column_list
616 %type  <str>    columnref values_clause AllConstVar prep_type_clause ExecuteStmt
617 %type  <str>    insert_column_item DropRuleStmt ctext_expr execute_param_clause 
618 %type  <str>    createfunc_opt_item set_rest alter_rel_cmd
619 %type  <str>    CreateFunctionStmt createfunc_opt_list func_table
620 %type  <str>    DropUserStmt copy_from copy_opt_list copy_opt_item
621 %type  <str>    opt_oids TableLikeClause key_action opt_definition
622 %type  <str>    cast_context row qual_Op qual_all_Op opt_default
623 %type  <str>    CreateConversionStmt any_operator opclass_item_list
624 %type  <str>    iso_level type_list CharacterWithLength ConstCharacter
625 %type  <str>    CharacterWithoutLength BitWithLength BitWithoutLength
626 %type  <str>    ConstBit GenericType TableFuncElementList opt_analyze
627 %type  <str>    opt_sort_clause subquery_Op transaction_mode_item
628 %type  <str>    ECPGWhenever ECPGConnect connection_target ECPGOpen
629 %type  <str>    indicator ecpg_using ecpg_into DeallocateStmt
630 %type  <str>    storage_declaration storage_clause opt_initializer c_anything
631 %type  <str>    variable_list variable c_thing c_term ECPGKeywords_vanames
632 %type  <str>    opt_pointer ECPGDisconnect dis_name storage_modifier
633 %type  <str>    execstring server_name ECPGVarDeclaration func_expr
634 %type  <str>    connection_object opt_server opt_port c_stuff c_stuff_item
635 %type  <str>    user_name opt_user char_variable ora_user ident opt_reference
636 %type  <str>    var_type_declarations quoted_ident_stringvar ECPGKeywords_rest
637 %type  <str>    db_prefix server opt_options opt_connection_name c_list
638 %type  <str>    ECPGSetConnection ECPGTypedef c_args ECPGKeywords ECPGCKeywords
639 %type  <str>    enum_type civar civarind ECPGCursorStmt PreparableStmt
640 %type  <str>    ECPGFree ECPGDeclare ECPGVar at enum_definition
641 %type  <str>    struct_union_type s_struct_union vt_declarations execute_rest
642 %type  <str>    var_declaration type_declaration single_vt_declaration
643 %type  <str>    ECPGSetAutocommit on_off variable_declarations ECPGDescribe
644 %type  <str>    ECPGAllocateDescr ECPGDeallocateDescr symbol opt_output
645 %type  <str>    ECPGGetDescriptorHeader ECPGColLabel SetResetClause AlterUserSetStmt
646 %type  <str>    reserved_keyword unreserved_keyword ecpg_interval opt_ecpg_using
647 %type  <str>    col_name_keyword precision opt_scale ECPGExecuteImmediateStmt
648 %type  <str>    ECPGTypeName using_list ECPGColLabelCommon UsingConst 
649 %type  <str>    using_descriptor into_descriptor opt_nulls_order opt_asc_desc
650 %type  <str>    prepared_name struct_union_type_with_symbol OptConsTableSpace
651 %type  <str>    ECPGunreserved ECPGunreserved_interval cvariable opt_bit_field
652 %type  <str>    AlterOwnerStmt OptTableSpaceOwner CreateTableSpaceStmt
653 %type  <str>    DropTableSpaceStmt indirection indirection_el ECPGSetDescriptorHeader
654 %type  <str>    AlterDatabaseStmt CreateRoleStmt OptRoleList AlterRoleStmt AlterRoleSetStmt
655 %type  <str>    DropRoleStmt add_drop opt_validator common_func_opt_item
656 %type  <str>    opt_grant_admin_option AlterFunctionStmt alterfunc_opt_list opt_restrict
657 %type  <str>    AlterObjectSchemaStmt alterdb_opt_list for_locking_clause opt_for_locking_clause
658 %type  <str>    locked_rels_list opt_granted_by RevokeRoleStmt alterdb_opt_item using_clause
659 %type  <str>    GrantRoleStmt opt_asymmetric aggr_args old_aggr_definition
660 %type  <str>    old_aggr_elem for_locking_items TableLikeOptionList TableLikeOption
661 %type  <str>    set_target_list set_clause_list set_clause multiple_set_clause
662 %type  <str>    ctext_expr_list ctext_row single_set_clause set_target opt_type_modifiers
663 %type  <str>    opclass_drop_list opclass_drop DropOpFamilyStmt opt_opfamily
664 %type  <str>    CreateOpFamilyStmt AlterOpFamilyStmt create_as_target
665 %type  <str>    xml_attributes xml_attribute_list document_or_content xml_whitespace_option
666 %type  <str>    opt_xml_root_standalone xml_root_version xml_attribute_el 
667 %type  <str>    where_or_current_clause AlterTSConfigurationStmt AlterTSDictionaryStmt
668
669 %type  <struct_union> s_struct_union_symbol
670
671 %type  <descriptor> ECPGGetDescriptor ECPGSetDescriptor
672
673 %type  <type_enum> simple_type signed_type unsigned_type
674
675 %type  <dtype_enum> descriptor_item desc_header_item
676
677 %type  <type>   var_type
678
679 %type  <prep>   PrepareStmt
680
681 %type  <action> action
682
683 %type  <index>  opt_array_bounds
684
685 %%
686 prog: statements;
687
688 statements: /*EMPTY*/
689                 | statements statement
690                 ;
691
692 statement: ecpgstart at stmt ';'        { connection = NULL; }
693                 | ecpgstart stmt ';'
694                 | ecpgstart ECPGVarDeclaration
695                 {
696                         fprintf(yyout, "%s", $2);
697                         free($2);
698                         output_line_number();
699                 }
700                 | ECPGDeclaration
701                 | c_thing               { fprintf(yyout, "%s", $1); free($1); }
702                 | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
703                 | '{'                   { braces_open++; fputs("{", yyout); }
704                 | '}'                   { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); }
705                 ;
706
707 at: AT connection_object
708                 {
709                         connection = $2;
710                         /*
711                          *      Do we have a variable as connection target?
712                          *      Remove the variable from the variable
713                          *      list or else it will be used twice
714                          */
715                         if (argsinsert != NULL)
716                                 argsinsert = NULL;
717                 }
718         ;
719
720 stmt:  AlterDatabaseStmt                { output_statement($1, 0, ECPGst_normal); }
721                 | AlterDatabaseSetStmt  { output_statement($1, 0, ECPGst_normal); }
722                 | AlterDomainStmt       { output_statement($1, 0, ECPGst_normal); }
723                 | AlterFunctionStmt     { output_statement($1, 0, ECPGst_normal); }
724                 | AlterGroupStmt        { output_statement($1, 0, ECPGst_normal); }
725                 | AlterObjectSchemaStmt { output_statement($1, 0, ECPGst_normal); }
726                 | AlterOwnerStmt        { output_statement($1, 0, ECPGst_normal); }
727                 | AlterSeqStmt          { output_statement($1, 0, ECPGst_normal); }
728                 | AlterTableStmt        { output_statement($1, 0, ECPGst_normal); }
729                 | AlterRoleSetStmt      { output_statement($1, 0, ECPGst_normal); }
730                 | AlterRoleStmt         { output_statement($1, 0, ECPGst_normal); }
731                 | AlterTSConfigurationStmt      { output_statement($1, 0, ECPGst_normal); }
732                 | AlterTSDictionaryStmt { output_statement($1, 0, ECPGst_normal); }
733                 | AlterUserStmt         { output_statement($1, 0, ECPGst_normal); }
734                 | AlterUserSetStmt      { output_statement($1, 0, ECPGst_normal); }
735                 | AnalyzeStmt           { output_statement($1, 0, ECPGst_normal); }
736                 | CheckPointStmt        { output_statement($1, 0, ECPGst_normal); }
737                 | ClosePortalStmt
738                 {
739                         if (INFORMIX_MODE)
740                         {
741                                 /*
742                                  *      Informix also has a CLOSE DATABASE command that
743                                  *      essantially works like a DISCONNECT CURRENT
744                                  *      as far as I know.
745                                  */
746                                 if (pg_strcasecmp($1+strlen("close "), "database") == 0)
747                                 {
748                                         if (connection)
749                                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement.\n");
750
751                                         fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
752                                         whenever_action(2);
753                                         free($1);
754                                 }
755                                 else
756                                         output_statement($1, 0, ECPGst_normal);
757                         }
758                         else
759                                 output_statement($1, 0, ECPGst_normal);
760                 }
761                 | ClusterStmt           { output_statement($1, 0, ECPGst_normal); }
762                 | CommentStmt           { output_statement($1, 0, ECPGst_normal); }
763                 | ConstraintsSetStmt    { output_statement($1, 0, ECPGst_normal); }
764                 | CopyStmt              { output_statement($1, 0, ECPGst_normal); }
765                 | CreateAsStmt          { output_statement($1, 0, ECPGst_normal); }
766                 | CreateAssertStmt      { output_statement($1, 0, ECPGst_normal); }
767                 | CreateCastStmt        { output_statement($1, 0, ECPGst_normal); }
768                 | CreateConversionStmt  { output_statement($1, 0, ECPGst_normal); }
769                 | CreateDomainStmt      { output_statement($1, 0, ECPGst_normal); }
770                 | CreateFunctionStmt    { output_statement($1, 0, ECPGst_normal); }
771                 | CreateGroupStmt       { output_statement($1, 0, ECPGst_normal); }
772                 | CreatePLangStmt       { output_statement($1, 0, ECPGst_normal); }
773                 | CreateOpClassStmt     { output_statement($1, 0, ECPGst_normal); }
774                 | CreateOpFamilyStmt    { output_statement($1, 0, ECPGst_normal); }
775                 | AlterOpFamilyStmt     { output_statement($1, 0, ECPGst_normal); }
776                 | CreateRoleStmt        { output_statement($1, 0, ECPGst_normal); }
777                 | CreateSchemaStmt      { output_statement($1, 0, ECPGst_normal); }
778                 | CreateSeqStmt         { output_statement($1, 0, ECPGst_normal); }
779                 | CreateStmt            { output_statement($1, 0, ECPGst_normal); }
780                 | CreateTableSpaceStmt  { output_statement($1, 0, ECPGst_normal); }
781                 | CreateTrigStmt        { output_statement($1, 0, ECPGst_normal); }
782                 | CreateUserStmt        { output_statement($1, 0, ECPGst_normal); }
783                 | CreatedbStmt          { output_statement($1, 0, ECPGst_normal); }
784                 | DeallocateStmt
785                 {
786                         if (connection)
787                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement.\n");
788                                 
789                         output_deallocate_prepare_statement($1);
790                 }
791                 | DeclareCursorStmt     { output_simple_statement($1); }
792                 | DefineStmt            { output_statement($1, 0, ECPGst_normal); }
793                 | DeleteStmt            { output_statement($1, 1, ECPGst_normal); }
794                 | DiscardStmt           { output_statement($1, 1, ECPGst_normal); }
795                 | DropAssertStmt        { output_statement($1, 0, ECPGst_normal); }
796                 | DropCastStmt          { output_statement($1, 0, ECPGst_normal); }
797                 | DropGroupStmt         { output_statement($1, 0, ECPGst_normal); }
798                 | DropOpClassStmt       { output_statement($1, 0, ECPGst_normal); }
799                 | DropOpFamilyStmt      { output_statement($1, 0, ECPGst_normal); }
800                 | DropOwnedStmt         { output_statement($1, 0, ECPGst_normal); }
801                 | DropPLangStmt         { output_statement($1, 0, ECPGst_normal); }
802                 | DropRoleStmt          { output_statement($1, 0, ECPGst_normal); }
803                 | DropRuleStmt          { output_statement($1, 0, ECPGst_normal); }
804                 | DropStmt              { output_statement($1, 0, ECPGst_normal); }
805                 | DropTableSpaceStmt    { output_statement($1, 0, ECPGst_normal); }
806                 | DropTrigStmt          { output_statement($1, 0, ECPGst_normal); }
807                 | DropUserStmt          { output_statement($1, 0, ECPGst_normal); }
808                 | DropdbStmt            { output_statement($1, 0, ECPGst_normal); }
809                 | ExplainStmt           { output_statement($1, 0, ECPGst_normal); }
810                 | ExecuteStmt           { output_statement($1, 0, ECPGst_execute); }
811                 | FetchStmt             { output_statement($1, 1, ECPGst_normal); }
812                 | GrantStmt             { output_statement($1, 0, ECPGst_normal); }
813                 | GrantRoleStmt         { output_statement($1, 0, ECPGst_normal); }
814                 | IndexStmt             { output_statement($1, 0, ECPGst_normal); }
815                 | InsertStmt            { output_statement($1, 1, ECPGst_normal); }
816                 | ListenStmt            { output_statement($1, 0, ECPGst_normal); }
817                 | LoadStmt              { output_statement($1, 0, ECPGst_normal); }
818                 | LockStmt              { output_statement($1, 0, ECPGst_normal); }
819                 | NotifyStmt            { output_statement($1, 0, ECPGst_normal); }
820                 | PrepareStmt           { 
821                                                 if ($1.type == NULL || strlen($1.type) == 0) /* use PQprepare without type parameters */
822                                                         output_prepare_statement($1.name, $1.stmt);  
823                                                 else    /* use PQexec and let backend do its stuff */
824                                                 {
825                                                         char *txt = cat_str(5, make_str("prepare"), $1.name, $1.type, make_str("as"), $1.stmt);
826                                                         output_statement(txt, 0, ECPGst_normal);
827                                                 }
828                                         }               
829                 | ReassignOwnedStmt     { output_statement($1, 0, ECPGst_normal); }
830                 | ReindexStmt           { output_statement($1, 0, ECPGst_normal); }
831                 | RemoveAggrStmt        { output_statement($1, 0, ECPGst_normal); }
832                 | RemoveOperStmt        { output_statement($1, 0, ECPGst_normal); }
833                 | RemoveFuncStmt        { output_statement($1, 0, ECPGst_normal); }
834                 | RenameStmt            { output_statement($1, 0, ECPGst_normal); }
835                 | RevokeStmt            { output_statement($1, 0, ECPGst_normal); }
836                 | RevokeRoleStmt        { output_statement($1, 0, ECPGst_normal); }
837                 | RuleStmt              { output_statement($1, 0, ECPGst_normal); }
838                 | SelectStmt            { output_statement($1, 1, ECPGst_normal); }
839                 | TransactionStmt
840                 {
841                         fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
842                         whenever_action(2);
843                         free($1);
844                 }
845                 | TruncateStmt          { output_statement($1, 0, ECPGst_normal); }
846                 | UnlistenStmt          { output_statement($1, 0, ECPGst_normal); }
847                 | UpdateStmt            { output_statement($1, 1, ECPGst_normal); }
848                 | VacuumStmt            { output_statement($1, 0, ECPGst_normal); }
849                 | VariableSetStmt       { output_statement($1, 0, ECPGst_normal); }
850                 | VariableShowStmt      { output_statement($1, 0, ECPGst_normal); }
851                 | VariableResetStmt     { output_statement($1, 0, ECPGst_normal); }
852                 | ViewStmt              { output_statement($1, 0, ECPGst_normal); }
853                 | ECPGAllocateDescr
854                 {
855                         fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
856                         whenever_action(0);
857                         free($1);
858                 }
859                 | ECPGConnect
860                 {
861                         if (connection)
862                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
863
864                         fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
865                         reset_variables();
866                         whenever_action(2);
867                         free($1);
868                 }
869                 | ECPGCursorStmt
870                 {
871                         output_simple_statement($1);
872                 }
873                 | ECPGDeallocateDescr
874                 {
875                         if (connection)
876                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement.\n");
877                         fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
878                         whenever_action(0);
879                         free($1);
880                 }
881                 | ECPGDeclare
882                 {
883                         output_simple_statement($1);
884                 }
885                 | ECPGDescribe
886                 {
887                         fprintf(yyout, "{ ECPGdescribe(__LINE__, %s,", $1);
888                         dump_variables(argsresult, 1);
889                         fputs("ECPGt_EORT);", yyout);
890                         fprintf(yyout, "}");
891                         output_line_number();
892
893                         /* whenever_action(2); */
894                         free($1);
895                 }
896                 | ECPGDisconnect
897                 {
898                         if (connection)
899                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for disconnect statement.\n");
900
901                         fprintf(yyout, "{ ECPGdisconnect(__LINE__, %s);",
902                                         $1 ? $1 : "\"CURRENT\"");
903                         whenever_action(2);
904                         free($1);
905                 }
906                 | ECPGExecuteImmediateStmt      { output_statement($1, 0, ECPGst_exec_immediate); }
907                 | ECPGFree
908                 {
909                         const char *con = connection ? connection : "NULL";
910                         if (strcmp($1, "all"))
911                                 fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s, \"%s\");", compat, con, $1);
912                         else
913                                 fprintf(yyout, "{ ECPGdeallocate_all(__LINE__, %d, %s);", compat, con);
914
915                         whenever_action(2);
916                         free($1);
917                 }
918                 | ECPGGetDescriptor
919                 {
920                         lookup_descriptor($1.name, connection);
921                         output_get_descr($1.name, $1.str);
922                         free($1.name);
923                         free($1.str);
924                 }
925                 | ECPGGetDescriptorHeader
926                 {
927                         lookup_descriptor($1, connection);
928                         output_get_descr_header($1);
929                         free($1);
930                 }
931                 | ECPGOpen
932                 {
933                         struct cursor *ptr;
934
935                         if ((ptr = add_additional_variables($1, true)) != NULL)
936                         {
937                                 connection = ptr->connection ? mm_strdup(ptr->connection) : NULL;
938                                 output_statement(mm_strdup(ptr->command), 0, 0);
939                                 ptr->opened = true;
940                         }
941                 }
942                 | ECPGSetAutocommit
943                 {
944                         fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
945                         whenever_action(2);
946                         free($1);
947                 }
948                 | ECPGSetConnection
949                 {
950                         if (connection)
951                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for set connection statement.\n");
952
953                         fprintf(yyout, "{ ECPGsetconn(__LINE__, %s);", $1);
954                         whenever_action(2);
955                         free($1);
956                 }
957                 | ECPGSetDescriptor
958                 {
959                         lookup_descriptor($1.name, connection);
960                         output_set_descr($1.name, $1.str);
961                         free($1.name);
962                         free($1.str);
963                 }
964                 | ECPGSetDescriptorHeader
965                 {
966                         lookup_descriptor($1, connection);
967                         output_set_descr_header($1);
968                         free($1);
969                 }
970                 | ECPGTypedef
971                 {
972                         if (connection)
973                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement.\n");
974
975                         fprintf(yyout, "%s", $1);
976                         free($1);
977                         output_line_number();
978                 }
979                 | ECPGVar
980                 {
981                         if (connection)
982                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for var statement.\n");
983
984                         output_simple_statement($1);
985                 }
986                 | ECPGWhenever
987                 {
988                         if (connection)
989                                 mmerror(PARSE_ERROR, ET_ERROR, "no at option for whenever statement.\n");
990
991                         output_simple_statement($1);
992                 }
993                 ;
994
995
996 /*
997  * We start with a lot of stuff that's very similar to the backend's parsing
998  */
999
1000 /*****************************************************************************
1001  *
1002  * Create a new Postgres DBMS role
1003  *
1004  *
1005  *****************************************************************************/
1006
1007 CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList
1008                         { $$ = cat_str(4, make_str("create role"), $3, make_str("with"), $5); }
1009                 ;
1010
1011 opt_with:  WITH                 { $$ = make_str("with"); }
1012                 | /*EMPTY*/     { $$ = EMPTY; }
1013                 ;
1014
1015 /*
1016  * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER
1017  * for backwards compatibility).  Note: the only option required by SQL99
1018  * is "WITH ADMIN name".
1019  */
1020 OptRoleList:
1021         PASSWORD Sconst                 { $$ = cat2_str(make_str("password"), $2); }
1022         | PASSWORD NULL_P               { $$ = make_str("password null"); }
1023         | ENCRYPTED PASSWORD Sconst     { $$ = cat2_str(make_str("encrypted password"), $3); }
1024         | UNENCRYPTED PASSWORD Sconst   { $$ = cat2_str(make_str("unencrypted password"), $3); }
1025         | SUPERUSER_P                   { $$ = make_str("superuser"); }
1026         | NOSUPERUSER                   { $$ = make_str("nosuperuser"); }
1027         | INHERIT                               { $$ = make_str("inherit"); }
1028         | NOINHERIT                             { $$ = make_str("noinherit"); }
1029         | CREATEDB                              { $$ = make_str("createdb"); }
1030         | NOCREATEDB                    { $$ = make_str("nocreatedb"); }
1031         | CREATEROLE                    { $$ = make_str("createrole"); }
1032         | NOCREATEROLE                  { $$ = make_str("nocreaterole"); }
1033         | LOGIN_P                               { $$ = make_str("login"); }
1034         | NOLOGIN_P                             { $$ = make_str("nologin"); }
1035         | CONNECTION LIMIT IntConst     { $$ = cat2_str(make_str("connection limit"), $3); }
1036         | VALID UNTIL Sconst            { $$ = cat2_str(make_str("valid until"), $3); }
1037         | USER name_list                { $$ = cat2_str(make_str("user"), $2); }
1038         | SYSID PosIntConst             { $$ = cat2_str(make_str("sysid"), $2); }
1039         | ADMIN name_list               { $$ = cat2_str(make_str("admin"), $2); }
1040         | ROLE name_list                { $$ = cat2_str(make_str("role"), $2); }
1041         | IN_P ROLE name_list   { $$ = cat2_str(make_str("in role"), $3); }
1042         | IN_P GROUP_P name_list        { $$ = cat2_str(make_str("in group"), $3); }
1043         ;
1044
1045 /*****************************************************************************
1046  *
1047  * Create a new Postgres DBMS user (role with implied login ability)
1048  *
1049  *****************************************************************************/
1050
1051 CreateUserStmt:
1052         CREATE USER RoleId opt_with OptRoleList
1053                 {$$ = cat_str(4, make_str("create user"), $3, $4, $5); }
1054         ;
1055
1056         /*****************************************************************************
1057          *
1058          * Alter a postgresql DBMS role
1059          *
1060          *
1061          *****************************************************************************/
1062
1063         AlterRoleStmt: ALTER ROLE RoleId opt_with OptRoleList
1064                         { $$ = cat_str(4, make_str("alter role"), $3, $4, $5); }
1065                 ;
1066
1067         AlterRoleSetStmt: ALTER ROLE RoleId SetResetClause
1068                         { $$ = cat_str(3, make_str("alter role"), $3, $4); }
1069                 ;
1070
1071         /*****************************************************************************
1072          *
1073          * Alter a postgresql DBMS user
1074          *
1075          *****************************************************************************/
1076
1077         AlterUserStmt: ALTER USER RoleId opt_with OptRoleList
1078                 { $$ = cat_str(4, make_str("alter user"), $3, $4, $5); };
1079
1080         AlterUserSetStmt: ALTER USER RoleId SetResetClause
1081                         { $$ = cat_str(3, make_str("alter user"), $3, $4); }
1082                 ;
1083
1084         /*****************************************************************************
1085          *
1086          * Drop a postgresql DBMS role
1087          *
1088          *
1089          *****************************************************************************/
1090         DropRoleStmt:  DROP ROLE name_list
1091                         { $$ = cat2_str(make_str("drop role"), $3);}
1092                      | DROP ROLE IF_P EXISTS name_list
1093                         { $$ = cat2_str(make_str("drop role if exists"), $5);}
1094                 ;
1095
1096         /*****************************************************************************
1097          *
1098          * Drop a postgresql DBMS user
1099          *
1100          *
1101          *****************************************************************************/
1102         DropUserStmt:  DROP USER name_list
1103                         { $$ = cat2_str(make_str("drop user"), $3);}
1104                      | DROP USER IF_P EXISTS name_list
1105                         { $$ = cat2_str(make_str("drop user if exists"), $5);}
1106
1107                 ;
1108
1109         /*****************************************************************************
1110          *
1111          * Create a postgresql group
1112          *
1113          *
1114          ****************************************************************************/
1115         CreateGroupStmt:  CREATE GROUP_P RoleId opt_with OptRoleList
1116                         { $$ = cat_str(4, make_str("create group"), $3, $4, $5); }
1117                 ;
1118
1119         /*****************************************************************************
1120          *
1121          * Alter a postgresql group
1122          *
1123          *
1124          *****************************************************************************/
1125         AlterGroupStmt: ALTER GROUP_P RoleId add_drop USER name_list
1126                         { $$ = cat_str(5, make_str("alter group"), $3, $4, make_str("user"), $6); }
1127                 ;
1128
1129         add_drop: ADD_P         { $$ = make_str("add"); }
1130                 | DROP          { $$ = make_str("drop"); }
1131                 ;
1132
1133         /*****************************************************************************
1134          *
1135          * Drop a postgresql group
1136          *
1137          *
1138          *****************************************************************************/
1139         DropGroupStmt: DROP GROUP_P name_list
1140                         { $$ = cat2_str(make_str("drop group"), $3); }
1141                      | DROP GROUP_P IF_P EXISTS name_list
1142                         { $$ = cat2_str(make_str("drop group if exists"), $5); }
1143                 ;
1144
1145         /*****************************************************************************
1146          *
1147          * Manipulate a schema
1148          *
1149          *
1150          *****************************************************************************/
1151
1152         CreateSchemaStmt:  CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
1153                         { $$ = cat_str(5, make_str("create schema"), $3, make_str("authorization"), $5, $6); }
1154                 | CREATE SCHEMA ColId OptSchemaEltList
1155                         { $$ = cat_str(3, make_str("create schema"), $3, $4); }
1156                 ;
1157
1158         OptSchemaName: ColId            { $$ = $1; }
1159                 | /* EMPTY */   { $$ = EMPTY; }
1160                 ;
1161
1162 OptSchemaEltList: OptSchemaEltList schema_stmt         { $$ = cat2_str($1, $2); }
1163                 | /* EMPTY */   { $$ = EMPTY; }
1164                 ;
1165
1166 /*
1167  *     schema_stmt are the ones that can show up inside a CREATE SCHEMA
1168  *     statement (in addition to by themselves).
1169  */
1170 schema_stmt: CreateStmt         { $$ = $1; }
1171                    | IndexStmt          { $$ = $1; }
1172                    | CreateSeqStmt      { $$ = $1; }
1173                    | CreateTrigStmt { $$ = $1; }
1174                    | GrantStmt          { $$ = $1; }
1175                    | ViewStmt           { $$ = $1; }
1176                    ;
1177
1178
1179
1180 /*****************************************************************************
1181  *
1182  * Set PG internal variable
1183  *        SET name TO 'var_value'
1184  * Include SQL92 syntax (thomas 1997-10-22):
1185  *        SET TIME ZONE 'var_value'
1186  *
1187  *****************************************************************************/
1188 VariableSetStmt:  SET set_rest
1189                         { $$ = cat2_str(make_str("set"), $2 ); }
1190                 | SET LOCAL set_rest
1191                         { $$ = cat2_str(make_str("set local"), $3 ); }
1192                 | SET SESSION set_rest
1193                         { $$ = cat2_str(make_str("set session"), $3 ); }
1194                 ;
1195
1196 set_rest:       /* Generic SET syntaxes: */
1197                 var_name TO var_list
1198                         { $$ = cat_str(3, $1, make_str("to"), $3); }
1199                 | var_name "=" var_list
1200                         { $$ = cat_str(3, $1, make_str("="), $3); }
1201                 | var_name TO DEFAULT
1202                         { $$ = cat2_str($1, make_str("to default")); }
1203                 | var_name "=" DEFAULT
1204                         { $$ = cat2_str($1, make_str("= default")); }
1205                 | var_name FROM CURRENT_P
1206                         { $$ = cat2_str($1, make_str("from current")); }
1207                 /* Special syntaxes mandated by SQL standard: */
1208                 | TIME ZONE zone_value
1209                         { $$ = cat2_str(make_str("time zone"), $3); }
1210                 | TRANSACTION transaction_mode_list
1211                         { $$ = cat2_str(make_str("transaction"), $2); }
1212                 | SESSION CHARACTERISTICS AS TRANSACTION transaction_mode_list
1213                         { $$ = cat2_str(make_str("session characteristics as transaction"), $5); }
1214                 | NAMES opt_encoding
1215                         { $$ = cat2_str(make_str("names"), $2); }
1216                 | ROLE ColId_or_Sconst
1217                         { $$ = cat2_str(make_str("role"), $2); }
1218                 | SESSION AUTHORIZATION ColId_or_Sconst
1219                         { $$ = cat2_str(make_str("session authorization"), $3); }
1220                 | SESSION AUTHORIZATION DEFAULT
1221                         { $$ = make_str("session authorization default"); }
1222                 | XML_P OPTION document_or_content
1223                         { $$ = cat2_str(make_str("xml option"), $3); }
1224                 ;
1225
1226 var_name:       ECPGColId               { $$ = $1; }
1227                 | var_name '.' ColId    { $$ = cat_str(3, $1, make_str("."), $3); }
1228                 ;
1229
1230
1231 var_list:  var_value
1232                         { $$ = $1; }
1233                 | var_list ',' var_value
1234                         { $$ = cat_str(3, $1, make_str(","), $3); }
1235                 ;
1236
1237 iso_level:      READ UNCOMMITTED        { $$ = make_str("read uncommitted"); }
1238                 | READ COMMITTED                { $$ = make_str("read committed"); }
1239                 | REPEATABLE READ               { $$ = make_str("repeatable read"); }
1240                 | SERIALIZABLE                  { $$ = make_str("serializable"); }
1241                 ;
1242
1243 var_value:      opt_boolean             { $$ = $1; }
1244                 | AllConst                      { $$ = $1; }
1245                 | ColId                         { $$ = $1; }
1246                 ;
1247
1248 opt_boolean:  TRUE_P            { $$ = make_str("true"); }
1249                 | FALSE_P                       { $$ = make_str("false"); }
1250                 | ON                            { $$ = make_str("on"); }
1251                 | OFF                           { $$ = make_str("off"); }
1252                 ;
1253 /* Timezone values can be:
1254  * - a string such as 'pst8pdt'
1255  * - a column identifier such as "pst8pdt"
1256  * - an integer or floating point number
1257  * - a time interval per SQL99
1258  * ConstInterval and ColId give shift/reduce errors,
1259  * so use IDENT and reject anything which is a reserved word.
1260  */
1261 zone_value:  AllConst           { $$ = $1; }
1262                 | ident         { $$ = $1; }
1263                 | ConstInterval StringConst opt_interval
1264                         { $$ = cat_str(3, $1, $2, $3); }
1265                 | ConstInterval '(' PosIntConst ')' StringConst opt_interval
1266                         { $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
1267                 | DEFAULT
1268                         { $$ = make_str("default"); }
1269                 | LOCAL
1270                         { $$ = make_str("local"); }
1271                 ;
1272
1273 opt_encoding:   StringConst             { $$ = $1; }
1274                 | DEFAULT                               { $$ = make_str("default"); }
1275                 | /*EMPTY*/                             { $$ = EMPTY; }
1276                 ;
1277
1278 ColId_or_Sconst: ColId                  { $$ = $1; }
1279                 | StringConst                   { $$ = $1; }
1280                 ;
1281
1282 VariableShowStmt:  SHOW var_name ecpg_into
1283                         { $$ = cat2_str(make_str("show"), $2); }
1284                 | SHOW TIME ZONE ecpg_into
1285                         { $$ = make_str("show time zone"); }
1286                 | SHOW TRANSACTION ISOLATION LEVEL ecpg_into
1287                         { $$ = make_str("show transaction isolation level"); }
1288                 | SHOW SESSION AUTHORIZATION ecpg_into
1289                         { $$ = make_str("show session authorization"); }
1290                 | SHOW ALL
1291                         { mmerror(PARSE_ERROR, ET_ERROR, "SHOW ALL not implemented"); }
1292                 ;
1293
1294 VariableResetStmt:      RESET var_name
1295                         { $$ = cat2_str(make_str("reset"), $2); }
1296                 | RESET TIME ZONE
1297                         { $$ = make_str("reset time zone"); }
1298                 | RESET TRANSACTION ISOLATION LEVEL
1299                         { $$ = make_str("reset transaction isolation level"); }
1300                 | RESET SESSION AUTHORIZATION
1301                         { $$ = make_str("reset session authorization"); }
1302                 | RESET ALL
1303                         { $$ = make_str("reset all"); }
1304                 ;
1305
1306 /* SetResetClause allows SET or RESET without LOCAL */
1307 SetResetClause:
1308                 SET set_rest            { $$ = cat2_str(make_str("set"), $2); }
1309                 | VariableResetStmt     { $$ = $1; }
1310                 ;
1311
1312 ConstraintsSetStmt:    SET CONSTRAINTS constraints_set_list constraints_set_mode
1313                         { $$ = cat_str(3, make_str("set constraints"), $3, $4); }
1314                 ;
1315
1316 constraints_set_list:  ALL
1317                         { $$ = make_str("all"); }
1318                 | qualified_name_list
1319                         { $$ = $1; }
1320                 ;
1321
1322 constraints_set_mode:  DEFERRED         { $$ = make_str("deferred"); }
1323                 | IMMEDIATE             { $$ = make_str("immediate"); }
1324                 ;
1325
1326 /*
1327  * Checkpoint statement
1328  */
1329 CheckPointStmt: CHECKPOINT         { $$= make_str("checkpoint"); }
1330                 ;
1331
1332 DiscardStmt:
1333                 DISCARD ALL             { $$ = make_str("discard all"); }
1334                 | DISCARD TEMP          { $$ = make_str("discard temp"); }
1335                 | DISCARD TEMPORARY     { $$ = make_str("discard temporary"); }
1336                 | DISCARD PLANS         { $$ = make_str("discard plans"); }
1337                 ;
1338
1339 /*****************************************************************************
1340  *
1341  *      ALTER [ TABLE | INDEX ] variations
1342  *
1343  *****************************************************************************/
1344
1345 AlterTableStmt:
1346                 ALTER TABLE relation_expr alter_table_cmds
1347                         { $$ = cat_str(3, make_str("alter table"), $3, $4); }
1348                 |       ALTER INDEX relation_expr alter_rel_cmds
1349                         { $$ = cat_str(3, make_str("alter table"), $3, $4); }
1350                 ;
1351
1352 /* Subcommands that are for ALTER TABLE only */
1353 alter_table_cmds:
1354                 alter_table_cmd                         { $$ = $1; }
1355                 | alter_table_cmds ',' alter_table_cmd  { $$ = cat_str(3, $1, make_str(","), $3); }
1356                 ;
1357
1358 alter_table_cmd:
1359                 ADD_P opt_column columnDef
1360 /* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
1361                         { $$ = cat_str(3, make_str("add"), $2, $3); }
1362 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
1363                 | ALTER opt_column ColId alter_column_default
1364                         { $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
1365 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
1366                 | ALTER opt_column ColId DROP NOT NULL_P
1367                         { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
1368 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
1369                 | ALTER opt_column ColId SET NOT NULL_P
1370                         { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
1371 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
1372                 | ALTER opt_column ColId SET STATISTICS PosIntConst
1373                         { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
1374 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
1375                 | ALTER opt_column ColId SET STORAGE ColId
1376                         { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
1377 /* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
1378                 | DROP opt_column ColId opt_drop_behavior
1379                         { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
1380 /* ALTER TABLE <relation> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
1381                 | ALTER opt_column ColId TYPE_P Typename alter_using
1382                         { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
1383 /* ALTER TABLE <relation> ADD CONSTRAINT ... */
1384                 | ADD_P TableConstraint
1385                         { $$ = cat_str(2, make_str("add"), $2); }
1386 /* ALTER TABLE <relation> DROP CONSTRAINT ... */
1387                 | DROP CONSTRAINT name opt_drop_behavior
1388                         { $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
1389 /* ALTER TABLE <relation> SET WITHOUT OIDS  */
1390                 | SET WITHOUT OIDS
1391                         { $$ = make_str("set without oids"); }
1392 /* ALTER TABLE <name> CLUSTER ON <indexname> */
1393                 | CLUSTER ON name
1394                         { $$ = cat_str(2, make_str("cluster on"), $3); }
1395 /* ALTER TABLE <name> SET WITHOUT CLUSTER */
1396                 | SET WITHOUT CLUSTER
1397                         { $$ = make_str("set without cluster"); }
1398 /* ALTER TABLE <name> ENABLE TRIGGER <trig> */
1399                 | ENABLE_P TRIGGER name
1400                         { $$ = cat2_str(make_str("enable trigger"), $3); }
1401 /* ALTER TABLE <name> ENABLE ALWAYS TRIGGER <trig> */
1402                 | ENABLE_P ALWAYS TRIGGER name
1403                         { $$ = cat2_str(make_str("enable always trigger"), $4); }
1404 /* ALTER TABLE <name> ENABLE REPLICA TRIGGER <trig> */
1405                 | ENABLE_P REPLICA TRIGGER name
1406                         { $$ = cat2_str(make_str("enable replica trigger"), $4); }
1407 /* ALTER TABLE <name> ENABLE TRIGGER ALL */
1408                 | ENABLE_P TRIGGER ALL
1409                         { $$ = make_str("enable trigger all"); }
1410 /* ALTER TABLE <name> ENABLE TRIGGER USER */
1411                 | ENABLE_P TRIGGER USER
1412                         { $$ = make_str("enable trigger user"); }
1413 /* ALTER TABLE <name> DISABLE TRIGGER <trig> */
1414                 | DISABLE_P TRIGGER name
1415                         { $$ = cat2_str(make_str("disable trigger"), $3); }
1416 /* ALTER TABLE <name> DISABLE TRIGGER ALL */
1417                 | DISABLE_P TRIGGER ALL
1418                         { $$ = make_str("disable trigger all"); }
1419 /* ALTER TABLE <name> DISABLE TRIGGER USER */
1420                 | DISABLE_P TRIGGER USER
1421                         { $$ = make_str("disable trigger user"); }
1422 /* ALTER TABLE <name> ENABLE RULE <rule> */
1423                 | ENABLE_P RULE name
1424                         { $$ = cat2_str(make_str("enable rule"), $3); }
1425 /* ALTER TABLE <name> ENABLE ALWAYS RULE <rule> */
1426                 | ENABLE_P ALWAYS RULE name
1427                         { $$ = cat2_str(make_str("enable always rule"), $4); }
1428 /* ALTER TABLE <name> ENABLE REPLICA RULE <rule> */
1429                 | ENABLE_P REPLICA RULE name
1430                         { $$ = cat2_str(make_str("enable replica rule"), $4); }
1431 /* ALTER TABLE <name> DISABLE RULE <rule> */
1432                 | DISABLE_P RULE name
1433                         { $$ = cat2_str(make_str("disable rule"), $3); }
1434 /* ALTER TABLE <name> ALTER INHERITS ADD <parent> */
1435                 | INHERIT qualified_name
1436                         { $$ = cat2_str(make_str("inherit"), $2); }
1437 /* ALTER TABLE <name> NO INHERITS <parent> */
1438                 | NO INHERIT qualified_name
1439                         { $$ = cat2_str(make_str("no inherit"), $3); }
1440                 | alter_rel_cmd
1441                         { $$ = $1; }
1442                 ;
1443
1444 alter_rel_cmds: alter_rel_cmd                           { $$ = $1; }
1445                 | alter_rel_cmds ',' alter_rel_cmd      { $$ = cat_str(3, $1, make_str(","), $3); }
1446                 ;
1447
1448 /* Subcommands that are for ALTER TABLE or ALTER INDEX */
1449 alter_rel_cmd:
1450                 /* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
1451                 OWNER TO RoleId
1452                         { $$ = cat2_str(make_str("owner to"), $3); }
1453                 /* ALTER [TABLE|INDEX] <name> SET TABLESPACE <tablespacename> */
1454                 | SET TABLESPACE name
1455                         { $$ = cat2_str(make_str("set tablespace"), $3); }
1456                 | SET definition
1457                         { $$ = cat2_str(make_str("set"), $2); }
1458                 | RESET definition
1459                         { $$ = cat2_str(make_str("reset"), $2); }
1460                 ;
1461
1462 alter_column_default:
1463                 SET DEFAULT a_expr              { $$ = cat2_str(make_str("set default"), $3); }
1464                 | DROP DEFAULT                  { $$ = make_str("drop default"); }
1465                 ;
1466
1467 opt_drop_behavior: CASCADE              { $$ = make_str("cascade"); }
1468                 | RESTRICT                              { $$ = make_str("restrict"); }
1469                 | /* EMPTY */                   { $$ = EMPTY; }
1470                 ;
1471
1472 alter_using:    USING a_expr    { $$ = cat2_str(make_str("using"), $2); }
1473                 | /* EMPTY */                   { $$ = EMPTY; }
1474                 ;
1475
1476 /*****************************************************************************
1477  *
1478  *              QUERY :
1479  *                              close <portalname>
1480  *
1481  *****************************************************************************/
1482
1483 ClosePortalStmt:  CLOSE name
1484                         { $$ = cat2_str(make_str("close"), $2); }
1485                 | CLOSE ALL
1486                         { $$ = make_str("close all"); }
1487                 ;
1488
1489 CopyStmt:  COPY opt_binary qualified_name opt_oids copy_from
1490                 copy_file_name copy_delimiter opt_with copy_opt_list
1491                         {
1492                                 if (strcmp($5, "to") == 0 && strcmp($6, "stdin") == 0)
1493                                         mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible.\n");
1494                                 else if (strcmp($5, "from") == 0 && strcmp($6, "stdout") == 0)
1495                                         mmerror(PARSE_ERROR, ET_ERROR, "copy from stdout not possible.\n");
1496                                 else if (strcmp($5, "from") == 0 && strcmp($6, "stdin") == 0)
1497                                         mmerror(PARSE_ERROR, ET_WARNING, "copy from stdin not implemented.\n");
1498                                 
1499                                 $$ = cat_str(9, make_str("copy"), $2, $3, $4, $5, $6, $7, $8, $9);
1500                         }
1501                 | COPY select_with_parens TO copy_file_name opt_with copy_opt_list
1502                         {
1503                                 if (strcmp($4, "stdin") == 0)
1504                                         mmerror(PARSE_ERROR, ET_ERROR, "copy to stdin not possible.\n");
1505                                 
1506                                 $$ = cat_str(6, make_str("copy"), $2, make_str("to"), $4, $5, $6);
1507                         }
1508                 ;
1509
1510 copy_from:      TO                                      { $$ = make_str("to"); }
1511                 | FROM                                  { $$ = make_str("from"); }
1512                 ;
1513
1514 copy_file_name:  StringConst                            { $$ = $1; }
1515                 | STDIN                                 { $$ = make_str("stdin"); }
1516                 | STDOUT                                { $$ = make_str("stdout"); }
1517                 ;
1518
1519 copy_opt_list: copy_opt_list copy_opt_item      { $$ = cat2_str($1, $2); }
1520                 | /* EMPTY */                   { $$ = EMPTY; }
1521                 ;
1522
1523 copy_opt_item:  BINARY          { $$ = make_str("binary"); }
1524                 | OIDS          { $$ = make_str("oids"); }
1525                 | DELIMITER opt_as StringConst
1526                         { $$ = cat_str(3, make_str("delimiter"), $2, $3); }
1527                 | NULL_P opt_as StringConst
1528                         { $$ = cat_str(3, make_str("null"), $2, $3); }
1529                 | CSV           { $$ = make_str("csv"); }
1530                 | HEADER_P      { $$ = make_str("header"); }
1531                 | QUOTE opt_as Sconst
1532                         { $$ = cat_str(3, make_str("quote"), $2, $3); }
1533                 | ESCAPE opt_as Sconst
1534                         { $$ = cat_str(3, make_str("escape"), $2, $3); }
1535                 | FORCE QUOTE columnList
1536                         { $$ = cat2_str(make_str("force quote"), $3); }
1537                 | FORCE NOT NULL_P columnList
1538                         { $$ = cat2_str(make_str("force not null"), $4); }
1539
1540                 ;
1541
1542 opt_binary:     BINARY          { $$ = make_str("binary"); }
1543                 | /* EMPTY */   { $$ = EMPTY; }
1544                 ;
1545
1546 opt_oids:       WITH OIDS       { $$ = make_str("with oids"); }
1547                 | /* EMPTY */   { $$ = EMPTY; }
1548                 ;
1549
1550
1551 /*
1552  * the default copy delimiter is tab but the user can configure it
1553  */
1554 copy_delimiter:  opt_using DELIMITERS StringConst
1555                         { $$ = cat_str(3, $1, make_str("delimiters"), $3); }
1556                 | /*EMPTY*/
1557                         { $$ = EMPTY; }
1558                 ;
1559
1560 opt_using:      USING           { $$ = make_str("using"); }
1561                 | /* EMPTY */   { $$ = EMPTY; }
1562                 ;
1563
1564 /*****************************************************************************
1565  *
1566  *              QUERY :
1567  *                              CREATE TABLE relname
1568  *
1569  *****************************************************************************/
1570
1571 CreateStmt:  CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
1572                                 OptInherit OptWith OnCommitOption OptTableSpace
1573                         { $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9, $10, $11); }
1574                 | CREATE OptTemp TABLE qualified_name OF qualified_name
1575                         '(' OptTableElementList ')' OptWith OnCommitOption OptTableSpace
1576                         { $$ = cat_str(12, make_str("create"), $2, make_str("table"), $4, make_str("of"), $6, make_str("("), $8, make_str(")"), $10, $11, $12); }
1577                 ;
1578
1579 /*
1580  * Redundancy here is needed to avoid shift/reduce conflicts,
1581  * since TEMP is not a reserved word.  See also OptTempTableName.
1582  */
1583
1584 OptTemp: TEMPORARY                      { $$ = make_str("temporary"); }
1585                 | TEMP                          { $$ = make_str("temp"); }
1586                 | LOCAL TEMPORARY       { $$ = make_str("local temporary"); }
1587                 | LOCAL TEMP            { $$ = make_str("local temp"); }
1588                 | GLOBAL TEMPORARY      { $$ = make_str("global temporary"); }
1589                 | GLOBAL TEMP           { $$ = make_str("global temp"); }
1590                 | /*EMPTY*/                     { $$ = EMPTY; }
1591                 ;
1592
1593
1594 OptTableElementList:  TableElementList
1595                         { $$ = $1; }
1596                 | /*EMPTY*/
1597                         { $$ = EMPTY; }
1598                 ;
1599 TableElementList: TableElement
1600                         { $$ = $1; }
1601                 | TableElementList ',' TableElement
1602                         { $$ = cat_str(3, $1, make_str(","), $3); }
1603                 ;
1604
1605 TableElement:  columnDef                { $$ = $1; }
1606                 | TableLikeClause       { $$ = $1; }
1607                 | TableConstraint       { $$ = $1; }
1608                 ;
1609
1610 columnDef:      ColId Typename ColQualList
1611                         {$$ = cat_str(3, $1, $2, $3); }
1612                 ;
1613
1614 ColQualList:  ColQualList ColConstraint { $$ = cat2_str($1,$2); }
1615                 | /*EMPTY*/                                             { $$ = EMPTY; }
1616                 ;
1617
1618 ColConstraint:  CONSTRAINT name ColConstraintElem
1619                         { $$ = cat_str(3, make_str("constraint"), $2, $3); }
1620                 | ColConstraintElem             { $$ = $1; }
1621                 | ConstraintAttr                { $$ = $1; }
1622                 ;
1623
1624 /* DEFAULT NULL is already the default for Postgres.
1625  * But define it here and carry it forward into the system
1626  * to make it explicit.
1627  * - thomas 1998-09-13
1628  *
1629  * WITH NULL and NULL are not SQL92-standard syntax elements,
1630  * so leave them out. Use DEFAULT NULL to explicitly indicate
1631  * that a column may have that value. WITH NULL leads to
1632  * shift/reduce conflicts with WITH TIME ZONE anyway.
1633  * - thomas 1999-01-08
1634  */
1635 ColConstraintElem:      NOT NULL_P
1636                         { $$ = make_str("not null"); }
1637                 | NULL_P
1638                         { $$ = make_str("null"); }
1639                 | UNIQUE opt_definition OptConsTableSpace
1640                         { $$ = cat_str(3, make_str("unique"), $2, $3); }
1641                 | PRIMARY KEY opt_definition OptConsTableSpace
1642                         { $$ = cat_str(3, make_str("primary key"), $3, $4); }
1643                 | CHECK '(' a_expr ')'
1644                         { $$ = cat_str(3, make_str("check ("), $3, make_str(")")); }
1645                 | DEFAULT b_expr
1646                         { $$ = cat2_str(make_str("default"), $2); }
1647                 |  REFERENCES qualified_name opt_column_list key_match key_actions
1648                         { $$ = cat_str(5, make_str("references"), $2, $3, $4, $5); }
1649                 ;
1650
1651 /*
1652  * ConstraintAttr represents constraint attributes, which we parse as if
1653  * they were independent constraint clauses, in order to avoid shift/reduce
1654  * conflicts (since NOT might start either an independent NOT NULL clause
1655  * or an attribute).  analyze.c is responsible for attaching the attribute
1656  * information to the preceding "real" constraint node, and for complaining
1657  * if attribute clauses appear in the wrong place or wrong combinations.
1658  *
1659  * See also ConstraintAttributeSpec, which can be used in places where
1660  * there is no parsing conflict.
1661  */
1662 ConstraintAttr: DEFERRABLE              { $$ = make_str("deferrable"); }
1663                 | NOT DEFERRABLE        { $$ = make_str("not deferrable"); }
1664                 | INITIALLY DEFERRED    { $$ = make_str("initially deferred"); }
1665                 | INITIALLY IMMEDIATE   { $$ = make_str("initially immediate"); }
1666                 ;
1667
1668 TableLikeClause:  LIKE qualified_name TableLikeOptionList
1669                         {$$ = cat_str(3, make_str("like"), $2, $3); }
1670                 ;
1671
1672 TableLikeOptionList: TableLikeOptionList TableLikeOption
1673                                 { $$ = cat2_str($1, $2); }
1674                 | /* EMPTY */   { $$ = EMPTY; }
1675                 ;
1676
1677 TableLikeOption:
1678                 INCLUDING DEFAULTS      { $$ = make_str("including defaults"); }
1679                 | EXCLUDING DEFAULTS    { $$ = make_str("excluding defaults"); }
1680                 | INCLUDING CONSTRAINTS { $$ = make_str("including constraints"); }
1681                 | EXCLUDING CONSTRAINTS { $$ = make_str("excluding constraints"); }
1682                 | INCLUDING INDEXES     { $$ = make_str("including indexes"); }
1683                 | EXCLUDING INDEXES     { $$ = make_str("excluding indexes"); }
1684                 ;
1685
1686 /* ConstraintElem specifies constraint syntax which is not embedded into
1687  *      a column definition. ColConstraintElem specifies the embedded form.
1688  * - thomas 1997-12-03
1689  */
1690 TableConstraint:  CONSTRAINT name ConstraintElem
1691                         { $$ = cat_str(3, make_str("constraint"), $2, $3); }
1692                 | ConstraintElem
1693                         { $$ = $1; }
1694                 ;
1695
1696 ConstraintElem:  CHECK '(' a_expr ')'
1697                         { $$ = cat_str(3, make_str("check("), $3, make_str(")")); }
1698                 | UNIQUE '(' columnList ')' opt_definition OptConsTableSpace
1699                         { $$ = cat_str(5, make_str("unique("), $3, make_str(")"), $5, $6); }
1700                 | PRIMARY KEY '(' columnList ')' opt_definition OptConsTableSpace
1701                         { $$ = cat_str(5, make_str("primary key("), $4, make_str(")"), $6, $7); }
1702                 | FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
1703                         key_match key_actions ConstraintAttributeSpec
1704                         { $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11); }
1705                 ;
1706
1707 opt_column_list:  '(' columnList ')'    { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1708                 | /*EMPTY*/             { $$ = EMPTY; }
1709                 ;
1710
1711 columnList:  columnList ',' columnElem
1712                         { $$ = cat_str(3, $1, make_str(","), $3); }
1713                 | columnElem
1714                         { $$ = $1; }
1715                 ;
1716
1717 columnElem:  ColId      { $$ = $1; }
1718                 ;
1719
1720 key_match:      MATCH FULL
1721                         { $$ = make_str("match full"); }
1722                 | MATCH PARTIAL
1723                 {
1724                         mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported FOREIGN KEY/MATCH PARTIAL will be passed to backend");
1725                         $$ = make_str("match partial");
1726                 }
1727                 | /*EMPTY*/
1728                         { $$ = EMPTY; }
1729                 ;
1730
1731 key_actions:  key_delete                        { $$ = $1; }
1732                 | key_update                            { $$ = $1; }
1733                 | key_delete key_update         { $$ = cat2_str($1, $2); }
1734                 | key_update key_delete         { $$ = cat2_str($1, $2); }
1735                 | /*EMPTY*/                                     { $$ = EMPTY; }
1736                 ;
1737
1738 key_delete: ON DELETE_P key_action
1739                         { $$ = cat2_str(make_str("on delete"), $3); }
1740                 ;
1741
1742 key_update: ON UPDATE key_action
1743                         { $$ = cat2_str(make_str("on update"), $3); }
1744                 ;
1745
1746 key_action:     NO ACTION                               { $$ = make_str("no action"); }
1747                 | RESTRICT                                      { $$ = make_str("restrict"); }
1748                 | CASCADE                                       { $$ = make_str("cascade"); }
1749                 | SET DEFAULT                           { $$ = make_str("set default"); }
1750                 | SET NULL_P                            { $$ = make_str("set null"); }
1751                 ;
1752
1753 OptInherit:  INHERITS '(' qualified_name_list ')'
1754                         { $$ = cat_str(3, make_str("inherits ("), $3, make_str(")")); }
1755                 | /*EMPTY*/
1756                         { $$ = EMPTY; }
1757                 ;
1758
1759 OptWith:        WITH definition                 { $$ = cat2_str(make_str("with"), $2); }
1760                 | WITH OIDS                     { $$ = make_str("with oids"); }
1761                 | WITHOUT OIDS                  { $$ = make_str("without oids"); }
1762                 | /*EMPTY*/                     { $$ = EMPTY; }
1763                 ;
1764
1765 OnCommitOption:   ON COMMIT DROP        { $$ = make_str("on commit drop"); }
1766                 | ON COMMIT DELETE_P ROWS       { $$ = make_str("on commit delete rows"); }
1767                 | ON COMMIT PRESERVE ROWS       { $$ = make_str("on commit preserve rows"); }
1768                 | /*EMPTY*/                                     { $$ = EMPTY; }
1769                 ;
1770
1771 OptTableSpace:  TABLESPACE name { $$ = cat2_str(make_str("tablespace"), $2); }
1772                 | /*EMPTY*/     { $$ = EMPTY; }
1773                 ;
1774
1775 OptConsTableSpace: USING INDEX TABLESPACE name  { $$ = cat2_str(make_str("using index tablespace"), $4); }
1776                         | /*EMPTY*/             { $$ = EMPTY; }
1777                         ;
1778
1779 /*
1780  * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
1781  * SELECT ... INTO.
1782  */
1783
1784 CreateAsStmt:  CREATE OptTemp TABLE create_as_target AS
1785                 { FoundInto = 0; }
1786                 SelectStmt
1787                 {
1788                         if (FoundInto == 1)
1789                                 mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT cannot specify INTO");
1790
1791                         $$ = cat_str(6, make_str("create"), $2, make_str("table"), $4, make_str("as"), $7);
1792                 }
1793                 ;
1794
1795 create_as_target:  qualified_name OptCreateAs OptWith OnCommitOption OptTableSpace
1796                 {
1797                         $$ = cat_str(5, $1, $2, $3, $4, $5);
1798                 }
1799                 ;
1800
1801 OptCreateAs:  '(' CreateAsList ')'
1802                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1803                 | /*EMPTY*/
1804                         { $$ = EMPTY; }
1805                 ;
1806
1807 CreateAsList:  CreateAsList ',' CreateAsElement
1808                         { $$ = cat_str(3, $1, make_str(","), $3); }
1809                 | CreateAsElement
1810                         { $$ = $1; }
1811                 ;
1812
1813 CreateAsElement:  ColId { $$ = $1; }
1814                 ;
1815
1816 /*****************************************************************************
1817  *
1818  *              QUERY :
1819  *                              CREATE SEQUENCE seqname
1820  *                              ALTER SEQUENCE seqname
1821  *
1822  *****************************************************************************/
1823
1824 CreateSeqStmt:  CREATE OptTemp SEQUENCE qualified_name OptSeqList
1825                         { $$ = cat_str(5, make_str("create"), $2, make_str("sequence"), $4, $5); }
1826                 ;
1827
1828 AlterSeqStmt: ALTER SEQUENCE qualified_name OptSeqList
1829                         { $$ = cat_str(3,make_str("alter sequence"), $3, $4); }
1830                 ;
1831
1832 OptSeqList:  OptSeqList OptSeqElem      { $$ = cat2_str($1, $2); }
1833                 | /*EMPTY*/                                     { $$ = EMPTY; }
1834                 ;
1835
1836 OptSeqElem:  CACHE NumConst
1837                         { $$ = cat2_str(make_str("cache"), $2); }
1838                 | CYCLE
1839                         { $$ = make_str("cycle"); }
1840                 | NO CYCLE
1841                         { $$ = make_str("no cycle"); }
1842                 | INCREMENT opt_by NumConst
1843                         { $$ = cat_str(3, make_str("increment"), $2, $3); }
1844                 | MAXVALUE NumConst
1845                         { $$ = cat2_str(make_str("maxvalue"), $2); }
1846                 | MINVALUE NumConst
1847                         { $$ = cat2_str(make_str("minvalue"), $2); }
1848                 | NO MAXVALUE
1849                         { $$ = make_str("no maxvalue"); }
1850                 | NO MINVALUE
1851                         { $$ = make_str("no minvalue"); }
1852                 | OWNED BY any_name
1853                         { $$ = cat2_str(make_str("owned by"), $3); }
1854                 | START opt_with NumConst
1855                         { $$ = cat_str(3, make_str("start"), $2, $3); }
1856                 | RESTART opt_with NumConst
1857                         { $$ = cat_str(3, make_str("restart"), $2, $3); }
1858                 ;
1859
1860 opt_by:         BY      { $$ = make_str("by"); }
1861                 | /*EMPTY*/     { $$ = EMPTY; }
1862                 ;
1863
1864 /*****************************************************************************
1865  *
1866  *              QUERIES :
1867  *                              CREATE PROCEDURAL LANGUAGE ...
1868  *                              DROP PROCEDURAL LANGUAGE ...
1869  *
1870  *****************************************************************************/
1871
1872 CreatePLangStmt:  CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
1873                         { $$ = cat_str(5, make_str("create"), $2, $3, make_str("language"), $5); }
1874                 | CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
1875                         HANDLER handler_name opt_validator opt_lancompiler
1876                         { $$ = cat_str(9, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8, $9); }
1877                 ;
1878
1879 opt_trusted:    TRUSTED { $$ = make_str("trusted"); }
1880                 | /*EMPTY*/             { $$ = EMPTY; }
1881                 ;
1882
1883 /* This ought to be just func_name, but that causes reduce/reduce conflicts
1884  * (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
1885  * Work around by using simple names instead.
1886  */
1887 handler_name: name      { $$ = $1; }
1888                 | name attrs    { $$ = cat2_str($1, $2); }
1889                 ;
1890
1891 opt_validator: VALIDATOR handler_name
1892                         { $$ = cat2_str(make_str("validator"), $2); }
1893                 | /*EMPTY*/
1894                         { $$ = ""; }
1895                 ;
1896 opt_lancompiler: LANCOMPILER StringConst
1897                         { $$ = cat2_str(make_str("lancompiler"), $2); }
1898                 | /*EMPTY*/
1899                         { $$ = ""; }
1900                 ;
1901
1902 DropPLangStmt:  DROP opt_procedural LANGUAGE StringConst opt_drop_behavior
1903                         { $$ = cat_str(5, make_str("drop"), $2, make_str("language"), $4, $5); }
1904                 | DROP opt_procedural LANGUAGE IF_P EXISTS StringConst opt_drop_behavior
1905                         { $$ = cat_str(5, make_str("drop"), $2, make_str("language if exists"), $6, $7); }
1906                 ;
1907
1908 opt_procedural: PROCEDURAL      { $$ = make_str("prcedural"); }
1909                 | /*EMPTY*/                     { $$ = EMPTY; }
1910                 ;
1911
1912 /*****************************************************************************
1913  *
1914  *             QUERY:
1915  *             CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'
1916  *
1917  *****************************************************************************/
1918
1919 CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
1920                         { $$ = cat_str(5,make_str("create tablespace"), $3, $4, make_str("location"), $6); }
1921                 ;
1922
1923 OptTableSpaceOwner: OWNER name  { $$ = cat2_str(make_str("owner"), $2); }
1924                 | /*EMPTY*/     { $$ = EMPTY; }
1925                 ;
1926
1927 /*****************************************************************************
1928  *
1929  *             QUERY :
1930  *                             DROP TABLESPACE <tablespace>
1931  *
1932  *             No need for drop behaviour as we cannot implement dependencies for
1933  *             objects in other databases; we can only support RESTRICT.
1934  *
1935  ****************************************************************************/
1936
1937
1938 DropTableSpaceStmt: DROP TABLESPACE name
1939                         { $$ = cat2_str(make_str("drop tablespace"), $3); }
1940                 | DROP TABLESPACE IF_P EXISTS name
1941                         { $$ = cat2_str(make_str("drop tablespace if exists"), $5); }
1942                 ;
1943
1944
1945 /*****************************************************************************
1946  *
1947  *              QUERIES :
1948  *                              CREATE TRIGGER ...
1949  *                              DROP TRIGGER ...
1950  *
1951  *****************************************************************************/
1952
1953 CreateTrigStmt:  CREATE TRIGGER name TriggerActionTime TriggerEvents ON
1954                                 qualified_name TriggerForSpec EXECUTE PROCEDURE name
1955                                 '(' TriggerFuncArgs ')'
1956                         { $$ = cat_str(12, make_str("create trigger"), $3, $4, $5, make_str("on"), $7, $8, make_str("execute procedure"), $11, make_str("("), $13, make_str(")")); }
1957                 |       CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON
1958                                 qualified_name OptConstrFromTable ConstraintAttributeSpec
1959                                 FOR EACH ROW EXECUTE PROCEDURE
1960                                 func_name '(' TriggerFuncArgs ')'
1961                         { $$ = cat_str(13, make_str("create constraint trigger"), $4, make_str("after"), $6, make_str("on"), $8, $9, $10, make_str("for each row execute procedure"), $16, make_str("("), $18, make_str(")")); }
1962                 ;
1963
1964 TriggerActionTime:      BEFORE          { $$ = make_str("before"); }
1965                 | AFTER                                 { $$ = make_str("after"); }
1966                 ;
1967
1968 TriggerEvents:  TriggerOneEvent
1969                         { $$ = $1; }
1970                 | TriggerOneEvent OR TriggerOneEvent
1971                         { $$ = cat_str(3, $1, make_str("or"), $3); }
1972                 | TriggerOneEvent OR TriggerOneEvent OR TriggerOneEvent
1973                         { $$ = cat_str(5, $1, make_str("or"), $3, make_str("or"), $5); }
1974                 ;
1975
1976 TriggerOneEvent:  INSERT        { $$ = make_str("insert"); }
1977                 | DELETE_P                      { $$ = make_str("delete"); }
1978                 | UPDATE                        { $$ = make_str("update"); }
1979                 ;
1980
1981 TriggerForSpec:  FOR TriggerForOpt TriggerForType
1982                         { $$ = cat_str(3, make_str("for"), $2, $3); }
1983                 | /* EMPTY */
1984                         { $$ = EMPTY; }
1985                 ;
1986
1987 TriggerForOpt:  EACH            { $$ = make_str("each"); }
1988                 | /*EMPTY*/                     { $$ = EMPTY; }
1989                 ;
1990
1991 TriggerForType:  ROW            { $$ = make_str("row"); }
1992                 | STATEMENT                     { $$ = make_str("statement"); }
1993                 ;
1994
1995 TriggerFuncArgs:  TriggerFuncArg
1996                         { $$ = $1; }
1997                 | TriggerFuncArgs ',' TriggerFuncArg
1998                         { $$ = cat_str(3, $1, make_str(","), $3); }
1999                 | /*EMPTY*/
2000                         { $$ = EMPTY; }
2001                 ;
2002
2003 TriggerFuncArg:  PosAllConst    { $$ = $1; }
2004                 | ColId         { $$ = $1; }
2005                 ;
2006
2007 OptConstrFromTable: /* Empty */         { $$ = EMPTY; }
2008                 | FROM qualified_name           { $$ = cat2_str(make_str("from"), $2); }
2009                 ;
2010
2011 ConstraintAttributeSpec: ConstraintDeferrabilitySpec    { $$ = $1; }
2012                 | ConstraintDeferrabilitySpec ConstraintTimeSpec
2013                 {
2014                         if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 )
2015                                 mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2016
2017                         $$ = cat2_str($1, $2);
2018                 }
2019                 | ConstraintTimeSpec            { $$ = $1; }
2020                 | ConstraintTimeSpec ConstraintDeferrabilitySpec
2021                 {
2022                         if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 )
2023                                 mmerror(PARSE_ERROR, ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE");
2024
2025                         $$ = cat2_str($1, $2);
2026                 }
2027                 ;
2028
2029 ConstraintDeferrabilitySpec: NOT DEFERRABLE
2030                         { $$ = make_str("not deferrable"); }
2031                 | DEFERRABLE
2032                         { $$ = make_str("deferrable"); }
2033                 ;
2034
2035 ConstraintTimeSpec: INITIALLY IMMEDIATE
2036                         { $$ = make_str("initially immediate"); }
2037                 | INITIALLY DEFERRED
2038                         { $$ = make_str("initially deferred"); }
2039                 ;
2040
2041 DropTrigStmt:  DROP TRIGGER name ON qualified_name opt_drop_behavior
2042                         { $$ = cat_str(5, make_str("drop trigger"), $3, make_str("on"), $5, $6); }
2043                 | DROP TRIGGER IF_P EXISTS name ON qualified_name opt_drop_behavior
2044                         { $$ = cat_str(5, make_str("drop trigger if exists"), $5, make_str("on"), $7, $8); }
2045                 ;
2046
2047 /*****************************************************************************
2048  *
2049  *             QUERIES :
2050  *                             CREATE ASSERTION ...
2051  *                             DROP ASSERTION ...
2052  *
2053  *****************************************************************************/
2054 CreateAssertStmt:  CREATE ASSERTION name
2055                 CHECK '(' a_expr ')' ConstraintAttributeSpec
2056                 {
2057                         mmerror(PARSE_ERROR, ET_ERROR, "CREATE ASSERTION is not yet supported");
2058                         $$ = cat_str(6, make_str("create assertion"), $3, make_str("check ("), $6, make_str(")"), $8);
2059                 }
2060                 ;
2061
2062 DropAssertStmt:  DROP ASSERTION name
2063                 {
2064                         mmerror(PARSE_ERROR, ET_ERROR, "DROP ASSERTION is not yet supported");
2065                         $$ = cat2_str(make_str("drop assertion"), $3);
2066                 }
2067                 ;
2068
2069
2070 /*****************************************************************************
2071  *
2072  *              QUERY :
2073  *                              define (type,operator,aggregate)
2074  *
2075  *****************************************************************************/
2076
2077 DefineStmt:  CREATE AGGREGATE func_name aggr_args definition
2078                         { $$ = cat_str(4, make_str("create aggregate"), $3, $4, $5); }
2079                 | CREATE AGGREGATE func_name old_aggr_definition
2080                         { $$ = cat_str(3, make_str("create aggregate"), $3, $4); }
2081                 | CREATE OPERATOR all_Op definition
2082                         { $$ = cat_str(3, make_str("create operator"), $3, $4); }
2083                 | CREATE TYPE_P any_name definition
2084                         { $$ = cat_str(3, make_str("create type"), $3, $4); }
2085                 | CREATE TYPE_P any_name
2086                         { $$ = cat2_str(make_str("create type"), $3); }
2087                 | CREATE TYPE_P any_name AS '(' TableFuncElementList ')'
2088                         { $$ = cat_str(5, make_str("create type"), $3, make_str("as ("), $6, make_str(")")); }
2089                 | CREATE TYPE_P any_name AS ENUM_P '(' enum_val_list ')'
2090                         { $$ = cat_str(5, make_str("create type"), $3, make_str("as enum ("), $7, make_str(")")); }
2091                 | CREATE TEXT_P SEARCH PARSER any_name definition
2092                         { $$ = cat_str(3, make_str("create text search parser"), $5, $6); }
2093                 | CREATE TEXT_P SEARCH DICTIONARY any_name definition
2094                         { $$ = cat_str(3, make_str("create text search dictionary"), $5, $6); }
2095                 | CREATE TEXT_P SEARCH TEMPLATE any_name definition
2096                         { $$ = cat_str(3, make_str("create text search template"), $5, $6); }
2097                 | CREATE TEXT_P SEARCH CONFIGURATION any_name definition
2098                         { $$ = cat_str(3, make_str("create text search configuration"), $5, $6); }
2099                 ;
2100
2101 definition:  '(' def_list ')'
2102                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2103                 ;
2104
2105 def_list:  def_elem                                     { $$ = $1; }
2106                 | def_list ',' def_elem         { $$ = cat_str(3, $1, make_str(","), $3); }
2107                 ;
2108
2109 def_elem:  ColLabel '=' def_arg         { $$ = cat_str(3, $1, make_str("="), $3); }
2110                 | ColLabel                                      { $$ = $1; }
2111                 ;
2112
2113 /* Note: any simple identifier will be returned as a type name! */
2114 def_arg:  func_type                             { $$ = $1; }
2115                 | reserved_keyword              { $$ = $1; }
2116                 | qual_all_Op                   { $$ = $1; }
2117                 | AllConst                      { $$ = $1; }
2118                 ;
2119
2120 aggr_args:      '(' type_list ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2121                 | '(' '*' ')'                   { $$ = make_str("(*)"); }
2122                 ;
2123
2124 old_aggr_definition: '(' old_aggr_list ')'      { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2125                 ;
2126
2127 old_aggr_list: old_aggr_elem                            { $$ = $1; }
2128                  | old_aggr_list ',' old_aggr_elem      { $$ = cat_str(3, $1, make_str(","), $3); }
2129                  ;
2130
2131 old_aggr_elem:  ident '=' def_arg       { $$ = cat_str(3, $1, make_str("="), $3); }
2132                 ;
2133
2134 enum_val_list:  StringConst                     { $$ = $1; }
2135                 | enum_val_list ',' StringConst { $$ = cat_str(3, $1, make_str(","), $3);}
2136                 ;
2137
2138 CreateOpClassStmt:      CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
2139                                                 USING access_method opt_opfamily AS opclass_item_list
2140                 {
2141                         $$ = cat_str(10, make_str("create operator class"), $4, $5, make_str("for type"), $8, make_str("using"), $10, $11, make_str("as"), $13);
2142                 }
2143                 ;
2144
2145 opclass_item_list:      opclass_item            { $$ = $1; }
2146                 | opclass_item_list ',' opclass_item    { $$ = cat_str(3, $1, make_str(","), $3); }
2147                 ;
2148
2149 opclass_item:   OPERATOR PosIntConst any_operator opt_recheck
2150                         { $$ = cat_str(4, make_str("operator"), $2, $3, $4); }
2151                 | OPERATOR PosIntConst any_operator '(' oper_argtypes ')' opt_recheck
2152                         { $$ =  cat_str(7, make_str("operator"), $2, $3, make_str("("), $5, make_str(")"), $7); }
2153                 | FUNCTION PosIntConst func_name func_args
2154                         { $$ = cat_str(4, make_str("function"), $2, $3, $4); }
2155                 | FUNCTION PosIntConst '(' type_list ')' func_name func_args
2156                         { $$ = cat_str(7, make_str("function"), $2, make_str("("), $4, make_str(")"), $6, $7); }
2157                 | STORAGE Typename
2158                         { $$ = cat2_str(make_str("storage"), $2); }
2159                 ;
2160
2161 opt_default:   DEFAULT  { $$ = make_str("default"); }
2162                 |  /*EMPTY*/    { $$ = EMPTY; }
2163                 ;
2164
2165 opt_opfamily:  FAMILY any_name          { $$ = cat2_str(make_str("family"), $2); }
2166                        | /*EMPTY*/      { $$ = EMPTY; }
2167                ;
2168
2169 opt_recheck:   RECHECK  { $$ = make_str("recheck"); }
2170                 |  /*EMPTY*/    { $$ = EMPTY; }
2171                 ;
2172
2173 CreateOpFamilyStmt: CREATE OPERATOR FAMILY any_name USING access_method
2174                 { $$ = cat_str(4, make_str("create operator family"), $4, make_str("using"), $6); }
2175                 ;
2176
2177 AlterOpFamilyStmt: ALTER OPERATOR FAMILY any_name USING access_method ADD_P opclass_item_list
2178                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("add"), $8); }
2179                  | ALTER OPERATOR FAMILY any_name USING access_method DROP opclass_drop_list
2180                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("drop"), $8); }
2181                  ;
2182
2183 opclass_drop_list: opclass_drop                         { $$ = $1; }
2184                 | opclass_drop_list ',' opclass_drop    { $$ = cat_str(3, $1, make_str(","), $3); }
2185                 ;
2186
2187 opclass_drop:
2188                 OPERATOR PosIntConst '(' type_list ')'
2189                         { $$ = cat_str(5, make_str("operator"), $2, make_str("("), $4, make_str(")")); }
2190                 | FUNCTION PosIntConst '(' type_list ')'
2191                         { $$ = cat_str(5, make_str("function"), $2, make_str("("), $4, make_str(")")); }
2192                 ;
2193
2194 DropOpClassStmt: DROP OPERATOR CLASS any_name USING access_method opt_drop_behavior
2195                         { $$ = cat_str(5,make_str("drop operator class"), $4, make_str("using"), $6, $7); }
2196                 | DROP OPERATOR CLASS IF_P EXISTS any_name USING access_method opt_drop_behavior
2197                         { $$ = cat_str(5,make_str("drop operator class if exists"), $6, make_str("using"), $8, $9); }
2198                 ;
2199
2200 DropOpFamilyStmt: DROP OPERATOR FAMILY any_name USING access_method opt_drop_behavior
2201                         { $$ = cat_str(5,make_str("drop operator family"), $4, make_str("using"), $6, $7); }
2202                 | DROP OPERATOR FAMILY IF_P EXISTS any_name USING access_method opt_drop_behavior
2203                         { $$ = cat_str(5,make_str("drop operator family if exists"), $6, make_str("using"), $8, $9); }
2204                 ;
2205
2206 /*****************************************************************************
2207  *
2208  *              QUERY:
2209  *
2210  *              DROP OWNED BY username [, username ...] [ RESTRICT | CASCADE ]
2211  *              REASSIGN OWNED BY username [, username ...] TO username
2212  *
2213  *****************************************************************************/
2214 DropOwnedStmt:
2215         DROP OWNED BY name_list opt_drop_behavior
2216                         {$$ = cat_str(3, make_str("drop owned by"), $4, $5); }
2217                 ;
2218
2219 ReassignOwnedStmt:
2220         REASSIGN OWNED BY name_list TO name
2221                         {$$ = cat_str(4, make_str("reassign owned by"), $4, make_str("to"), $6); }
2222                 ;
2223
2224 /*****************************************************************************
2225  *
2226  *              QUERY:
2227  *
2228  *                         DROP itemtype [ IF EXISTS ] itemname [, itemname ...] [ RESTRICT | CASCADE ]
2229  *
2230  *****************************************************************************/
2231
2232 DropStmt:  DROP drop_type IF_P EXISTS any_name_list opt_drop_behavior
2233                         { $$ = cat_str(5, make_str("drop"), $2, make_str("if exists"), $5, $6); }
2234                 | DROP drop_type any_name_list opt_drop_behavior
2235                         { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
2236                 ;
2237
2238 drop_type:      TABLE                           { $$ = make_str("table"); }
2239                 | SEQUENCE                      { $$ = make_str("sequence"); }
2240                 | VIEW                          { $$ = make_str("view"); }
2241                 | INDEX                         { $$ = make_str("index"); }
2242                 | TYPE_P                        { $$ = make_str("type"); }
2243                 | DOMAIN_P                      { $$ = make_str("domain"); }
2244                 | CONVERSION_P                  { $$ = make_str("conversion"); }
2245                 | SCHEMA                        { $$ = make_str("schema"); }
2246                 | TEXT_P SEARCH PARSER          { $$ = make_str("text search parser"); }
2247                 | TEXT_P SEARCH DICTIONARY      { $$ = make_str("text search dictionary"); }
2248                 | TEXT_P SEARCH TEMPLATE        { $$ = make_str("text search template"); }
2249                 | TEXT_P SEARCH CONFIGURATION   { $$ = make_str("text search configuration"); }
2250                 ;
2251
2252 any_name_list:  any_name
2253                         { $$ = $1; }
2254                 | any_name_list ',' any_name
2255                         { $$ = cat_str(3, $1, make_str(","), $3); }
2256                 ;
2257
2258 any_name: ColId        { $$ = $1; }
2259                 | ColId attrs  { $$ = cat2_str($1, $2); }
2260                 ;
2261
2262 attrs: '.' attr_name            { $$ = cat2_str(make_str("."), $2); }
2263                 | attrs '.' attr_name   { $$ = cat_str(3, $1, make_str("."), $3); }
2264                 ;
2265
2266 /*****************************************************************************
2267  *
2268  *                         QUERY:
2269  *                                 truncate table relname1, relname2, ....
2270  *
2271  *****************************************************************************/
2272 TruncateStmt:  TRUNCATE opt_table qualified_name_list opt_drop_behavior
2273                         { $$ = cat_str(4, make_str("truncate table"), $2, $3, $4); }
2274                 ;
2275
2276 /*****************************************************************************
2277  *
2278  *              QUERY:
2279  *                      fetch/move
2280  *
2281  *****************************************************************************/
2282
2283 /* This is different from the backend as we try to be compatible with many other
2284  * embedded SQL implementations. So we accept their syntax as well and
2285  * translate it to the PGSQL syntax. */
2286
2287 FetchStmt: FETCH fetch_direction from_in name ecpg_into
2288                         {
2289                                 add_additional_variables($4, false);
2290                                 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
2291                         }
2292                 | FETCH fetch_direction name ecpg_into
2293                         {
2294                                 add_additional_variables($3, false);
2295                                 $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
2296                         }
2297                 | FETCH from_in name ecpg_into
2298                         {
2299                         add_additional_variables($3, false);
2300                                 $$ = cat_str(3, make_str("fetch"), $2, $3);
2301                         }
2302                 | FETCH name ecpg_into
2303                         {
2304                         add_additional_variables($2, false);
2305                                 $$ = cat2_str(make_str("fetch"), $2);
2306                         }
2307                 | FETCH fetch_direction from_in name
2308                         {
2309                         add_additional_variables($4, false);
2310                                 $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
2311                         }
2312                 | FETCH fetch_direction name
2313                         {
2314                         add_additional_variables($3, false);
2315                                 $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
2316                         }
2317                 | FETCH from_in name
2318                         {
2319                                 add_additional_variables($3, false);
2320                                 $$ = cat_str(3, make_str("fetch"), $2, $3);
2321                         }
2322                 | FETCH name
2323                         {
2324                         add_additional_variables($2, false);
2325                                 $$ = cat2_str(make_str("fetch"), $2);
2326                         }
2327                 | MOVE fetch_direction from_in name
2328                         { $$ = cat_str(4, make_str("move"), $2, $3, $4); }
2329                 | MOVE name
2330                         { $$ = cat2_str(make_str("move"), $2); }
2331                 ;
2332
2333 fetch_direction:  NEXT                  { $$ = make_str("next"); }
2334                 | PRIOR                 { $$ = make_str("prior"); }
2335                 | FIRST_P               { $$ = make_str("first"); }
2336                 | LAST_P                { $$ = make_str("last"); }
2337                 | ABSOLUTE_P IntConst   { 
2338                                           if ($2[1] == '$')
2339                                                  mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2340                                           else
2341                                                 $$ = cat2_str(make_str("absolute"), $2);
2342                                         }
2343                 | RELATIVE_P IntConst   { 
2344                                           if ($2[1] == '$')
2345                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2346                                           else
2347                                                 $$ = cat2_str(make_str("relative"), $2);
2348                                         }
2349                 | IntConst              {  
2350                                           if ($1[1] == '$')
2351                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2352                                           else
2353                                                 $$ = $1;
2354                                         }
2355                 | ALL                   { $$ = make_str("all"); }
2356                 | FORWARD               { $$ = make_str("forward"); }
2357                 | FORWARD IntConst      {  
2358                                           if ($2[1] == '$')
2359                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2360                                           else
2361                                                 $$ = cat2_str(make_str("forward"), $2);
2362                                         }
2363                 | FORWARD ALL           { $$ = make_str("forward all"); }
2364                 | BACKWARD              { $$ = make_str("backward"); }
2365                 | BACKWARD IntConst     {  
2366                                           if ($2[1] == '$')
2367                                                 mmerror(PARSE_ERROR, ET_ERROR, "fetch/move count must not be a variable.\n");
2368                                           else
2369                                                 $$ = cat2_str(make_str("backward"), $2);
2370                                         }
2371                 | BACKWARD ALL          { $$ = make_str("backward all"); }
2372                 ;
2373
2374 from_in: IN_P                   { $$ = make_str("in"); }
2375                 | FROM                  { $$ = make_str("from"); }
2376                 ;
2377
2378 CommentStmt:   COMMENT ON comment_type name IS comment_text
2379                         { $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6); }
2380                 | COMMENT ON AGGREGATE func_name aggr_args IS comment_text
2381                         { $$ = cat_str(5, make_str("comment on aggregate"), $4, $5, make_str("is"), $7); }
2382                 | COMMENT ON FUNCTION func_name func_args IS comment_text
2383                         { $$ = cat_str(5, make_str("comment on function"), $4, $5, make_str("is"), $7); }
2384                 | COMMENT ON OPERATOR all_Op '(' oper_argtypes ')' IS comment_text
2385                         { $$ = cat_str(6, make_str("comment on operator"), $4, make_str("("), $6, make_str(") is"), $9); }
2386                 | COMMENT ON TRIGGER name ON any_name IS comment_text
2387                         { $$ = cat_str(6, make_str("comment on trigger"), $4, make_str("on"), $6, make_str("is"), $8); }
2388                 | COMMENT ON RULE name ON any_name IS comment_text
2389                         { $$ = cat_str(6, make_str("comment on rule"), $4, make_str("on"), $6, make_str("is"), $8); }
2390                 | COMMENT ON RULE name IS comment_text
2391                         { $$ = cat_str(4, make_str("comment on rule"), $4, make_str("is"), $6); }
2392                 | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text
2393                         { $$ = cat_str(6, make_str("comment on operator class"), $5, make_str("using"), $7, make_str("is"), $9); }
2394                 | COMMENT ON OPERATOR FAMILY any_name USING access_method IS comment_text
2395                         { $$ = cat_str(6, make_str("comment on operator family"), $5, make_str("using"), $7, make_str("is"), $9); }
2396                 | COMMENT ON LARGE_P OBJECT_P NumConst IS comment_text
2397                         { $$ = cat_str(4, make_str("comment on large object"), $5, make_str("is"), $7); }
2398                 | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text
2399                         { $$ = cat_str(6, make_str("comment on cast ("), $5, make_str("as"), $7, make_str(") is"), $10); }
2400                 | COMMENT ON opt_procedural LANGUAGE any_name IS comment_text
2401                         { $$ = cat_str(6, make_str("comment on"), $3, make_str("language"), $5, make_str("is"), $7); }
2402                 | COMMENT ON TEXT_P SEARCH PARSER any_name IS comment_text
2403                         { $$ = cat_str(4, make_str("comment on test search parser"), $6, make_str("is"), $8); }
2404                 | COMMENT ON TEXT_P SEARCH DICTIONARY any_name IS comment_text
2405                         { $$ = cat_str(4, make_str("comment on test search dictionary"), $6, make_str("is"), $8); }
2406                 | COMMENT ON TEXT_P SEARCH TEMPLATE any_name IS comment_text
2407                         { $$ = cat_str(4, make_str("comment on test search template"), $6, make_str("is"), $8); }
2408                 | COMMENT ON TEXT_P SEARCH CONFIGURATION any_name IS comment_text
2409                         { $$ = cat_str(4, make_str("comment on test search configuration"), $6, make_str("is"), $8); }
2410                 ;
2411
2412 comment_type:  COLUMN           { $$ = make_str("column"); }
2413                 | DATABASE                      { $$ = make_str("database"); }
2414                 | SCHEMA                        { $$ = make_str("schema"); }
2415                 | INDEX                         { $$ = make_str("idnex"); }
2416                 | SEQUENCE                      { $$ = make_str("sequence"); }
2417                 | TABLE                         { $$ = make_str("table"); }
2418                 | DOMAIN_P                      { $$ = make_str("domain"); }
2419                 | TYPE_P                        { $$ = make_str("type"); }
2420                 | VIEW                          { $$ = make_str("view"); }
2421                 | CONVERSION_P                  { $$ = make_str("conversion"); }
2422                 | TABLESPACE                    { $$ = make_str("tablespace"); }
2423                 | ROLE                          { $$ = make_str("role"); }
2424                 ;
2425
2426 comment_text:   StringConst { $$ = $1; }
2427                 | NULL_P                        { $$ = make_str("null"); }
2428                 ;
2429
2430 /*****************************************************************************
2431  *
2432  *              QUERY:
2433  * GRANT and REVOKE statements
2434  *
2435  *****************************************************************************/
2436
2437 GrantStmt:      GRANT privileges ON privilege_target TO grantee_list opt_grant_grant_option
2438                         { $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6, $7); }
2439                 ;
2440
2441 RevokeStmt:  REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior
2442                         {$$ = cat_str(7, make_str("revoke"), $2, make_str("on"), $4, make_str("from"), $6, $7); }
2443                 | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior
2444                         {$$ = cat_str(7, make_str("revoke grant option for"), $5, make_str("on"), $7, make_str("from"), $9, $10); }
2445                 ;
2446
2447 privileges:  ALL PRIVILEGES             { $$ = make_str("all privileges"); }
2448                 | ALL                                   { $$ = make_str("all"); }
2449                 | privilege_list                { $$ = $1; }
2450                 ;
2451
2452 privilege_list:  privilege
2453                         { $$ = $1; }
2454                 | privilege_list ',' privilege
2455                         { $$ = cat_str(3, $1, make_str(","), $3); }
2456                 ;
2457
2458 privilege:      SELECT                  { $$ = make_str("select"); }
2459                 | REFERENCES            { $$ = make_str("references"); }
2460                 | CREATE                        { $$ = make_str("create"); }
2461                 | ColId                         { $$ = $1; }
2462                 ;
2463
2464 privilege_target: qualified_name_list
2465                         { $$ = $1; }
2466                 | TABLE qualified_name_list
2467                         { $$ = cat2_str(make_str("table"), $2); }
2468                 | SEQUENCE qualified_name_list
2469                         { $$ = cat2_str(make_str("sequence"), $2); }
2470                 | FUNCTION function_with_argtypes_list
2471                         { $$ = cat2_str(make_str("function"), $2); }
2472                 | DATABASE name_list
2473                         { $$ = cat2_str(make_str("database"), $2); }
2474                 | LANGUAGE name_list
2475                         { $$ = cat2_str(make_str("language") , $2); }
2476                 | SCHEMA name_list
2477                         { $$ = cat2_str(make_str("schema") , $2); }
2478                 | TABLESPACE name_list
2479                         { $$ = cat2_str(make_str("tablespace") , $2); }
2480                 ;
2481
2482 grantee_list: grantee
2483                         { $$ = $1; }
2484                 | grantee_list ',' grantee
2485                         { $$ = cat_str(3, $1, make_str(","), $3); }
2486                 ;
2487
2488 grantee:  RoleId                        { $$ = $1; }
2489                 | GROUP_P RoleId        { $$ = cat2_str(make_str("group"), $2); }
2490                 ;
2491
2492 opt_grant_grant_option:  WITH GRANT OPTION
2493                 {
2494                         mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported GRANT/WITH GRANT OPTION will be passed to backend");
2495                         $$ = make_str("with grant option");
2496                 }
2497                 | /*EMPTY*/             { $$ = EMPTY; }
2498                 ;
2499
2500 function_with_argtypes_list: function_with_argtypes
2501                         { $$ = $1; }
2502                 | function_with_argtypes_list ',' function_with_argtypes
2503                         { $$ = cat_str(3, $1, make_str(","), $3); }
2504                 ;
2505
2506 function_with_argtypes: func_name func_args { $$ = cat2_str($1, $2); };
2507
2508 /*****************************************************************************
2509  *
2510  * GRANT and REVOKE ROLE statements
2511  *
2512  *****************************************************************************/
2513
2514 GrantRoleStmt:
2515                 GRANT privilege_list TO name_list opt_grant_admin_option opt_granted_by
2516                         { $$ = cat_str(6, make_str("grant"), $2, make_str("to"), $4, $5, $6); }
2517                 ;
2518
2519 RevokeRoleStmt:
2520                 REVOKE privilege_list FROM name_list opt_granted_by opt_drop_behavior
2521                         { $$ = cat_str(6, make_str("revoke"), $2, make_str("from"), $4, $5, $6); }
2522                 ;
2523
2524 opt_grant_admin_option: WITH ADMIN OPTION       { $$ = make_str("with admin option"); }
2525                 | /*EMPTY*/                     { $$ = EMPTY; }
2526                 ;
2527
2528 opt_granted_by: GRANTED BY RoleId        { $$ = cat2_str(make_str("granted by"), $3); }
2529                 | /*EMPTY*/              { $$ = EMPTY; }
2530                 ;
2531
2532 /*****************************************************************************
2533  *
2534  *              QUERY:
2535  *             QUERY: CREATE INDEX
2536  *
2537  * Note: we can't factor CONCURRENTLY into a separate production without
2538  * making it a reserved word.
2539  *
2540  * Note: we cannot put TABLESPACE clause after WHERE clause unless we are
2541  * willing to make TABLESPACE a fully reserved word.
2542  *
2543  *****************************************************************************/
2544
2545 IndexStmt:      CREATE index_opt_unique INDEX index_name ON qualified_name
2546                                 access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
2547                         { $$ = cat_str(13, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12, $13); }
2548                 | CREATE index_opt_unique INDEX CONCURRENTLY index_name ON qualified_name
2549                                 access_method_clause '(' index_params ')' opt_definition OptTableSpace where_clause
2550                         { $$ = cat_str(13, make_str("create"), $2, make_str("index concurrently"), $5, make_str("on"), $7, $8, make_str("("), $10, make_str(")"), $12, $13, $14); }
2551                 ;
2552
2553 index_opt_unique:  UNIQUE       { $$ = make_str("unique"); }
2554                 | /*EMPTY*/             { $$ = EMPTY; }
2555                 ;
2556
2557 access_method_clause:  USING access_method
2558                         { $$ = cat2_str(make_str("using"), $2); }
2559                 | /*EMPTY*/
2560                         { $$ = EMPTY; }
2561                 ;
2562
2563 index_params:  index_elem                       { $$ = $1; }
2564                 | index_params ',' index_elem   { $$ = cat_str(3, $1, make_str(","), $3); }
2565                 ;
2566
2567 index_elem:  ColId opt_class opt_asc_desc opt_nulls_order
2568                         { $$ = cat_str(4, $1, $2, $3, $4); }
2569                 | func_expr opt_class opt_asc_desc opt_nulls_order
2570                         { $$ = cat_str(4, $1, $2, $3, $4); }
2571                 | '(' a_expr ')' opt_class opt_asc_desc opt_nulls_order
2572                         { $$ = cat_str(6, make_str("("), $2, make_str(")"), $4, $5, $6); }
2573                 ;
2574
2575 opt_class:      any_name        { $$ = $1; }
2576                 | USING any_name        { $$ = cat2_str(make_str("using"), $2); }
2577                 | /*EMPTY*/             { $$ = EMPTY; }
2578                 ;
2579
2580 opt_asc_desc:   ASC             { $$ = make_str("asc"); }
2581                 | DESC          { $$ = make_str("desc"); } 
2582                 | /*EMPTY*/     { $$ = EMPTY; }
2583                 ;
2584
2585 opt_nulls_order:        NULLS_FIRST             { $$ = make_str("nulls first"); }
2586                         | NULLS_LAST            { $$ = make_str("nulls last"); } 
2587                         | /*EMPTY*/     { $$ = EMPTY; }
2588                         ;
2589
2590 CreateFunctionStmt:     CREATE opt_or_replace FUNCTION func_name func_args
2591                                         RETURNS func_return createfunc_opt_list opt_definition
2592                         { $$ = cat_str(8, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, $8); }
2593                 | CREATE opt_or_replace FUNCTION func_name func_args
2594                                         createfunc_opt_list opt_definition
2595                         { $$ = cat_str(6, make_str("create"), $2, make_str("function"), $4, $5, $6, $7); }
2596                 ;
2597
2598 opt_or_replace:  OR REPLACE             { $$ = make_str("or replace"); }
2599                 | /*EMPTY*/                             { $$ = EMPTY; }
2600                 ;
2601
2602 func_args:      '(' func_args_list ')'
2603                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2604                 | '(' ')'
2605                         { $$ = make_str("()"); }
2606                 ;
2607
2608 func_args_list:  func_arg
2609                         { $$ = $1; }
2610                 | func_args_list ',' func_arg
2611                         { $$ = cat_str(3, $1, make_str(","), $3); }
2612                 ;
2613
2614 func_arg:  arg_class param_name func_type               { $$ = cat_str(3, $1, $2, $3); }
2615                 | param_name arg_class func_type        { $$ = cat_str(3, $1, $2, $3); }
2616                 | param_name func_type                  { $$ = cat2_str($1, $2); }
2617                 | arg_class func_type                   { $$ = cat2_str($1, $2); }
2618                 | func_type                             { $$ = $1; }
2619                 ;
2620
2621 arg_class:  IN_P                { $$ = make_str("in"); }
2622                 | OUT_P         { $$ = make_str("out"); }
2623                 | INOUT         { $$ = make_str("inout"); }
2624                 | IN_P OUT_P    { $$ = make_str("in out"); }
2625                 ;
2626
2627 func_as: StringConst
2628                         { $$ = $1; }
2629                 | StringConst ',' StringConst
2630                         { $$ = cat_str(3, $1, make_str(","), $3); }
2631                 ;
2632
2633 param_name:    type_function_name       { $$ = $1; };
2634
2635 func_return:  func_type
2636                 {
2637                         /* We can catch over-specified arguments here if we want to,
2638                          * but for now better to silently swallow typmod, etc.
2639                          * - thomas 2000-03-22
2640                          */
2641                         $$ = $1;
2642                 }
2643                 ;
2644
2645 func_type:      Typename
2646                         { $$ = $1; }
2647                 | type_function_name attrs '%' TYPE_P
2648                         { $$ = cat_str(3, $1, $2, make_str("% type")); }
2649                 | SETOF type_function_name attrs '%' TYPE_P
2650                         { $$ = cat_str(4, make_str("setof"), $2, $3, make_str("% type")); }
2651                 ;
2652
2653
2654 createfunc_opt_list: createfunc_opt_item
2655                         { $$ = $1; }
2656                 | createfunc_opt_list createfunc_opt_item
2657                         { $$ = cat2_str($1, $2); }
2658                 ;
2659
2660 common_func_opt_item:
2661                 CALLED ON NULL_P INPUT_P
2662                                 { $$ = make_str("called on null input"); }
2663                 | RETURNS NULL_P ON NULL_P INPUT_P
2664                                 { $$ = make_str("returns null on null input"); }
2665                 | STRICT_P
2666                                 { $$ = make_str("strict"); }
2667                 | IMMUTABLE
2668                                 { $$ = make_str("immutable"); }
2669                 | STABLE
2670                                 { $$ = make_str("stable"); }
2671                 | VOLATILE
2672                                 { $$ = make_str("volatile"); }
2673                 | EXTERNAL SECURITY DEFINER
2674                                 { $$ = make_str("external security definer"); }
2675                 | EXTERNAL SECURITY INVOKER
2676                                 { $$ = make_str("external security invoker"); }
2677                 | SECURITY DEFINER
2678                                 { $$ = make_str("security definer"); }
2679                 | SECURITY INVOKER
2680                                 { $$ = make_str("security invoker"); }
2681                 | COST NumConst
2682                                 { $$ = cat2_str(make_str("cost"), $2); }
2683                 | ROWS NumConst
2684                                 { $$ = cat2_str(make_str("rows"), $2); }
2685                 | SetResetClause
2686                                 { $$ = $1; }
2687                 ;
2688
2689 createfunc_opt_item: AS func_as
2690                                 { $$ = cat2_str(make_str("as"), $2); }
2691                 | LANGUAGE ColId_or_Sconst
2692                                 { $$ = cat2_str(make_str("language"), $2); }
2693                 | common_func_opt_item
2694                                 { $$ = $1; }
2695                 ;
2696
2697 opt_definition: WITH definition { $$ = cat2_str(make_str("with"), $2); }
2698                 | /*EMPTY*/     { $$ = EMPTY; }
2699                 ;
2700
2701 AlterFunctionStmt:
2702                 ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
2703                         { $$ = cat_str(4, make_str("alter function"), $3, $4, $5); }
2704                 ;
2705
2706 alterfunc_opt_list: common_func_opt_item                        { $$ = $1; }
2707                 | alterfunc_opt_list common_func_opt_item       { $$ = cat2_str($1, $2);}
2708                 ;
2709
2710 opt_restrict:   RESTRICT        { $$ = make_str("restrict"); }
2711                 | /*EMPTY*/       { $$ = EMPTY; }
2712                 ;
2713
2714 /*****************************************************************************
2715  *
2716  *              QUERY:
2717  *
2718  *                         DROP FUNCTION funcname (arg1, arg2, ...)
2719  *                         DROP AGGREGATE (arg1, ...) [ RESTRICT | CASCADE ]
2720  *                         DROP OPERATOR opname (leftoperand_typ rightoperand_typ)
2721  *
2722  *****************************************************************************/
2723
2724 RemoveFuncStmt:  DROP FUNCTION func_name func_args opt_drop_behavior
2725                         { $$ = cat_str(4, make_str("drop function"), $3, $4, $5); }
2726                 | DROP FUNCTION IF_P EXISTS func_name func_args opt_drop_behavior
2727                         { $$ = cat_str(4, make_str("drop function if exists"), $5, $6, $7); }
2728                 ;
2729
2730 RemoveAggrStmt:  DROP AGGREGATE func_name aggr_args opt_drop_behavior
2731                         { $$ = cat_str(4, make_str("drop aggregate"), $3, $4, $5); }
2732                 | DROP AGGREGATE IF_P EXISTS func_name aggr_args opt_drop_behavior
2733                         { $$ = cat_str(4, make_str("drop aggregate if exists"), $5, $6, $7); }
2734                 ;
2735
2736 RemoveOperStmt:  DROP OPERATOR all_Op '(' oper_argtypes ')' opt_drop_behavior
2737                         { $$ = cat_str(6, make_str("drop operator"), $3, make_str("("), $5, make_str(")"), $7); }
2738                 | DROP OPERATOR IF_P EXISTS any_operator '(' oper_argtypes ')' opt_drop_behavior
2739                         { $$ = cat_str(6, make_str("drop operator if exists"), $5, make_str("("), $7, make_str(")"), $9); }
2740                 ;
2741
2742 oper_argtypes:  Typename
2743                         { mmerror(PARSE_ERROR, ET_ERROR, "parser: argument type missing (use NONE for unary operators)"); }
2744                 | Typename ',' Typename
2745                         { $$ = cat_str(3, $1, make_str(","), $3); }
2746                 | NONE ',' Typename                     /* left unary */
2747                         { $$ = cat2_str(make_str("none,"), $3); }
2748                 | Typename ',' NONE                     /* right unary */
2749                         { $$ = cat2_str($1, make_str(", none")); }
2750                 ;
2751
2752 any_operator:
2753                 all_Op
2754                         { $$ = $1; }
2755                 | ColId '.' any_operator
2756                         { $$ = cat_str(3, $1, make_str("."), $3); }
2757                 ;
2758
2759 CreateCastStmt:         CREATE CAST '(' Typename AS Typename ')'
2760                                 WITH FUNCTION function_with_argtypes cast_context
2761                         { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") with function"), $10); }
2762                 | CREATE CAST '(' Typename AS Typename ')'
2763                                 WITHOUT FUNCTION cast_context
2764                         { $$ = cat_str(6, make_str("create cast ("), $4, make_str("as"), $6, make_str(") without function"), $10); }
2765                 ;
2766
2767 cast_context: AS ASSIGNMENT   { $$ = make_str("as assignment"); }
2768                 | /*EMPTY*/     { $$ = EMPTY; }
2769                 ;
2770
2771
2772 DropCastStmt: DROP CAST opt_if_exists  '(' Typename AS Typename ')' opt_drop_behavior
2773                         { $$ = cat_str(8, make_str("drop cast"), $3, make_str("("), $5, make_str("as"), $7, make_str(")"), $9); }
2774                 ;
2775
2776 opt_if_exists: IF_P EXISTS      { $$ = make_str("if exists"); }
2777                 | /* EMPTY */   { $$ = EMPTY; }
2778                 ;
2779
2780 /*****************************************************************************
2781  *
2782  *                              QUERY:
2783  *
2784  *                              REINDEX type <typename> [FORCE] [ALL]
2785  *
2786  *****************************************************************************/
2787 ReindexStmt:  REINDEX reindex_type qualified_name opt_force
2788                         { $$ = cat_str(4, make_str("reindex"), $2, $3, $4); }
2789                 | REINDEX SYSTEM_P name opt_force
2790                         { $$ = cat_str(3, make_str("reindex system"), $3, $4); }
2791                 | REINDEX DATABASE name opt_force
2792                         { $$ = cat_str(3, make_str("reindex database"), $3, $4); }
2793                 ;
2794
2795 reindex_type:   INDEX           { $$ = make_str("index"); }
2796                 | TABLE         { $$ = make_str("table"); }
2797                 ;
2798
2799 opt_force: FORCE                        { $$ = make_str("force"); }
2800                 | /* EMPTY */           { $$ = EMPTY; }
2801                 ;
2802
2803 /*****************************************************************************
2804  *
2805  *              QUERY:
2806  *                              rename <attrname1> in <relname> [*] to <attrname2>
2807  *                              rename <relname1> to <relname2>
2808  *
2809  *****************************************************************************/
2810
2811 RenameStmt:  ALTER AGGREGATE func_name aggr_args RENAME TO name
2812                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("rename to"), $7); }
2813                 | ALTER CONVERSION_P any_name RENAME TO name
2814                         { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("rename to"), $6); }
2815                 | ALTER DATABASE database_name RENAME TO database_name
2816                         { $$ = cat_str(4, make_str("alter database"), $3, make_str("rename to"), $6); }
2817                 | ALTER FUNCTION function_with_argtypes RENAME TO name
2818                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("rename to"), $6); }
2819                 | ALTER GROUP_P RoleId RENAME TO RoleId
2820                         { $$ = cat_str(4, make_str("alter group"), $3, make_str("rename to"), $6); }
2821                 | ALTER opt_procedural LANGUAGE name RENAME TO name
2822                         { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("rename to"), $7); }
2823                 | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
2824                         { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
2825                 | ALTER OPERATOR FAMILY any_name USING access_method RENAME TO name
2826                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("rename to"), $9); }
2827                 | ALTER SCHEMA name RENAME TO name
2828                         { $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
2829                 | ALTER TABLE relation_expr RENAME TO name
2830                         { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
2831                 | ALTER SEQUENCE relation_expr RENAME TO name
2832                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("rename to"), $6); }
2833                 | ALTER VIEW relation_expr RENAME TO name
2834                         { $$ = cat_str(4, make_str("alter view"), $3, make_str("rename to"), $6); }
2835                 | ALTER INDEX relation_expr RENAME TO name
2836                         { $$ = cat_str(4, make_str("alter index"), $3, make_str("rename to"), $6); }
2837                 | ALTER TABLE relation_expr RENAME opt_column name TO name
2838                         { $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
2839                 | ALTER TRIGGER name ON relation_expr RENAME TO name
2840                         { $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
2841                 | ALTER USER RoleId RENAME TO RoleId
2842                         { $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
2843                 | ALTER TABLESPACE name RENAME TO name
2844                         { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("rename to"), $6); }
2845                 | ALTER TEXT_P SEARCH PARSER any_name RENAME TO name
2846                         { $$ = cat_str(4, make_str("alter text search parser"), $5, make_str("rename to"), $8); }
2847                 | ALTER TEXT_P SEARCH DICTIONARY any_name RENAME TO name
2848                         { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("rename to"), $8); }
2849                 | ALTER TEXT_P SEARCH TEMPLATE any_name RENAME TO name
2850                         { $$ = cat_str(4, make_str("alter text search template"), $5, make_str("rename to"), $8); }
2851                 | ALTER TEXT_P SEARCH CONFIGURATION any_name RENAME TO name
2852                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("rename to"), $8); }
2853                 ;
2854
2855 opt_column:  COLUMN                     { $$ = make_str("column"); }
2856                 | /*EMPTY*/                     { $$ = EMPTY; }
2857                 ;
2858
2859 /*****************************************************************************
2860  *
2861  * ALTER THING name SET SCHEMA name
2862  *
2863  *****************************************************************************/
2864
2865 AlterObjectSchemaStmt:
2866                 ALTER AGGREGATE func_name aggr_args SET SCHEMA name
2867                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("set schema"), $7); }
2868                 | ALTER DOMAIN_P any_name SET SCHEMA name
2869                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("set schema"), $6); }
2870                 | ALTER FUNCTION function_with_argtypes SET SCHEMA name
2871                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("set schema"), $6); }
2872                 | ALTER SEQUENCE relation_expr SET SCHEMA name
2873                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
2874                 | ALTER TABLE relation_expr SET SCHEMA name
2875                         { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
2876                 | ALTER TYPE_P any_name SET SCHEMA name
2877                         { $$ = cat_str(4, make_str("alter type"), $3, make_str("set schema"), $6); }
2878                 ;
2879
2880 /*****************************************************************************
2881  *
2882  * ALTER THING name OWNER TO newname
2883  *
2884  *****************************************************************************/
2885
2886 AlterOwnerStmt: ALTER AGGREGATE func_name aggr_args OWNER TO RoleId
2887                         { $$ = cat_str(5, make_str("alter aggregate"), $3, $4, make_str("owner to"), $7); }
2888                 | ALTER CONVERSION_P any_name OWNER TO RoleId
2889                         { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("owner to"), $6); }
2890                 | ALTER DATABASE database_name OWNER TO RoleId
2891                         { $$ = cat_str(4, make_str("alter database"), $3, make_str("owner to"), $6); }
2892                 | ALTER DOMAIN_P database_name OWNER TO RoleId
2893                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("owner to"), $6); }
2894                 | ALTER FUNCTION function_with_argtypes OWNER TO RoleId
2895                         { $$ = cat_str(4, make_str("alter function"), $3, make_str("owner to"), $6); }
2896                 | ALTER opt_procedural LANGUAGE name OWNER TO RoleId
2897                         { $$ = cat_str(6, make_str("alter"), $2, make_str("language"), $4, make_str("owner to"), $7); }
2898                 | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
2899                         { $$ = cat_str(6, make_str("alter operator"), $3, make_str("("), $5, make_str(") owner to"), $9); }
2900                 | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
2901                         { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("owner to"), $9); }
2902                 | ALTER OPERATOR FAMILY any_name USING access_method OWNER TO RoleId
2903                         { $$ = cat_str(6, make_str("alter operator family"), $4, make_str("using"), $6, make_str("owner to"), $9); }
2904                 | ALTER SCHEMA name OWNER TO RoleId
2905                         { $$ = cat_str(4, make_str("alter schema"), $3, make_str("owner to"), $6); }
2906                 | ALTER TYPE_P any_name OWNER TO RoleId
2907                         { $$ = cat_str(4, make_str("alter type"), $3, make_str("owner to"), $6); }
2908                 | ALTER TABLESPACE name OWNER TO RoleId
2909                         { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("owner to"), $6); }
2910                 | ALTER TEXT_P SEARCH DICTIONARY any_name OWNER TO RoleId
2911                         { $$ = cat_str(4, make_str("alter text search dictionary"), $5, make_str("owner to"), $8); }
2912                 | ALTER TEXT_P SEARCH CONFIGURATION any_name OWNER TO RoleId
2913                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("owner to"), $8); }
2914                 ;
2915
2916
2917 /*****************************************************************************
2918  *
2919  *              QUERY:  Define Rewrite Rule
2920  *
2921  *****************************************************************************/
2922
2923 RuleStmt:  CREATE opt_or_replace RULE name AS
2924                    { QueryIsRule=1; }
2925                    ON event TO qualified_name where_clause
2926                    DO opt_instead RuleActionList
2927                 {
2928                         QueryIsRule=0;
2929                         $$ = cat_str(12, make_str("create"), $2, make_str("rule"), $4, make_str("as on"), $8, make_str("to"), $10, $11, make_str("do"), $13, $14);
2930                 }
2931                 ;
2932
2933 RuleActionList:  NOTHING                                { $$ = make_str("nothing"); }
2934                 | RuleActionStmt                                { $$ = $1; }
2935                 | '(' RuleActionMulti ')'               { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
2936                                 ;
2937
2938 /* the thrashing around here is to discard "empty" statements... */
2939 RuleActionMulti:  RuleActionMulti ';' RuleActionStmtOrEmpty
2940                         {  $$ = cat_str(3, $1, make_str(";"), $3); }
2941                 | RuleActionStmtOrEmpty
2942                         { $$ = cat2_str($1, make_str(";")); }
2943                 ;
2944
2945 RuleActionStmt:   SelectStmt
2946                 | InsertStmt
2947                 | UpdateStmt
2948                 | DeleteStmt
2949                 | NotifyStmt
2950                 ;
2951
2952 RuleActionStmtOrEmpty: RuleActionStmt   { $$ = $1; }
2953                 | /*EMPTY*/                                             { $$ = EMPTY; }
2954                 ;
2955
2956 /* change me to select, update, etc. some day */
2957 event:  SELECT                          { $$ = make_str("select"); }
2958                 | UPDATE                        { $$ = make_str("update"); }
2959                 | DELETE_P                      { $$ = make_str("delete"); }
2960                 | INSERT                        { $$ = make_str("insert"); }
2961                 ;
2962
2963 opt_instead:  INSTEAD           { $$ = make_str("instead"); }
2964                 | ALSO          { $$ = make_str("also"); }
2965                 | /*EMPTY*/                     { $$ = EMPTY; }
2966                 ;
2967
2968 DropRuleStmt:  DROP RULE name ON qualified_name opt_drop_behavior
2969                         { $$ = cat_str(5, make_str("drop rule"), $3, make_str("on"), $5, $6);}
2970                 | DROP RULE IF_P EXISTS name ON qualified_name opt_drop_behavior
2971                         { $$ = cat_str(5, make_str("drop rule if exists"), $5, make_str("on"), $7, $8);}
2972                 ;
2973
2974 /*****************************************************************************
2975  *
2976  *              QUERY:
2977  *                              NOTIFY <qualified_name> can appear both in rule bodies and
2978  *                              as a query-level command
2979  *
2980  *****************************************************************************/
2981
2982 NotifyStmt:  NOTIFY ColId
2983                         { $$ = cat2_str(make_str("notify"), $2); }
2984                 ;
2985
2986 ListenStmt:  LISTEN ColId
2987                         { $$ = cat2_str(make_str("listen"), $2); }
2988                 ;
2989
2990 UnlistenStmt:  UNLISTEN ColId
2991                         { $$ = cat2_str(make_str("unlisten"), $2); }
2992                 | UNLISTEN '*'
2993                         { $$ = make_str("unlisten *"); }
2994                 ;
2995
2996
2997 /*****************************************************************************
2998  *
2999  *                              Transactions:
3000  *
3001  *        BEGIN / COMMIT / ROLLBACK
3002  *              (also older versions END / ABORT)
3003  *
3004  *****************************************************************************/
3005 TransactionStmt:  ABORT_P opt_transaction        { $$ = make_str("rollback"); }
3006                 | BEGIN_P opt_transaction transaction_mode_list_or_empty { $$ = cat2_str(make_str("begin transaction"), $3); }
3007                 | START TRANSACTION transaction_mode_list_or_empty       { $$ = cat2_str(make_str("start transaction"), $3); }
3008                 | COMMIT opt_transaction                         { $$ = make_str("commit"); }
3009                 | END_P opt_transaction                          { $$ = make_str("commit"); }
3010                 | ROLLBACK opt_transaction                       { $$ = make_str("rollback"); }
3011                 | SAVEPOINT ColId                                        { $$ = cat2_str(make_str("savepoint"), $2); }
3012                 | RELEASE SAVEPOINT ColId                        { $$ = cat2_str(make_str("release savepoint"), $3); }
3013                 | RELEASE ColId                                          { $$ = cat2_str(make_str("release"), $2); }
3014                 | ROLLBACK opt_transaction TO SAVEPOINT ColId            { $$ = cat_str(4, make_str("rollback"), $2, make_str("to savepoint"), $5); }
3015                 | ROLLBACK opt_transaction TO ColId      { $$ = cat_str(4, make_str("rollback"), $2, make_str("to"), $4); }
3016                 | PREPARE TRANSACTION StringConst        { $$ = cat2_str(make_str("prepare transaction"), $3); }
3017                 | COMMIT PREPARED StringConst            { $$ = cat2_str(make_str("commit prepared"), $3); }
3018                 | ROLLBACK PREPARED StringConst          { $$ = cat2_str(make_str("rollback prepared"), $3); }
3019                 ;
3020
3021 opt_transaction: WORK   { $$ = EMPTY; }
3022                 | TRANSACTION   { $$ = EMPTY; }
3023                 | /*EMPTY*/             { $$ = EMPTY; }
3024                 ;
3025
3026 transaction_mode_item:
3027                 ISOLATION LEVEL iso_level
3028                         { $$ = cat2_str(make_str("isolation level"), $3); }
3029                 | READ ONLY     { $$ = make_str("read only"); }
3030                 | READ WRITE    { $$ = make_str("read write"); }
3031                 ;
3032
3033 transaction_mode_list:
3034                 transaction_mode_item                                   { $$ = $1; }
3035                 | transaction_mode_list ',' transaction_mode_item       { $$ = cat_str(3, $1, make_str(","), $3); }
3036                 | transaction_mode_list transaction_mode_item           { $$ = cat_str(3, $1, make_str(" "), $2); }
3037                 ;
3038
3039 transaction_mode_list_or_empty:
3040                 transaction_mode_list   { $$ = $1; }
3041                 | /* EMPTY */           { $$ = EMPTY; }
3042                 ;
3043
3044 /*****************************************************************************
3045  *
3046  *      QUERY:
3047  *              CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')'
3048  *                     AS <query> [ WITH [ CASCADED | LOCAL ] CHECK OPTION ]
3049  *
3050  *****************************************************************************/
3051
3052 ViewStmt:  CREATE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
3053                         { $$ = cat_str(8, make_str("create"), $2, make_str("view"), $4, $5, make_str("as"), $7, $8); }
3054                 | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list AS SelectStmt opt_check_option
3055                         { $$ = cat_str(8, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9, $10); }
3056                 ;
3057
3058 /*
3059  * We use merged tokens here to avoid creating shift/reduce conflicts against
3060  * a whole lot of other uses of WITH.
3061  */
3062 opt_check_option:
3063                    WITH_CHECK OPTION
3064                    { 
3065                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3066                         $$ = EMPTY;
3067                    }
3068                    | WITH_CASCADED CHECK OPTION
3069                    { 
3070                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3071                         $$ = EMPTY;
3072                    }
3073                    | WITH_LOCAL CHECK OPTION
3074                    {
3075                         mmerror(PARSE_ERROR, ET_ERROR, "WITH CHECK OPTION not implemented");
3076                         $$ = EMPTY;
3077                    }
3078                    | /* EMPTY */
3079                    { $$ = EMPTY; } 
3080                    ;
3081
3082 /*****************************************************************************
3083  *
3084  *              QUERY:
3085  *                              load make_str("filename")
3086  *
3087  *****************************************************************************/
3088
3089 LoadStmt:  LOAD file_name
3090                         { $$ = cat2_str(make_str("load"), $2); }
3091                 ;
3092
3093
3094 /*****************************************************************************
3095  *
3096  *              CREATE DATABASE
3097  *
3098  *
3099  *****************************************************************************/
3100
3101 CreatedbStmt:  CREATE DATABASE database_name WITH createdb_opt_list
3102                         { $$ = cat_str(4, make_str("create database"), $3, make_str("with"), $5); }
3103                 | CREATE DATABASE database_name
3104                         { $$ = cat2_str(make_str("create database"), $3); }
3105                 ;
3106
3107 createdb_opt_list:      createdb_opt_item
3108                         { $$ = $1; }
3109                 | createdb_opt_list createdb_opt_item
3110                         { $$ = cat2_str($1, $2); }
3111                 ;
3112
3113 createdb_opt_item:      TABLESPACE opt_equal name
3114                         { $$ = cat_str(3,make_str("tablespace"), $2, $3); }
3115                 | TABLESPACE opt_equal DEFAULT
3116                         { $$ = cat_str(3, make_str("tablespace"), $2, make_str("default")); }
3117                 | LOCATION opt_equal StringConst
3118                         { $$ = cat_str(3,make_str("location"), $2, $3); }
3119                 | LOCATION opt_equal DEFAULT
3120                         { $$ = cat_str(3, make_str("location"), $2, make_str("default")); }
3121                 | TEMPLATE opt_equal name
3122                         { $$ = cat_str(3, make_str("template"), $2, $3); }
3123                 | TEMPLATE opt_equal DEFAULT
3124                         { $$ = cat_str(3, make_str("template"), $2, make_str("default")); }
3125                 | ENCODING opt_equal PosIntStringConst
3126                         { $$ = cat_str(3, make_str("encoding"), $2, $3); }
3127                 | ENCODING opt_equal DEFAULT
3128                         { $$ = cat_str(3, make_str("encoding"), $2, make_str("default")); }
3129                 | CONNECTION LIMIT opt_equal PosIntConst
3130                         { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
3131                 | OWNER opt_equal name
3132                         { $$ = cat_str(3, make_str("owner"), $2, $3); }
3133                 | OWNER opt_equal DEFAULT
3134                         { $$ = cat_str(3, make_str("owner"), $2, make_str("default")); }
3135                 ;
3136
3137 opt_equal: '='                                  { $$ = make_str("="); }
3138                 | /* EMPTY */                   { $$ = EMPTY; }
3139                 ;
3140
3141
3142 /*****************************************************************************
3143  *
3144  *                              ALTER DATABASE
3145  *
3146  *
3147  *****************************************************************************/
3148
3149 AlterDatabaseStmt: ALTER DATABASE database_name opt_with alterdb_opt_list
3150                         { $$ = cat_str(4, make_str("alter database"), $3, $4, $5); }
3151                 ;
3152
3153 AlterDatabaseSetStmt: ALTER DATABASE database_name SetResetClause
3154                         { $$ = cat_str(3, make_str("alter database"), $3, $4); }
3155                 ;
3156
3157 alterdb_opt_list:
3158                 alterdb_opt_list alterdb_opt_item       { $$ = cat2_str($1, $2);}
3159                 | /* EMPTY */                           { $$ = EMPTY; }
3160                 ;
3161
3162 alterdb_opt_item:
3163                 CONNECTION LIMIT opt_equal PosIntConst { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
3164                 ;
3165
3166 /*****************************************************************************
3167  *
3168  *              DROP DATABASE [ IF EXISTS ]
3169  *
3170  *
3171  *****************************************************************************/
3172
3173 DropdbStmt: DROP DATABASE database_name
3174                         { $$ = cat2_str(make_str("drop database"), $3); }
3175                 | DROP DATABASE IF_P EXISTS database_name
3176                         { $$ = cat2_str(make_str("drop database if exists"), $5); }
3177                 ;
3178
3179
3180 /*****************************************************************************
3181  *
3182  * Manipulate a domain
3183  *
3184  *****************************************************************************/
3185
3186 CreateDomainStmt:  CREATE DOMAIN_P any_name opt_as Typename ColQualList
3187                 {
3188                         $$ = cat_str(5, make_str("create domain"), $3, $4, $5, $6);
3189                 }
3190                 ;
3191
3192 AlterDomainStmt:
3193                 ALTER DOMAIN_P any_name alter_column_default
3194                         { $$ = cat_str(3, make_str("alter domain"), $3, $4); }
3195                 | ALTER DOMAIN_P any_name DROP NOT NULL_P
3196                         { $$ = cat_str(3, make_str("alter domain"), $3, make_str("drop not null")); }
3197                 | ALTER DOMAIN_P any_name SET NOT NULL_P
3198                         { $$ = cat_str(3, make_str("alter domain"), $3, make_str("set not null")); }
3199                 | ALTER DOMAIN_P any_name ADD_P TableConstraint
3200                         { $$ = cat_str(4, make_str("alter domain"), $3, make_str("add"), $5); }
3201                 | ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
3202                         { $$ = cat_str(5, make_str("alter domain"), $3, make_str("drop constraint"), $6, $7); }
3203                 ;
3204
3205 opt_as: AS      {$$ = make_str("as"); }
3206                 | /* EMPTY */   {$$ = EMPTY; }
3207                 ;
3208
3209 AlterTSDictionaryStmt:
3210                 ALTER TEXT_P SEARCH DICTIONARY any_name definition
3211                         { $$ = cat_str(3, make_str("alter text search dictionary"), $5, $6); }
3212                 ;
3213
3214 AlterTSConfigurationStmt:
3215                 ALTER TEXT_P SEARCH CONFIGURATION any_name ADD_P MAPPING FOR name_list WITH any_name_list
3216                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("add mapping for"), $9, make_str("with"), $11); }
3217                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list WITH any_name_list
3218                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("with"), $11); }
3219                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING REPLACE any_name WITH any_name
3220                         { $$ = cat_str(6, make_str("alter text search configuration"), $5, make_str("alter mapping replace"), $9, make_str("with"), $11); }
3221                 | ALTER TEXT_P SEARCH CONFIGURATION any_name ALTER MAPPING FOR name_list REPLACE any_name WITH any_name
3222                         { $$ = cat_str(8, make_str("alter text search configuration"), $5, make_str("alter mapping for"), $9, make_str("replace"), $11, make_str("with"), $13); }
3223                 | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING FOR name_list
3224                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping for"), $9); }
3225                 | ALTER TEXT_P SEARCH CONFIGURATION any_name DROP MAPPING IF_P EXISTS FOR name_list
3226                         { $$ = cat_str(4, make_str("alter text search configuration"), $5, make_str("drop mapping if exists for"), $11); }
3227                 ;
3228
3229 CreateConversionStmt:
3230            CREATE opt_default CONVERSION_P any_name FOR StringConst
3231            TO StringConst FROM any_name
3232                    { $$ = cat_str(10, make_str("create"), $2, make_str("conversion"), $4, make_str("for"), $6, make_str("to"), $8, make_str("from"), $10); }
3233            ;
3234
3235 /*****************************************************************************
3236  *
3237  *              QUERY:
3238  *                             cluster <index_name> on <qualified_name>
3239  *                             cluster <qualified_name>
3240  *                             cluster
3241  *
3242  *****************************************************************************/
3243
3244 ClusterStmt:  CLUSTER qualified_name cluster_index_specification
3245                                 { $$ = cat_str(3,make_str("cluster"), $2, $3); }
3246                 | CLUSTER
3247                                 { $$ = make_str("cluster"); }
3248                 | CLUSTER qualified_name ON qualified_name
3249                                 { $$ = cat_str(4, make_str("cluster"), $2, make_str("on"), $4); }
3250                 ;
3251
3252 cluster_index_specification:
3253                 USING index_name        { $$ = cat2_str(make_str("using"), $2); }
3254                 | /*EMPTY*/             { $$ = EMPTY; }
3255                 ;
3256
3257 /*****************************************************************************
3258  *
3259  *              QUERY:
3260  *                              vacuum
3261  *                              analyze
3262  *
3263  *****************************************************************************/
3264
3265 VacuumStmt:  VACUUM opt_full opt_freeze opt_verbose
3266                         { $$ = cat_str(4, make_str("vacuum"), $2, $3, $4); }
3267                 | VACUUM opt_full opt_freeze opt_verbose qualified_name
3268                         { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
3269                 | VACUUM opt_full opt_freeze opt_verbose AnalyzeStmt
3270                         { $$ = cat_str(5, make_str("vacuum"), $2, $3, $4, $5); }
3271                 ;
3272
3273 AnalyzeStmt:  analyze_keyword opt_verbose
3274                         { $$ = cat_str(2, $1, $2); }
3275                 | analyze_keyword opt_verbose qualified_name opt_name_list
3276                         { $$ = cat_str(4, $1, $2, $3, $4); }
3277                 ;
3278
3279 analyze_keyword:  ANALYZE               { $$ = make_str("analyze"); }
3280                 | ANALYSE               { $$ = make_str("analyse"); }
3281                 ;
3282
3283 opt_verbose:  VERBOSE                   { $$ = make_str("verbose"); }
3284                 | /*EMPTY*/                             { $$ = EMPTY; }
3285                 ;
3286
3287 opt_full:  FULL                                 { $$ = make_str("full"); }
3288                 | /*EMPTY*/                             { $$ = EMPTY; }
3289                 ;
3290
3291 opt_freeze:  FREEZE                             { $$ = make_str("freeze"); }
3292                 | /*EMPTY*/                             { $$ = EMPTY; }
3293                 ;
3294
3295 opt_name_list:  '(' name_list ')'
3296                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3297                 | /*EMPTY*/
3298                         { $$ = EMPTY; }
3299                 ;
3300
3301
3302 /*****************************************************************************
3303  *
3304  *              QUERY:
3305  *                              EXPLAIN query
3306  *
3307  *****************************************************************************/
3308
3309 ExplainStmt:  EXPLAIN opt_analyze opt_verbose ExplainableStmt
3310                         { $$ = cat_str(4, make_str("explain"), $2, $3, $4); }
3311                 ;
3312
3313 ExplainableStmt:
3314                 SelectStmt
3315                 | InsertStmt
3316                 | UpdateStmt
3317                 | DeleteStmt
3318                 | DeclareCursorStmt
3319                 | ExecuteStmt
3320                 ;
3321 opt_analyze:
3322                 analyze_keyword                 { $$ = $1; }
3323                 | /* EMPTY */                   { $$ = EMPTY; }
3324                 ;
3325
3326 PrepareStmt: PREPARE prepared_name prep_type_clause AS PreparableStmt
3327                 {
3328                         $$.name = $2;
3329                         $$.type = $3;
3330                         $$.stmt = cat_str(3, make_str("\""), $5, make_str("\""));
3331                 }
3332                 | PREPARE prepared_name FROM execstring /* ECPG addon */
3333                 {
3334                         $$.name = $2;
3335                         $$.type = NULL;
3336                         $$.stmt = $4;
3337                 }
3338                 ;
3339
3340 PreparableStmt:
3341                 SelectStmt
3342                 | InsertStmt
3343                 | UpdateStmt
3344                 | DeleteStmt
3345                 ;
3346
3347 prep_type_clause: '(' type_list ')'     { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3348                 | /* EMPTY */           { $$ = EMPTY; }
3349                         ;
3350
3351 ExecuteStmt: EXECUTE prepared_name execute_param_clause execute_rest /* execute_rest is an ecpg addon */
3352                         {
3353                                 /* $$ = cat_str(3, make_str("ECPGprepared_statement("), connection, $2, make_str("__LINE__)"));*/
3354                                 $$ = $2;
3355                         }
3356                 | CREATE OptTemp TABLE create_as_target AS
3357                         EXECUTE prepared_name execute_param_clause
3358                         { $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4,  make_str("as execute"), $7, $8); }
3359                 ;
3360
3361 execute_param_clause: '(' expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3362                 | /* EMPTY */           { $$ = EMPTY; }
3363                 ;
3364
3365 DeallocateStmt: DEALLOCATE prepared_name                { $$ = $2; }
3366                 | DEALLOCATE PREPARE prepared_name      { $$ = $3; }
3367                 | DEALLOCATE ALL                        { $$ = make_str("all"); }
3368                 | DEALLOCATE PREPARE ALL                { $$ = make_str("all"); }
3369                 ;
3370
3371 /*****************************************************************************
3372  *
3373  *              QUERY:
3374  *                              INSERT STATEMENTS
3375  *
3376  *****************************************************************************/
3377
3378 InsertStmt:  INSERT INTO qualified_name insert_rest returning_clause
3379                         { $$ = cat_str(4, make_str("insert into"), $3, $4, $5); }
3380                 ;
3381
3382 insert_rest:  
3383                 SelectStmt
3384                         { $$ = $1; }
3385                 | '(' insert_column_list ')' SelectStmt
3386                         { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
3387                 | DEFAULT VALUES
3388                         { $$ = make_str("default values"); }
3389                 ;
3390
3391 insert_column_list: insert_column_list ',' insert_column_item
3392                         { $$ = cat_str(3, $1, make_str(","), $3); }
3393                 | insert_column_item
3394                         { $$ = $1; }
3395                 ;
3396
3397 insert_column_item:  ColId opt_indirection
3398                         { $$ = cat2_str($1, $2); }
3399                 ;
3400
3401 returning_clause:  RETURNING target_list        { $$ = cat2_str(make_str("returning"), $2); }
3402                 | /* EMPTY */                   { $$ = EMPTY; }
3403                 ;
3404
3405 /*****************************************************************************
3406  *
3407  *              QUERY:
3408  *                              DELETE STATEMENTS
3409  *
3410  *****************************************************************************/
3411
3412 DeleteStmt:  DELETE_P FROM relation_expr_opt_alias using_clause where_or_current_clause returning_clause
3413                         { $$ = cat_str(5, make_str("delete from"), $3, $4, $5, $6); }
3414                 ;
3415
3416 using_clause: USING from_list   { cat2_str(make_str("using"), $2); }
3417                         | /* EMPTY */           { $$ = EMPTY; }
3418                 ;
3419
3420 LockStmt:  LOCK_P opt_table qualified_name_list opt_lock opt_nowait
3421                         { $$ = cat_str(5, make_str("lock"), $2, $3, $4, $5); }
3422                 ;
3423
3424 opt_lock:  IN_P lock_type MODE
3425                         { $$ = cat_str(3, make_str("in"), $2, make_str("mode")); }
3426                 | /*EMPTY*/
3427                         { $$ = EMPTY;}
3428                 ;
3429
3430 lock_type:      ACCESS SHARE            { $$ = make_str("access share"); }
3431                 | ROW SHARE                             { $$ = make_str("access share"); }
3432                 | ROW EXCLUSIVE                 { $$ = make_str("row exclusive"); }
3433                 | SHARE UPDATE EXCLUSIVE { $$ = make_str("share update exclusive"); }
3434                 | SHARE                                 { $$ = make_str("share"); }
3435                 | SHARE ROW EXCLUSIVE   { $$ = make_str("share row exclusive"); }
3436                 | EXCLUSIVE                             { $$ = make_str("exclusive"); }
3437                 | ACCESS EXCLUSIVE              { $$ = make_str("access exclusive"); }
3438                 ;
3439
3440 opt_nowait:    NOWAIT                   { $$ = make_str("nowait"); }
3441                 | /* EMPTY */           { $$ = EMPTY; }
3442                 ;
3443
3444 /*****************************************************************************
3445  *
3446  *              QUERY:
3447  *                              UpdateStmt (UPDATE)
3448  *
3449  *****************************************************************************/
3450
3451 UpdateStmt:  UPDATE relation_expr_opt_alias
3452                                 SET set_clause_list
3453                                 from_clause
3454                                 where_or_current_clause
3455                                 returning_clause
3456                         {$$ = cat_str(7, make_str("update"), $2, make_str("set"), $4, $5, $6, $7); }
3457                 ;
3458
3459 set_clause_list:
3460                 set_clause                              { $$ = $1; }
3461                 | set_clause_list ',' set_clause        { $$ = cat_str(3, $1, make_str(","), $3); }
3462                 ;
3463
3464 set_clause:
3465                 single_set_clause               { $$ = $1; }
3466                 | multiple_set_clause           { $$ = $1; }
3467                 ;
3468
3469 single_set_clause:
3470                 set_target '=' ctext_expr       { $$ = cat_str(3, $1, make_str("="), $3); };
3471
3472 multiple_set_clause:
3473                 '(' set_target_list ')' '=' ctext_row   { $$ = cat_str(4, make_str("("), $2, make_str(")="), $5); };
3474
3475 set_target:
3476                 ColId opt_indirection           { $$ = cat2_str($1, $2); };
3477
3478 set_target_list:
3479                 set_target                              { $$ = $1; }
3480                 | set_target_list ',' set_target        { $$ = cat_str(3, $1, make_str(","), $3); }
3481                 ;
3482
3483 /*****************************************************************************
3484  *
3485  *              QUERY:
3486  *                              CURSOR STATEMENTS
3487  *
3488  *****************************************************************************/
3489 DeclareCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
3490                 {
3491                         struct cursor *ptr, *this;
3492
3493                         for (ptr = cur; ptr != NULL; ptr = ptr->next)
3494                         {
3495                                 if (strcmp($2, ptr->name) == 0)
3496                                         /* re-definition is a bug */
3497                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
3498                         }
3499
3500                         this = (struct cursor *) mm_alloc(sizeof(struct cursor));
3501
3502                         /* initial definition */
3503                         this->next = cur;
3504                         this->name = $2;
3505                         this->connection = connection;
3506                         this->opened = false;
3507                         this->command =  cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
3508                         this->argsinsert = argsinsert;
3509                         this->argsresult = argsresult;
3510                         argsinsert = argsresult = NULL;
3511                         cur = this;
3512
3513                         if (INFORMIX_MODE)
3514                                 $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
3515                         else
3516                                 $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
3517                 }
3518                 ;
3519
3520 cursor_options:  /* EMPTY */            { $$ = EMPTY; }
3521                 | cursor_options BINARY         { $$ = cat2_str($1, make_str("binary")); }
3522                 | cursor_options INSENSITIVE    { $$ = cat2_str($1, make_str("insensitive")); }
3523                 | cursor_options SCROLL         { $$ = cat2_str($1, make_str("scroll")); }
3524                 | cursor_options NO SCROLL      { $$ = cat2_str($1, make_str("no scroll")); }
3525                 ;
3526
3527 opt_hold:       /* EMPTY */
3528                 {
3529                         if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit == true)
3530                                 $$ = make_str("with hold");
3531                         else
3532                                  $$ = EMPTY;
3533                 }
3534                 | WITH HOLD                     { $$ = make_str("with hold"); }
3535                 | WITHOUT HOLD                  { $$ = make_str("without hold"); }
3536                 ;
3537
3538 /*****************************************************************************
3539  *
3540  *              QUERY:
3541  *                              SELECT STATEMENTS
3542  *
3543  *****************************************************************************/
3544
3545 SelectStmt: select_no_parens            %prec UMINUS
3546                         { $$ = $1; }
3547                 |       select_with_parens              %prec UMINUS
3548                         { $$ = $1; }
3549                 ;
3550
3551 select_with_parens: '(' select_no_parens ')'
3552                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3553                 | '(' select_with_parens ')'
3554                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3555                 ;
3556
3557 select_no_parens:          simple_select
3558                         { $$ = $1; }
3559                 | select_clause sort_clause
3560                         { $$ = cat2_str($1, $2); }
3561                 | select_clause opt_sort_clause for_locking_clause opt_select_limit
3562                         { $$ = cat_str(4, $1, $2, $3, $4); }
3563                 | select_clause opt_sort_clause select_limit opt_for_locking_clause
3564                         { $$ = cat_str(4, $1, $2, $3, $4); }
3565                 ;
3566
3567 select_clause: simple_select            { $$ = $1; }
3568                 | select_with_parens            { $$ = $1; }
3569                 ;
3570
3571 simple_select:  SELECT opt_distinct target_list
3572                                         into_clause from_clause where_clause
3573                                         group_clause having_clause
3574                         { $$ = cat_str(8, make_str("select"), $2, $3, $4, $5, $6, $7, $8); }
3575                 | values_clause
3576                         { $$ = $1; }
3577                 | select_clause UNION opt_all select_clause
3578                         { $$ = cat_str(4, $1, make_str("union"), $3, $4); }
3579                 | select_clause INTERSECT opt_all select_clause
3580                         { $$ = cat_str(4, $1, make_str("intersect"), $3, $4); }
3581                 | select_clause EXCEPT opt_all select_clause
3582                         { $$ = cat_str(4, $1, make_str("except"), $3, $4); }
3583                 ;
3584
3585 into_clause:  INTO OptTempTableName
3586                 {
3587                         FoundInto = 1;
3588                         $$= cat2_str(make_str("into"), $2);
3589                 }
3590                 | ecpg_into                     { $$ = EMPTY; }
3591                 | /*EMPTY*/                     { $$ = EMPTY; }
3592                 ;
3593
3594 /*
3595  * Redundancy here is needed to avoid shift/reduce conflicts,
3596  * since TEMP is not a reserved word.  See also OptTemp.
3597  *
3598  * The result is a cons cell (not a true list!) containing
3599  * a boolean and a table name.
3600  */
3601 OptTempTableName:  TEMPORARY opt_table qualified_name
3602                         { $$ = cat_str(3, make_str("temporary"), $2, $3); }
3603                 | TEMP opt_table qualified_name
3604                         { $$ = cat_str(3, make_str("temp"), $2, $3); }
3605                 | LOCAL TEMPORARY opt_table qualified_name
3606                         { $$ = cat_str(3, make_str("local temporary"), $3, $4); }
3607                 | LOCAL TEMP opt_table qualified_name
3608                         { $$ = cat_str(3, make_str("local temp"), $3, $4); }
3609                 | GLOBAL TEMPORARY opt_table qualified_name
3610                         { $$ = cat_str(3, make_str("global temporary"), $3, $4); }
3611                 | GLOBAL TEMP opt_table qualified_name
3612                         { $$ = cat_str(3, make_str("global temp"), $3, $4); }
3613                 | TABLE qualified_name
3614                         { $$ = cat2_str(make_str("table"), $2); }
3615                 | qualified_name
3616                         { $$ = $1; }
3617                 ;
3618
3619 opt_table:      TABLE                           { $$ = make_str("table"); }
3620                 | /*EMPTY*/                             { $$ = EMPTY; }
3621                 ;
3622
3623 opt_all:  ALL                                   { $$ = make_str("all"); }
3624                 | /*EMPTY*/                             { $$ = EMPTY; }
3625                 ;
3626
3627 opt_distinct:  DISTINCT
3628                         { $$ = make_str("distinct"); }
3629                 | DISTINCT ON '(' expr_list ')'
3630                         { $$ = cat_str(3, make_str("distinct on ("), $4, make_str(")")); }
3631                 | ALL
3632                         { $$ = make_str("all"); }
3633                 | /*EMPTY*/
3634                         { $$ = EMPTY; }
3635                 ;
3636
3637 opt_sort_clause:        sort_clause     { $$ = $1; }
3638                 | /* EMPTY */           { $$ = EMPTY; }
3639                 ;
3640
3641 sort_clause:  ORDER BY sortby_list
3642                         { $$ = cat2_str(make_str("order by"), $3); }
3643                 ;
3644
3645 sortby_list:  sortby                                    { $$ = $1; }
3646                 | sortby_list ',' sortby                { $$ = cat_str(3, $1, make_str(","), $3); }
3647                 ;
3648
3649 sortby: a_expr USING qual_all_Op opt_nulls_order
3650                         { $$ = cat_str(4, $1, make_str("using"), $3, $4); }
3651                 | a_expr opt_asc_desc opt_nulls_order
3652                         { $$ = cat_str(3, $1, $2, $3); }
3653                 ;
3654
3655 select_limit:   LIMIT select_limit_value OFFSET select_offset_value
3656                    { $$ = cat_str(4, make_str("limit"), $2, make_str("offset"), $4); }
3657                 | OFFSET select_offset_value LIMIT select_limit_value
3658                    { $$ = cat_str(4, make_str("offset"), $2, make_str("limit"), $4); }
3659                 | LIMIT select_limit_value
3660                    { $$ = cat2_str(make_str("limit"), $2); }
3661                 | OFFSET select_offset_value
3662                    { $$ = cat2_str(make_str("offset"), $2); }
3663                 | LIMIT select_limit_value ',' select_offset_value
3664                    { mmerror(PARSE_ERROR, ET_WARNING, "No longer supported LIMIT #,# syntax passed to backend."); }
3665                 ;
3666
3667 opt_select_limit:       select_limit    { $$ = $1; }
3668                 | /*EMPTY*/                                     { $$ = EMPTY; }
3669                 ;
3670
3671 select_limit_value: a_expr      { $$ = $1; }
3672                 | ALL           { $$ = make_str("all"); }
3673                 ;
3674
3675 select_offset_value: a_expr { $$ = $1; }
3676                 ;
3677
3678 /*
3679  *      jimmy bell-style recursive queries aren't supported in the
3680  *      current system.
3681  *
3682  *      ...however, recursive addattr and rename supported.  make special
3683  *      cases for these.
3684  */
3685 group_clause:  GROUP_P BY expr_list
3686                         { $$ = cat2_str(make_str("group by"), $3); }
3687                 | /*EMPTY*/
3688                         { $$ = EMPTY; }
3689                 ;
3690
3691 having_clause:  HAVING a_expr
3692                         { $$ = cat2_str(make_str("having"), $2); }
3693                 | /*EMPTY*/
3694                         { $$ = EMPTY; }
3695                 ;
3696
3697 for_locking_clause:
3698                 for_locking_items       { $$ = $1; }
3699                 | FOR READ ONLY         { $$ = make_str("for read only");}
3700                 ;
3701
3702 opt_for_locking_clause: 
3703                 for_locking_clause      { $$ = $1; }
3704                 | /* EMPTY */           { $$ = EMPTY; }
3705                 ;
3706
3707 for_locking_items:
3708                 for_locking_item                        { $$ = $1; }
3709                 | for_locking_items for_locking_item    { $$ = cat2_str($1, $2); }
3710                 ;
3711
3712 for_locking_item:
3713                 FOR UPDATE locked_rels_list opt_nowait
3714                         { $$ = cat_str(3, make_str("for update"), $3, $4); }
3715                 | FOR SHARE locked_rels_list opt_nowait
3716                         { $$ = cat_str(3, make_str("for share"), $3, $4); }
3717                 ;
3718
3719 locked_rels_list:
3720                 OF name_list            { $$ = cat2_str(make_str("of"), $2); }
3721                 | /* EMPTY */           { $$ = EMPTY; }
3722                 ;
3723
3724 values_clause:  VALUES ctext_row
3725                         { $$ = cat2_str(make_str("values"), $2); }
3726                 | values_clause ',' ctext_row
3727                         { $$ = cat_str(3, $1, make_str(","), $3); }
3728                 ;
3729
3730 /*****************************************************************************
3731  *
3732  *      clauses common to all Optimizable Stmts:
3733  *              from_clause - allow list of both JOIN expressions and table names
3734  *              where_clause    - qualifications for joins or restrictions
3735  *
3736  *****************************************************************************/
3737
3738 from_clause:    FROM from_list          { $$ = cat2_str(make_str("from"), $2); }
3739                 | /* EMPTY */                           { $$ = EMPTY; }
3740                 ;
3741
3742 from_list:      from_list ',' table_ref { $$ = cat_str(3, $1, make_str(","), $3); }
3743                 | table_ref                                     { $$ = $1; }
3744                 ;
3745
3746 /*
3747  * table_ref is where an alias clause can be attached.  Note we cannot make
3748  * alias_clause have an empty production because that causes parse conflicts
3749  * between table_ref := '(' joined_table ')' alias_clause
3750  * and joined_table := '(' joined_table ')'.  So, we must have the
3751  * redundant-looking productions here instead.
3752  */
3753 table_ref:      relation_expr
3754                         { $$ = $1; }
3755                 | relation_expr alias_clause
3756                         { $$= cat2_str($1, $2); }
3757                 | func_table
3758                         { $$ = $1; }
3759                 | func_table alias_clause
3760                 { $$= cat2_str($1, $2); }
3761                 | func_table AS '(' TableFuncElementList ')'
3762                         { $$=cat_str(4, $1, make_str("as ("), $4, make_str(")")); }
3763                 | func_table AS ColId '(' TableFuncElementList ')'
3764                         { $$=cat_str(6, $1, make_str("as"), $3, make_str("("), $5, make_str(")"));}
3765                 | func_table ColId '(' TableFuncElementList ')'
3766                         { $$=cat_str(5, $1, $2, make_str("("), $4, make_str(")")); }
3767                 | select_with_parens
3768                         {mmerror(PARSE_ERROR, ET_ERROR, "sub-SELECT in FROM must have an alias");}
3769                 | select_with_parens alias_clause
3770                         { $$=cat2_str($1, $2); }
3771                 | joined_table
3772                         { $$ = $1; }
3773                 | '(' joined_table ')' alias_clause
3774                         { $$=cat_str(4, make_str("("), $2, make_str(")"), $4); }
3775                 ;
3776
3777 /*
3778  * It may seem silly to separate joined_table from table_ref, but there is
3779  * method in SQL92's madness: if you don't do it this way you get reduce-
3780  * reduce conflicts, because it's not clear to the parser generator whether
3781  * to expect alias_clause after ')' or not.  For the same reason we must
3782  * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing
3783  * join_type to expand to empty; if we try it, the parser generator can't
3784  * figure out when to reduce an empty join_type right after table_ref.
3785  *
3786  * Note that a CROSS JOIN is the same as an unqualified
3787  * INNER JOIN, and an INNER JOIN/ON has the same shape
3788  * but a qualification expression to limit membership.
3789  * A NATURAL JOIN implicitly matches column names between
3790  * tables and the shape is determined by which columns are
3791  * in common. We'll collect columns during the later transformations.
3792  */
3793
3794 joined_table:  '(' joined_table ')'
3795                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3796                 | table_ref CROSS JOIN table_ref
3797                         { $$ = cat_str(3, $1, make_str("cross join"), $4); }
3798                 | table_ref join_type JOIN table_ref join_qual
3799                         { $$ = cat_str(5, $1, $2, make_str("join"), $4, $5); }
3800                 | table_ref JOIN table_ref join_qual
3801                         { $$ = cat_str(4, $1, make_str("join"), $3, $4); }
3802                 | table_ref NATURAL join_type JOIN table_ref
3803                         { $$ = cat_str(5, $1, make_str("natural"), $3, make_str("join"), $5); }
3804                 | table_ref NATURAL JOIN table_ref
3805                         { $$ = cat_str(3, $1, make_str("natural join"), $4); }
3806                 ;
3807
3808 alias_clause:  AS ColId '(' name_list ')'
3809                         { $$ = cat_str(5, make_str("as"), $2, make_str("("), $4, make_str(")")); }
3810                 | AS ColId
3811                         { $$ = cat2_str(make_str("as"), $2); }
3812                 | ColId '(' name_list ')'
3813                         { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
3814                 | ColId
3815                         { $$ = $1; }
3816                 ;
3817
3818 join_type:      FULL join_outer         { $$ = cat2_str(make_str("full"), $2); }
3819                 | LEFT join_outer               { $$ = cat2_str(make_str("left"), $2); }
3820                 | RIGHT join_outer              { $$ = cat2_str(make_str("right"), $2); }
3821                 | INNER_P                               { $$ = make_str("inner"); }
3822                 ;
3823
3824 /* OUTER is just noise... */
3825 join_outer:  OUTER_P                    { $$ = make_str("outer"); }
3826                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3827                 ;
3828
3829 /* JOIN qualification clauses
3830  * Possibilities are:
3831  *      USING ( column list ) allows only unqualified column names,
3832  *                                                which must match between tables.
3833  *      ON expr allows more general qualifications.
3834  */
3835
3836 join_qual:      USING '(' name_list ')'
3837                         { $$ = cat_str(3, make_str("using ("), $3, make_str(")")); }
3838                 | ON a_expr
3839                         { $$ = cat2_str(make_str("on"), $2); }
3840                 ;
3841
3842 relation_expr:  qualified_name
3843                         { /* normal relations */ $$ = $1; }
3844                 | qualified_name '*'
3845                         { /* inheritance query */ $$ = cat2_str($1, make_str("*")); }
3846                 | ONLY qualified_name
3847                         { /* inheritance query */ $$ = cat2_str(make_str("only "), $2); }
3848                 | ONLY '(' qualified_name ')'
3849                         { /* inheritance query */ $$ = cat_str(3, make_str("only ("), $3, make_str(")")); }
3850                 ;
3851
3852 relation_expr_opt_alias: relation_expr                                 %prec UMINUS
3853                 { $$ = $1; }
3854                 | relation_expr ColId
3855                 { $$ = cat2_str($1, $2); }
3856                 | relation_expr AS ColId
3857                 { $$ = cat_str(3, $1, make_str("as"), $3); }
3858                 ;
3859
3860 func_table:  func_expr  { $$ = $1; }
3861                 ;
3862
3863 where_clause:  WHERE a_expr             { $$ = cat2_str(make_str("where"), $2); }
3864                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3865                 ;
3866
3867 where_or_current_clause:  WHERE a_expr                  { $$ = cat2_str(make_str("where"), $2); }
3868                 | WHERE CURRENT_P OF name               { $$ = cat2_str(make_str("where current of"), $4); }
3869                 | WHERE CURRENT_P OF PARAM              { $$ = make_str("where current of param"); }
3870                 | /*EMPTY*/                             { $$ = EMPTY;  /* no qualifiers */ }
3871                 ;
3872
3873 TableFuncElementList: TableFuncElement
3874                         { $$ = $1; }
3875                 | TableFuncElementList ',' TableFuncElement
3876                         { $$ = cat_str(3, $1, make_str(","), $3); }
3877                 ;
3878
3879 TableFuncElement:       ColId Typename  { $$ = cat2_str($1, $2); }
3880                 ;
3881
3882 /*****************************************************************************
3883  *
3884  *      Type syntax
3885  *              SQL92 introduces a large amount of type-specific syntax.
3886  *              Define individual clauses to handle these cases, and use
3887  *               the generic case to handle regular type-extensible Postgres syntax.
3888  *              - thomas 1997-10-10
3889  *
3890  *****************************************************************************/
3891
3892 Typename:  SimpleTypename opt_array_bounds
3893                         { $$ = cat2_str($1, $2.str); }
3894                 | SETOF SimpleTypename opt_array_bounds
3895                         { $$ = cat_str(3, make_str("setof"), $2, $3); }
3896                 | SimpleTypename ARRAY '[' PosIntConst ']'
3897                         { $$ = cat_str(4, $1, make_str("array ["), $4, make_str("]")); }
3898                 | SETOF SimpleTypename ARRAY '[' PosIntConst ']'
3899                         { $$ = cat_str(5, make_str("setof"), $2, make_str("array ["), $5, make_str("]")); }
3900                 ;
3901
3902
3903 opt_array_bounds:  '[' ']' opt_array_bounds
3904                 {
3905                         $$.index1 = make_str("0");
3906                         $$.index2 = $3.index1;
3907                         $$.str = cat2_str(make_str("[]"), $3.str);
3908                 }
3909                 | '[' Iresult ']' opt_array_bounds
3910                 {
3911                         $$.index1 = strdup($2);
3912                         $$.index2 = $4.index1;
3913                         $$.str = cat_str(4, make_str("["), $2, make_str("]"), $4.str);
3914                 }
3915                 | /* EMPTY */
3916                 {
3917                         $$.index1 = make_str("-1");
3918                         $$.index2 = make_str("-1");
3919                         $$.str= EMPTY;
3920                 }
3921                 ;
3922
3923 Iresult:        PosIntConst             { $$ = $1; }
3924                 | '(' Iresult ')'       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3925                 | Iresult '+' Iresult   { $$ = cat_str(3, $1, make_str("+"), $3); }
3926                 | Iresult '-' Iresult   { $$ = cat_str(3, $1, make_str("-"), $3); }
3927                 | Iresult '*' Iresult   { $$ = cat_str(3, $1, make_str("*"), $3); }
3928                 | Iresult '/' Iresult   { $$ = cat_str(3, $1, make_str("/"), $3); }
3929                 | Iresult '%' Iresult   { $$ = cat_str(3, $1, make_str("%"), $3); }
3930                 | Sconst                { $$ = $1; }
3931                 | ColId                 { $$ = $1; }
3932                 ;
3933
3934 SimpleTypename:  GenericType            { $$ = $1; }
3935                 | ConstDatetime         { $$ = $1; }
3936                 | Numeric               { $$ = $1; }
3937                 | Bit                   { $$ = $1; }
3938                 | Character             { $$ = $1; }
3939                 | ConstInterval opt_interval
3940                         { $$ = cat2_str($1, $2); }
3941                 | ConstInterval '(' PosIntConst ')' opt_interval
3942                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
3943                 ;
3944
3945 ConstTypename:  Numeric                 { $$ = $1; }
3946                 | ConstBit              { $$ = $1; }
3947                 | ConstCharacter        { $$ = $1; }
3948                 | ConstDatetime         { $$ = $1; }
3949                 ;
3950
3951 GenericType:    type_function_name opt_type_modifiers           { $$ = cat2_str($1, $2); }
3952                 | type_function_name attrs opt_type_modifiers   { $$ = cat_str(3, $1, $2, $3); }
3953                 ;
3954
3955 opt_type_modifiers: '(' expr_list ')'   { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3956                 | /* EMPTY */           { $$ = EMPTY; }
3957                 ;
3958                 
3959 /* SQL92 numeric data types
3960  * Check FLOAT() precision limits assuming IEEE floating types.
3961  * Provide real DECIMAL() and NUMERIC() implementations now - Jan 1998-12-30
3962  * - thomas 1997-09-18
3963  */
3964 Numeric:  INT_P
3965                         { $$ = make_str("int"); }
3966                 | INTEGER
3967                         { $$ = make_str("integer"); }
3968                 | SMALLINT
3969                         { $$ = make_str("smallint"); }
3970                 | BIGINT
3971                         { $$ = make_str("bigint"); }
3972                 | REAL
3973                         { $$ = make_str("real"); }
3974                 | FLOAT_P opt_float
3975                         { $$ = cat2_str(make_str("float"), $2); }
3976                 | DOUBLE_P PRECISION
3977                         { $$ = make_str("double precision"); }
3978                 | DECIMAL_P opt_type_modifiers
3979                         { $$ = cat2_str(make_str("decimal"), $2); }
3980                 | DEC opt_type_modifiers
3981                         { $$ = cat2_str(make_str("dec"), $2); }
3982                 | NUMERIC opt_type_modifiers
3983                         { $$ = cat2_str(make_str("numeric"), $2); }
3984                 | BOOLEAN_P
3985                         { $$ = make_str("boolean"); }
3986                 ;
3987
3988 opt_float:      '(' PosIntConst ')'
3989                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
3990                 | /*EMPTY*/
3991                         { $$ = EMPTY; }
3992                 ;
3993
3994 /*
3995  * SQL92 bit-field data types
3996  * The following implements BIT() and BIT VARYING().
3997  */
3998
3999 Bit:    BitWithLength           { $$ = $1; }
4000                 | BitWithoutLength      { $$ = $1; }
4001                 ;
4002
4003 ConstBit:       BitWithLength   { $$ = $1; }
4004                 | BitWithoutLength      { $$ = $1; }
4005                 ;
4006
4007 BitWithLength:  BIT opt_varying '(' expr_list ')'
4008                         { $$ = cat_str(5, make_str("bit"), $2, make_str("("), $4, make_str(")")); }
4009                 ;
4010
4011 BitWithoutLength: BIT opt_varying
4012                         { $$ = cat2_str(make_str("bit"), $2); }
4013                 ;
4014
4015 /*
4016  * SQL92 character data types
4017  * The following implements CHAR() and VARCHAR().
4018  *                                                              - ay 6/95
4019  */
4020 Character:      CharacterWithLength             { $$ = $1; }
4021                 | CharacterWithoutLength        { $$ = $1; }
4022                 ;
4023
4024 ConstCharacter: CharacterWithLength     { $$ = $1; }
4025                 | CharacterWithoutLength        { $$ = $1; }
4026                 ;
4027
4028 CharacterWithLength: character '(' PosIntConst ')' opt_charset
4029                         { $$ = cat_str(5, $1, make_str("("), $3, make_str(")"), $5); }
4030                 ;
4031
4032 CharacterWithoutLength: character opt_charset
4033                         { $$ = cat2_str($1, $2); }
4034                 ;
4035
4036 character:      CHARACTER opt_varying
4037                         { $$ = cat2_str(make_str("character"), $2); }
4038                 | CHAR_P opt_varying
4039                         { $$ = cat2_str(make_str("char"), $2); }
4040                 | VARCHAR
4041                         { $$ = make_str("varchar"); }
4042                 | NATIONAL CHARACTER opt_varying
4043                         { $$ = cat2_str(make_str("national character"), $3); }
4044                 | NATIONAL CHAR_P opt_varying
4045                         { $$ = cat2_str(make_str("national char"), $3); }
4046                 | NCHAR opt_varying
4047                         { $$ = cat2_str(make_str("nchar"), $2); }
4048                 ;
4049
4050 opt_varying:  VARYING
4051                         { $$ = make_str("varying"); }
4052                 | /*EMPTY*/
4053                         { $$ = EMPTY; }
4054                 ;
4055
4056 opt_charset:  CHARACTER SET ColId
4057                         { $$ = cat2_str(make_str("character set"), $3); }
4058                 | /*EMPTY*/
4059                         { $$ = EMPTY; }
4060                 ;
4061
4062 ConstDatetime:  TIMESTAMP '(' PosIntConst ')' opt_timezone
4063                         { $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5); }
4064                 | TIMESTAMP opt_timezone
4065                         { $$ = cat2_str(make_str("timestamp"), $2); }
4066                 | TIME '(' PosIntConst ')' opt_timezone
4067                         { $$ = cat_str(4, make_str("time("), $3, make_str(")"), $5); }
4068                 | TIME opt_timezone
4069                         { $$ = cat2_str(make_str("time"), $2); }
4070                 ;
4071
4072 ConstInterval:  INTERVAL
4073                         { $$ = make_str("interval"); }
4074                 ;
4075
4076 opt_timezone:  WITH TIME ZONE
4077                         { $$ = make_str("with time zone"); }
4078                 | WITHOUT TIME ZONE
4079                         { $$ = make_str("without time zone"); }
4080                 | /*EMPTY*/
4081                         { $$ = EMPTY; }
4082                 ;
4083
4084 opt_interval:  YEAR_P                   { $$ = make_str("year"); }
4085                 | MONTH_P                               { $$ = make_str("month"); }
4086                 | DAY_P                                 { $$ = make_str("day"); }
4087                 | HOUR_P                                { $$ = make_str("hour"); }
4088                 | MINUTE_P                              { $$ = make_str("minute"); }
4089                 | SECOND_P                              { $$ = make_str("second"); }
4090                 | YEAR_P TO MONTH_P             { $$ = make_str("year to month"); }
4091                 | DAY_P TO HOUR_P               { $$ = make_str("day to hour"); }
4092                 | DAY_P TO MINUTE_P             { $$ = make_str("day to minute"); }
4093                 | DAY_P TO SECOND_P             { $$ = make_str("day to second"); }
4094                 | HOUR_P TO MINUTE_P    { $$ = make_str("hour to minute"); }
4095                 | MINUTE_P TO SECOND_P  { $$ = make_str("minute to second"); }
4096                 | HOUR_P TO SECOND_P    { $$ = make_str("hour to second"); }
4097                 | /*EMPTY*/                             { $$ = EMPTY; }
4098                 ;
4099
4100
4101 /*****************************************************************************
4102  *
4103  *      expression grammar
4104  *
4105  *****************************************************************************/
4106
4107 /* General expressions
4108  * This is the heart of the expression syntax.
4109  *
4110  * We have two expression types: a_expr is the unrestricted kind, and
4111  * b_expr is a subset that must be used in some places to avoid shift/reduce
4112  * conflicts.  For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
4113  * because that use of AND conflicts with AND as a boolean operator.  So,
4114  * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
4115  *
4116  * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
4117  * always be used by surrounding it with parens.
4118  *
4119  * c_expr is all the productions that are common to a_expr and b_expr;
4120  * it's factored out just to eliminate redundant coding.
4121  */
4122
4123 a_expr:  c_expr
4124                         { $$ = $1; }
4125                 | a_expr TYPECAST Typename
4126                         { $$ = cat_str(3, $1, make_str("::"), $3); }
4127                 | a_expr AT TIME ZONE a_expr
4128                         { $$ = cat_str(3, $1, make_str("at time zone"), $5); }
4129                 /*
4130                  * These operators must be called out explicitly in order to make use
4131                  * of yacc/bison's automatic operator-precedence handling.  All other
4132                  * operator names are handled by the generic productions using "Op",
4133                  * below; and all those operators will have the same precedence.
4134                  *
4135                  * If you add more explicitly-known operators, be sure to add them
4136                  * also to b_expr and to the MathOp list above.
4137                  */
4138                 | '+' a_expr %prec UMINUS
4139                         { $$ = cat2_str(make_str("+"), $2); }
4140                 | '-' a_expr %prec UMINUS
4141                         { $$ = cat2_str(make_str("-"), $2); }
4142                 | a_expr '+' a_expr
4143                         { $$ = cat_str(3, $1, make_str("+"), $3); }
4144                 | a_expr '-' a_expr
4145                         { $$ = cat_str(3, $1, make_str("-"), $3); }
4146                 | a_expr '*' a_expr
4147                         { $$ = cat_str(3, $1, make_str("*"), $3); }
4148                 | a_expr '/' a_expr
4149                         { $$ = cat_str(3, $1, make_str("/"), $3); }
4150                 | a_expr '%' a_expr
4151                         { $$ = cat_str(3, $1, make_str("%"), $3); }
4152                 | a_expr '^' a_expr
4153                         { $$ = cat_str(3, $1, make_str("^"), $3); }
4154                 | a_expr '<' a_expr
4155                         { $$ = cat_str(3, $1, make_str("<"), $3); }
4156                 | a_expr '>' a_expr
4157                         { $$ = cat_str(3, $1, make_str(">"), $3); }
4158                 | a_expr '=' a_expr
4159                         { $$ = cat_str(3, $1, make_str("="), $3); }
4160                 | a_expr qual_Op a_expr         %prec Op
4161                         { $$ = cat_str(3, $1, $2, $3); }
4162                 | qual_Op a_expr                %prec Op
4163                         { $$ = cat2_str($1, $2); }
4164                 | a_expr qual_Op                %prec POSTFIXOP
4165                         { $$ = cat2_str($1, $2); }
4166                 | a_expr AND a_expr
4167                         { $$ = cat_str(3, $1, make_str("and"), $3); }
4168                 | a_expr OR a_expr
4169                         { $$ = cat_str(3, $1, make_str("or"), $3); }
4170                 | NOT a_expr
4171                         { $$ = cat2_str(make_str("not"), $2); }
4172                 | a_expr LIKE a_expr
4173                         { $$ = cat_str(3, $1, make_str("like"), $3); }
4174                 | a_expr LIKE a_expr ESCAPE a_expr
4175                         { $$ = cat_str(5, $1, make_str("like"), $3, make_str("escape"), $5); }
4176                 | a_expr NOT LIKE a_expr
4177                         { $$ = cat_str(3, $1, make_str("not like"), $4); }
4178                 | a_expr NOT LIKE a_expr ESCAPE a_expr
4179                         { $$ = cat_str(5, $1, make_str("not like"), $4, make_str("escape"), $6); }
4180                 | a_expr ILIKE a_expr
4181                         { $$ = cat_str(3, $1, make_str("ilike"), $3); }
4182                 | a_expr ILIKE a_expr ESCAPE a_expr
4183                         { $$ = cat_str(5, $1, make_str("ilike"), $3, make_str("escape"), $5); }
4184                 | a_expr NOT ILIKE a_expr
4185                         { $$ = cat_str(3, $1, make_str("not ilike"), $4); }
4186                 | a_expr NOT ILIKE a_expr ESCAPE a_expr
4187                         { $$ = cat_str(5, $1, make_str("not ilike"), $4, make_str("escape"), $6); }
4188                 | a_expr SIMILAR TO a_expr      %prec SIMILAR
4189                         { $$ = cat_str(3, $1, make_str("similar to"), $4); }
4190                 | a_expr SIMILAR TO a_expr ESCAPE a_expr
4191                         { $$ = cat_str(5, $1, make_str("similar to"), $4, make_str("escape"), $6); }
4192                 | a_expr NOT SIMILAR TO a_expr  %prec SIMILAR
4193                         { $$ = cat_str(3, $1, make_str("not similar to"), $5); }
4194                 | a_expr NOT SIMILAR TO a_expr ESCAPE a_expr
4195                         { $$ = cat_str(5, $1, make_str("not similar to"), $5, make_str("escape"), $7); }
4196                 | a_expr ISNULL
4197                         { $$ = cat2_str($1, make_str("isnull")); }
4198                 | a_expr IS NULL_P
4199                         { $$ = cat2_str($1, make_str("is null")); }
4200                 | a_expr NOTNULL
4201                         { $$ = cat2_str($1, make_str("notnull")); }
4202                 | a_expr IS NOT NULL_P
4203                         { $$ = cat2_str($1, make_str("is not null")); }
4204                 | row OVERLAPS row
4205                         { $$ = cat_str(3, $1, make_str("overlaps"), $3); }
4206                 /* IS TRUE, IS FALSE, etc used to be function calls
4207                  *      but let's make them expressions to allow the optimizer
4208                  *      a chance to eliminate them if a_expr is a constant string.
4209                  * - thomas 1997-12-22
4210                  *
4211                  *      Created BooleanTest Node type, and changed handling
4212                  *      for NULL inputs
4213                  * - jec 2001-06-18
4214                  */
4215                 | a_expr IS TRUE_P
4216                         { $$ = cat2_str($1, make_str("is true")); }
4217                 | a_expr IS NOT TRUE_P
4218                         { $$ = cat2_str($1, make_str("is not true")); }
4219                 | a_expr IS FALSE_P
4220                         { $$ = cat2_str($1, make_str("is false")); }
4221                 | a_expr IS NOT FALSE_P
4222                         { $$ = cat2_str($1, make_str("is not false")); }
4223                 | a_expr IS UNKNOWN
4224                         { $$ = cat2_str($1, make_str("is unknown")); }
4225                 | a_expr IS NOT UNKNOWN
4226                         { $$ = cat2_str($1, make_str("is not unknown")); }
4227                 | a_expr IS DISTINCT FROM a_expr %prec IS
4228                         { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
4229                 | a_expr IS NOT DISTINCT FROM a_expr %prec IS
4230                         { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
4231                 | a_expr IS OF '(' type_list ')' %prec IS
4232                         { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
4233                 | a_expr IS NOT OF '(' type_list ')' %prec IS
4234                         { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
4235                 | a_expr BETWEEN opt_asymmetric b_expr AND b_expr       %prec BETWEEN
4236                         { $$ = cat_str(6, $1, make_str("between"), $3, $4, make_str("and"), $6); }
4237                 | a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr   %prec BETWEEN
4238                         { $$ = cat_str(6, $1, make_str("not between"), $4, $5, make_str("and"), $7); }
4239                 | a_expr BETWEEN SYMMETRIC b_expr AND b_expr    %prec BETWEEN
4240                         { $$ = cat_str(5, $1, make_str("between symmetric"), $4, make_str("and"), $6); }
4241                 | a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr        %prec BETWEEN
4242                         { $$ = cat_str(5, $1, make_str("not between symmetric"), $5, make_str("and"), $7); }
4243                 | a_expr IN_P in_expr
4244                         { $$ = cat_str(3, $1, make_str("in"), $3); }
4245                 | a_expr NOT IN_P in_expr
4246                         { $$ = cat_str(3, $1, make_str("not in"), $4); }
4247                 | a_expr subquery_Op sub_type select_with_parens %prec Op
4248                         { $$ = cat_str(4, $1, $2, $3, $4); }
4249                 | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
4250                         { $$ = cat_str(6, $1, $2, $3, make_str("("), $5, make_str(")")); }
4251                 | UNIQUE select_with_parens 
4252                         { $$ = cat2_str(make_str("unique"), $2); }
4253                 | a_expr IS DOCUMENT_P
4254                         { $$ = cat2_str($1, make_str("is document")); }
4255                 | a_expr IS NOT DOCUMENT_P
4256                         { $$ = cat2_str($1, make_str("is not document")); }
4257                 ;
4258
4259 /* Restricted expressions
4260  *
4261  * b_expr is a subset of the complete expression syntax
4262  *
4263  * Presently, AND, NOT, IS and IN are the a_expr keywords that would
4264  * cause trouble in the places where b_expr is used.  For simplicity, we
4265  * just eliminate all the boolean-keyword-operator productions from b_expr.
4266  */
4267 b_expr:  c_expr
4268                         { $$ = $1; }
4269                 | b_expr TYPECAST Typename
4270                         { $$ = cat_str(3, $1, make_str("::"), $3); }
4271                 | '-' b_expr %prec UMINUS
4272                         { $$ = cat2_str(make_str("-"), $2); }
4273                 | b_expr '+' b_expr
4274                         { $$ = cat_str(3, $1, make_str("+"), $3); }
4275                 | b_expr '-' b_expr
4276                         { $$ = cat_str(3, $1, make_str("-"), $3); }
4277                 | b_expr '*' b_expr
4278                         { $$ = cat_str(3, $1, make_str("*"), $3); }
4279                 | b_expr '/' b_expr
4280                         { $$ = cat_str(3, $1, make_str("/"), $3); }
4281                 | b_expr '%' b_expr
4282                         { $$ = cat_str(3, $1, make_str("%"), $3); }
4283                 | b_expr '^' b_expr
4284                         { $$ = cat_str(3, $1, make_str("^"), $3); }
4285                 | b_expr '<' b_expr
4286                         { $$ = cat_str(3, $1, make_str("<"), $3); }
4287                 | b_expr '>' b_expr
4288                         { $$ = cat_str(3, $1, make_str(">"), $3); }
4289                 | b_expr '=' b_expr
4290                         { $$ = cat_str(3, $1, make_str("="), $3); }
4291                 | b_expr Op b_expr
4292                         { $$ = cat_str(3, $1, $2, $3); }
4293                 | qual_Op b_expr                %prec Op
4294                         { $$ = cat2_str($1, $2); }
4295                 | b_expr qual_Op                %prec POSTFIXOP
4296                         { $$ = cat2_str($1, $2); }
4297                 | b_expr IS DISTINCT FROM b_expr %prec IS
4298                         { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
4299                 | b_expr IS NOT DISTINCT FROM b_expr %prec IS
4300                         { $$ = cat_str(3, $1, make_str("is not distinct from"), $6); }
4301                 | b_expr IS OF '(' b_expr ')' %prec IS
4302                         { $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
4303                 | b_expr IS NOT OF '(' b_expr ')' %prec IS
4304                         { $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
4305                 | b_expr IS DOCUMENT_P
4306                         { $$ = cat2_str($1, make_str("is document")); }
4307                 | b_expr IS NOT DOCUMENT_P
4308                         { $$ = cat2_str($1, make_str("is not document")); }
4309                 ;
4310
4311 /*
4312  * Productions that can be used in both a_expr and b_expr.
4313  *
4314  * Note: productions that refer recursively to a_expr or b_expr mostly
4315  * cannot appear here.  However, it's OK to refer to a_exprs that occur
4316  * inside parentheses, such as function arguments; that cannot introduce
4317  * ambiguity to the b_expr syntax.
4318  */
4319 c_expr: columnref
4320                         { $$ = $1;      }
4321                 | AexprConst
4322                         { $$ = $1;      }
4323                 | PARAM opt_indirection
4324                         { $$ = cat2_str(make_str("param"), $2); }
4325                 | '(' a_expr ')' opt_indirection
4326                         { $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
4327                 | case_expr
4328                         { $$ = $1; }
4329                 | func_expr
4330                         { $$ = $1; }
4331                 | select_with_parens    %prec UMINUS
4332                         { $$ = $1; }
4333                 | EXISTS select_with_parens
4334                         { $$ = cat2_str(make_str("exists"), $2); }
4335                 | ARRAY select_with_parens
4336                         { $$ = cat2_str(make_str("array"), $2); }
4337                 | ARRAY array_expr
4338                         { $$ = cat2_str(make_str("array"), $2); }
4339                 | row
4340                         { $$ = $1; }
4341                 ;
4342
4343 /*
4344  * func_expr is split out from c_expr just so that we have a classification
4345  * for "everything that is a function call or looks like one".  This isn't
4346  * very important, but it saves us having to document which variants are
4347  * legal in the backwards-compatible functional-index syntax for CREATE INDEX.
4348  * (Note that many of the special SQL functions wouldn't actually make any
4349  * sense as functional index entries, but we ignore that consideration here.)
4350  */
4351 func_expr:      func_name '(' ')'
4352                         { $$ = cat2_str($1, make_str("()"));    }
4353                 | func_name '(' expr_list ')'
4354                         { $$ = cat_str(4, $1, make_str("("), $3, make_str(")"));        }
4355                 | func_name '(' ALL expr_list ')'
4356                         { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")"));    }
4357                 | func_name '(' DISTINCT expr_list ')'
4358                         { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")"));  }
4359                 | func_name '(' '*' ')'
4360                         { $$ = cat2_str($1, make_str("(*)")); }
4361                 | CURRENT_DATE
4362                         { $$ = make_str("current_date"); }
4363                 | CURRENT_TIME
4364                         { $$ = make_str("current_time"); }
4365                 | CURRENT_TIME '(' PosIntConst ')'
4366                         { $$ = cat_str(3, make_str("current_time ("), $3, make_str(")")); }
4367                 | CURRENT_TIMESTAMP
4368                         { $$ = make_str("current_timestamp"); }
4369                 | CURRENT_TIMESTAMP '(' PosIntConst ')'
4370                         { $$ = cat_str(3, make_str("current_timestamp ("), $3, make_str(")")); }
4371                 | LOCALTIME
4372                         { $$ = make_str("localtime"); }
4373                 | LOCALTIME '(' PosIntConst ')'
4374                         { $$ = cat_str(3, make_str("localtime ("), $3, make_str(")")); }
4375                 | LOCALTIMESTAMP
4376                         { $$ = make_str("local_timestamp"); }
4377                 | LOCALTIMESTAMP '(' PosIntConst ')'
4378                         { $$ = cat_str(3, make_str("locale_timestamp ("), $3, make_str(")")); }
4379                 | CURRENT_ROLE
4380                         { $$ = make_str("current_role"); }
4381                 | CURRENT_USER
4382                         { $$ = make_str("current_user"); }
4383                 | SESSION_USER
4384                         { $$ = make_str("session_user"); }
4385                 | USER
4386                         { $$ = make_str("user"); }
4387                 | CAST '(' a_expr AS Typename ')'
4388                         { $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
4389                 | EXTRACT '(' extract_list ')'
4390                         { $$ = cat_str(3, make_str("extract("), $3, make_str(")")); }
4391                 | OVERLAY '(' overlay_list ')'
4392                         { $$ = cat_str(3, make_str("overlay("), $3, make_str(")")); }
4393                 | POSITION '(' position_list ')'
4394                         { $$ = cat_str(3, make_str("position("), $3, make_str(")")); }
4395                 | SUBSTRING '(' substr_list ')'
4396                         { $$ = cat_str(3, make_str("substring("), $3, make_str(")")); }
4397                 | TREAT '(' a_expr AS Typename ')'
4398                         { $$ = cat_str(5, make_str("treat("), $3, make_str("as"), $5, make_str(")")); }
4399                 /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
4400                 | TRIM '(' BOTH trim_list ')'
4401                         { $$ = cat_str(3, make_str("trim(both"), $4, make_str(")")); }
4402                 | TRIM '(' LEADING trim_list ')'
4403                         { $$ = cat_str(3, make_str("trim(leading"), $4, make_str(")")); }
4404                 | TRIM '(' TRAILING trim_list ')'
4405                         { $$ = cat_str(3, make_str("trim(trailing"), $4, make_str(")")); }
4406                 | TRIM '(' trim_list ')'
4407                         { $$ = cat_str(3, make_str("trim("), $3, make_str(")")); }
4408                 | CONVERT '(' a_expr USING any_name ')'
4409                         { $$ = cat_str(5, make_str("convert("), $3, make_str("using"), $5, make_str(")"));}
4410                 | CONVERT '(' expr_list ')'
4411                         { $$ = cat_str(3, make_str("convert("), $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 (strcmp($1, " ?") == 0) /* 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                 | CONVERT               { $$ = make_str("convert"); }
6656                 | DEC                   { $$ = make_str("dec"); }
6657                 | DECIMAL_P             { $$ = make_str("decimal"); }
6658                 | EXISTS                { $$ = make_str("exists"); }
6659                 | EXTRACT               { $$ = make_str("extract"); }
6660                 | FLOAT_P               { $$ = make_str("float"); }
6661                 | GREATEST              { $$ = make_str("greatest"); }
6662                 | INOUT                 { $$ = make_str("inout"); }
6663 /* INT must be excluded from ECPGColLabel because of conflict
6664                 | INT_P                 { $$ = make_str("int"); }
6665  */
6666                 | INTEGER               { $$ = make_str("integer"); }
6667                 | INTERVAL              { $$ = make_str("interval"); }
6668                 | LEAST                 { $$ = make_str("least"); }
6669                 | NATIONAL              { $$ = make_str("national"); }
6670                 | NCHAR                 { $$ = make_str("nchar"); }
6671                 | NONE                  { $$ = make_str("none"); }
6672                 | NULLIF                { $$ = make_str("nullif"); }
6673                 | NUMERIC               { $$ = make_str("numeric"); }
6674                 | OUT_P                 { $$ = make_str("out"); }
6675                 | OVERLAY               { $$ = make_str("overlay"); }
6676                 | POSITION              { $$ = make_str("position"); }
6677                 | PRECISION             { $$ = make_str("precision"); }
6678                 | REAL                  { $$ = make_str("real"); }
6679                 | ROW                   { $$ = make_str("row"); }
6680                 | SETOF                 { $$ = make_str("setof"); }
6681                 | SMALLINT              { $$ = make_str("smallint"); }
6682                 | SUBSTRING             { $$ = make_str("substring"); }
6683                 | TIME                  { $$ = make_str("time"); }
6684                 | TIMESTAMP             { $$ = make_str("timestamp"); }
6685                 | TREAT                 { $$ = make_str("treat"); }
6686                 | TRIM                  { $$ = make_str("trim"); }
6687                 /* VALUES creates a shift/reduce problem if listed here
6688                 | VALUES                { $$ = make_str("values"); } */
6689                 | VARCHAR               { $$ = make_str("varchar"); }
6690                 | XMLATTRIBUTES         { $$ = make_str("xmlattributes"); }
6691                 | XMLCONCAT             { $$ = make_str("xmlconcat"); }
6692                 | XMLELEMENT            { $$ = make_str("xmlelement"); }
6693                 | XMLFOREST             { $$ = make_str("xmlforest"); }
6694                 | XMLPARSE              { $$ = make_str("xmlparse"); }
6695                 | XMLPI                 { $$ = make_str("xmlpi"); }
6696                 | XMLROOT               { $$ = make_str("xmlroot"); }
6697                 | XMLSERIALIZE          { $$ = make_str("xmlserialize"); }
6698                 ;
6699
6700 /* Function identifier --- keywords that can be function names.
6701  *
6702  * Most of these are keywords that are used as operators in expressions;
6703  * in general such keywords can't be column names because they would be
6704  * ambiguous with variables, but they are unambiguous as function identifiers.
6705  *
6706  * Do not include POSITION, SUBSTRING, etc here since they have explicit
6707  * productions in a_expr to support the goofy SQL9x argument syntax.
6708  *      - thomas 2000-11-28
6709  */
6710 type_func_name_keyword:
6711                   AUTHORIZATION         { $$ = make_str("authorization"); }
6712                 | BETWEEN               { $$ = make_str("between"); }
6713                 | BINARY                { $$ = make_str("binary"); }
6714                 | CROSS                 { $$ = make_str("cross"); }
6715                 | FREEZE                { $$ = make_str("freeze"); }
6716                 | FULL                  { $$ = make_str("full"); }
6717                 | ILIKE                 { $$ = make_str("ilike"); }
6718                 | INNER_P               { $$ = make_str("inner"); }
6719                 | IS                    { $$ = make_str("is"); }
6720                 | ISNULL                { $$ = make_str("isnull"); }
6721                 | JOIN                  { $$ = make_str("join"); }
6722                 | LEFT                  { $$ = make_str("left"); }
6723                 | LIKE                  { $$ = make_str("like"); }
6724                 | NATURAL               { $$ = make_str("natural"); }
6725                 | NOTNULL               { $$ = make_str("notnull"); }
6726                 | OUTER_P               { $$ = make_str("outer"); }
6727                 | OVERLAPS              { $$ = make_str("overlaps"); }
6728                 | RIGHT                 { $$ = make_str("right"); }
6729                 | SIMILAR               { $$ = make_str("similar"); }
6730                 | VERBOSE               { $$ = make_str("verbose"); }
6731                 ;
6732
6733 /* Reserved keyword --- these keywords are usable only as a ColLabel.
6734  *
6735  * Keywords appear here if they could not be distinguished from variable,
6736  * type, or function names in some contexts.  Don't put things here unless
6737  * forced to.
6738  */
6739 reserved_keyword:
6740                   ALL                           { $$ = make_str("all"); }
6741                 | ANALYSE                       { $$ = make_str("analyse"); } /* British */
6742                 | ANALYZE                       { $$ = make_str("analyze"); }
6743                 | AND                           { $$ = make_str("and"); }
6744                 | ANY                           { $$ = make_str("any"); }
6745                 | ARRAY                         { $$ = make_str("array"); }
6746                 | AS                            { $$ = make_str("as"); }
6747                 | ASC                           { $$ = make_str("asc"); }
6748                 | ASYMMETRIC            { $$ = make_str("asymmetric"); }
6749                 | BOTH                          { $$ = make_str("both"); }
6750                 | CASE                          { $$ = make_str("case"); }
6751                 | CAST                          { $$ = make_str("cast"); }
6752                 | CHECK                         { $$ = make_str("check"); }
6753                 | COLLATE                       { $$ = make_str("collate"); }
6754                 | COLUMN                        { $$ = make_str("column"); }
6755                 | CONSTRAINT            { $$ = make_str("constraint"); }
6756                 | CREATE                        { $$ = make_str("create"); }
6757                 | CURRENT_P                     { $$ = make_str("current"); }
6758                 | CURRENT_DATE          { $$ = make_str("current_date"); }
6759                 | CURRENT_TIME          { $$ = make_str("current_time"); }
6760                 | CURRENT_TIMESTAMP     { $$ = make_str("current_timestamp"); }
6761                 | CURRENT_ROLE          { $$ = make_str("current_role"); }
6762                 | CURRENT_USER          { $$ = make_str("current_user"); }
6763                 | DEFAULT                       { $$ = make_str("default"); }
6764                 | DEFERRABLE            { $$ = make_str("deferrable"); }
6765                 | DESC                          { $$ = make_str("desc"); }
6766                 | DISTINCT                      { $$ = make_str("distinct"); }
6767                 | DO                            { $$ = make_str("do"); }
6768                 | ELSE                          { $$ = make_str("else"); }
6769                 | END_P                         { $$ = make_str("end"); }
6770                 | EXCEPT                        { $$ = make_str("except"); }
6771                 | FALSE_P                       { $$ = make_str("false"); }
6772                 | FOR                           { $$ = make_str("for"); }
6773                 | FOREIGN                       { $$ = make_str("foreign"); }
6774                 | FROM                          { $$ = make_str("from"); }
6775                 | GRANT                         { $$ = make_str("grant"); }
6776                 | GROUP_P                       { $$ = make_str("group"); }
6777                 | HAVING                        { $$ = make_str("having"); }
6778                 | IN_P                          { $$ = make_str("in"); }
6779                 | INITIALLY                     { $$ = make_str("initially"); }
6780                 | INTERSECT                     { $$ = make_str("intersect"); }
6781                 | INTO                          { $$ = make_str("into"); }
6782                 | LEADING                       { $$ = make_str("leading"); }
6783                 | LIMIT                         { $$ = make_str("limit"); }
6784                 | NEW                           { $$ = make_str("new"); }
6785                 | NOT                           { $$ = make_str("not"); }
6786                 | NULL_P                        { $$ = make_str("null"); }
6787                 | OFF                           { $$ = make_str("off"); }
6788                 | OFFSET                        { $$ = make_str("offset"); }
6789                 | OLD                           { $$ = make_str("old"); }
6790                 | ON                            { $$ = make_str("on"); }
6791                 | ONLY                          { $$ = make_str("only"); }
6792                 | OR                            { $$ = make_str("or"); }
6793                 | ORDER                         { $$ = make_str("order"); }
6794                 | PRIMARY                       { $$ = make_str("primary"); }
6795                 | REFERENCES                    { $$ = make_str("references"); }
6796                 | RETURNING                     { $$ = make_str("returning"); }
6797                 | SELECT                        { $$ = make_str("select"); }
6798                 | SESSION_USER                  { $$ = make_str("session_user"); }
6799                 | SOME                          { $$ = make_str("some"); }
6800                 | SYMMETRIC                     { $$ = make_str("symmetric"); }
6801                 | TABLE                         { $$ = make_str("table"); }
6802                 | THEN                          { $$ = make_str("then"); }
6803 /* TO must be excluded from ECPGColLabel because of a conflict in variable name parsing
6804                 | TO                            { $$ = make_str("to"); }
6805  */
6806                 | TRAILING                      { $$ = make_str("trailing"); }
6807                 | TRUE_P                        { $$ = make_str("true"); }
6808 /* UNION must be excluded from ECPGColLabel because of conflict with s_union
6809                 | UNION                         { $$ = make_str("union"); }
6810  */
6811                 | UNIQUE                        { $$ = make_str("unique"); }
6812                 | USER                          { $$ = make_str("user"); }
6813                 | USING                         { $$ = make_str("using"); }
6814                 | WHEN                          { $$ = make_str("when"); }
6815                 | WHERE                         { $$ = make_str("where"); }
6816                 ;
6817
6818
6819 into_list : coutputvariable | into_list ',' coutputvariable
6820                 ;
6821
6822 ecpgstart: SQL_START    {
6823                                 reset_variables();
6824                                 pacounter = 1;
6825                         }
6826                 ;
6827
6828 c_args: /*EMPTY*/               { $$ = EMPTY; }
6829                 | c_list                { $$ = $1; }
6830                 ;
6831
6832 coutputvariable: cvariable indicator
6833                         { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
6834                 | cvariable
6835                         { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
6836                 ;
6837
6838
6839 civarind: cvariable indicator
6840                 {
6841                         if (find_variable($2)->type->type == ECPGt_array)
6842                                 mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
6843
6844                         add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
6845                         $$ = create_questionmarks($1, false);
6846                 }
6847                 ;
6848
6849 civar: cvariable
6850                 {
6851                         add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
6852                         $$ = create_questionmarks($1, false);
6853                 }
6854                 ;
6855
6856 indicator: cvariable                            { check_indicator((find_variable($1))->type); $$ = $1; }
6857                 | SQL_INDICATOR cvariable       { check_indicator((find_variable($2))->type); $$ = $2; }
6858                 | SQL_INDICATOR name            { check_indicator((find_variable($2))->type); $$ = $2; }
6859                 ;
6860
6861 cvariable:      CVARIABLE
6862                 {
6863                         /* As long as multidimensional arrays are not implemented we have to check for those here */
6864                         char *ptr = $1;
6865                         int brace_open=0, brace = false;
6866
6867                         for (; *ptr; ptr++)
6868                         {
6869                                 switch (*ptr)
6870                                 {
6871                                         case '[':
6872                                                         if (brace)
6873                                                                 mmerror(PARSE_ERROR, ET_FATAL, "No multidimensional array support for simple data types");
6874                                                         brace_open++;
6875                                                         break;
6876                                         case ']':
6877                                                         brace_open--;
6878                                                         if (brace_open == 0)
6879                                                                 brace = true;
6880                                                         break;
6881                                         case '\t':
6882                                         case ' ':
6883                                                         break;
6884                                         default:
6885                                                         if (brace_open == 0)
6886                                                                 brace = false;
6887                                                         break;
6888                                 }
6889                         }
6890                         $$ = $1;
6891                 }
6892                 ;
6893 ident: IDENT                            { $$ = $1; }
6894                 | CSTRING               { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6895                 ;
6896
6897 quoted_ident_stringvar: name
6898                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6899                 | char_variable
6900                         { $$ = make3_str(make_str("("), $1, make_str(")")); }
6901                 ;
6902
6903 /*
6904  * C stuff
6905  */
6906
6907 c_stuff_item: c_anything                        { $$ = $1; }
6908                 | '(' ')'                       { $$ = make_str("()"); }
6909                 | '(' c_stuff ')'
6910                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
6911                 ;
6912
6913 c_stuff: c_stuff_item                   { $$ = $1; }
6914                 | c_stuff c_stuff_item
6915                         { $$ = cat2_str($1, $2); }
6916                 ;
6917
6918 c_list: c_term                          { $$ = $1; }
6919                 | c_list ',' c_term     { $$ = cat_str(3, $1, make_str(","), $3); }
6920                 ;
6921
6922 c_term:  c_stuff                        { $$ = $1; }
6923                 | '{' c_list '}'        { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
6924                 ;
6925
6926 c_thing:        c_anything              { $$ = $1; }
6927                 |       '('             { $$ = make_str("("); }
6928                 |       ')'             { $$ = make_str(")"); }
6929                 |       ','             { $$ = make_str(","); }
6930                 |       ';'             { $$ = make_str(";"); }
6931                 ;
6932
6933 c_anything:  IDENT                              { $$ = $1; }
6934                 | CSTRING                       { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
6935                 | Iconst                        { $$ = $1; }
6936                 | Fconst                        { $$ = $1; }
6937                 | Sconst                        { $$ = $1; }
6938                 | '*'                           { $$ = make_str("*"); }
6939                 | '+'                           { $$ = make_str("+"); }
6940                 | '-'                           { $$ = make_str("-"); }
6941                 | '/'                           { $$ = make_str("/"); }
6942                 | '%'                           { $$ = make_str("%"); }
6943                 | NULL_P                        { $$ = make_str("NULL"); }
6944                 | S_ADD                         { $$ = make_str("+="); }
6945                 | S_AND                         { $$ = make_str("&&"); }
6946                 | S_ANYTHING                    { $$ = make_name(); }
6947                 | S_AUTO                        { $$ = make_str("auto"); }
6948                 | S_CONST                       { $$ = make_str("const"); }
6949                 | S_DEC                         { $$ = make_str("--"); }
6950                 | S_DIV                         { $$ = make_str("/="); }
6951                 | S_DOTPOINT                    { $$ = make_str(".*"); }
6952                 | S_EQUAL                       { $$ = make_str("=="); }
6953                 | S_EXTERN                      { $$ = make_str("extern"); }
6954                 | S_INC                         { $$ = make_str("++"); }
6955                 | S_LSHIFT                      { $$ = make_str("<<"); }
6956                 | S_MEMBER                      { $$ = make_str("->"); }
6957                 | S_MEMPOINT                    { $$ = make_str("->*"); }
6958                 | S_MOD                         { $$ = make_str("%="); }
6959                 | S_MUL                         { $$ = make_str("*="); }
6960                 | S_NEQUAL                      { $$ = make_str("!="); }
6961                 | S_OR                          { $$ = make_str("||"); }
6962                 | S_REGISTER                    { $$ = make_str("register"); }
6963                 | S_RSHIFT                      { $$ = make_str(">>"); }
6964                 | S_STATIC                      { $$ = make_str("static"); }
6965                 | S_SUB                         { $$ = make_str("-="); }
6966                 | S_TYPEDEF                     { $$ = make_str("typedef"); }
6967                 | S_VOLATILE                    { $$ = make_str("volatile"); }
6968                 | SQL_BOOL                      { $$ = make_str("bool"); }
6969                 | ENUM_P                        { $$ = make_str("enum"); }
6970                 | HOUR_P                        { $$ = make_str("hour"); }
6971                 | INT_P                         { $$ = make_str("int"); }
6972                 | SQL_LONG                      { $$ = make_str("long"); }
6973                 | MINUTE_P                      { $$ = make_str("minute"); }
6974                 | MONTH_P                       { $$ = make_str("month"); }
6975                 | SECOND_P                      { $$ = make_str("second"); }
6976                 | SQL_SHORT                     { $$ = make_str("short"); }
6977                 | SQL_SIGNED                    { $$ = make_str("signed"); }
6978                 | SQL_STRUCT                    { $$ = make_str("struct"); }
6979                 | SQL_UNSIGNED                  { $$ = make_str("unsigned"); }
6980                 | YEAR_P                        { $$ = make_str("year"); }
6981                 | CHAR_P                        { $$ = make_str("char"); }
6982                 | FLOAT_P                       { $$ = make_str("float"); }
6983                 | TO                            { $$ = make_str("to"); }
6984                 | UNION                         { $$ = make_str("union"); }
6985                 | VARCHAR                       { $$ = make_str("varchar"); }
6986                 | '['                           { $$ = make_str("["); }
6987                 | ']'                           { $$ = make_str("]"); }
6988                 | '='                           { $$ = make_str("="); }
6989                 | ':'                           { $$ = make_str(":"); }
6990                 ;
6991
6992 %%
6993
6994 void base_yyerror(const char * error)
6995 {
6996         char buf[1024];
6997
6998         snprintf(buf,sizeof buf,"%s at or near \"%s\"", error, token_start ? token_start : yytext);
6999         buf[sizeof(buf)-1]=0;
7000         mmerror(PARSE_ERROR, ET_ERROR, buf);
7001 }
7002
7003 void parser_init(void)
7004 {
7005  /* This function is empty. It only exists for compatibility with the backend parser right now. */
7006 }
7007
7008 /*
7009  * Must undefine base_yylex before including pgc.c, since we want it
7010  * to create the function base_yylex not filtered_base_yylex.
7011  */
7012 #undef base_yylex
7013
7014 #include "pgc.c"