Fix xslt_process() to ensure that it inserts a NULL terminator after the
[PostgreSQL.git] / src / interfaces / ecpg / preproc / ecpg.trailer
blobf124a15488ceee3d33d83bcc1c7b6dcd14650da1
1 /* $PostgreSQL$ */
3 statements: /*EMPTY*/
4                 | statements statement
5                 ;
7 statement: ecpgstart at stmt ';'        { connection = NULL; }
8                 | ecpgstart stmt ';'
9                 | ecpgstart ECPGVarDeclaration
10                 {
11                         fprintf(yyout, "%s", $2);
12                         free($2);
13                         output_line_number();
14                 }
15                 | ECPGDeclaration
16                 | c_thing               { fprintf(yyout, "%s", $1); free($1); }
17                 | CPP_LINE              { fprintf(yyout, "%s", $1); free($1); }
18                 | '{'                   { braces_open++; fputs("{", yyout); }
19                 | '}'                   { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); }
20                 ;
22 CreateAsStmt: CREATE OptTemp TABLE create_as_target AS {FoundInto = 0;} SelectStmt opt_with_data
23                 {
24                         if (FoundInto == 1)
25                                 mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE AS cannot specify INTO");
27                         $$ = cat_str(6, make_str("create"), $2, make_str("table"), $4, make_str("as"), $7);
28                 }
29         ;
31 RuleStmt: CREATE opt_or_replace RULE name AS
32                 {QueryIsRule = 1;}
33                 ON event TO qualified_name where_clause
34                 DO opt_instead RuleActionList
35                 {
36                         QueryIsRule=0;
37                         $$ = 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);
38                 }
39         ;
41 at: AT connection_object
42                 {
43                         connection = $2;
44                         /*
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
48                          */
49                         if (argsinsert != NULL)
50                                 argsinsert = NULL;
51                 }
52         ;
55  * the exec sql connect statement: connect to the given database
56  */
57 ECPGConnect: SQL_CONNECT TO connection_target opt_connection_name opt_user
58                         { $$ = cat_str(5, $3, make_str(","), $5, make_str(","), $4); }
59                 | SQL_CONNECT TO DEFAULT
60                         { $$ = make_str("NULL, NULL, NULL, \"DEFAULT\""); }
61                   /* also allow ORACLE syntax */
62                 | SQL_CONNECT ora_user
63                         { $$ = cat_str(3, make_str("NULL,"), $2, make_str(", NULL")); }
64                 | DATABASE connection_target
65                         { $$ = cat2_str($2, make_str(", NULL, NULL, NULL")); }
66                 ;
68 connection_target: opt_database_name opt_server opt_port
69                 {
70                         /* old style: dbname[@server][:port] */
71                         if (strlen($2) > 0 && *($2) != '@')
72                                 mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\", found \"%s\"", $2);
73                         
74                         /* C strings need to be handled differently */
75                         if ($1[0] == '\"')
76                                 $$ = $1;
77                         else
78                                 $$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
79                 }
80                 |  db_prefix ':' server opt_port '/' opt_database_name opt_options
81                 {
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(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6),    $7, make_str("\"")));
95                 }
96                 | char_variable
97                 {
98                         $$ = $1;
99                 }
100                 | ecpg_sconst
101                 {
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. */
105                         $1[0] = '\"';
106                         $1[strlen($1)-1] = '\"';
107                         $$ = $1;
108                 }
109                 ;
111 opt_database_name: database_name                { $$ = $1; }
112                 | /*EMPTY*/                     { $$ = EMPTY; }
113                 ;
115 db_prefix: ecpg_ident cvariable
116                 {
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, make_str(":"), $2);
124                 }
125                 ;
127 server: Op server_name
128                 {
129                         if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
130                                 mmerror(PARSE_ERROR, ET_ERROR, "expected \"@\" or \"://\", found \"%s\"", $1);
132                         $$ = make2_str($1, $2);
133                 }
134                 ;
136 opt_server: server                      { $$ = $1; }
137                 | /*EMPTY*/                     { $$ = EMPTY; }
138                 ;
140 server_name: ColId                                      { $$ = $1; }
141                 | ColId '.' server_name         { $$ = make3_str($1, make_str("."), $3); }
142                 | IP                                            { $$ = make_name(); }
143                 ;
145 opt_port: ':' Iconst            { $$ = make2_str(make_str(":"), $2); }
146                 | /*EMPTY*/     { $$ = EMPTY; }
147                 ;
149 opt_connection_name: AS connection_object       { $$ = $2; }
150                 | /*EMPTY*/                     { $$ = make_str("NULL"); }
151                 ;
153 opt_user: USER ora_user         { $$ = $2; }
154                 | /*EMPTY*/                     { $$ = make_str("NULL, NULL"); }
155                 ;
157 ora_user: user_name
158                         { $$ = cat2_str($1, make_str(", NULL")); }
159                 | user_name '/' user_name
160                         { $$ = cat_str(3, $1, make_str(","), $3); }
161                 | user_name SQL_IDENTIFIED BY user_name
162                         { $$ = cat_str(3, $1, make_str(","), $4); }
163                 | user_name USING user_name
164                         { $$ = cat_str(3, $1, make_str(","), $3); }
165                 ;
167 user_name: RoleId
168                 {
169                         if ($1[0] == '\"')
170                                 $$ = $1;
171                         else
172                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
173                 }
174                 | ecpg_sconst
175                 {
176                         if ($1[0] == '\"')
177                                 $$ = $1;
178                         else
179                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
180                 }
181                 | civar
182                 {
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), make_str(".arr"));
192                         else
193                                 $$ = mm_strdup(argsinsert->variable->name);
194                 }
195                 ;
197 char_variable: cvariable
198                 {
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");
206                         else
207                         {
208                                 /* if array see what's inside */
209                                 if (type == ECPGt_array)
210                                         type = p->type->u.element->type;
212                                 switch (type)
213                                 {
214                                         case ECPGt_char:
215                                         case ECPGt_unsigned_char:
216                                                 $$ = $1;
217                                                 break;
218                                         case ECPGt_varchar:
219                                                 $$ = make2_str($1, make_str(".arr"));
220                                                 break;
221                                         default:
222                                                 mmerror(PARSE_ERROR, ET_ERROR, "invalid data type");
223                                                 $$ = $1;
224                                                 break;
225                                 }
226                         }
227                 }
228                 ;
230 opt_options: Op connect_options
231                 {
232                         if (strlen($1) == 0)
233                                 mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
235                         if (strcmp($1, "?") != 0)
236                                 mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $1);
238                         $$ = make2_str(make_str("?"), $2);
239                 }
240                 | /*EMPTY*/     { $$ = EMPTY; }
241                 ;
243 connect_options:  ColId opt_opt_value 
244                         { $$ = make2_str($1, $2); }
245         | ColId opt_opt_value Op connect_options
246                         {
247                                 if (strlen($3) == 0)
248                                         mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
250                                 if (strcmp($3, "&") != 0)
251                                         mmerror(PARSE_ERROR, ET_ERROR, "unrecognized token \"%s\"", $3);
253                                 $$ = cat_str(3, make2_str($1, $2), $3, $4);
254                         }
255         ;
257 opt_opt_value: /*EMPTY*/
258                         { $$ = EMPTY; }
259                 | '=' Iconst
260                         { $$ = make2_str(make_str("="), $2); }
261                 | '=' ecpg_ident
262                         { $$ = make2_str(make_str("="), $2); }
263                 | '=' civar
264                         { $$ = make2_str(make_str("="), $2); }
265                 ;
267 prepared_name: name             {
268                                         if ($1[0] == '\"' && $1[strlen($1)-1] == '\"') /* already quoted? */
269                                                 $$ = $1;
270                                         else /* not quoted => convert to lowercase */
271                                         {
272                                                 int i;
274                                                 for (i = 0; i< strlen($1); i++)
275                                                         $1[i] = tolower((unsigned char) $1[i]);
277                                                 $$ = make3_str(make_str("\""), $1, make_str("\""));
278                                         }
279                                 }
280                 | char_variable { $$ = $1; }
281                 ;
284  * Declare a prepared cursor. The syntax is different from the standard
285  * declare statement, so we create a new rule.
286  */
287 ECPGCursorStmt:  DECLARE name cursor_options CURSOR opt_hold FOR prepared_name
288                 {
289                         struct cursor *ptr, *this;
290                         struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
291                         const char *con = connection ? connection : "NULL";
293                         for (ptr = cur; ptr != NULL; ptr = ptr->next)
294                         {
295                                 if (strcmp($2, ptr->name) == 0)
296                                         /* re-definition is a bug */
297                                         mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" is already defined", $2);
298                         }
300                         this = (struct cursor *) mm_alloc(sizeof(struct cursor));
302                         /* initial definition */
303                         this->next = cur;
304                         this->name = $2;
305                         this->connection = connection;
306                         this->command =  cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for $1"));
307                         this->argsresult = NULL;
309                         thisquery->type = &ecpg_query;
310                         thisquery->brace_level = 0;
311                         thisquery->next = NULL;
312                         thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(, , __LINE__)") + strlen(con) + strlen($7));
313                         sprintf(thisquery->name, "ECPGprepared_statement(%s, %s, __LINE__)", con, $7);
315                         this->argsinsert = NULL;
316                         add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
318                         cur = this;
320                         $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
321                 }
322                 ;
324 ECPGExecuteImmediateStmt: EXECUTE IMMEDIATE execstring
325                         { 
326                           /* execute immediate means prepare the statement and
327                            * immediately execute it */
328                           $$ = $3;
329                         };
331  * variable decalartion outside exec sql declare block
332  */
333 ECPGVarDeclaration: single_vt_declaration;
335 single_vt_declaration: type_declaration         { $$ = $1; }
336                 | var_declaration               { $$ = $1; }
337                 ;
339 precision:      NumericOnly     { $$ = $1; };
341 opt_scale:      ',' NumericOnly { $$ = $2; }
342                 | /* EMPTY */   { $$ = EMPTY; }
343                 ;
345 ecpg_interval:  opt_interval    { $$ = $1; }
346                 | YEAR_P TO MINUTE_P    { $$ = make_str("year to minute"); }
347                 | YEAR_P TO SECOND_P    { $$ = make_str("year to second"); }
348                 | DAY_P TO DAY_P                { $$ = make_str("day to day"); }
349                 | MONTH_P TO MONTH_P    { $$ = make_str("month to month"); }
350                 ;
353  * variable declaration inside exec sql declare block
354  */
355 ECPGDeclaration: sql_startdeclare
356                 { fputs("/* exec sql begin declare section */", yyout); }
357                 var_type_declarations sql_enddeclare
358                 {
359                         fprintf(yyout, "%s/* exec sql end declare section */", $3);
360                         free($3);
361                         output_line_number();
362                 }
363                 ;
365 sql_startdeclare: ecpgstart BEGIN_P DECLARE SQL_SECTION ';' {};
367 sql_enddeclare: ecpgstart END_P DECLARE SQL_SECTION ';' {};
369 var_type_declarations:  /*EMPTY*/                       { $$ = EMPTY; }
370                 | vt_declarations                       { $$ = $1; }
371                 | CPP_LINE                              { $$ = $1; }
372                 ;
374 vt_declarations:  var_declaration                       { $$ = $1; }
375                 | type_declaration                      { $$ = $1; }
376                 | vt_declarations var_declaration       { $$ = cat2_str($1, $2); }
377                 | vt_declarations type_declaration      { $$ = cat2_str($1, $2); }
378                 | vt_declarations CPP_LINE              { $$ = cat2_str($1, $2); }
379                 ;
381 variable_declarations:  var_declaration         { $$ = $1; }
382                 | variable_declarations var_declaration         { $$ = cat2_str($1, $2); }
383                 ;
385 type_declaration: S_TYPEDEF
386         {
387                 /* reset this variable so we see if there was */
388                 /* an initializer specified */
389                 initializer = 0;
390         }
391         var_type opt_pointer ECPGColLabelCommon opt_array_bounds ';'
392         {
393                 add_typedef($5, $6.index1, $6.index2, $3.type_enum, $3.type_dimension, $3.type_index, initializer, *$4 ? 1 : 0);
395                 fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4 ? "*" : "", $5, $6.str);
396                 output_line_number();
397                 $$ = make_str("");
398         };
400 var_declaration: storage_declaration
401                 var_type
402                 {
403                         actual_type[struct_level].type_enum = $2.type_enum;
404                         actual_type[struct_level].type_dimension = $2.type_dimension;
405                         actual_type[struct_level].type_index = $2.type_index;
406                         actual_type[struct_level].type_sizeof = $2.type_sizeof;
408                         actual_startline[struct_level] = hashline_number();
409                 }
410                 variable_list ';'
411                 {
412                         $$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
413                 }
414                 | var_type
415                 {
416                         actual_type[struct_level].type_enum = $1.type_enum;
417                         actual_type[struct_level].type_dimension = $1.type_dimension;
418                         actual_type[struct_level].type_index = $1.type_index;
419                         actual_type[struct_level].type_sizeof = $1.type_sizeof;
421                         actual_startline[struct_level] = hashline_number();
422                 }
423                 variable_list ';'
424                 {
425                         $$ = cat_str(4, actual_startline[struct_level], $1.type_str, $3, make_str(";\n"));
426                 }
427                 | struct_union_type_with_symbol ';'
428                 {
429                         $$ = cat2_str($1, make_str(";"));
430                 }
431                 ;
433 opt_bit_field:  ':' Iconst      { $$ =cat2_str(make_str(":"), $2); }
434                 | /* EMPTY */   { $$ = EMPTY; }
435                 ;
437 storage_declaration: storage_clause storage_modifier
438                         {$$ = cat2_str ($1, $2); }
439                 | storage_clause                {$$ = $1; }
440                 | storage_modifier              {$$ = $1; }
441                 ;
443 storage_clause : S_EXTERN       { $$ = make_str("extern"); }
444                 | S_STATIC                      { $$ = make_str("static"); }
445                 | S_REGISTER            { $$ = make_str("register"); }
446                 | S_AUTO                        { $$ = make_str("auto"); }
447                 ;
449 storage_modifier : S_CONST      { $$ = make_str("const"); }
450                 | S_VOLATILE            { $$ = make_str("volatile"); }
451                 ;
453 var_type:       simple_type
454                 {
455                         $$.type_enum = $1;
456                         $$.type_str = mm_strdup(ecpg_type_name($1));
457                         $$.type_dimension = make_str("-1");
458                         $$.type_index = make_str("-1");
459                         $$.type_sizeof = NULL;
460                 }
461                 | struct_union_type
462                 {
463                         $$.type_str = $1;
464                         $$.type_dimension = make_str("-1");
465                         $$.type_index = make_str("-1");
467                         if (strncmp($1, "struct", sizeof("struct")-1) == 0)
468                         {
469                                 $$.type_enum = ECPGt_struct;
470                                 $$.type_sizeof = ECPGstruct_sizeof;
471                         }
472                         else
473                         {
474                                 $$.type_enum = ECPGt_union;
475                                 $$.type_sizeof = NULL;
476                         }
477                 }
478                 | enum_type
479                 {
480                         $$.type_str = $1;
481                         $$.type_enum = ECPGt_int;
482                         $$.type_dimension = make_str("-1");
483                         $$.type_index = make_str("-1");
484                         $$.type_sizeof = NULL;
485                 }
486                 | ECPGColLabelCommon '(' precision opt_scale ')'
487                 {
488                         if (strcmp($1, "numeric") == 0)
489                         {
490                                 $$.type_enum = ECPGt_numeric;
491                                 $$.type_str = make_str("numeric");
492                         }
493                         else if (strcmp($1, "decimal") == 0)
494                         {
495                                 $$.type_enum = ECPGt_decimal;
496                                 $$.type_str = make_str("decimal");
497                         }
498                         else
499                         {
500                                 mmerror(PARSE_ERROR, ET_ERROR, "only data types numeric and decimal have precision/scale argument");
501                                 $$.type_enum = ECPGt_numeric;
502                                 $$.type_str = make_str("numeric");
503                         }
505                         $$.type_dimension = make_str("-1");
506                         $$.type_index = make_str("-1");
507                         $$.type_sizeof = NULL;
508                 }
509                 | ECPGColLabelCommon ecpg_interval
510                 {
511                         if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
512                                 mmerror (PARSE_ERROR, ET_ERROR, "interval specification not allowed here");
514                         /*
515                          * Check for type names that the SQL grammar treats as
516                          * unreserved keywords
517                          */
518                         if (strcmp($1, "varchar") == 0)
519                         {
520                                 $$.type_enum = ECPGt_varchar;
521                                 $$.type_str = EMPTY; /*make_str("varchar");*/
522                                 $$.type_dimension = make_str("-1");
523                                 $$.type_index = make_str("-1");
524                                 $$.type_sizeof = NULL;
525                         }
526                         else if (strcmp($1, "float") == 0)
527                         {
528                                 $$.type_enum = ECPGt_float;
529                                 $$.type_str = make_str("float");
530                                 $$.type_dimension = make_str("-1");
531                                 $$.type_index = make_str("-1");
532                                 $$.type_sizeof = NULL;
533                         }
534                         else if (strcmp($1, "double") == 0)
535                         {
536                                 $$.type_enum = ECPGt_double;
537                                 $$.type_str = make_str("double");
538                                 $$.type_dimension = make_str("-1");
539                                 $$.type_index = make_str("-1");
540                                 $$.type_sizeof = NULL;
541                         }
542                         else if (strcmp($1, "numeric") == 0)
543                         {
544                                 $$.type_enum = ECPGt_numeric;
545                                 $$.type_str = make_str("numeric");
546                                 $$.type_dimension = make_str("-1");
547                                 $$.type_index = make_str("-1");
548                                 $$.type_sizeof = NULL;
549                         }
550                         else if (strcmp($1, "decimal") == 0)
551                         {
552                                 $$.type_enum = ECPGt_decimal;
553                                 $$.type_str = make_str("decimal");
554                                 $$.type_dimension = make_str("-1");
555                                 $$.type_index = make_str("-1");
556                                 $$.type_sizeof = NULL;
557                         }
558                         else if (strcmp($1, "date") == 0)
559                         {
560                                 $$.type_enum = ECPGt_date;
561                                 $$.type_str = make_str("date");
562                                 $$.type_dimension = make_str("-1");
563                                 $$.type_index = make_str("-1");
564                                 $$.type_sizeof = NULL;
565                         }
566                         else if (strcmp($1, "timestamp") == 0)
567                         {
568                                 $$.type_enum = ECPGt_timestamp;
569                                 $$.type_str = make_str("timestamp");
570                                 $$.type_dimension = make_str("-1");
571                                 $$.type_index = make_str("-1");
572                                 $$.type_sizeof = NULL;
573                         }
574                         else if (strcmp($1, "interval") == 0)
575                         {
576                                 $$.type_enum = ECPGt_interval;
577                                 $$.type_str = make_str("interval");
578                                 $$.type_dimension = make_str("-1");
579                                 $$.type_index = make_str("-1");
580                                 $$.type_sizeof = NULL;
581                         }
582                         else if (strcmp($1, "datetime") == 0)
583                         {
584                                 $$.type_enum = ECPGt_timestamp;
585                                 $$.type_str = make_str("timestamp");
586                                 $$.type_dimension = make_str("-1");
587                                 $$.type_index = make_str("-1");
588                                 $$.type_sizeof = NULL;
589                         }
590                         else
591                         {
592                                 /* this is for typedef'ed types */
593                                 struct typedefs *this = get_typedef($1);
595                                 $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
596                                 $$.type_enum = this->type->type_enum;
597                                 $$.type_dimension = this->type->type_dimension;
598                                 $$.type_index = this->type->type_index;
599                                 if (this->type->type_sizeof && strlen(this->type->type_sizeof) != 0)
600                                         $$.type_sizeof = this->type->type_sizeof;
601                                 else 
602                                         $$.type_sizeof = cat_str(3, make_str("sizeof("), mm_strdup(this->name), make_str(")"));
604                                 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
605                         }
606                 }
607                 | s_struct_union_symbol
608                 {
609                         /* this is for named structs/unions */
610                         char *name;
611                         struct typedefs *this;
612                         bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
614                         name = cat2_str($1.su, $1.symbol);
615                         /* Do we have a forward definition? */
616                         if (!forward)
617                         {
618                                 /* No */
620                                 this = get_typedef(name);
621                                 $$.type_str = mm_strdup(this->name);
622                                 $$.type_enum = this->type->type_enum;
623                                 $$.type_dimension = this->type->type_dimension;
624                                 $$.type_index = this->type->type_index;
625                                 $$.type_sizeof = this->type->type_sizeof;
626                                 struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
627                                 free(name);
628                         }
629                         else
630                         {
631                                 $$.type_str = name;
632                                 $$.type_enum = ECPGt_long;
633                                 $$.type_dimension = make_str("-1");
634                                 $$.type_index = make_str("-1");
635                                 $$.type_sizeof = make_str("");
636                                 struct_member_list[struct_level] = NULL;
637                         }
638                 }
639                 ;
641 enum_type: ENUM_P symbol enum_definition
642                         { $$ = cat_str(3, make_str("enum"), $2, $3); }
643                 | ENUM_P enum_definition
644                         { $$ = cat2_str(make_str("enum"), $2); }
645                 | ENUM_P symbol
646                         { $$ = cat2_str(make_str("enum"), $2); }
647                 ;
649 enum_definition: '{' c_list '}'
650                         { $$ = cat_str(3, make_str("{"), $2, make_str("}")); };
652 struct_union_type_with_symbol: s_struct_union_symbol
653                 {
654                         struct_member_list[struct_level++] = NULL;
655                         if (struct_level >= STRUCT_DEPTH)
656                                  mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
657                         forward_name = mm_strdup($1.symbol);
658                 }
659                 '{' variable_declarations '}'
660                 {
661                         struct typedefs *ptr, *this;
662                         struct this_type su_type;
664                         ECPGfree_struct_member(struct_member_list[struct_level]);
665                         struct_member_list[struct_level] = NULL;
666                         struct_level--;
667                         if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
668                                 su_type.type_enum = ECPGt_struct;
669                         else
670                                 su_type.type_enum = ECPGt_union;
671                         su_type.type_str = cat2_str($1.su, $1.symbol);
672                         free(forward_name);
673                         forward_name = NULL;
675                         /* This is essantially a typedef but needs the keyword struct/union as well.
676                          * So we create the typedef for each struct definition with symbol */
677                         for (ptr = types; ptr != NULL; ptr = ptr->next)
678                         {
679                                         if (strcmp(su_type.type_str, ptr->name) == 0)
680                                                         /* re-definition is a bug */
681                                                         mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" is already defined", su_type.type_str);
682                         }
684                         this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
686                         /* initial definition */
687                         this->next = types;
688                         this->name = mm_strdup(su_type.type_str);
689                         this->brace_level = braces_open;
690                         this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
691                         this->type->type_enum = su_type.type_enum;
692                         this->type->type_str = mm_strdup(su_type.type_str);
693                         this->type->type_dimension = make_str("-1"); /* dimension of array */
694                         this->type->type_index = make_str("-1");        /* length of string */
695                         this->type->type_sizeof = ECPGstruct_sizeof;
696                         this->struct_member_list = struct_member_list[struct_level];
698                         types = this;
699                         $$ = cat_str(4, su_type.type_str, make_str("{"), $4, make_str("}"));
700                 }
701                 ;
703 struct_union_type: struct_union_type_with_symbol        { $$ = $1; }
704                 | s_struct_union
705                 {
706                         struct_member_list[struct_level++] = NULL;
707                         if (struct_level >= STRUCT_DEPTH)
708                                  mmerror(PARSE_ERROR, ET_ERROR, "too many levels in nested structure/union definition");
709                 }
710                 '{' variable_declarations '}'
711                 {
712                         ECPGfree_struct_member(struct_member_list[struct_level]);
713                         struct_member_list[struct_level] = NULL;
714                         struct_level--;
715                         $$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
716                 }
717                 ;
719 s_struct_union_symbol: SQL_STRUCT symbol
720                 {
721                         $$.su = make_str("struct");
722                         $$.symbol = $2;
723                         ECPGstruct_sizeof = cat_str(3, make_str("sizeof("), cat2_str(mm_strdup($$.su), mm_strdup($$.symbol)), make_str(")"));
724                 }
725                 | UNION symbol
726                 {
727                         $$.su = make_str("union");
728                         $$.symbol = $2;
729                 }
730                 ;
732 s_struct_union: SQL_STRUCT
733                 {
734                         ECPGstruct_sizeof = make_str(""); /* This must not be NULL to distinguish from simple types. */
735                         $$ = make_str("struct");
736                 }
737                 | UNION         { $$ = make_str("union"); }
738                 ;
740 simple_type: unsigned_type                                      { $$=$1; }
741                 |       opt_signed signed_type                  { $$=$2; }
742                 ;
744 unsigned_type: SQL_UNSIGNED SQL_SHORT           { $$ = ECPGt_unsigned_short; }
745                 | SQL_UNSIGNED SQL_SHORT INT_P  { $$ = ECPGt_unsigned_short; }
746                 | SQL_UNSIGNED                                          { $$ = ECPGt_unsigned_int; }
747                 | SQL_UNSIGNED INT_P                            { $$ = ECPGt_unsigned_int; }
748                 | SQL_UNSIGNED SQL_LONG                         { $$ = ECPGt_unsigned_long; }
749                 | SQL_UNSIGNED SQL_LONG INT_P           { $$ = ECPGt_unsigned_long; }
750                 | SQL_UNSIGNED SQL_LONG SQL_LONG
751                 {
752 #ifdef HAVE_LONG_LONG_INT_64
753                         $$ = ECPGt_unsigned_long_long;
754 #else
755                         $$ = ECPGt_unsigned_long;
756 #endif
757                 }
758                 | SQL_UNSIGNED SQL_LONG SQL_LONG INT_P
759                 {
760 #ifdef HAVE_LONG_LONG_INT_64
761                         $$ = ECPGt_unsigned_long_long;
762 #else
763                         $$ = ECPGt_unsigned_long;
764 #endif
765                 }
766                 | SQL_UNSIGNED CHAR_P                   { $$ = ECPGt_unsigned_char; }
767                 ;
769 signed_type: SQL_SHORT                          { $$ = ECPGt_short; }
770                 | SQL_SHORT INT_P                       { $$ = ECPGt_short; }
771                 | INT_P                                         { $$ = ECPGt_int; }
772                 | SQL_LONG                                      { $$ = ECPGt_long; }
773                 | SQL_LONG INT_P                        { $$ = ECPGt_long; }
774                 | SQL_LONG SQL_LONG
775                 {
776 #ifdef HAVE_LONG_LONG_INT_64
777                         $$ = ECPGt_long_long;
778 #else
779                         $$ = ECPGt_long;
780 #endif
781                 }
782                 | SQL_LONG SQL_LONG INT_P
783                 {
784 #ifdef HAVE_LONG_LONG_INT_64
785                         $$ = ECPGt_long_long;
786 #else
787                         $$ = ECPGt_long;
788 #endif
789                 }
790                 | SQL_BOOL                                      { $$ = ECPGt_bool; }
791                 | CHAR_P                                        { $$ = ECPGt_char; }
792                 | DOUBLE_P                                      { $$ = ECPGt_double; }
793                 ;
795 opt_signed: SQL_SIGNED
796                 |       /* EMPTY */
797                 ;
799 variable_list: variable
800                         { $$ = $1; }
801                 | variable_list ',' variable
802                         { $$ = cat_str(3, $1, make_str(","), $3); }
803                 ;
805 variable: opt_pointer ECPGColLabel opt_array_bounds opt_bit_field opt_initializer
806                 {
807                         struct ECPGtype * type;
808                         char *dimension = $3.index1; /* dimension of array */
809                         char *length = $3.index2;    /* length of string */
810                         char dim[14L];
811                         char *vcn;
813                         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);
815                         switch (actual_type[struct_level].type_enum)
816                         {
817                                 case ECPGt_struct:
818                                 case ECPGt_union:
819                                         if (atoi(dimension) < 0)
820                                                 type = ECPGmake_struct_type(struct_member_list[struct_level], actual_type[struct_level].type_enum, actual_type[struct_level].type_sizeof);
821                                         else
822                                                 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);
824                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
825                                         break;
827                                 case ECPGt_varchar:
828                                         if (atoi(dimension) < 0)
829                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno);
830                                         else
831                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, yylineno), dimension);
832                                         
833                                         if (strcmp(dimension, "0") == 0 || abs(atoi(dimension)) == 1)
834                                                         *dim = '\0';
835                                         else
836                                                         sprintf(dim, "[%s]", dimension);
837                                         /* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
838                                         if (atoi(length) < 0 || strcmp(length, "0") == 0)
839                                                 mmerror(PARSE_ERROR, ET_ERROR, "pointers to varchar are not implemented");
841                                         /* make sure varchar struct name is unique by adding linenumer of its definition */
842                                         vcn = (char *) mm_alloc(strlen($2) + sizeof(int) * CHAR_BIT * 10 / 3);
843                                         sprintf(vcn, "%s_%d", $2, yylineno);
844                                         if (strcmp(dimension, "0") == 0)
845                                                 $$ = cat_str(7, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } *"), mm_strdup($2), $4, $5);
846                                         else
847                                                 $$ = cat_str(8, make2_str(make_str(" struct varchar_"), vcn), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4, $5);
848                                         break;
850                                 case ECPGt_char:
851                                 case ECPGt_unsigned_char:
852                                         if (atoi(dimension) == -1)
853                                         {
854                                                 int i = strlen($5);
856                                                 if (atoi(length) == -1 && i > 0) /* char <var>[] = "string" */
857                                                 {
858                                                         /* if we have an initializer but no string size set, let's use the initializer's length */
859                                                         free(length);
860                                                         length = mm_alloc(i+sizeof("sizeof()"));
861                                                         sprintf(length, "sizeof(%s)", $5+2);
862                                                 }
863                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0);
864                                         }
865                                         else
866                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length, 0), dimension);
868                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
869                                         break;
871                                 default:
872                                         if (atoi(dimension) < 0)
873                                                 type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0);
874                                         else
875                                                 type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"), 0), dimension);
877                                         $$ = cat_str(5, $1, mm_strdup($2), $3.str, $4, $5);
878                                         break;
879                         }
881                         if (struct_level == 0)
882                                 new_variable($2, type, braces_open);
883                         else
884                                 ECPGmake_struct_member($2, type, &(struct_member_list[struct_level - 1]));
886                         free($2);
887                 }
888                 ;
890 opt_initializer: /*EMPTY*/
891                         { $$ = EMPTY; }
892                 | '=' c_term
893                 {
894                         initializer = 1;
895                         $$ = cat2_str(make_str("="), $2);
896                 }
897                 ;
899 opt_pointer: /*EMPTY*/                          { $$ = EMPTY; }
900                 | '*'                                           { $$ = make_str("*"); }
901                 | '*' '*'                                       { $$ = make_str("**"); }
902                 ;
905  * We try to simulate the correct DECLARE syntax here so we get dynamic SQL
906  */
907 ECPGDeclare: DECLARE STATEMENT ecpg_ident
908                 {
909                         /* this is only supported for compatibility */
910                         $$ = cat_str(3, make_str("/* declare statement"), $3, make_str("*/"));
911                 }
912                 ;
914  * the exec sql disconnect statement: disconnect from the given database
915  */
916 ECPGDisconnect: SQL_DISCONNECT dis_name { $$ = $2; }
917                 ;
919 dis_name: connection_object                     { $$ = $1; }
920                 | CURRENT_P                     { $$ = make_str("\"CURRENT\""); }
921                 | ALL                           { $$ = make_str("\"ALL\""); }
922                 | /* EMPTY */                   { $$ = make_str("\"CURRENT\""); }
923                 ;
925 connection_object: database_name                { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
926                 | DEFAULT                       { $$ = make_str("\"DEFAULT\""); }
927                 | char_variable                 { $$ = $1; }
928                 ;
930 execstring: char_variable
931                         { $$ = $1; }
932                 |       CSTRING
933                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
934                 ;
937  * the exec sql free command to deallocate a previously
938  * prepared statement
939  */
940 ECPGFree:       SQL_FREE name   { $$ = $2; }
941                 | SQL_FREE ALL  { $$ = make_str("all"); }
942                 ;
945  * open is an open cursor, at the moment this has to be removed
946  */
947 ECPGOpen: SQL_OPEN name opt_ecpg_using { $$ = $2; };
949 opt_ecpg_using: /*EMPTY*/       { $$ = EMPTY; }
950                 | ecpg_using            { $$ = $1; }
951                 ;
953 ecpg_using:     USING using_list        { $$ = EMPTY; }
954                 | using_descriptor      { $$ = $1; }
955                 ;
957 using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
958                 {
959                         add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
960                         $$ = EMPTY;
961                 }
962                 ;
964 into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
965                 {
966                         add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
967                         $$ = EMPTY;
968                 }
969                 ;
971 opt_sql: /*EMPTY*/ | SQL_SQL;
973 using_list: UsingValue | UsingValue ',' using_list;
975 UsingValue: UsingConst
976                 {
977                         char *length = mm_alloc(32);
979                         sprintf(length, "%d", (int) strlen($1));
980                         add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0), &no_indicator);
981                 }
982                 | civar { $$ = EMPTY; }
983                 | civarind { $$ = EMPTY; }
984                 ; 
986 UsingConst: Iconst                      { $$ = $1; }
987                 | '+' Iconst            { $$ = cat_str(2, make_str("+"), $2); }
988                 | '-' Iconst            { $$ = cat_str(2, make_str("-"), $2); }
989                 | ecpg_fconst           { $$ = $1; }
990                 | '+' ecpg_fconst       { $$ = cat_str(2, make_str("+"), $2); }
991                 | '-' ecpg_fconst       { $$ = cat_str(2, make_str("-"), $2); }
992                 | ecpg_sconst           { $$ = $1; }
993                 | ecpg_bconst           { $$ = $1; }
994                 | ecpg_xconst           { $$ = $1; }
995                 ;
998  * We accept descibe but do nothing with it so far.
999  */
1000 ECPGDescribe: SQL_DESCRIBE INPUT_P name using_descriptor
1001         {
1002                 const char *con = connection ? connection : "NULL";
1003                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
1004                 $$ = (char *) mm_alloc(sizeof("1, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
1005                 sprintf($$, "1, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
1006         }
1007         | SQL_DESCRIBE opt_output name using_descriptor
1008         {
1009                 const char *con = connection ? connection : "NULL";
1010                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
1011                 $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
1012                 sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
1013         }
1014         | SQL_DESCRIBE opt_output name into_descriptor
1015         {
1016                 const char *con = connection ? connection : "NULL";
1017                 mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
1018                 $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
1019                 sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
1020         }
1021         ;
1023 opt_output:     SQL_OUTPUT      { $$ = make_str("output"); }
1024         |       /* EMPTY */     { $$ = EMPTY; }
1025         ;
1028  * dynamic SQL: descriptor based access
1029  *      originall written by Christof Petig <christof.petig@wtal.de>
1030  *                      and Peter Eisentraut <peter.eisentraut@credativ.de>
1031  */
1034  * allocate a descriptor
1035  */
1036 ECPGAllocateDescr:     SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
1037                 {
1038                         add_descriptor($3,connection);
1039                         $$ = $3;
1040                 }
1041                 ;
1045  * deallocate a descriptor
1046  */
1047 ECPGDeallocateDescr:    DEALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
1048                 {
1049                         drop_descriptor($3,connection);
1050                         $$ = $3;
1051                 }
1052                 ;
1055  * manipulate a descriptor header
1056  */
1058 ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
1059                         {  $$ = $3; }
1060                 ;
1062 ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
1063                 | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
1064                 ;
1066 ECPGGetDescHeaderItem: cvariable '=' desc_header_item
1067                         { push_assignment($1, $3); }
1068                 ;
1071 ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
1072                         { $$ = $3; }
1073                 ;
1075 ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
1076                 | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
1077                 ;
1079 ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
1080                 {
1081                         push_assignment($3, $1);
1082                 }
1083                 ;
1085 IntConstVar:    Iconst
1086                 {
1087                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1089                         sprintf(length, "%d", (int) strlen($1));
1090                         new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1091                         $$ = $1;
1092                 }
1093                 | cvariable     { $$ = $1; }
1094                 ;
1096 desc_header_item:       SQL_COUNT                       { $$ = ECPGd_count; }
1097                 ;
1100  * manipulate a descriptor
1101  */
1103 ECPGGetDescriptor:      SQL_GET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGGetDescItems
1104                         {  $$.str = $5; $$.name = $3; }
1105                 ;
1107 ECPGGetDescItems: ECPGGetDescItem
1108                 | ECPGGetDescItems ',' ECPGGetDescItem
1109                 ;
1111 ECPGGetDescItem: cvariable '=' descriptor_item  { push_assignment($1, $3); };
1114 ECPGSetDescriptor:      SET SQL_DESCRIPTOR quoted_ident_stringvar VALUE_P IntConstVar ECPGSetDescItems
1115                         {  $$.str = $5; $$.name = $3; }
1116                 ;
1118 ECPGSetDescItems: ECPGSetDescItem
1119                 | ECPGSetDescItems ',' ECPGSetDescItem
1120                 ;
1122 ECPGSetDescItem: descriptor_item '=' AllConstVar
1123                 {
1124                         push_assignment($3, $1);
1125                 }
1126                 ;
1128 AllConstVar:    ecpg_fconst
1129                 {
1130                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1132                         sprintf(length, "%d", (int) strlen($1));
1133                         new_variable($1, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1134                         $$ = $1;
1135                 }
1136                 | IntConstVar           { $$ = $1; }
1137                 | '-' ecpg_fconst
1138                 {
1139                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1140                         char *var = cat2_str(make_str("-"), $2);
1142                         sprintf(length, "%d", (int) strlen(var));
1143                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1144                         $$ = var;
1145                 }
1146                 | '-' Iconst
1147                 {
1148                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1149                         char *var = cat2_str(make_str("-"), $2);
1151                         sprintf(length, "%d", (int) strlen(var));
1152                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1153                         $$ = var;
1154                 }
1155                 | ecpg_sconst
1156                 {
1157                         char *length = mm_alloc(sizeof(int) * CHAR_BIT * 10 / 3);
1158                         char *var = $1 + 1;
1160                         var[strlen(var) - 1] = '\0';
1161                         sprintf(length, "%d", (int) strlen(var));
1162                         new_variable(var, ECPGmake_simple_type(ECPGt_const, length, 0), 0);
1163                         $$ = var;
1164                 }
1165                 ;
1167 descriptor_item:        SQL_CARDINALITY                 { $$ = ECPGd_cardinality; }
1168                 | DATA_P                                { $$ = ECPGd_data; }
1169                 | SQL_DATETIME_INTERVAL_CODE            { $$ = ECPGd_di_code; }
1170                 | SQL_DATETIME_INTERVAL_PRECISION       { $$ = ECPGd_di_precision; }
1171                 | SQL_INDICATOR                         { $$ = ECPGd_indicator; }
1172                 | SQL_KEY_MEMBER                        { $$ = ECPGd_key_member; }
1173                 | SQL_LENGTH                            { $$ = ECPGd_length; }
1174                 | NAME_P                                { $$ = ECPGd_name; }
1175                 | SQL_NULLABLE                          { $$ = ECPGd_nullable; }
1176                 | SQL_OCTET_LENGTH                      { $$ = ECPGd_octet; }
1177                 | PRECISION                             { $$ = ECPGd_precision; }
1178                 | SQL_RETURNED_LENGTH                   { $$ = ECPGd_length; }
1179                 | SQL_RETURNED_OCTET_LENGTH             { $$ = ECPGd_ret_octet; }
1180                 | SQL_SCALE                             { $$ = ECPGd_scale; }
1181                 | TYPE_P                                { $$ = ECPGd_type; }
1182                 ;
1185  * set/reset the automatic transaction mode, this needs a differnet handling
1186  * as the other set commands
1187  */
1188 ECPGSetAutocommit:      SET SQL_AUTOCOMMIT '=' on_off   { $$ = $4; }
1189                 |  SET SQL_AUTOCOMMIT TO on_off   { $$ = $4; }
1190                 ;
1192 on_off: ON                              { $$ = make_str("on"); }
1193                 | OFF                   { $$ = make_str("off"); }
1194                 ;
1197  * set the actual connection, this needs a differnet handling as the other
1198  * set commands
1199  */
1200 ECPGSetConnection:      SET CONNECTION TO connection_object { $$ = $4; }
1201                 | SET CONNECTION '=' connection_object { $$ = $4; }
1202                 | SET CONNECTION  connection_object { $$ = $3; }
1203                 ;
1206  * define a new type for embedded SQL
1207  */
1208 ECPGTypedef: TYPE_P
1209                 {
1210                         /* reset this variable so we see if there was */
1211                         /* an initializer specified */
1212                         initializer = 0;
1213                 }
1214                 ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
1215                 {
1216                         add_typedef($3, $6.index1, $6.index2, $5.type_enum, $5.type_dimension, $5.type_index, initializer, *$7 ? 1 : 0);
1218                         if (auto_create_c == false)
1219                                 $$ = 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("*/"));
1220                         else
1221                                 $$ = 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(";"));
1222                 }
1223                 ;
1225 opt_reference: SQL_REFERENCE            { $$ = make_str("reference"); }
1226                 | /*EMPTY*/                                     { $$ = EMPTY; }
1227                 ;
1230  * define the type of one variable for embedded SQL
1231  */
1232 ECPGVar: SQL_VAR
1233                 {
1234                         /* reset this variable so we see if there was */
1235                         /* an initializer specified */
1236                         initializer = 0;
1237                 }
1238                 ColLabel IS var_type opt_array_bounds opt_reference
1239                 {
1240                         struct variable *p = find_variable($3);
1241                         char *dimension = $6.index1;
1242                         char *length = $6.index2;
1243                         struct ECPGtype * type;
1245                         if (($5.type_enum == ECPGt_struct ||
1246                                  $5.type_enum == ECPGt_union) &&
1247                                 initializer == 1)
1248                                 mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in EXEC SQL VAR command");
1249                         else
1250                         {
1251                                 adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
1253                                 switch ($5.type_enum)
1254                                 {
1255                                         case ECPGt_struct:
1256                                         case ECPGt_union:
1257                                                 if (atoi(dimension) < 0)
1258                                                         type = ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum, $5.type_sizeof);
1259                                                 else
1260                                                         type = ECPGmake_array_type(ECPGmake_struct_type(struct_member_list[struct_level], $5.type_enum,$5.type_sizeof), dimension);
1261                                                 break;
1263                                         case ECPGt_varchar:
1264                                                 if (atoi(dimension) == -1)
1265                                                         type = ECPGmake_simple_type($5.type_enum, length, 0);
1266                                                 else
1267                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
1268                                                 break;
1270                                         case ECPGt_char:
1271                                         case ECPGt_unsigned_char:
1272                                                 if (atoi(dimension) == -1)
1273                                                         type = ECPGmake_simple_type($5.type_enum, length, 0);
1274                                                 else
1275                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, length, 0), dimension);
1276                                                 break;
1278                                         default:
1279                                                 if (atoi(length) >= 0)
1280                                                         mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported");
1282                                                 if (atoi(dimension) < 0)
1283                                                         type = ECPGmake_simple_type($5.type_enum, make_str("1"), 0);
1284                                                 else
1285                                                         type = ECPGmake_array_type(ECPGmake_simple_type($5.type_enum, make_str("1"), 0), dimension);
1286                                                 break;
1287                                 }
1289                                 ECPGfree_type(p->type);
1290                                 p->type = type;
1291                         }
1293                         $$ = 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("*/"));
1294                 }
1295                 ;
1298  * whenever statement: decide what to do in case of error/no data found
1299  * according to SQL standards we lack: SQLSTATE, CONSTRAINT and SQLEXCEPTION
1300  */
1301 ECPGWhenever: SQL_WHENEVER SQL_SQLERROR action
1302                 {
1303                         when_error.code = $<action>3.code;
1304                         when_error.command = $<action>3.command;
1305                         $$ = cat_str(3, make_str("/* exec sql whenever sqlerror "), $3.str, make_str("; */"));
1306                 }
1307                 | SQL_WHENEVER NOT SQL_FOUND action
1308                 {
1309                         when_nf.code = $<action>4.code;
1310                         when_nf.command = $<action>4.command;
1311                         $$ = cat_str(3, make_str("/* exec sql whenever not found "), $4.str, make_str("; */"));
1312                 }
1313                 | SQL_WHENEVER SQL_SQLWARNING action
1314                 {
1315                         when_warn.code = $<action>3.code;
1316                         when_warn.command = $<action>3.command;
1317                         $$ = cat_str(3, make_str("/* exec sql whenever sql_warning "), $3.str, make_str("; */"));
1318                 }
1319                 ;
1321 action : CONTINUE_P
1322                 {
1323                         $<action>$.code = W_NOTHING;
1324                         $<action>$.command = NULL;
1325                         $<action>$.str = make_str("continue");
1326                 }
1327                 | SQL_SQLPRINT
1328                 {
1329                         $<action>$.code = W_SQLPRINT;
1330                         $<action>$.command = NULL;
1331                         $<action>$.str = make_str("sqlprint");
1332                 }
1333                 | SQL_STOP
1334                 {
1335                         $<action>$.code = W_STOP;
1336                         $<action>$.command = NULL;
1337                         $<action>$.str = make_str("stop");
1338                 }
1339                 | SQL_GOTO name
1340                 {
1341                         $<action>$.code = W_GOTO;
1342                         $<action>$.command = strdup($2);
1343                         $<action>$.str = cat2_str(make_str("goto "), $2);
1344                 }
1345                 | SQL_GO TO name
1346                 {
1347                         $<action>$.code = W_GOTO;
1348                         $<action>$.command = strdup($3);
1349                         $<action>$.str = cat2_str(make_str("goto "), $3);
1350                 }
1351                 | DO name '(' c_args ')'
1352                 {
1353                         $<action>$.code = W_DO;
1354                         $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
1355                         $<action>$.str = cat2_str(make_str("do"), mm_strdup($<action>$.command));
1356                 }
1357                 | DO SQL_BREAK
1358                 {
1359                         $<action>$.code = W_BREAK;
1360                         $<action>$.command = NULL;
1361                         $<action>$.str = make_str("break");
1362                 }
1363                 | SQL_CALL name '(' c_args ')'
1364                 {
1365                         $<action>$.code = W_DO;
1366                         $<action>$.command = cat_str(4, $2, make_str("("), $4, make_str(")"));
1367                         $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
1368                 }
1369                 | SQL_CALL name
1370                 {
1371                         $<action>$.code = W_DO;
1372                         $<action>$.command = cat2_str($2, make_str("()"));
1373                         $<action>$.str = cat2_str(make_str("call"), mm_strdup($<action>$.command));
1374                 }
1375                 ;
1377 /* some other stuff for ecpg */
1379 /* additional unreserved keywords */
1380 ECPGKeywords: ECPGKeywords_vanames      { $$ = $1; }
1381                 | ECPGKeywords_rest     { $$ = $1; }
1382                 ;
1384 ECPGKeywords_vanames:  SQL_BREAK                { $$ = make_str("break"); }
1385                 | SQL_CALL                                              { $$ = make_str("call"); }
1386                 | SQL_CARDINALITY                               { $$ = make_str("cardinality"); }
1387                 | SQL_COUNT                                             { $$ = make_str("count"); }
1388                 | SQL_DATETIME_INTERVAL_CODE    { $$ = make_str("datetime_interval_code"); }
1389                 | SQL_DATETIME_INTERVAL_PRECISION       { $$ = make_str("datetime_interval_precision"); }
1390                 | SQL_FOUND                                             { $$ = make_str("found"); }
1391                 | SQL_GO                                                { $$ = make_str("go"); }
1392                 | SQL_GOTO                                              { $$ = make_str("goto"); }
1393                 | SQL_IDENTIFIED                                { $$ = make_str("identified"); }
1394                 | SQL_INDICATOR                         { $$ = make_str("indicator"); }
1395                 | SQL_KEY_MEMBER                        { $$ = make_str("key_member"); }
1396                 | SQL_LENGTH                            { $$ = make_str("length"); }
1397                 | SQL_NULLABLE                          { $$ = make_str("nullable"); }
1398                 | SQL_OCTET_LENGTH                      { $$ = make_str("octet_length"); }
1399                 | SQL_RETURNED_LENGTH           { $$ = make_str("returned_length"); }
1400                 | SQL_RETURNED_OCTET_LENGTH     { $$ = make_str("returned_octet_length"); }
1401                 | SQL_SCALE                                     { $$ = make_str("scale"); }
1402                 | SQL_SECTION                           { $$ = make_str("section"); }
1403                 | SQL_SQL                               { $$ = make_str("sql"); }
1404                 | SQL_SQLERROR                          { $$ = make_str("sqlerror"); }
1405                 | SQL_SQLPRINT                          { $$ = make_str("sqlprint"); }
1406                 | SQL_SQLWARNING                        { $$ = make_str("sqlwarning"); }
1407                 | SQL_STOP                                      { $$ = make_str("stop"); }
1408                 ;
1410 ECPGKeywords_rest:  SQL_CONNECT         { $$ = make_str("connect"); }
1411                 | SQL_DESCRIBE                          { $$ = make_str("describe"); }
1412                 | SQL_DISCONNECT                        { $$ = make_str("disconnect"); }
1413                 | SQL_OPEN                                      { $$ = make_str("open"); }
1414                 | SQL_VAR                                       { $$ = make_str("var"); }
1415                 | SQL_WHENEVER                          { $$ = make_str("whenever"); }
1416                 ;
1418 /* additional keywords that can be SQL type names (but not ECPGColLabels) */
1419 ECPGTypeName:  SQL_BOOL                         { $$ = make_str("bool"); }
1420                 | SQL_LONG                                      { $$ = make_str("long"); }
1421                 | SQL_OUTPUT                            { $$ = make_str("output"); }
1422                 | SQL_SHORT                                     { $$ = make_str("short"); }
1423                 | SQL_STRUCT                            { $$ = make_str("struct"); }
1424                 | SQL_SIGNED                            { $$ = make_str("signed"); }
1425                 | SQL_UNSIGNED                          { $$ = make_str("unsigned"); }
1426                 ;
1428 symbol: ColLabel                                        { $$ = $1; }
1429                 ;
1431 ECPGColId: ecpg_ident                           { $$ = $1; }
1432                 | ECPGunreserved_interval       { $$ = $1; }
1433                 | ECPGunreserved_con            { $$ = $1; }
1434                 | col_name_keyword              { $$ = $1; }
1435                 | ECPGKeywords                  { $$ = $1; }
1436                 | ECPGCKeywords                 { $$ = $1; }
1437                 | CHAR_P                        { $$ = make_str("char"); }
1438                 | VALUES                        { $$ = make_str("values"); }
1439                 ;
1440 /* Column label --- allowed labels in "AS" clauses.
1441  * This presently includes *all* Postgres keywords.
1442  */
1443 ColLabel:  ECPGColLabel                         { $$ = $1; }
1444                 | ECPGTypeName                  { $$ = $1; }
1445                 | CHAR_P                        { $$ = make_str("char"); }
1446                 | INPUT_P                       { $$ = make_str("input"); }
1447                 | INT_P                         { $$ = make_str("int"); }
1448                 | UNION                         { $$ = make_str("union"); }
1449                 | TO                            { $$ = make_str("to"); }
1450                 | ECPGCKeywords                 { $$ = $1; }
1451                 | ECPGunreserved_interval       { $$ = $1; }
1452                 ;
1454 ECPGColLabelCommon:  ecpg_ident                 { $$ = $1; }
1455                 | col_name_keyword              { $$ = $1; }
1456                 | type_func_name_keyword        { $$ = $1; }
1457                 | ECPGKeywords_vanames          { $$ = $1; }
1458                 ;
1460 ECPGColLabel:  ECPGColLabelCommon       { $$ = $1; }
1461                 | reserved_keyword              { $$ = $1; }
1462                 | ECPGunreserved                { $$ = $1; }
1463                 | ECPGKeywords_rest             { $$ = $1; }
1464                 ;
1466 ECPGCKeywords: S_AUTO                   { $$ = make_str("auto"); }
1467                 | S_CONST                               { $$ = make_str("const"); }
1468                 | S_EXTERN                              { $$ = make_str("extern"); }
1469                 | S_REGISTER                    { $$ = make_str("register"); }
1470                 | S_STATIC                              { $$ = make_str("static"); }
1471                 | S_TYPEDEF                             { $$ = make_str("typedef"); }
1472                 | S_VOLATILE                    { $$ = make_str("volatile"); }
1473                 ;
1476  * Keyword classification lists.  Generally, every keyword present in
1477  * the Postgres grammar should appear in exactly one of these lists.
1479  * Put a new keyword into the first list that it can go into without causing
1480  * shift or reduce conflicts.  The earlier lists define "less reserved"
1481  * categories of keywords.
1482  */
1484 /* "Unreserved" keywords --- available for use as any kind of name.
1485  */
1486 /* The following symbols must be excluded from ECPGColLabel and directly included into ColLabel
1487    to enable C variables to get names from ECPGColLabel:
1488    DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P
1489  */
1490 unreserved_keyword: ECPGunreserved_interval | ECPGunreserved;
1492 ECPGunreserved_interval: DAY_P                  { $$ = make_str("day"); }
1493                 | HOUR_P                        { $$ = make_str("hour"); }
1494                 | MINUTE_P                      { $$ = make_str("minute"); }
1495                 | MONTH_P                       { $$ = make_str("month"); }
1496                 | SECOND_P                      { $$ = make_str("second"); }
1497                 | YEAR_P                        { $$ = make_str("year"); }
1498                 ;
1500 /* The following symbol must be excluded from var_name but still included in ColId
1501    to enable ecpg special postgresql variables with this name:  CONNECTION
1502  */
1503 ECPGunreserved: ECPGunreserved_con              { $$ = $1; }
1504                 | CONNECTION                    { $$ = make_str("connection"); }
1505                 ;
1507 ECPGunreserved_con:       ABORT_P                       { $$ = make_str("abort"); }
1508                 | ABSOLUTE_P            { $$ = make_str("absolute"); }
1509                 | ACCESS                        { $$ = make_str("access"); }
1510                 | ACTION                        { $$ = make_str("action"); }
1511                 | ADD_P                         { $$ = make_str("add"); }
1512                 | ADMIN                         { $$ = make_str("admin"); }
1513                 | AFTER                         { $$ = make_str("after"); }
1514                 | AGGREGATE                     { $$ = make_str("aggregate"); }
1515                 | ALSO                          { $$ = make_str("also"); }
1516                 | ALTER                         { $$ = make_str("alter"); }
1517                 | ALWAYS                        { $$ = make_str("always"); }
1518                 | ASSERTION                     { $$ = make_str("assertion"); }
1519                 | ASSIGNMENT            { $$ = make_str("assignment"); }
1520                 | AT                            { $$ = make_str("at"); }
1521                 | BACKWARD                      { $$ = make_str("backward"); }
1522                 | BEFORE                        { $$ = make_str("before"); }
1523                 | BEGIN_P                       { $$ = make_str("begin"); }
1524                 | BY                            { $$ = make_str("by"); }
1525                 | CACHE                         { $$ = make_str("cache"); }
1526                 | CASCADE                       { $$ = make_str("cascade"); }
1527                 | CASCADED                      { $$ = make_str("cascaded"); }
1528                 | CHAIN                         { $$ = make_str("chain"); }
1529                 | CHARACTERISTICS       { $$ = make_str("characteristics"); }
1530                 | CHECKPOINT            { $$ = make_str("checkpoint"); }
1531                 | CLASS                         { $$ = make_str("class"); }
1532                 | CLOSE                         { $$ = make_str("close"); }
1533                 | CLUSTER                       { $$ = make_str("cluster"); }
1534                 | COMMENT                       { $$ = make_str("comment"); }
1535                 | COMMIT                        { $$ = make_str("commit"); }
1536                 | COMMITTED                     { $$ = make_str("committed"); }
1537                 | CONCURRENTLY          { $$ = make_str("concurrently"); }
1538                 | CONFIGURATION         { $$ = make_str("configuration"); }
1539 /*              | CONNECTION            { $$ = make_str("connection"); }*/
1540                 | CONSTRAINTS           { $$ = make_str("constraints"); }
1541                 | CONTENT_P             { $$ = make_str("content"); }
1542                 | CONTINUE_P            { $$ = make_str("continue"); }
1543                 | CONVERSION_P          { $$ = make_str("conversion"); }
1544                 | COPY                          { $$ = make_str("copy"); }
1545                 | COST                          { $$ = make_str("cost"); }
1546                 | CREATEDB                      { $$ = make_str("createdb"); }
1547                 | CREATEROLE            { $$ = make_str("createrole"); }
1548                 | CREATEUSER            { $$ = make_str("createuser"); }
1549                 | CSV                           { $$ = make_str("csv"); }
1550                 | CURSOR                        { $$ = make_str("cursor"); }
1551                 | CYCLE                         { $$ = make_str("cycle"); }
1552                 | DATA_P                        { $$ = make_str("data"); }
1553                 | DATABASE                      { $$ = make_str("database"); }
1554 /*              | DAY_P                         { $$ = make_str("day"); }*/
1555                 | DEALLOCATE            { $$ = make_str("deallocate"); }
1556                 | DECLARE                       { $$ = make_str("declare"); }
1557                 | DEFAULTS                      { $$ = make_str("defaults"); }
1558                 | DEFERRED                      { $$ = make_str("deferred"); }
1559                 | DELETE_P                      { $$ = make_str("delete"); }
1560                 | DELIMITER                     { $$ = make_str("delimiter"); }
1561                 | DELIMITERS            { $$ = make_str("delimiters"); }
1562                 | DICTIONARY            { $$ = make_str("dictionary"); }
1563                 | DISABLE_P                     { $$ = make_str("disable"); }
1564                 | DISCARD                       { $$ = make_str("discard"); }
1565                 | DOCUMENT_P                    { $$ = make_str("document"); }
1566                 | DOMAIN_P                      { $$ = make_str("domain"); }
1567                 | DOUBLE_P                      { $$ = make_str("double"); }
1568                 | DROP                          { $$ = make_str("drop"); }
1569                 | EACH                          { $$ = make_str("each"); }
1570                 | ENABLE_P                      { $$ = make_str("enable"); }
1571                 | ENCODING                      { $$ = make_str("encoding"); }
1572                 | ENCRYPTED                     { $$ = make_str("encrypted"); }
1573 /*              | ENUM_P                        { $$ = make_str("enum"); }*/
1574                 | ESCAPE                        { $$ = make_str("escape"); }
1575                 | EXCLUDING                     { $$ = make_str("excluding"); }
1576                 | EXCLUSIVE                     { $$ = make_str("exclusive"); }
1577                 | EXECUTE                       { $$ = make_str("execute"); }
1578                 | EXPLAIN                       { $$ = make_str("explain"); }
1579                 | EXTERNAL                      { $$ = make_str("external"); }
1580                 | FAMILY                        { $$ = make_str("family"); }
1581 /*              | FETCH                         { $$ = make_str("fetch"); }*/
1582                 | FIRST_P                       { $$ = make_str("first"); }
1583                 | FORCE                         { $$ = make_str("force"); }
1584                 | FORWARD                       { $$ = make_str("forward"); }
1585                 | FUNCTION                      { $$ = make_str("function"); }
1586                 | GLOBAL                        { $$ = make_str("global"); }
1587                 | GRANTED                       { $$ = make_str("granted"); }
1588                 | HANDLER                       { $$ = make_str("handler"); }
1589                 | HEADER_P                      { $$ = make_str("header"); }
1590                 | HOLD                          { $$ = make_str("hold"); }
1591 /*              | HOUR_P                        { $$ = make_str("hour"); }*/
1592                 | IDENTITY_P                    { $$ = make_str("identity"); }
1593                 | IF_P                          { $$ = make_str("if"); }
1594                 | IMMEDIATE                     { $$ = make_str("immediate"); }
1595                 | IMMUTABLE                     { $$ = make_str("immutable"); }
1596                 | IMPLICIT_P            { $$ = make_str("implicit"); }
1597                 | INCLUDING                     { $$ = make_str("including"); }
1598                 | INCREMENT                     { $$ = make_str("increment"); }
1599                 | INDEX                         { $$ = make_str("index"); }
1600                 | INDEXES                       { $$ = make_str("indexes"); }
1601                 | INHERIT                       { $$ = make_str("inherit"); }
1602                 | INHERITS                      { $$ = make_str("inherits"); }
1603                 | INSENSITIVE           { $$ = make_str("insensitive"); }
1604                 | INSERT                        { $$ = make_str("insert"); }
1605                 | INSTEAD                       { $$ = make_str("instead"); }
1606                 | ISOLATION                     { $$ = make_str("isolation"); }
1607                 | KEY                           { $$ = make_str("key"); }
1608                 | LANCOMPILER           { $$ = make_str("lancompiler"); }
1609                 | LANGUAGE                      { $$ = make_str("language"); }
1610                 | LARGE_P                       { $$ = make_str("large"); }
1611                 | LAST_P                        { $$ = make_str("last"); }
1612                 | LC_COLLATE_P          { $$ = make_str("lc_collate"); }
1613                 | LC_CTYPE_P            { $$ = make_str("lc_ctype"); }
1614                 | LEVEL                         { $$ = make_str("level"); }
1615                 | LISTEN                        { $$ = make_str("listen"); }
1616                 | LOAD                          { $$ = make_str("load"); }
1617                 | LOCAL                         { $$ = make_str("local"); }
1618                 | LOCATION                      { $$ = make_str("location"); }
1619                 | LOCK_P                        { $$ = make_str("lock"); }
1620                 | LOGIN_P                       { $$ = make_str("login"); }
1621                 | MAPPING                       { $$ = make_str("mapping"); }
1622                 | MATCH                         { $$ = make_str("match"); }
1623                 | MAXVALUE                      { $$ = make_str("maxvalue"); }
1624 /*              | MINUTE_P                      { $$ = make_str("minute"); }*/
1625                 | MINVALUE                      { $$ = make_str("minvalue"); }
1626                 | MODE                          { $$ = make_str("mode"); }
1627 /*              | MONTH_P                       { $$ = make_str("month"); }*/
1628                 | MOVE                          { $$ = make_str("move"); }
1629                 | NAME_P                        { $$ = make_str("name"); }
1630                 | NAMES                         { $$ = make_str("names"); }
1631                 | NEXT                          { $$ = make_str("next"); }
1632                 | NO                            { $$ = make_str("no"); }
1633                 | NOCREATEDB            { $$ = make_str("nocreatedb"); }
1634                 | NOCREATEROLE          { $$ = make_str("nocreaterole"); }
1635                 | NOCREATEUSER          { $$ = make_str("nocreateuser"); }
1636                 | NOINHERIT                     { $$ = make_str("noinherit"); }
1637                 | NOLOGIN_P             { $$ = make_str("nologin"); }
1638                 | NOSUPERUSER           { $$ = make_str("nosuperuser"); }
1639                 | NOTHING                       { $$ = make_str("nothing"); }
1640                 | NOTIFY                        { $$ = make_str("notify"); }
1641                 | NOWAIT                        { $$ = make_str("nowait"); }
1642                 | NULLS_P                       { $$ = make_str("nulls"); }
1643                 | OBJECT_P                      { $$ = make_str("object"); }
1644                 | OF                            { $$ = make_str("of"); }
1645                 | OIDS                          { $$ = make_str("oids"); }
1646                 | OPERATOR                      { $$ = make_str("operator"); }
1647                 | OPTION                        { $$ = make_str("option"); }
1648                 | OWNED                         { $$ = make_str("owned"); }
1649                 | OWNER                         { $$ = make_str("owner"); }
1650                 | PARSER                        { $$ = make_str("parser"); }
1651                 | PARTIAL                       { $$ = make_str("partial"); }
1652                 | PASSWORD                      { $$ = make_str("password"); }
1653                 | PLANS                         { $$ = make_str("plans"); }
1654                 | PREPARE                       { $$ = make_str("prepare"); }
1655                 | PREPARED                      { $$ = make_str("prepared"); }
1656                 | PRESERVE                      { $$ = make_str("preserver"); }
1657                 | PRIOR                         { $$ = make_str("prior"); }
1658                 | PRIVILEGES            { $$ = make_str("privileges"); }
1659                 | PROCEDURAL            { $$ = make_str("procedural"); }
1660                 | PROCEDURE                     { $$ = make_str("procedure"); }
1661                 | QUOTE                         { $$ = make_str("quote"); }
1662                 | READ                          { $$ = make_str("read"); }
1663                 | REASSIGN                      { $$ = make_str("reassign"); }
1664                 | RECHECK                       { $$ = make_str("recheck"); }
1665                 | RECURSIVE                     { $$ = make_str("recursive"); }
1666                 | REINDEX                       { $$ = make_str("reindex"); }
1667                 | RELATIVE_P            { $$ = make_str("relative"); }
1668                 | RELEASE                       { $$ = make_str("release"); }
1669                 | RENAME                        { $$ = make_str("rename"); }
1670                 | REPEATABLE            { $$ = make_str("repeatable"); }
1671                 | REPLACE                       { $$ = make_str("replace"); }
1672                 | REPLICA                       { $$ = make_str("replica"); }
1673                 | RESET                         { $$ = make_str("reset"); }
1674                 | RESTART                       { $$ = make_str("restart"); }
1675                 | RESTRICT                      { $$ = make_str("restrict"); }
1676                 | RETURNS                       { $$ = make_str("returns"); }
1677                 | REVOKE                        { $$ = make_str("revoke"); }
1678                 | ROLE                          { $$ = make_str("role"); }
1679                 | ROLLBACK                      { $$ = make_str("rollback"); }
1680                 | ROWS                          { $$ = make_str("rows"); }
1681                 | RULE                          { $$ = make_str("rule"); }
1682                 | SAVEPOINT                     { $$ = make_str("savepoint"); }
1683                 | SCHEMA                        { $$ = make_str("schema"); }
1684                 | SCROLL                        { $$ = make_str("scroll"); }
1685                 | SEARCH                        { $$ = make_str("search"); }
1686 /*              | SECOND_P                      { $$ = make_str("second"); }*/
1687                 | SEQUENCE                      { $$ = make_str("sequence"); }
1688                 | SERIALIZABLE          { $$ = make_str("serializable"); }
1689                 | SESSION                       { $$ = make_str("session"); }
1690                 | SET                           { $$ = make_str("set"); }
1691                 | SHARE                         { $$ = make_str("share"); }
1692                 | SHOW                          { $$ = make_str("show"); }
1693                 | SIMPLE                        { $$ = make_str("simple"); }
1694                 | STABLE                        { $$ = make_str("stable"); }
1695                 | STANDALONE_P                  { $$ = make_str("standalone"); }
1696                 | START                         { $$ = make_str("start"); }
1697                 | STATEMENT                     { $$ = make_str("statement"); }
1698                 | STATISTICS            { $$ = make_str("statistics"); }
1699                 | STDIN                         { $$ = make_str("stdin"); }
1700                 | STDOUT                        { $$ = make_str("stdout"); }
1701                 | STORAGE                       { $$ = make_str("storage"); }
1702                 | STRICT_P                      { $$ = make_str("strict"); }
1703                 | STRIP_P                       { $$ = make_str("strip"); }
1704                 | SUPERUSER_P           { $$ = make_str("superuser"); }
1705                 | SYSTEM_P                      { $$ = make_str("system"); }
1706                 | SYSID                         { $$ = make_str("sysid"); }
1707                 | TABLESPACE            { $$ = make_str("tablespace"); }
1708                 | TEMP                          { $$ = make_str("temp"); }
1709                 | TEMPLATE                      { $$ = make_str("template"); }
1710                 | TEMPORARY                     { $$ = make_str("temporary"); }
1711                 | TEXT_P                        { $$ = make_str("text"); }
1712                 | TRANSACTION           { $$ = make_str("transaction"); }
1713                 | TRIGGER                       { $$ = make_str("trigger"); }
1714                 | TRUNCATE                      { $$ = make_str("truncate"); }
1715                 | TRUSTED                       { $$ = make_str("trusted"); }
1716                 | TYPE_P                        { $$ = make_str("type"); }
1717                 | UNCOMMITTED           { $$ = make_str("uncommitted"); }
1718                 | UNENCRYPTED           { $$ = make_str("unencrypted"); }
1719                 | UNKNOWN                       { $$ = make_str("unknown"); }
1720                 | UNLISTEN                      { $$ = make_str("unlisten"); }
1721                 | UNTIL                         { $$ = make_str("until"); }
1722                 | UPDATE                        { $$ = make_str("update"); }
1723                 | VACUUM                        { $$ = make_str("vacuum"); }
1724                 | VALID                         { $$ = make_str("valid"); }
1725                 | VALIDATOR                     { $$ = make_str("validator"); }
1726                 | VALUE_P                       { $$ = make_str("value"); }
1727                 | VARYING                       { $$ = make_str("varying"); }
1728                 | VERSION_P                     { $$ = make_str("version"); }
1729                 | VIEW                          { $$ = make_str("view"); }
1730                 | VOLATILE                      { $$ = make_str("volatile"); }
1731                 | WHITESPACE_P                  { $$ = make_str("whitespace"); }
1732                 | WITHOUT                       { $$ = make_str("without"); }
1733                 | WORK                          { $$ = make_str("work"); }
1734                 | WRITE                         { $$ = make_str("write"); }
1735                 | XML_P                         { $$ = make_str("xml"); }
1736                 | YES_P                         { $$ = make_str("yes"); }
1737 /*              | YEAR_P                        { $$ = make_str("year"); }*/
1738                 | ZONE                          { $$ = make_str("zone"); }
1739                 ;
1741 into_list : coutputvariable | into_list ',' coutputvariable
1742                 ;
1744 ecpgstart: SQL_START    {
1745                                 reset_variables();
1746                                 pacounter = 1;
1747                         }
1748                 ;
1750 c_args: /*EMPTY*/               { $$ = EMPTY; }
1751                 | c_list                { $$ = $1; }
1752                 ;
1754 coutputvariable: cvariable indicator
1755                         { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
1756                 | cvariable
1757                         { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
1758                 ;
1761 civarind: cvariable indicator
1762                 {
1763                         if (find_variable($2)->type->type == ECPGt_array)
1764                                 mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
1766                         add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
1767                         $$ = create_questionmarks($1, false);
1768                 }
1769                 ;
1771 civar: cvariable
1772                 {
1773                         add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
1774                         $$ = create_questionmarks($1, false);
1775                 }
1776                 ;
1778 indicator: cvariable                            { check_indicator((find_variable($1))->type); $$ = $1; }
1779                 | SQL_INDICATOR cvariable       { check_indicator((find_variable($2))->type); $$ = $2; }
1780                 | SQL_INDICATOR name            { check_indicator((find_variable($2))->type); $$ = $2; }
1781                 ;
1783 cvariable:      CVARIABLE
1784                 {
1785                         /* As long as multidimensional arrays are not implemented we have to check for those here */
1786                         char *ptr = $1;
1787                         int brace_open=0, brace = false;
1789                         for (; *ptr; ptr++)
1790                         {
1791                                 switch (*ptr)
1792                                 {
1793                                         case '[':
1794                                                         if (brace)
1795                                                                 mmerror(PARSE_ERROR, ET_FATAL, "multidimensional arrays for simple data types are not supported");
1796                                                         brace_open++;
1797                                                         break;
1798                                         case ']':
1799                                                         brace_open--;
1800                                                         if (brace_open == 0)
1801                                                                 brace = true;
1802                                                         break;
1803                                         case '\t':
1804                                         case ' ':
1805                                                         break;
1806                                         default:
1807                                                         if (brace_open == 0)
1808                                                                 brace = false;
1809                                                         break;
1810                                 }
1811                         }
1812                         $$ = $1;
1813                 }
1814                 ;
1816 ecpg_param:     PARAM           { $$ = make_name(); } ;
1818 ecpg_bconst:    BCONST          { $$ = make_name(); } ;
1820 ecpg_fconst:    FCONST          { $$ = make_name(); } ;
1822 ecpg_sconst:
1823                 SCONST
1824                 {
1825                         /* could have been input as '' or $$ */
1826                         $$ = (char *)mm_alloc(strlen($1) + 3);
1827                         $$[0]='\'';
1828                         strcpy($$+1, $1);
1829                         $$[strlen($1)+1]='\'';
1830                         $$[strlen($1)+2]='\0';
1831                         free($1);
1832                 }
1833                 | ECONST
1834                 {
1835                         $$ = (char *)mm_alloc(strlen($1) + 4);
1836                         $$[0]='E';
1837                         $$[1]='\'';
1838                         strcpy($$+2, $1);
1839                         $$[strlen($1)+2]='\'';
1840                         $$[strlen($1)+3]='\0';
1841                         free($1);
1842                 }
1843                 | NCONST
1844                 {
1845                         $$ = (char *)mm_alloc(strlen($1) + 4);
1846                         $$[0]='N';
1847                         $$[1]='\'';
1848                         strcpy($$+2, $1);
1849                         $$[strlen($1)+2]='\'';
1850                         $$[strlen($1)+3]='\0';
1851                         free($1);
1852                 }
1853                 | UCONST        { $$ = $1; }
1854                 | DOLCONST      { $$ = $1; }
1855                 ;
1857 ecpg_xconst:    XCONST          { $$ = make_name(); } ;
1859 ecpg_ident:     IDENT           { $$ = make_name(); }
1860                 | CSTRING       { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
1861                 | UIDENT        { $$ = $1; }
1862                 ;
1864 quoted_ident_stringvar: name
1865                         { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
1866                 | char_variable
1867                         { $$ = make3_str(make_str("("), $1, make_str(")")); }
1868                 ;
1871  * C stuff
1872  */
1874 c_stuff_item: c_anything                        { $$ = $1; }
1875                 | '(' ')'                       { $$ = make_str("()"); }
1876                 | '(' c_stuff ')'
1877                         { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1878                 ;
1880 c_stuff: c_stuff_item                   { $$ = $1; }
1881                 | c_stuff c_stuff_item
1882                         { $$ = cat2_str($1, $2); }
1883                 ;
1885 c_list: c_term                          { $$ = $1; }
1886                 | c_list ',' c_term     { $$ = cat_str(3, $1, make_str(","), $3); }
1887                 ;
1889 c_term:  c_stuff                        { $$ = $1; }
1890                 | '{' c_list '}'        { $$ = cat_str(3, make_str("{"), $2, make_str("}")); }
1891                 ;
1893 c_thing:        c_anything              { $$ = $1; }
1894                 |       '('             { $$ = make_str("("); }
1895                 |       ')'             { $$ = make_str(")"); }
1896                 |       ','             { $$ = make_str(","); }
1897                 |       ';'             { $$ = make_str(";"); }
1898                 ;
1900 c_anything:  ecpg_ident                         { $$ = $1; }
1901                 | Iconst                        { $$ = $1; }
1902                 | ecpg_fconst                   { $$ = $1; }
1903                 | ecpg_sconst                   { $$ = $1; }
1904                 | '*'                           { $$ = make_str("*"); }
1905                 | '+'                           { $$ = make_str("+"); }
1906                 | '-'                           { $$ = make_str("-"); }
1907                 | '/'                           { $$ = make_str("/"); }
1908                 | '%'                           { $$ = make_str("%"); }
1909                 | NULL_P                        { $$ = make_str("NULL"); }
1910                 | S_ADD                         { $$ = make_str("+="); }
1911                 | S_AND                         { $$ = make_str("&&"); }
1912                 | S_ANYTHING                    { $$ = make_name(); }
1913                 | S_AUTO                        { $$ = make_str("auto"); }
1914                 | S_CONST                       { $$ = make_str("const"); }
1915                 | S_DEC                         { $$ = make_str("--"); }
1916                 | S_DIV                         { $$ = make_str("/="); }
1917                 | S_DOTPOINT                    { $$ = make_str(".*"); }
1918                 | S_EQUAL                       { $$ = make_str("=="); }
1919                 | S_EXTERN                      { $$ = make_str("extern"); }
1920                 | S_INC                         { $$ = make_str("++"); }
1921                 | S_LSHIFT                      { $$ = make_str("<<"); }
1922                 | S_MEMBER                      { $$ = make_str("->"); }
1923                 | S_MEMPOINT                    { $$ = make_str("->*"); }
1924                 | S_MOD                         { $$ = make_str("%="); }
1925                 | S_MUL                         { $$ = make_str("*="); }
1926                 | S_NEQUAL                      { $$ = make_str("!="); }
1927                 | S_OR                          { $$ = make_str("||"); }
1928                 | S_REGISTER                    { $$ = make_str("register"); }
1929                 | S_RSHIFT                      { $$ = make_str(">>"); }
1930                 | S_STATIC                      { $$ = make_str("static"); }
1931                 | S_SUB                         { $$ = make_str("-="); }
1932                 | S_TYPEDEF                     { $$ = make_str("typedef"); }
1933                 | S_VOLATILE                    { $$ = make_str("volatile"); }
1934                 | SQL_BOOL                      { $$ = make_str("bool"); }
1935                 | ENUM_P                        { $$ = make_str("enum"); }
1936                 | HOUR_P                        { $$ = make_str("hour"); }
1937                 | INT_P                         { $$ = make_str("int"); }
1938                 | SQL_LONG                      { $$ = make_str("long"); }
1939                 | MINUTE_P                      { $$ = make_str("minute"); }
1940                 | MONTH_P                       { $$ = make_str("month"); }
1941                 | SECOND_P                      { $$ = make_str("second"); }
1942                 | SQL_SHORT                     { $$ = make_str("short"); }
1943                 | SQL_SIGNED                    { $$ = make_str("signed"); }
1944                 | SQL_STRUCT                    { $$ = make_str("struct"); }
1945                 | SQL_UNSIGNED                  { $$ = make_str("unsigned"); }
1946                 | YEAR_P                        { $$ = make_str("year"); }
1947                 | CHAR_P                        { $$ = make_str("char"); }
1948                 | FLOAT_P                       { $$ = make_str("float"); }
1949                 | TO                            { $$ = make_str("to"); }
1950                 | UNION                         { $$ = make_str("union"); }
1951                 | VARCHAR                       { $$ = make_str("varchar"); }
1952                 | '['                           { $$ = make_str("["); }
1953                 | ']'                           { $$ = make_str("]"); }
1954                 | '='                           { $$ = make_str("="); }
1955                 | ':'                           { $$ = make_str(":"); }
1956                 ;
1958 DeallocateStmt: DEALLOCATE prepared_name                { $$ = $2; }
1959                 | DEALLOCATE PREPARE prepared_name      { $$ = $3; }
1960                 | DEALLOCATE ALL                        { $$ = make_str("all"); }
1961                 | DEALLOCATE PREPARE ALL                { $$ = make_str("all"); }
1962                 ;
1964 Iresult:        Iconst                  { $$ = $1; }
1965                 | '(' Iresult ')'       { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
1966                 | Iresult '+' Iresult   { $$ = cat_str(3, $1, make_str("+"), $3); }
1967                 | Iresult '-' Iresult   { $$ = cat_str(3, $1, make_str("-"), $3); }
1968                 | Iresult '*' Iresult   { $$ = cat_str(3, $1, make_str("*"), $3); }
1969                 | Iresult '/' Iresult   { $$ = cat_str(3, $1, make_str("/"), $3); }
1970                 | Iresult '%' Iresult   { $$ = cat_str(3, $1, make_str("%"), $3); }
1971                 | ecpg_sconst           { $$ = $1; }
1972                 | ColId                 { $$ = $1; }
1973                 ;
1975 execute_rest: /* EMPTY */       { $$ = EMPTY; }
1976         | ecpg_using ecpg_into  { $$ = EMPTY; }
1977         | ecpg_into ecpg_using  { $$ = EMPTY; }
1978         | ecpg_using            { $$ = EMPTY; }
1979         | ecpg_into             { $$ = EMPTY; }
1980         ; 
1982 ecpg_into: INTO into_list       { $$ = EMPTY; }
1983         | into_descriptor       { $$ = $1; }
1984         ;
1988 void base_yyerror(const char *error)
1990         /* translator: %s is typically the translation of "syntax error" */
1991         mmerror(PARSE_ERROR, ET_ERROR, "%s at or near \"%s\"",
1992                         _(error), token_start ? token_start : yytext);
1995 void parser_init(void)
1997  /* This function is empty. It only exists for compatibility with the backend parser right now. */
2001  * Must undefine base_yylex before including pgc.c, since we want it
2002  * to create the function base_yylex not filtered_base_yylex.
2003  */
2004 #undef base_yylex
2006 #include "pgc.c"