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