@@ -169,6 +169,7 @@ make_name(void)
169169 S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
170170 S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
171171 S_STATIC S_SUB S_VOLATILE
172+ S_TYPEDEF
172173
173174/* I need this and don't know where it is defined inside the backend */
174175%token TYPECAST
@@ -354,12 +355,13 @@ make_name(void)
354355%type <str> stmt ECPGRelease execstring server_name
355356%type <str> connection_object opt_server opt_port c_stuff c_stuff_item
356357%type <str> user_name opt_user char_variable ora_user ident opt_reference
357- %type <str> quoted_ident_stringvar
358+ %type <str> quoted_ident_stringvar var_type_declarations
358359%type <str> db_prefix server opt_options opt_connection_name c_list
359360%type <str> ECPGSetConnection cpp_line ECPGTypedef c_args ECPGKeywords
360361%type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
361362%type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
362- %type <str> struct_type s_struct declaration declarations variable_declarations
363+ %type <str> struct_type s_struct vt_declarations variable_declarations
364+ %type <str> var_declaration type_declaration
363365%type <str> s_union union_type ECPGSetAutocommit on_off
364366%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
365367%type <str> ECPGGetDescriptorHeader ECPGColLabel
@@ -418,7 +420,7 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
418420 | AlterUserSetStmt { output_statement($1 , 0 , connection); }
419421 | ClosePortalStmt { output_statement($1 , 0 , connection); }
420422 | CommentStmt { output_statement($1 , 0 , connection); }
421- | CopyStmt { output_statement($1 , 0 , connection); }
423+ | CopyStmt { output_statement($1 , 0 , connection); }
422424 | CreateStmt { output_statement($1 , 0 , connection); }
423425 | CreateAsStmt { output_statement($1 , 0 , connection); }
424426 | CreateSchemaStmt { output_statement($1 , 0 , connection); }
@@ -429,20 +431,20 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
429431 | CreateUserStmt { output_statement($1 , 0 , connection); }
430432 | ClusterStmt { output_statement($1 , 0 , connection); }
431433 | DefineStmt { output_statement($1 , 0 , connection); }
432- | DropStmt { output_statement($1 , 0 , connection); }
434+ | DropStmt { output_statement($1 , 0 , connection); }
433435 | DropSchemaStmt { output_statement($1 , 0 , connection); }
434436 | TruncateStmt { output_statement($1 , 0 , connection); }
435437 | DropGroupStmt { output_statement($1 , 0 , connection); }
436438 | DropPLangStmt { output_statement($1 , 0 , connection); }
437439 | DropTrigStmt { output_statement($1 , 0 , connection); }
438440 | DropUserStmt { output_statement($1 , 0 , connection); }
439441 | ExplainStmt { output_statement($1 , 0 , connection); }
440- | FetchStmt { output_statement($1 , 1 , connection); }
441- | GrantStmt { output_statement($1 , 0 , connection); }
442- | IndexStmt { output_statement($1 , 0 , connection); }
442+ | FetchStmt { output_statement($1 , 1 , connection); }
443+ | GrantStmt { output_statement($1 , 0 , connection); }
444+ | IndexStmt { output_statement($1 , 0 , connection); }
443445 | ListenStmt { output_statement($1 , 0 , connection); }
444446 | UnlistenStmt { output_statement($1 , 0 , connection); }
445- | LockStmt { output_statement($1 , 0 , connection); }
447+ | LockStmt { output_statement($1 , 0 , connection); }
446448 | NotifyStmt { output_statement($1 , 0 , connection); }
447449 | ProcedureStmt { output_statement($1 , 0 , connection); }
448450 | ReindexStmt { output_statement($1 , 0 , connection); }
@@ -458,23 +460,23 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
458460 else
459461 output_statement ($1 , 1 , connection);
460462 }
461- | RuleStmt { output_statement($1 , 0 , connection); }
463+ | RuleStmt { output_statement($1 , 0 , connection); }
462464 | TransactionStmt
463465 {
464466 fprintf (yyout, " { ECPGtrans(__LINE__, %s, \" %s\" );" , connection ? connection : " NULL" , $1 );
465467 whenever_action (2 );
466468 free ($1 );
467469 }
468- | ViewStmt { output_statement($1 , 0 , connection); }
469- | LoadStmt { output_statement($1 , 0 , connection); }
470+ | ViewStmt { output_statement($1 , 0 , connection); }
471+ | LoadStmt { output_statement($1 , 0 , connection); }
470472 | CreatedbStmt { output_statement($1 , 0 , connection); }
471473 | DropdbStmt { output_statement($1 , 0 , connection); }
472474 | VacuumStmt { output_statement($1 , 0 , connection); }
473475 | AnalyzeStmt { output_statement($1 , 0 , connection); }
474476 | VariableSetStmt { output_statement($1 , 0 , connection); }
475477 | VariableShowStmt { output_statement($1 , 0 , connection); }
476- | VariableResetStmt { output_statement($1 , 0 , connection); }
477- | ConstraintsSetStmt { output_statement($1 , 0 , connection); }
478+ | VariableResetStmt { output_statement($1 , 0 , connection); }
479+ | ConstraintsSetStmt { output_statement($1 , 0 , connection); }
478480 | CheckPointStmt { output_statement($1 , 0 , connection); }
479481 | ECPGAllocateDescr
480482 {
@@ -605,7 +607,9 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
605607 if (connection)
606608 mmerror (PARSE_ERROR, ET_ERROR, " no at option for typedef statement.\n " );
607609
608- output_simple_statement ($1 );
610+ fprintf (yyout, " %s" , $1 );
611+ free ($1 );
612+ output_line_number ();
609613 }
610614 | ECPGVar
611615 {
@@ -3666,7 +3670,7 @@ ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident
36663670 */
36673671ECPGDeclaration : sql_startdeclare
36683672 { fputs(" /* exec sql begin declare section */" , yyout); }
3669- variable_declarations sql_enddeclare
3673+ var_type_declarations sql_enddeclare
36703674 {
36713675 fprintf (yyout, " %s/* exec sql end declare section */" , $3 );
36723676 free ($3 );
@@ -3678,15 +3682,82 @@ sql_startdeclare: ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {};
36783682
36793683sql_enddeclare : ecpgstart END_TRANS DECLARE SQL_SECTION ' ;' {};
36803684
3681- variable_declarations : /* EMPTY*/ { $$ = EMPTY; }
3682- | declarations { $$ = $1 ; }
3685+ var_type_declarations : /* EMPTY*/ { $$ = EMPTY; }
3686+ | vt_declarations { $$ = $1 ; }
36833687 ;
36843688
3685- declarations : declaration { $$ = $1 ; }
3686- | declarations declaration { $$ = cat2_str($1 , $2 ); }
3689+ vt_declarations : var_declaration { $$ = $1 ; }
3690+ | type_declaration { $$ = $1 ; }
3691+ | vt_declarations var_declaration { $$ = cat2_str($1 , $2 ); }
3692+ | vt_declarations type_declaration { $$ = cat2_str($1 , $2 ); }
36873693 ;
36883694
3689- declaration : storage_clause storage_modifier
3695+ variable_declarations : var_declaration { $$ = $1 ; }
3696+ | variable_declarations var_declaration { $$ = cat2_str($1 , $2 ); }
3697+ ;
3698+
3699+ type_declaration : S_TYPEDEF
3700+ {
3701+ /* reset this variable so we see if there was */
3702+ /* an initializer specified */
3703+ initializer = 0 ;
3704+ }
3705+ type opt_pointer ECPGColLabel opt_type_array_bounds ' ;'
3706+ {
3707+ /* add entry to list */
3708+ struct typedefs *ptr, *this ;
3709+ int dimension = $6 .index1;
3710+ int length = $6 .index2;
3711+
3712+ if (($3 .type_enum == ECPGt_struct ||
3713+ $3 .type_enum == ECPGt_union) &&
3714+ initializer == 1 )
3715+ {
3716+ mmerror (PARSE_ERROR, ET_ERROR, " Initializer not allowed in typedef command" );
3717+
3718+ }
3719+ else
3720+ {
3721+ for (ptr = types; ptr != NULL ; ptr = ptr->next)
3722+ {
3723+ if (strcmp($5 , ptr->name) == 0 )
3724+ {
3725+ /* re-definition is a bug */
3726+ sprintf (errortext, " Type %s already defined" , $5 );
3727+ mmerror (PARSE_ERROR, ET_ERROR, errortext);
3728+ }
3729+ }
3730+
3731+ adjust_array ($3 .type_enum, &dimension, &length, $3 .type_dimension, $3 .type_index, *$4 ?1 :0 );
3732+
3733+ this = (struct typedefs *) mm_alloc(sizeof (struct typedefs ));
3734+
3735+ /* initial definition */
3736+ this ->next = types;
3737+ this ->name = $5 ;
3738+ this ->type = (struct this_type *) mm_alloc(sizeof (struct this_type ));
3739+ this ->type->type_enum = $3 .type_enum;
3740+ this ->type->type_str = mm_strdup($5 );
3741+ this ->type->type_dimension = dimension; /* dimension of array */
3742+ this ->type->type_index = length; /* lenght of string */
3743+ this ->struct_member_list = ($3 .type_enum == ECPGt_struct || $3 .type_enum == ECPGt_union) ?
3744+ struct_member_list[struct_level] : NULL ;
3745+
3746+ if ($3 .type_enum != ECPGt_varchar &&
3747+ $3 .type_enum != ECPGt_char &&
3748+ $3 .type_enum != ECPGt_unsigned_char &&
3749+ this ->type->type_index >= 0 )
3750+ mmerror (PARSE_ERROR, ET_ERROR, " No multi-dimensional array support for simple data types" );
3751+
3752+ types = this ;
3753+ }
3754+
3755+ fprintf (yyout, " typedef %s %s %s %s;\n " , $3 .type_str, *$4 ?" *" :" " , $5 , $6 .str);
3756+ output_line_number ();
3757+ $$ = make_str(" " );
3758+ };
3759+
3760+ var_declaration : storage_clause storage_modifier
36903761 {
36913762 actual_storage[struct_level] = cat2_str(mm_strdup($1 ), mm_strdup($2 ));
36923763 actual_startline[struct_level] = hashline_number();
@@ -4239,7 +4310,7 @@ ECPGTypedef: TYPE_P
42394310 if (($5 .type_enum == ECPGt_struct ||
42404311 $5 .type_enum == ECPGt_union) &&
42414312 initializer == 1 )
4242- mmerror (PARSE_ERROR, ET_ERROR, " Initializer not allowed in EXEC SQL VAR command" );
4313+ mmerror (PARSE_ERROR, ET_ERROR, " Initializer not allowed in EXEC SQL TYPE command" );
42434314 else
42444315 {
42454316 for (ptr = types; ptr != NULL ; ptr = ptr->next)
@@ -4276,7 +4347,10 @@ ECPGTypedef: TYPE_P
42764347 types = this ;
42774348 }
42784349
4279- $$ = 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(" */" ));
4350+ if (auto_create_c == false )
4351+ $$ = 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(" */" ));
4352+ else
4353+ $$ = 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(" ;" ));
42804354 }
42814355 ;
42824356
@@ -4504,10 +4578,10 @@ ECPGKeywords: SQL_BREAK { $$ = make_str("break"); }
45044578 ;
45054579
45064580/* additional keywords that can be SQL type names (but not ECPGColLabels) */
4507- ECPGTypeName : SQL_BOOL { $$ = make_str(" bool" ); }
4508- | SQL_INT { $$ = make_str(" int" ); }
4509- | SQL_LONG { $$ = make_str(" long" ); }
4510- | SQL_SHORT { $$ = make_str(" short" ); }
4581+ ECPGTypeName : SQL_BOOL { $$ = make_str(" bool" ); }
4582+ | SQL_INT { $$ = make_str(" int" ); }
4583+ | SQL_LONG { $$ = make_str(" long" ); }
4584+ | SQL_SHORT { $$ = make_str(" short" ); }
45114585 | SQL_STRUCT { $$ = make_str(" struct" ); }
45124586 | SQL_SIGNED { $$ = make_str(" signed" ); }
45134587 | SQL_UNSIGNED { $$ = make_str(" unsigned" ); }
@@ -5006,6 +5080,7 @@ c_anything: IDENT { $$ = $1; }
50065080 | S_RSHIFT { $$ = make_str(" >>" ); }
50075081 | S_STATIC { $$ = make_str(" static" ); }
50085082 | S_SUB { $$ = make_str(" -=" ); }
5083+ | S_TYPEDEF { $$ = make_str(" typedef" ); }
50095084 | SQL_BOOL { $$ = make_str(" bool" ); }
50105085 | SQL_ENUM { $$ = make_str(" enum" ); }
50115086 | SQL_INT { $$ = make_str(" int" ); }
0 commit comments