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