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