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