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