@@ -169,6 +169,7 @@ make_name(void)
169169S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
170170S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
171171S_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); }
458460else
459461output_statement ($1 ,1 , connection);
460462}
461- | RuleStmt { output_statement($1 ,0 , connection); }
463+ | RuleStmt { output_statement($1 ,0 , connection); }
462464| TransactionStmt
463465{
464466fprintf (yyout," { ECPGtrans(__LINE__, %s,\" %s\" );" , connection ? connection :" NULL" , $1 );
465467whenever_action (2 );
466468free ($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); }
605607if (connection)
606608mmerror (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{
36713675fprintf (yyout," %s/* exec sql end declare section */" , $3 );
36723676free ($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{
36913762actual_storage[struct_level] = cat2_str(mm_strdup($1 ), mm_strdup($2 ));
36923763actual_startline[struct_level] = hashline_number();
@@ -4239,7 +4310,7 @@ ECPGTypedef: TYPE_P
42394310if (($5 .type_enum == ECPGt_struct ||
42404311$5 .type_enum == ECPGt_union) &&
42414312initializer ==1 )
4242- mmerror (PARSE_ERROR, ET_ERROR," Initializer not allowed in EXEC SQLVAR command" );
4313+ mmerror (PARSE_ERROR, ET_ERROR," Initializer not allowed in EXEC SQLTYPE command" );
42434314else
42444315{
42454316for (ptr = types; ptr !=NULL ; ptr = ptr->next)
@@ -4276,7 +4347,10 @@ ECPGTypedef: TYPE_P
42764347types =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" ); }