~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/interfaces/ecpg/preproc/preproc.y

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

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