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