1
/* src/interfaces/ecpg/preproc/ecpg.trailer */
7
statement: ecpgstart at stmt ';' { connection = NULL; }
9
| ecpgstart ECPGVarDeclaration
11
fprintf(yyout, "%s", $2);
16
| c_thing { fprintf(yyout, "%s", $1); free($1); }
17
| CPP_LINE { fprintf(yyout, "%s", $1); free($1); }
18
| '{' { braces_open++; fputs("{", yyout); }
21
remove_typedefs(braces_open);
22
remove_variables(braces_open--);
25
free(current_function);
26
current_function = NULL;
32
CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data
35
mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO");
37
$$ = cat_str(6, mm_strdup("create"), $2, mm_strdup("table"), $4, mm_strdup("as"), $7);
41
at: AT connection_object
45
* Do we have a variable as connection target?
46
* Remove the variable from the variable
47
* list or else it will be used twice
49
if (argsinsert != NULL)
55
* the exec sql connect statement: connect to the given database
57
ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
58
{ $$ = cat_str(5, $3, mm_strdup(","), $5, mm_strdup(","), $4); }
59
| SQL_CONNECT TO DEFAULT
60
{ $$ = mm_strdup("NULL, NULL, NULL, \"DEFAULT\""); }
61
/* also allow ORACLE syntax */
62
| SQL_CONNECT ora_user
63
{ $$ = cat_str(3, mm_strdup("NULL,"), $2, mm_strdup(", NULL")); }
64
| DATABASE connection_target
65
{ $$ = cat2_str($2, mm_strdup(", NULL, NULL, NULL")); }
68
connection_target: opt_database_name opt_server opt_port
70
/* old style: dbname[@server][:port] */
71
if (strlen($2) > 0 && *($2) != '@')
72
mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\", found \"%s\"", $2);
74
/* C strings need to be handled differently */
78
$$ = make3_str(mm_strdup("\""), make3_str($1, $2, $3), mm_strdup("\""));
80
| db_prefix ':' server opt_port '/' opt_database_name opt_options
82
/* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
83
if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
84
mmerror(PARSE_ERROR, ET_ERROR, "only protocols \"tcp\" and \"unix\" and database type \"postgresql\" are supported");
86
if (strncmp($3, "//", strlen("//")) != 0)
87
mmerror(PARSE_ERROR, ET_ERROR, "expected \"://\", found \"%s\"", $3);
89
if (strncmp($1, "unix", strlen("unix")) == 0 &&
90
strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
91
strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
92
mmerror(PARSE_ERROR, ET_ERROR, "Unix-domain sockets only work on \"localhost\" but not on \"%s\"", $3 + strlen("//"));
94
$$ = make3_str(make3_str(mm_strdup("\""), $1, mm_strdup(":")), $3, make3_str(make3_str($4, mm_strdup("/"), $6), $7, mm_strdup("\"")));
102
/* We can only process double quoted strings not single quotes ones,
103
* so we change the quotes.
104
* Note, that the rule for ecpg_sconst adds these single quotes. */
106
$1[strlen($1)-1] = '\"';
111
opt_database_name: database_name { $$ = $1; }
112
| /*EMPTY*/ { $$ = EMPTY; }
115
db_prefix: ecpg_ident cvariable
117
if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
118
mmerror(PARSE_ERROR, ET_ERROR, "expected \"postgresql\", found \"%s\"", $2);
120
if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
121
mmerror(PARSE_ERROR, ET_ERROR, "invalid connection type: %s", $1);
123
$$ = make3_str($1, mm_strdup(":"), $2);
127
server: Op server_name
129
if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
130
mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\" or \"://\", found \"%s\"", $1);
132
$$ = make2_str($1, $2);
136
opt_server: server { $$ = $1; }
137
| /*EMPTY*/ { $$ = EMPTY; }
140
server_name: ColId { $$ = $1; }
141
| ColId '.' server_name { $$ = make3_str($1, mm_strdup("."), $3); }
142
| IP { $$ = make_name(); }
145
opt_port: ':' Iconst { $$ = make2_str(mm_strdup(":"), $2); }
146
| /*EMPTY*/ { $$ = EMPTY; }
149
opt_connection_name: AS connection_object { $$ = $2; }
150
| /*EMPTY*/ { $$ = mm_strdup("NULL"); }
153
opt_user: USER ora_user { $$ = $2; }
154
| /*EMPTY*/ { $$ = mm_strdup("NULL, NULL"); }
158
{ $$ = cat2_str($1, mm_strdup(", NULL")); }
159
| user_name '/' user_name
160
{ $$ = cat_str(3, $1, mm_strdup(","), $3); }
161
| user_name SQL_IDENTIFIED BY user_name
162
{ $$ = cat_str(3, $1, mm_strdup(","), $4); }
163
| user_name USING user_name
164
{ $$ = cat_str(3, $1, mm_strdup(","), $3); }
172
$$ = make3_str(mm_strdup("\""), $1, mm_strdup("\""));
179
$$ = make3_str(mm_strdup("\""), $1, mm_strdup("\""));
183
enum ECPGttype type = argsinsert->variable->type->type;
185
/* if array see what's inside */
186
if (type == ECPGt_array)
187
type = argsinsert->variable->type->u.element->type;
189
/* handle varchars */
190
if (type == ECPGt_varchar)
191
$$ = make2_str(mm_strdup(argsinsert->variable->name), mm_strdup(".arr"));
193
$$ = mm_strdup(argsinsert->variable->name);
197
char_variable: cvariable
199
/* check if we have a string variable */
200
struct variable *p = find_variable($1);
201
enum ECPGttype type = p->type->type;
203
/* If we have just one character this is not a string */
204
if (atol(p->type->size) == 1)
205
mmerror(PARSE_ERROR, ET_ERROR, "invalid data type");
208
/* if array see what's inside */
209
if (type == ECPGt_array)
210
type = p->type->u.element->type;
215
case ECPGt_unsigned_char:
220
$$ = make2_str($1, mm_strdup(".arr"));
223
mmerror(PARSE_ERROR, ET_ERROR, "invalid data type");
231
opt_options: Op connect_options
234
mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
236
if (strcmp($1, "?") != 0)
237
mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $1);
239
$$ = make2_str(mm_strdup("?"), $2);
241
| /*EMPTY*/ { $$ = EMPTY; }
244
connect_options: ColId opt_opt_value
245
{ $$ = make2_str($1, $2); }
246
| ColId opt_opt_value Op connect_options
249
mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
251
if (strcmp($3, "&") != 0)
252
mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $3);
254
$$ = cat_str(3, make2_str($1, $2), $3, $4);
258
opt_opt_value: /*EMPTY*/
261
{ $$ = make2_str(mm_strdup("="), $2); }
263
{ $$ = make2_str(mm_strdup("="), $2); }
265
{ $$ = make2_str(mm_strdup("="), $2); }
268
prepared_name: name {
269
if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */
271
else /* not quoted => convert to lowercase */
275
for (i = 0; i< strlen($1); i++)
276
$1[i] = tolower((unsigned char) $1[i]);
278
$$ = make3_str(mm_strdup("\""), $1, mm_strdup("\""));
281
| char_variable { $$ = $1; }
285
* Declare a prepared cursor. The syntax is different from the standard
286
* declare statement, so we create a new rule.
288
ECPGCursorStmt: DECLARE cursor_name cursor_options CURSOR opt_hold FOR prepared_name
290
struct cursor *ptr, *this;
291
char *cursor_marker = $2[0] == ':' ? mm_strdup("$0") : mm_strdup($2);
292
int (* strcmp_fn)(const char *, const char *) = ($2[0] == ':' ? strcmp : pg_strcasecmp);
293
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
294
const char *con = connection ? connection : "NULL";
297
for (ptr = cur; ptr != NULL; ptr = ptr->next)
299
if (strcmp_fn($2, ptr->name) == 0)
301
/* re-definition is a bug */
303
mmerror(PARSE_ERROR, ET_ERROR, "using variable \"%s\" in different declare statements is not supported", $2+1);
305
mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" is already defined", $2);
309
this = (struct cursor *) mm_alloc(sizeof(struct cursor));
311
/* initial definition */
314
this->function = (current_function ? mm_strdup(current_function) : NULL);
315
this->connection = connection;
316
this->command = cat_str(6, mm_strdup("declare"), cursor_marker, $3, mm_strdup("cursor"), $5, mm_strdup("for $1"));
317
this->argsresult = NULL;
318
this->argsresult_oos = NULL;
320
thisquery->type = &ecpg_query;
321
thisquery->brace_level = 0;
322
thisquery->next = NULL;
323
thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
324
sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
326
this->argsinsert = NULL;
327
this->argsinsert_oos = NULL;
330
struct variable *var = find_variable($2 + 1);
331
remove_variable_from_list(&argsinsert, var);
332
add_variable_to_head(&(this->argsinsert), var, &no_indicator);
334
add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
338
comment = cat_str(3, mm_strdup("/*"), mm_strdup(this->command), mm_strdup("*/"));
340
if ((braces_open > 0) && INFORMIX_MODE) /* we're in a function */
341
$$ = cat_str(3, adjust_outofscope_cursor_vars(this),
342
mm_strdup("ECPG_informix_reset_sqlca();"),
345
$$ = cat2_str(adjust_outofscope_cursor_vars(this), comment);
349
ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
351
/* execute immediate means prepare the statement and
352
* immediately execute it */
356
* variable decalartion outside exec sql declare block
358
ECPGVarDeclaration: single_vt_declaration;
360
single_vt_declaration: type_declaration { $$ = $1; }
361
| var_declaration { $$ = $1; }
364
precision: NumericOnly { $$ = $1; };
366
opt_scale: ',' NumericOnly { $$ = $2; }
367
| /* EMPTY */ { $$ = EMPTY; }
370
ecpg_interval: opt_interval { $$ = $1; }
371
| YEAR_P TO MINUTE_P { $$ = mm_strdup("year to minute"); }
372
| YEAR_P TO SECOND_P { $$ = mm_strdup("year to second"); }
373
| DAY_P TO DAY_P { $$ = mm_strdup("day to day"); }
374
| MONTH_P TO MONTH_P { $$ = mm_strdup("month to month"); }
378
* variable declaration inside exec sql declare block
380
ECPGDeclaration: sql_startdeclare
381
{ fputs("/* exec sql begin declare section */", yyout); }
382
var_type_declarations sql_enddeclare
384
fprintf(yyout, "%s/* exec sql end declare section */", $3);
386
output_line_number();
390
sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {};
392
sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {};
394
var_type_declarations: /*EMPTY*/ { $$ = EMPTY; }
395
| vt_declarations { $$ = $1; }
398
vt_declarations: single_vt_declaration { $$ = $1; }
399
| CPP_LINE { $$ = $1; }
400
| vt_declarations single_vt_declaration { $$ = cat2_str($1, $2); }
401
| vt_declarations CPP_LINE { $$ = cat2_str($1, $2); }
404
variable_declarations: var_declaration { $$ = $1; }
405
| variable_declarations var_declaration { $$ = cat2_str($1, $2); }
408
type_declaration: S_TYPEDEF
410
/* reset this variable so we see if there was */
411
/* an initializer specified */
414
var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
416
add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
418
fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
419
output_line_number();
423
var_declaration: storage_declaration
426
actual_type[struct_level].type_enum = $2.type_enum;
427
actual_type[struct_level].type_str = $2.type_str;
428
actual_type[struct_level].type_dimension = $2.type_dimension;
429
actual_type[struct_level].type_index = $2.type_index;
430
actual_type[struct_level].type_sizeof = $2.type_sizeof;
432
actual_startline[struct_level] = hashline_number();
436
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, mm_strdup(";\n"));
440
actual_type[struct_level].type_enum = $1.type_enum;
441
actual_type[struct_level].type_str = $1.type_str;
442
actual_type[struct_level].type_dimension = $1.type_dimension;
443
actual_type[struct_level].type_index = $1.type_index;
444
actual_type[struct_level].type_sizeof = $1.type_sizeof;
446
actual_startline[struct_level] = hashline_number();
450
$$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, mm_strdup(";\n"));
452
| struct_union_type_with_symbol ';'
454
$$ = cat2_str($1, mm_strdup(";"));
458
opt_bit_field: ':' Iconst { $$ =cat2_str(mm_strdup(":"), $2); }
459
| /* EMPTY */ { $$ = EMPTY; }
462
storage_declaration: storage_clause storage_modifier
463
{$$ = cat2_str ($1, $2); }
464
| storage_clause {$$ = $1; }
465
| storage_modifier {$$ = $1; }
468
storage_clause : S_EXTERN { $$ = mm_strdup("extern"); }
469
| S_STATIC { $$ = mm_strdup("static"); }
470
| S_REGISTER { $$ = mm_strdup("register"); }
471
| S_AUTO { $$ = mm_strdup("auto"); }
474
storage_modifier : S_CONST { $$ = mm_strdup("const"); }
475
| S_VOLATILE { $$ = mm_strdup("volatile"); }
478
var_type: simple_type
481
$$.type_str = mm_strdup(ecpg_type_name($1));
482
$$.type_dimension = mm_strdup("-1");
483
$$.type_index = mm_strdup("-1");
484
$$.type_sizeof = NULL;
489
$$.type_dimension = mm_strdup("-1");
490
$$.type_index = mm_strdup("-1");
492
if (strncmp($1, "struct", sizeof("struct")-1) == 0)
494
$$.type_enum = ECPGt_struct;
495
$$.type_sizeof = ECPGstruct_sizeof;
499
$$.type_enum = ECPGt_union;
500
$$.type_sizeof = NULL;
506
$$.type_enum = ECPGt_int;
507
$$.type_dimension = mm_strdup("-1");
508
$$.type_index = mm_strdup("-1");
509
$$.type_sizeof = NULL;
511
| ECPGColLabelCommon '(' precision opt_scale ')'
513
if (strcmp($1, "numeric") == 0)
515
$$.type_enum = ECPGt_numeric;
516
$$.type_str = mm_strdup("numeric");
518
else if (strcmp($1, "decimal") == 0)
520
$$.type_enum = ECPGt_decimal;
521
$$.type_str = mm_strdup("decimal");
525
mmerror(PARSE_ERROR, ET_ERROR, "only data types numeric and decimal have precision/scale argument");
526
$$.type_enum = ECPGt_numeric;
527
$$.type_str = mm_strdup("numeric");
530
$$.type_dimension = mm_strdup("-1");
531
$$.type_index = mm_strdup("-1");
532
$$.type_sizeof = NULL;
534
| ECPGColLabelCommon ecpg_interval
536
if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
537
mmerror (PARSE_ERROR, ET_ERROR, "interval specification not allowed here");
540
* Check for type names that the SQL grammar treats as
541
* unreserved keywords
543
if (strcmp($1, "varchar") == 0)
545
$$.type_enum = ECPGt_varchar;
546
$$.type_str = EMPTY; /*mm_strdup("varchar");*/
547
$$.type_dimension = mm_strdup("-1");
548
$$.type_index = mm_strdup("-1");
549
$$.type_sizeof = NULL;
551
else if (strcmp($1, "float") == 0)
553
$$.type_enum = ECPGt_float;
554
$$.type_str = mm_strdup("float");
555
$$.type_dimension = mm_strdup("-1");
556
$$.type_index = mm_strdup("-1");
557
$$.type_sizeof = NULL;
559
else if (strcmp($1, "double") == 0)
561
$$.type_enum = ECPGt_double;
562
$$.type_str = mm_strdup("double");
563
$$.type_dimension = mm_strdup("-1");
564
$$.type_index = mm_strdup("-1");
565
$$.type_sizeof = NULL;
567
else if (strcmp($1, "numeric") == 0)
569
$$.type_enum = ECPGt_numeric;
570
$$.type_str = mm_strdup("numeric");
571
$$.type_dimension = mm_strdup("-1");
572
$$.type_index = mm_strdup("-1");
573
$$.type_sizeof = NULL;
575
else if (strcmp($1, "decimal") == 0)
577
$$.type_enum = ECPGt_decimal;
578
$$.type_str = mm_strdup("decimal");
579
$$.type_dimension = mm_strdup("-1");
580
$$.type_index = mm_strdup("-1");
581
$$.type_sizeof = NULL;
583
else if (strcmp($1, "date") == 0)
585
$$.type_enum = ECPGt_date;
586
$$.type_str = mm_strdup("date");
587
$$.type_dimension = mm_strdup("-1");
588
$$.type_index = mm_strdup("-1");
589
$$.type_sizeof = NULL;
591
else if (strcmp($1, "timestamp") == 0)
593
$$.type_enum = ECPGt_timestamp;
594
$$.type_str = mm_strdup("timestamp");
595
$$.type_dimension = mm_strdup("-1");
596
$$.type_index = mm_strdup("-1");
597
$$.type_sizeof = NULL;
599
else if (strcmp($1, "interval") == 0)
601
$$.type_enum = ECPGt_interval;
602
$$.type_str = mm_strdup("interval");
603
$$.type_dimension = mm_strdup("-1");
604
$$.type_index = mm_strdup("-1");
605
$$.type_sizeof = NULL;
607
else if (strcmp($1, "datetime") == 0)
609
$$.type_enum = ECPGt_timestamp;
610
$$.type_str = mm_strdup("timestamp");
611
$$.type_dimension = mm_strdup("-1");
612
$$.type_index = mm_strdup("-1");
613
$$.type_sizeof = NULL;
615
else if ((strcmp($1, "string") == 0) && INFORMIX_MODE)
617
$$.type_enum = ECPGt_string;
618
$$.type_str = mm_strdup("char");
619
$$.type_dimension = mm_strdup("-1");
620
$$.type_index = mm_strdup("-1");
621
$$.type_sizeof = NULL;
625
/* this is for typedef'ed types */
626
struct typedefs *this = get_typedef($1);
628
$$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
629
$$.type_enum = this->type->type_enum;
630
$$.type_dimension = this->type->type_dimension;
631
$$.type_index = this->type->type_index;
632
if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
633
$$.type_sizeof = this->type->type_sizeof;
635
$$.type_sizeof = cat_str(3, mm_strdup("sizeof("), mm_strdup(this->name), mm_strdup(")"));
637
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
640
| s_struct_union_symbol
642
/* this is for named structs/unions */
644
struct typedefs *this;
645
bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
647
name = cat2_str($1.su, $1.symbol);
648
/* Do we have a forward definition? */
653
this = get_typedef(name);
654
$$.type_str = mm_strdup(this->name);
655
$$.type_enum = this->type->type_enum;
656
$$.type_dimension = this->type->type_dimension;
657
$$.type_index = this->type->type_index;
658
$$.type_sizeof = this->type->type_sizeof;
659
struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
665
$$.type_enum = ECPGt_long;
666
$$.type_dimension = mm_strdup("-1");
667
$$.type_index = mm_strdup("-1");
668
$$.type_sizeof = mm_strdup("");
669
struct_member_list[struct_level] = NULL;
674
enum_type: ENUM_P symbol enum_definition
675
{ $$ = cat_str(3, mm_strdup("enum"), $2, $3); }
676
| ENUM_P enum_definition
677
{ $$ = cat2_str(mm_strdup("enum"), $2); }
679
{ $$ = cat2_str(mm_strdup("enum"), $2); }
682
enum_definition: '{' c_list '}'
683
{ $$ = cat_str(3, mm_strdup("{"), $2, mm_strdup("}")); };
685
struct_union_type_with_symbol: s_struct_union_symbol
687
struct_member_list[struct_level++] = NULL;
688
if (struct_level >= STRUCT_DEPTH)
689
mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
690
forward_name = mm_strdup($1.symbol);
692
'{' variable_declarations '}'
694
struct typedefs *ptr, *this;
695
struct this_type su_type;
697
ECPGfree_struct_member(struct_member_list[struct_level]);
698
struct_member_list[struct_level] = NULL;
700
if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
701
su_type.type_enum = ECPGt_struct;
703
su_type.type_enum = ECPGt_union;
704
su_type.type_str = cat2_str($1.su, $1.symbol);
708
/* This is essantially a typedef but needs the keyword struct/union as well.
709
* So we create the typedef for each struct definition with symbol */
710
for (ptr = types; ptr != NULL; ptr = ptr->next)
712
if (strcmp(su_type.type_str, ptr->name) == 0)
713
/* re-definition is a bug */
714
mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" is already defined", su_type.type_str);
717
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
719
/* initial definition */
721
this->name = mm_strdup(su_type.type_str);
722
this->brace_level = braces_open;
723
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
724
this->type->type_enum = su_type.type_enum;
725
this->type->type_str = mm_strdup(su_type.type_str);
726
this->type->type_dimension = mm_strdup("-1"); /* dimension of array */
727
this->type->type_index = mm_strdup("-1"); /* length of string */
728
this->type->type_sizeof = ECPGstruct_sizeof;
729
this->struct_member_list = struct_member_list[struct_level];
732
$$ = cat_str(4, su_type.type_str, mm_strdup("{"), $4, mm_strdup("}"));
736
struct_union_type: struct_union_type_with_symbol { $$ = $1; }
739
struct_member_list[struct_level++] = NULL;
740
if (struct_level >= STRUCT_DEPTH)
741
mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
743
'{' variable_declarations '}'
745
ECPGfree_struct_member(struct_member_list[struct_level]);
746
struct_member_list[struct_level] = NULL;
748
$$ = cat_str(4, $1, mm_strdup("{"), $4, mm_strdup("}"));
752
s_struct_union_symbol: SQL_STRUCT symbol
754
$$.su = mm_strdup("struct");
756
ECPGstruct_sizeof = cat_str(3, mm_strdup("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), mm_strdup(")"));
760
$$.su = mm_strdup("union");
765
s_struct_union: SQL_STRUCT
767
ECPGstruct_sizeof = mm_strdup(""); /* This must not be NULL to distinguish from simple types. */
768
$$ = mm_strdup("struct");
770
| UNION { $$ = mm_strdup("union"); }
773
simple_type: unsigned_type { $$=$1; }
774
| opt_signed signed_type { $$=$2; }
777
unsigned_type: SQL_UNSIGNED SQL_SHORT { $$ = ECPGt_unsigned_short; }
778
| SQL_UNSIGNED SQL_SHORT INT_P { $$ = ECPGt_unsigned_short; }
779
| SQL_UNSIGNED { $$ = ECPGt_unsigned_int; }
780
| SQL_UNSIGNED INT_P { $$ = ECPGt_unsigned_int; }
781
| SQL_UNSIGNED SQL_LONG { $$ = ECPGt_unsigned_long; }
782
| SQL_UNSIGNED SQL_LONG INT_P { $$ = ECPGt_unsigned_long; }
783
| SQL_UNSIGNED SQL_LONG SQL_LONG
785
#ifdef HAVE_LONG_LONG_INT
786
$$ = ECPGt_unsigned_long_long;
788
$$ = ECPGt_unsigned_long;
791
| SQL_UNSIGNED SQL_LONG SQL_LONG INT_P
793
#ifdef HAVE_LONG_LONG_INT
794
$$ = ECPGt_unsigned_long_long;
796
$$ = ECPGt_unsigned_long;
799
| SQL_UNSIGNED CHAR_P { $$ = ECPGt_unsigned_char; }
802
signed_type: SQL_SHORT { $$ = ECPGt_short; }
803
| SQL_SHORT INT_P { $$ = ECPGt_short; }
804
| INT_P { $$ = ECPGt_int; }
805
| SQL_LONG { $$ = ECPGt_long; }
806
| SQL_LONG INT_P { $$ = ECPGt_long; }
809
#ifdef HAVE_LONG_LONG_INT
810
$$ = ECPGt_long_long;
815
| SQL_LONG SQL_LONG INT_P
817
#ifdef HAVE_LONG_LONG_INT
818
$$ = ECPGt_long_long;
823
| SQL_BOOL { $$ = ECPGt_bool; }
824
| CHAR_P { $$ = ECPGt_char; }
825
| DOUBLE_P { $$ = ECPGt_double; }
828
opt_signed: SQL_SIGNED
832
variable_list: variable
834
| variable_list ',' variable
835
{ $$ = cat_str(3, $1, mm_strdup(","), $3); }
838
variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
840
struct ECPGtype * type;
841
char *dimension = $3.index1; /* dimension of array */
842
char *length = $3.index2; /* length of string */
846
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);
848
switch (actual_type[struct_level].type_enum)
852
if (atoi(dimension) < 0)
853
type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof);
855
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_str, actual_type[struct_level].type_sizeof), dimension);
857
$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
861
if (atoi(dimension) < 0)
862
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter);
864
type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, varchar_counter), dimension);
866
if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1)
867
dim_str=mm_strdup("");
869
dim_str=cat_str(3, mm_strdup("["), mm_strdup(dimension), mm_strdup("]"));
870
/* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
871
if (atoi(length) < 0 || strcmp(length, "0") == 0)
872
mmerror(PARSE_ERROR, ET_ERROR, "pointers to varchar are not implemented");
874
/* make sure varchar struct name is unique by adding a unique counter to its definition */
875
vcn = (char *) mm_alloc(strlen($2) + sizeof(int) * CHAR_BIT * 10 / 3);
876
sprintf(vcn, "%s_%d", $2, varchar_counter);
877
if (strcmp(dimension, "0") == 0)
878
$$ = cat_str(7, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } *"), mm_strdup($2), $4, $5);
880
$$ = cat_str(8, make2_str(mm_strdup(" struct varchar_"), vcn), mm_strdup(" { int len; char arr["), mm_strdup(length), mm_strdup("]; } "), mm_strdup($2), dim_str, $4, $5);
885
case ECPGt_unsigned_char:
887
if (atoi(dimension) == -1)
891
if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
893
/* if we have an initializer but no string size set, let's use the initializer's length */
895
length = mm_alloc(i+sizeof("sizeof()"));
896
sprintf(length, "sizeof(%s)", $5+2);
898
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
901
type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
903
$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
907
if (atoi(dimension) < 0)
908
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, mm_strdup("1"), 0);
910
type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, mm_strdup("1"), 0), dimension);
912
$$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
916
if (struct_level == 0)
917
new_variable($2, type, braces_open);
919
ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
925
opt_initializer: /*EMPTY*/
930
$$ = cat2_str(mm_strdup("="), $2);
934
opt_pointer: /*EMPTY*/ { $$ = EMPTY; }
935
| '*' { $$ = mm_strdup("*"); }
936
| '*' '*' { $$ = mm_strdup("**"); }
940
* We try to simulate the correct DECLARE syntax here so we get dynamic SQL
942
ECPGDeclare: DECLARE STATEMENT ecpg_ident
944
/* this is only supported for compatibility */
945
$$ = cat_str(3, mm_strdup("/* declare statement"), $3, mm_strdup("*/"));
949
* the exec sql disconnect statement: disconnect from the given database
951
ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
954
dis_name: connection_object { $$ = $1; }
955
| CURRENT_P { $$ = mm_strdup("\"CURRENT\""); }
956
| ALL { $$ = mm_strdup("\"ALL\""); }
957
| /* EMPTY */ { $$ = mm_strdup("\"CURRENT\""); }
960
connection_object: database_name { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); }
961
| DEFAULT { $$ = mm_strdup("\"DEFAULT\""); }
962
| char_variable { $$ = $1; }
965
execstring: char_variable
968
{ $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); }
972
* the exec sql free command to deallocate a previously
975
ECPGFree: SQL_FREE cursor_name { $$ = $2; }
976
| SQL_FREE ALL { $$ = mm_strdup("all"); }
980
* open is an open cursor, at the moment this has to be removed
982
ECPGOpen: SQL_OPEN cursor_name opt_ecpg_using
985
remove_variable_from_list(&argsinsert, find_variable($2 + 1));
990
opt_ecpg_using: /*EMPTY*/ { $$ = EMPTY; }
991
| ecpg_using { $$ = $1; }
994
ecpg_using: USING using_list { $$ = EMPTY; }
995
| using_descriptor { $$ = $1; }
998
using_descriptor: USING SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
1000
add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
1003
| USING SQL_DESCRIPTOR name
1005
add_variable_to_head(&argsinsert, sqlda_variable($3), &no_indicator);
1010
into_descriptor: INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
1012
add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
1015
| INTO SQL_DESCRIPTOR name
1017
add_variable_to_head(&argsresult, sqlda_variable($3), &no_indicator);
1022
into_sqlda: INTO name
1024
add_variable_to_head(&argsresult, sqlda_variable($2), &no_indicator);
1029
using_list: UsingValue | UsingValue ',' using_list;
1031
UsingValue: UsingConst
1033
char *length = mm_alloc(32);
1035
sprintf(length, "%d", (int) strlen($1));
1036
add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
1038
| civar { $$ = EMPTY; }
1039
| civarind { $$ = EMPTY; }
1042
UsingConst: Iconst { $$ = $1; }
1043
| '+' Iconst { $$ = cat_str(2, mm_strdup("+"), $2); }
1044
| '-' Iconst { $$ = cat_str(2, mm_strdup("-"), $2); }
1045
| ecpg_fconst { $$ = $1; }
1046
| '+' ecpg_fconst { $$ = cat_str(2, mm_strdup("+"), $2); }
1047
| '-' ecpg_fconst { $$ = cat_str(2, mm_strdup("-"), $2); }
1048
| ecpg_sconst { $$ = $1; }
1049
| ecpg_bconst { $$ = $1; }
1050
| ecpg_xconst { $$ = $1; }
1054
* We accept DESCRIBE [OUTPUT] but do nothing with DESCRIBE INPUT so far.
1056
ECPGDescribe: SQL_DESCRIBE INPUT_P prepared_name using_descriptor
1058
const char *con = connection ? connection : "NULL";
1059
mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
1060
$$ = (char *) mm_alloc(sizeof("1, , ") + strlen(con) + strlen($3));
1061
sprintf($$, "1, %s, %s", con, $3);
1063
| SQL_DESCRIBE opt_output prepared_name using_descriptor
1065
const char *con = connection ? connection : "NULL";
1066
struct variable *var;
1068
var = argsinsert->variable;
1069
remove_variable_from_list(&argsinsert, var);
1070
add_variable_to_head(&argsresult, var, &no_indicator);
1072
$$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3));
1073
sprintf($$, "0, %s, %s", con, $3);
1075
| SQL_DESCRIBE opt_output prepared_name into_descriptor
1077
const char *con = connection ? connection : "NULL";
1078
$$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3));
1079
sprintf($$, "0, %s, %s", con, $3);
1081
| SQL_DESCRIBE INPUT_P prepared_name into_sqlda
1083
const char *con = connection ? connection : "NULL";
1084
mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
1085
$$ = (char *) mm_alloc(sizeof("1, , ") + strlen(con) + strlen($3));
1086
sprintf($$, "1, %s, %s", con, $3);
1088
| SQL_DESCRIBE opt_output prepared_name into_sqlda
1090
const char *con = connection ? connection : "NULL";
1091
$$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3));
1092
sprintf($$, "0, %s, %s", con, $3);
1096
opt_output: SQL_OUTPUT { $$ = mm_strdup("output"); }
1097
| /* EMPTY */ { $$ = EMPTY; }
1101
* dynamic SQL: descriptor based access
1102
* originall written by Christof Petig <christof.petig@wtal.de>
1103
* and Peter Eisentraut <peter.eisentraut@credativ.de>
1107
* allocate a descriptor
1109
ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
1111
add_descriptor($3,connection);
1118
* deallocate a descriptor
1120
ECPGDeallocateDescr: DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
1122
drop_descriptor($3,connection);
1128
* manipulate a descriptor header
1131
ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
1135
ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
1136
| ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
1139
ECPGGetDescHeaderItem: cvariable '=' desc_header_item
1140
{ push_assignment($1, $3); }
1144
ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
1148
ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
1149
| ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
1152
ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
1154
push_assignment($3, $1);
1160
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1162
sprintf(length, "%d", (int) strlen($1));
1163
new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1166
| cvariable { $$ = $1; }
1169
desc_header_item: SQL_COUNT { $$ = ECPGd_count; }
1173
* manipulate a descriptor
1176
ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
1177
{ $$.str = $5; $$.name = $3; }
1180
ECPGGetDescItems: ECPGGetDescItem
1181
| ECPGGetDescItems ',' ECPGGetDescItem
1184
ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); };
1187
ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems
1188
{ $$.str = $5; $$.name = $3; }
1191
ECPGSetDescItems: ECPGSetDescItem
1192
| ECPGSetDescItems ',' ECPGSetDescItem
1195
ECPGSetDescItem: descriptor_item '=' AllConstVar
1197
push_assignment($3, $1);
1201
AllConstVar: ecpg_fconst
1203
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1205
sprintf(length, "%d", (int) strlen($1));
1206
new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1209
| IntConstVar { $$ = $1; }
1212
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1213
char *var = cat2_str(mm_strdup("-"), $2);
1215
sprintf(length, "%d", (int) strlen(var));
1216
new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1221
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1222
char *var = cat2_str(mm_strdup("-"), $2);
1224
sprintf(length, "%d", (int) strlen(var));
1225
new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1230
char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1233
var[strlen(var) - 1] = '\0';
1234
sprintf(length, "%d", (int) strlen(var));
1235
new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1240
descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }
1241
| DATA_P { $$ = ECPGd_data; }
1242
| SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; }
1243
| SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; }
1244
| SQL_INDICATOR { $$ = ECPGd_indicator; }
1245
| SQL_KEY_MEMBER { $$ = ECPGd_key_member; }
1246
| SQL_LENGTH { $$ = ECPGd_length; }
1247
| NAME_P { $$ = ECPGd_name; }
1248
| SQL_NULLABLE { $$ = ECPGd_nullable; }
1249
| SQL_OCTET_LENGTH { $$ = ECPGd_octet; }
1250
| PRECISION { $$ = ECPGd_precision; }
1251
| SQL_RETURNED_LENGTH { $$ = ECPGd_length; }
1252
| SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; }
1253
| SQL_SCALE { $$ = ECPGd_scale; }
1254
| TYPE_P { $$ = ECPGd_type; }
1258
* set/reset the automatic transaction mode, this needs a differnet handling
1259
* as the other set commands
1261
ECPGSetAutocommit: SET SQL_AUTOCOMMIT '=' on_off { $$ = $4; }
1262
| SET SQL_AUTOCOMMIT TO on_off { $$ = $4; }
1265
on_off: ON { $$ = mm_strdup("on"); }
1266
| OFF { $$ = mm_strdup("off"); }
1270
* set the actual connection, this needs a differnet handling as the other
1273
ECPGSetConnection: SET CONNECTION TO connection_object { $$ = $4; }
1274
| SET CONNECTION '=' connection_object { $$ = $4; }
1275
| SET CONNECTION connection_object { $$ = $3; }
1279
* define a new type for embedded SQL
1283
/* reset this variable so we see if there was */
1284
/* an initializer specified */
1287
ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
1289
add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
1291
if (auto_create_c == false)
1292
$$ = cat_str(7, mm_strdup("/* exec sql type"), mm_strdup($3), mm_strdup("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, mm_strdup("*/"));
1294
$$ = cat_str(6, mm_strdup("typedef "), mm_strdup($5.type_str), *$7?mm_strdup("*"):mm_strdup(""), mm_strdup($6.str), mm_strdup($3), mm_strdup(";"));
1298
opt_reference: SQL_REFERENCE { $$ = mm_strdup("reference"); }
1299
| /*EMPTY*/ { $$ = EMPTY; }
1303
* define the type of one variable for embedded SQL
1307
/* reset this variable so we see if there was */
1308
/* an initializer specified */
1311
ColLabel IS var_type opt_array_bounds opt_reference
1313
struct variable *p = find_variable($3);
1314
char *dimension = $6.index1;
1315
char *length = $6.index2;
1316
struct ECPGtype * type;
1318
if (($5.type_enum == ECPGt_struct ||
1319
$5.type_enum == ECPGt_union) &&
1321
mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in EXEC SQL VAR command");
1324
adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
1326
switch ($5.type_enum)
1330
if (atoi(dimension) < 0)
1331
type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof);
1333
type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_str, $5.type_sizeof), dimension);
1337
if (atoi(dimension) == -1)
1338
type = ECPGmake_simple_type($5.type_enum, length, 0);
1340
type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
1344
case ECPGt_unsigned_char:
1346
if (atoi(dimension) == -1)
1347
type = ECPGmake_simple_type($5.type_enum, length, 0);
1349
type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
1353
if (atoi(length) >= 0)
1354
mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported");
1356
if (atoi(dimension) < 0)
1357
type = ECPGmake_simple_type($5.type_enum, mm_strdup("1"), 0);
1359
type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, mm_strdup("1"), 0), dimension);
1363
ECPGfree_type(p->type);
1367
$$ = cat_str(7, mm_strdup("/* exec sql var"), mm_strdup($3), mm_strdup("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, mm_strdup("*/"));
1372
* whenever statement: decide what to do in case of error/no data found
1373
* according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
1375
ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
1377
when_error.code = $<action>3.code;
1378
when_error.command = $<action>3.command;
1379
$$ = cat_str(3, mm_strdup("/* exec sql whenever sqlerror "), $3.str, mm_strdup("; */"));
1381
| SQL_WHENEVER NOT SQL_FOUND action
1383
when_nf.code = $<action>4.code;
1384
when_nf.command = $<action>4.command;
1385
$$ = cat_str(3, mm_strdup("/* exec sql whenever not found "), $4.str, mm_strdup("; */"));
1387
| SQL_WHENEVER SQL_SQLWARNING action
1389
when_warn.code = $<action>3.code;
1390
when_warn.command = $<action>3.command;
1391
$$ = cat_str(3, mm_strdup("/* exec sql whenever sql_warning "), $3.str, mm_strdup("; */"));
1397
$<action>$.code = W_NOTHING;
1398
$<action>$.command = NULL;
1399
$<action>$.str = mm_strdup("continue");
1403
$<action>$.code = W_SQLPRINT;
1404
$<action>$.command = NULL;
1405
$<action>$.str = mm_strdup("sqlprint");
1409
$<action>$.code = W_STOP;
1410
$<action>$.command = NULL;
1411
$<action>$.str = mm_strdup("stop");
1415
$<action>$.code = W_GOTO;
1416
$<action>$.command = strdup($2);
1417
$<action>$.str = cat2_str(mm_strdup("goto "), $2);
1421
$<action>$.code = W_GOTO;
1422
$<action>$.command = strdup($3);
1423
$<action>$.str = cat2_str(mm_strdup("goto "), $3);
1425
| DO name '(' c_args ')'
1427
$<action>$.code = W_DO;
1428
$<action>$.command = cat_str(4, $2, mm_strdup("("), $4, mm_strdup(")"));
1429
$<action>$.str = cat2_str(mm_strdup("do"), mm_strdup($<action>$.command));
1433
$<action>$.code = W_BREAK;
1434
$<action>$.command = NULL;
1435
$<action>$.str = mm_strdup("break");
1437
| SQL_CALL name '(' c_args ')'
1439
$<action>$.code = W_DO;
1440
$<action>$.command = cat_str(4, $2, mm_strdup("("), $4, mm_strdup(")"));
1441
$<action>$.str = cat2_str(mm_strdup("call"), mm_strdup($<action>$.command));
1445
$<action>$.code = W_DO;
1446
$<action>$.command = cat2_str($2, mm_strdup("()"));
1447
$<action>$.str = cat2_str(mm_strdup("call"), mm_strdup($<action>$.command));
1451
/* some other stuff for ecpg */
1453
/* additional unreserved keywords */
1454
ECPGKeywords: ECPGKeywords_vanames { $$ = $1; }
1455
| ECPGKeywords_rest { $$ = $1; }
1458
ECPGKeywords_vanames: SQL_BREAK { $$ = mm_strdup("break"); }
1459
| SQL_CALL { $$ = mm_strdup("call"); }
1460
| SQL_CARDINALITY { $$ = mm_strdup("cardinality"); }
1461
| SQL_COUNT { $$ = mm_strdup("count"); }
1462
| SQL_DATETIME_INTERVAL_CODE { $$ = mm_strdup("datetime_interval_code"); }
1463
| SQL_DATETIME_INTERVAL_PRECISION { $$ = mm_strdup("datetime_interval_precision"); }
1464
| SQL_FOUND { $$ = mm_strdup("found"); }
1465
| SQL_GO { $$ = mm_strdup("go"); }
1466
| SQL_GOTO { $$ = mm_strdup("goto"); }
1467
| SQL_IDENTIFIED { $$ = mm_strdup("identified"); }
1468
| SQL_INDICATOR { $$ = mm_strdup("indicator"); }
1469
| SQL_KEY_MEMBER { $$ = mm_strdup("key_member"); }
1470
| SQL_LENGTH { $$ = mm_strdup("length"); }
1471
| SQL_NULLABLE { $$ = mm_strdup("nullable"); }
1472
| SQL_OCTET_LENGTH { $$ = mm_strdup("octet_length"); }
1473
| SQL_RETURNED_LENGTH { $$ = mm_strdup("returned_length"); }
1474
| SQL_RETURNED_OCTET_LENGTH { $$ = mm_strdup("returned_octet_length"); }
1475
| SQL_SCALE { $$ = mm_strdup("scale"); }
1476
| SQL_SECTION { $$ = mm_strdup("section"); }
1477
| SQL_SQL { $$ = mm_strdup("sql"); }
1478
| SQL_SQLERROR { $$ = mm_strdup("sqlerror"); }
1479
| SQL_SQLPRINT { $$ = mm_strdup("sqlprint"); }
1480
| SQL_SQLWARNING { $$ = mm_strdup("sqlwarning"); }
1481
| SQL_STOP { $$ = mm_strdup("stop"); }
1484
ECPGKeywords_rest: SQL_CONNECT { $$ = mm_strdup("connect"); }
1485
| SQL_DESCRIBE { $$ = mm_strdup("describe"); }
1486
| SQL_DISCONNECT { $$ = mm_strdup("disconnect"); }
1487
| SQL_OPEN { $$ = mm_strdup("open"); }
1488
| SQL_VAR { $$ = mm_strdup("var"); }
1489
| SQL_WHENEVER { $$ = mm_strdup("whenever"); }
1492
/* additional keywords that can be SQL type names (but not ECPGColLabels) */
1493
ECPGTypeName: SQL_BOOL { $$ = mm_strdup("bool"); }
1494
| SQL_LONG { $$ = mm_strdup("long"); }
1495
| SQL_OUTPUT { $$ = mm_strdup("output"); }
1496
| SQL_SHORT { $$ = mm_strdup("short"); }
1497
| SQL_STRUCT { $$ = mm_strdup("struct"); }
1498
| SQL_SIGNED { $$ = mm_strdup("signed"); }
1499
| SQL_UNSIGNED { $$ = mm_strdup("unsigned"); }
1502
symbol: ColLabel { $$ = $1; }
1505
ECPGColId: ecpg_ident { $$ = $1; }
1506
| unreserved_keyword { $$ = $1; }
1507
| col_name_keyword { $$ = $1; }
1508
| ECPGunreserved_interval { $$ = $1; }
1509
| ECPGKeywords { $$ = $1; }
1510
| ECPGCKeywords { $$ = $1; }
1511
| CHAR_P { $$ = mm_strdup("char"); }
1512
| VALUES { $$ = mm_strdup("values"); }
1516
* Name classification hierarchy.
1518
* These productions should match those in the core grammar, except that
1519
* we use all_unreserved_keyword instead of unreserved_keyword, and
1520
* where possible include ECPG keywords as well as core keywords.
1523
/* Column identifier --- names that can be column, table, etc names.
1525
ColId: ecpg_ident { $$ = $1; }
1526
| all_unreserved_keyword { $$ = $1; }
1527
| col_name_keyword { $$ = $1; }
1528
| ECPGKeywords { $$ = $1; }
1529
| ECPGCKeywords { $$ = $1; }
1530
| CHAR_P { $$ = mm_strdup("char"); }
1531
| VALUES { $$ = mm_strdup("values"); }
1534
/* Type/function identifier --- names that can be type or function names.
1536
type_function_name: ecpg_ident { $$ = $1; }
1537
| all_unreserved_keyword { $$ = $1; }
1538
| type_func_name_keyword { $$ = $1; }
1539
| ECPGKeywords { $$ = $1; }
1540
| ECPGCKeywords { $$ = $1; }
1541
| ECPGTypeName { $$ = $1; }
1544
/* Column label --- allowed labels in "AS" clauses.
1545
* This presently includes *all* Postgres keywords.
1547
ColLabel: ECPGColLabel { $$ = $1; }
1548
| ECPGTypeName { $$ = $1; }
1549
| CHAR_P { $$ = mm_strdup("char"); }
1550
| CURRENT_P { $$ = mm_strdup("current"); }
1551
| INPUT_P { $$ = mm_strdup("input"); }
1552
| INT_P { $$ = mm_strdup("int"); }
1553
| TO { $$ = mm_strdup("to"); }
1554
| UNION { $$ = mm_strdup("union"); }
1555
| VALUES { $$ = mm_strdup("values"); }
1556
| ECPGCKeywords { $$ = $1; }
1557
| ECPGunreserved_interval { $$ = $1; }
1560
ECPGColLabel: ECPGColLabelCommon { $$ = $1; }
1561
| unreserved_keyword { $$ = $1; }
1562
| reserved_keyword { $$ = $1; }
1563
| ECPGKeywords_rest { $$ = $1; }
1564
| CONNECTION { $$ = mm_strdup("connection"); }
1567
ECPGColLabelCommon: ecpg_ident { $$ = $1; }
1568
| col_name_keyword { $$ = $1; }
1569
| type_func_name_keyword { $$ = $1; }
1570
| ECPGKeywords_vanames { $$ = $1; }
1573
ECPGCKeywords: S_AUTO { $$ = mm_strdup("auto"); }
1574
| S_CONST { $$ = mm_strdup("const"); }
1575
| S_EXTERN { $$ = mm_strdup("extern"); }
1576
| S_REGISTER { $$ = mm_strdup("register"); }
1577
| S_STATIC { $$ = mm_strdup("static"); }
1578
| S_TYPEDEF { $$ = mm_strdup("typedef"); }
1579
| S_VOLATILE { $$ = mm_strdup("volatile"); }
1582
/* "Unreserved" keywords --- available for use as any kind of name.
1586
* The following symbols must be excluded from ECPGColLabel and directly
1587
* included into ColLabel to enable C variables to get names from ECPGColLabel:
1588
* DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P.
1590
* We also have to exclude CONNECTION, CURRENT, and INPUT for various reasons.
1591
* CONNECTION can be added back in all_unreserved_keyword, but CURRENT and
1592
* INPUT are reserved for ecpg purposes.
1594
* The mentioned exclusions are done by $replace_line settings in parse2.pl.
1596
all_unreserved_keyword: unreserved_keyword { $$ = $1; }
1597
| ECPGunreserved_interval { $$ = $1; }
1598
| CONNECTION { $$ = mm_strdup("connection"); }
1601
ECPGunreserved_interval: DAY_P { $$ = mm_strdup("day"); }
1602
| HOUR_P { $$ = mm_strdup("hour"); }
1603
| MINUTE_P { $$ = mm_strdup("minute"); }
1604
| MONTH_P { $$ = mm_strdup("month"); }
1605
| SECOND_P { $$ = mm_strdup("second"); }
1606
| YEAR_P { $$ = mm_strdup("year"); }
1610
into_list : coutputvariable | into_list ',' coutputvariable
1613
ecpgstart: SQL_START {
1619
c_args: /*EMPTY*/ { $$ = EMPTY; }
1620
| c_list { $$ = $1; }
1623
coutputvariable: cvariable indicator
1624
{ add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
1626
{ add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
1630
civarind: cvariable indicator
1632
if (find_variable($2)->type->type == ECPGt_array)
1633
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
1635
add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
1636
$$ = create_questionmarks($1, false);
1640
char_civar: char_variable
1642
char *ptr = strstr($1, ".arr");
1644
if (ptr) /* varchar, we need the struct name here, not the struct element */
1646
add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
1653
add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
1654
$$ = create_questionmarks($1, false);
1658
indicator: cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
1659
| SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
1660
| SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
1663
cvariable: CVARIABLE
1665
/* As long as multidimensional arrays are not implemented we have to check for those here */
1667
int brace_open=0, brace = false;
1675
mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for simple data types are not supported");
1680
if (brace_open == 0)
1687
if (brace_open == 0)
1696
ecpg_param: PARAM { $$ = make_name(); } ;
1698
ecpg_bconst: BCONST { $$ = make_name(); } ;
1700
ecpg_fconst: FCONST { $$ = make_name(); } ;
1705
/* could have been input as '' or $$ */
1706
$$ = (char *)mm_alloc(strlen($1) + 3);
1709
$$[strlen($1)+1]='\'';
1710
$$[strlen($1)+2]='\0';
1715
$$ = (char *)mm_alloc(strlen($1) + 4);
1719
$$[strlen($1)+2]='\'';
1720
$$[strlen($1)+3]='\0';
1725
$$ = (char *)mm_alloc(strlen($1) + 4);
1729
$$[strlen($1)+2]='\'';
1730
$$[strlen($1)+3]='\0';
1733
| UCONST { $$ = $1; }
1734
| DOLCONST { $$ = $1; }
1737
ecpg_xconst: XCONST { $$ = make_name(); } ;
1739
ecpg_ident: IDENT { $$ = make_name(); }
1740
| CSTRING { $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); }
1741
| UIDENT { $$ = $1; }
1744
quoted_ident_stringvar: name
1745
{ $$ = make3_str(mm_strdup("\""), $1, mm_strdup("\"")); }
1747
{ $$ = make3_str(mm_strdup("("), $1, mm_strdup(")")); }
1754
c_stuff_item: c_anything { $$ = $1; }
1755
| '(' ')' { $$ = mm_strdup("()"); }
1757
{ $$ = cat_str(3, mm_strdup("("), $2, mm_strdup(")")); }
1760
c_stuff: c_stuff_item { $$ = $1; }
1761
| c_stuff c_stuff_item
1762
{ $$ = cat2_str($1, $2); }
1765
c_list: c_term { $$ = $1; }
1766
| c_list ',' c_term { $$ = cat_str(3, $1, mm_strdup(","), $3); }
1769
c_term: c_stuff { $$ = $1; }
1770
| '{' c_list '}' { $$ = cat_str(3, mm_strdup("{"), $2, mm_strdup("}")); }
1773
c_thing: c_anything { $$ = $1; }
1774
| '(' { $$ = mm_strdup("("); }
1775
| ')' { $$ = mm_strdup(")"); }
1776
| ',' { $$ = mm_strdup(","); }
1777
| ';' { $$ = mm_strdup(";"); }
1780
c_anything: ecpg_ident { $$ = $1; }
1781
| Iconst { $$ = $1; }
1782
| ecpg_fconst { $$ = $1; }
1783
| ecpg_sconst { $$ = $1; }
1784
| '*' { $$ = mm_strdup("*"); }
1785
| '+' { $$ = mm_strdup("+"); }
1786
| '-' { $$ = mm_strdup("-"); }
1787
| '/' { $$ = mm_strdup("/"); }
1788
| '%' { $$ = mm_strdup("%"); }
1789
| NULL_P { $$ = mm_strdup("NULL"); }
1790
| S_ADD { $$ = mm_strdup("+="); }
1791
| S_AND { $$ = mm_strdup("&&"); }
1792
| S_ANYTHING { $$ = make_name(); }
1793
| S_AUTO { $$ = mm_strdup("auto"); }
1794
| S_CONST { $$ = mm_strdup("const"); }
1795
| S_DEC { $$ = mm_strdup("--"); }
1796
| S_DIV { $$ = mm_strdup("/="); }
1797
| S_DOTPOINT { $$ = mm_strdup(".*"); }
1798
| S_EQUAL { $$ = mm_strdup("=="); }
1799
| S_EXTERN { $$ = mm_strdup("extern"); }
1800
| S_INC { $$ = mm_strdup("++"); }
1801
| S_LSHIFT { $$ = mm_strdup("<<"); }
1802
| S_MEMBER { $$ = mm_strdup("->"); }
1803
| S_MEMPOINT { $$ = mm_strdup("->*"); }
1804
| S_MOD { $$ = mm_strdup("%="); }
1805
| S_MUL { $$ = mm_strdup("*="); }
1806
| S_NEQUAL { $$ = mm_strdup("!="); }
1807
| S_OR { $$ = mm_strdup("||"); }
1808
| S_REGISTER { $$ = mm_strdup("register"); }
1809
| S_RSHIFT { $$ = mm_strdup(">>"); }
1810
| S_STATIC { $$ = mm_strdup("static"); }
1811
| S_SUB { $$ = mm_strdup("-="); }
1812
| S_TYPEDEF { $$ = mm_strdup("typedef"); }
1813
| S_VOLATILE { $$ = mm_strdup("volatile"); }
1814
| SQL_BOOL { $$ = mm_strdup("bool"); }
1815
| ENUM_P { $$ = mm_strdup("enum"); }
1816
| HOUR_P { $$ = mm_strdup("hour"); }
1817
| INT_P { $$ = mm_strdup("int"); }
1818
| SQL_LONG { $$ = mm_strdup("long"); }
1819
| MINUTE_P { $$ = mm_strdup("minute"); }
1820
| MONTH_P { $$ = mm_strdup("month"); }
1821
| SECOND_P { $$ = mm_strdup("second"); }
1822
| SQL_SHORT { $$ = mm_strdup("short"); }
1823
| SQL_SIGNED { $$ = mm_strdup("signed"); }
1824
| SQL_STRUCT { $$ = mm_strdup("struct"); }
1825
| SQL_UNSIGNED { $$ = mm_strdup("unsigned"); }
1826
| YEAR_P { $$ = mm_strdup("year"); }
1827
| CHAR_P { $$ = mm_strdup("char"); }
1828
| FLOAT_P { $$ = mm_strdup("float"); }
1829
| TO { $$ = mm_strdup("to"); }
1830
| UNION { $$ = mm_strdup("union"); }
1831
| VARCHAR { $$ = mm_strdup("varchar"); }
1832
| '[' { $$ = mm_strdup("["); }
1833
| ']' { $$ = mm_strdup("]"); }
1834
| '=' { $$ = mm_strdup("="); }
1835
| ':' { $$ = mm_strdup(":"); }
1838
DeallocateStmt: DEALLOCATE prepared_name { $$ = $2; }
1839
| DEALLOCATE PREPARE prepared_name { $$ = $3; }
1840
| DEALLOCATE ALL { $$ = mm_strdup("all"); }
1841
| DEALLOCATE PREPARE ALL { $$ = mm_strdup("all"); }
1844
Iresult: Iconst { $$ = $1; }
1845
| '(' Iresult ')' { $$ = cat_str(3, mm_strdup("("), $2, mm_strdup(")")); }
1846
| Iresult '+' Iresult { $$ = cat_str(3, $1, mm_strdup("+"), $3); }
1847
| Iresult '-' Iresult { $$ = cat_str(3, $1, mm_strdup("-"), $3); }
1848
| Iresult '*' Iresult { $$ = cat_str(3, $1, mm_strdup("*"), $3); }
1849
| Iresult '/' Iresult { $$ = cat_str(3, $1, mm_strdup("/"), $3); }
1850
| Iresult '%' Iresult { $$ = cat_str(3, $1, mm_strdup("%"), $3); }
1851
| ecpg_sconst { $$ = $1; }
1852
| ColId { $$ = $1; }
1855
execute_rest: /* EMPTY */ { $$ = EMPTY; }
1856
| ecpg_using ecpg_into { $$ = EMPTY; }
1857
| ecpg_into ecpg_using { $$ = EMPTY; }
1858
| ecpg_using { $$ = EMPTY; }
1859
| ecpg_into { $$ = EMPTY; }
1862
ecpg_into: INTO into_list { $$ = EMPTY; }
1863
| into_descriptor { $$ = $1; }
1866
ecpg_fetch_into: ecpg_into { $$ = $1; }
1869
struct variable *var;
1871
var = argsinsert->variable;
1872
remove_variable_from_list(&argsinsert, var);
1873
add_variable_to_head(&argsresult, var, &no_indicator);
1878
opt_ecpg_fetch_into: /* EMPTY */ { $$ = EMPTY; }
1879
| ecpg_fetch_into { $$ = $1; }
1884
void base_yyerror(const char *error)
1886
/* translator: %s is typically the translation of "syntax error" */
1887
mmerror(PARSE_ERROR, ET_ERROR, "%s at or near \"%s\"",
1888
_(error), token_start ? token_start : yytext);
1891
void parser_init(void)
1893
/* This function is empty. It only exists for compatibility with the backend parser right now. */
1897
* Must undefine base_yylex before including pgc.c, since we want it
1898
* to create the function base_yylex not filtered_base_yylex.