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