Commit be0b0528 authored by Tom Lane's avatar Tom Lane

Fix possible omission of variable storage markers in ECPG.

The ECPG preprocessor converted code such as

static varchar str1[10], str2[20], str3[30];

into

static  struct varchar_1  { int len; char arr[ 10 ]; }  str1 ;
        struct varchar_2  { int len; char arr[ 20 ]; }  str2 ;
        struct varchar_3  { int len; char arr[ 30 ]; }  str3 ;

thus losing the storage attribute for the later variables.
Repeat the declaration for each such variable.

(Note that this occurred only for variables declared "varchar"
or "bytea", which may help explain how it escaped detection
for so long.)

Andrey Sokolov

Discussion: https://postgr.es/m/942241662288242@mail.yandex.ru
parent e55ccb3b
...@@ -476,9 +476,10 @@ type_declaration: S_TYPEDEF ...@@ -476,9 +476,10 @@ type_declaration: S_TYPEDEF
$$ = mm_strdup(""); $$ = mm_strdup("");
}; };
var_declaration: storage_declaration var_declaration:
var_type storage_declaration var_type
{ {
actual_type[struct_level].type_storage = $1;
actual_type[struct_level].type_enum = $2.type_enum; actual_type[struct_level].type_enum = $2.type_enum;
actual_type[struct_level].type_str = $2.type_str; actual_type[struct_level].type_str = $2.type_str;
actual_type[struct_level].type_dimension = $2.type_dimension; actual_type[struct_level].type_dimension = $2.type_dimension;
...@@ -493,6 +494,7 @@ var_declaration: storage_declaration ...@@ -493,6 +494,7 @@ var_declaration: storage_declaration
} }
| var_type | var_type
{ {
actual_type[struct_level].type_storage = EMPTY;
actual_type[struct_level].type_enum = $1.type_enum; actual_type[struct_level].type_enum = $1.type_enum;
actual_type[struct_level].type_str = $1.type_str; actual_type[struct_level].type_str = $1.type_str;
actual_type[struct_level].type_dimension = $1.type_dimension; actual_type[struct_level].type_dimension = $1.type_dimension;
...@@ -873,7 +875,7 @@ variable_list: variable ...@@ -873,7 +875,7 @@ variable_list: variable
| variable_list ',' variable | variable_list ',' variable
{ {
if (actual_type[struct_level].type_enum == ECPGt_varchar || actual_type[struct_level].type_enum == ECPGt_bytea) if (actual_type[struct_level].type_enum == ECPGt_varchar || actual_type[struct_level].type_enum == ECPGt_bytea)
$$ = cat_str(3, $1, mm_strdup(";"), $3); $$ = cat_str(4, $1, mm_strdup(";"), mm_strdup(actual_type[struct_level].type_storage), $3);
else else
$$ = cat_str(3, $1, mm_strdup(","), $3); $$ = cat_str(3, $1, mm_strdup(","), $3);
} }
......
...@@ -114,6 +114,7 @@ struct exec ...@@ -114,6 +114,7 @@ struct exec
struct this_type struct this_type
{ {
char *type_storage;
enum ECPGttype type_enum; enum ECPGttype type_enum;
char *type_str; char *type_str;
char *type_dimension; char *type_dimension;
......
...@@ -71,6 +71,8 @@ main (void) ...@@ -71,6 +71,8 @@ main (void)
#line 27 "variable.pgc" #line 27 "variable.pgc"
struct personal_struct { struct personal_struct {
...@@ -98,27 +100,33 @@ main (void) ...@@ -98,27 +100,33 @@ main (void)
} ; struct t2 { } ; struct t2 {
#line 32 "variable.pgc" #line 32 "variable.pgc"
struct varchar_3 { int len; char arr[ BUFFERSIZ ]; } name ; struct varchar_3 { int len; char arr[ BUFFERSIZ ]; } name ;
} ;/* exec sql end declare section */ } ;
#line 33 "variable.pgc" #line 33 "variable.pgc"
static struct varchar_4 { int len; char arr[ 50 ]; } vc1 ; static struct varchar_5 { int len; char arr[ 50 ]; } vc2 ; static struct varchar_6 { int len; char arr[ 255 ]; } vc3 ;
#line 34 "variable.pgc"
static int i1 , i2 , i3 ;
/* exec sql end declare section */
#line 35 "variable.pgc"
#line 35 "variable.pgc" #line 37 "variable.pgc"
char * married = NULL ; char * married = NULL ;
#line 35 "variable.pgc" #line 37 "variable.pgc"
#line 36 "variable.pgc" #line 38 "variable.pgc"
long ind_married ; long ind_married ;
#line 36 "variable.pgc" #line 38 "variable.pgc"
#line 37 "variable.pgc" #line 39 "variable.pgc"
ind children ; ind children ;
#line 37 "variable.pgc" #line 39 "variable.pgc"
int loopcount; int loopcount;
char msg[128]; char msg[128];
...@@ -127,78 +135,78 @@ main (void) ...@@ -127,78 +135,78 @@ main (void)
strcpy(msg, "connect"); strcpy(msg, "connect");
{ ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0);
#line 44 "variable.pgc" #line 46 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 44 "variable.pgc" #line 46 "variable.pgc"
strcpy(msg, "set"); strcpy(msg, "set");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
#line 47 "variable.pgc" #line 49 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 47 "variable.pgc" #line 49 "variable.pgc"
strcpy(msg, "create"); strcpy(msg, "create");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table family ( name char ( 8 ) , born integer , age smallint , married date , children integer )", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table family ( name char ( 8 ) , born integer , age smallint , married date , children integer )", ECPGt_EOIT, ECPGt_EORT);
#line 50 "variable.pgc" #line 52 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 50 "variable.pgc" #line 52 "variable.pgc"
strcpy(msg, "insert"); strcpy(msg, "insert");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , married , children ) values ( 'Mum' , '19870714' , 3 )", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , married , children ) values ( 'Mum' , '19870714' , 3 )", ECPGt_EOIT, ECPGt_EORT);
#line 53 "variable.pgc" #line 55 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 53 "variable.pgc" #line 55 "variable.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , born , married , children ) values ( 'Dad' , '19610721' , '19870714' , 3 )", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , born , married , children ) values ( 'Dad' , '19610721' , '19870714' , 3 )", ECPGt_EOIT, ECPGt_EORT);
#line 54 "variable.pgc" #line 56 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 54 "variable.pgc" #line 56 "variable.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , age ) values ( 'Child 1' , 16 )", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , age ) values ( 'Child 1' , 16 )", ECPGt_EOIT, ECPGt_EORT);
#line 55 "variable.pgc" #line 57 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 55 "variable.pgc" #line 57 "variable.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , age ) values ( 'Child 2' , 14 )", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , age ) values ( 'Child 2' , 14 )", ECPGt_EOIT, ECPGt_EORT);
#line 56 "variable.pgc" #line 58 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 56 "variable.pgc" #line 58 "variable.pgc"
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , age ) values ( 'Child 3' , 9 )", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into family ( name , age ) values ( 'Child 3' , 9 )", ECPGt_EOIT, ECPGt_EORT);
#line 57 "variable.pgc" #line 59 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 57 "variable.pgc" #line 59 "variable.pgc"
strcpy(msg, "commit"); strcpy(msg, "commit");
{ ECPGtrans(__LINE__, NULL, "commit"); { ECPGtrans(__LINE__, NULL, "commit");
#line 60 "variable.pgc" #line 62 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 60 "variable.pgc" #line 62 "variable.pgc"
strcpy(msg, "open"); strcpy(msg, "open");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select name , born , age , married , children from family", ECPGt_EOIT, ECPGt_EORT);
#line 63 "variable.pgc" #line 65 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 63 "variable.pgc" #line 65 "variable.pgc"
/* exec sql whenever not found break ; */ /* exec sql whenever not found break ; */
#line 65 "variable.pgc" #line 67 "variable.pgc"
p=&personal; p=&personal;
...@@ -217,13 +225,13 @@ if (sqlca.sqlcode < 0) exit (1);} ...@@ -217,13 +225,13 @@ if (sqlca.sqlcode < 0) exit (1);}
ECPGt_long,&(ind_married),(long)1,(long)1,sizeof(long), ECPGt_long,&(ind_married),(long)1,(long)1,sizeof(long),
ECPGt_int,&(children.integer),(long)1,(long)1,sizeof(int), ECPGt_int,&(children.integer),(long)1,(long)1,sizeof(int),
ECPGt_short,&(ind_children.smallint),(long)1,(long)1,sizeof(short), ECPGt_EORT); ECPGt_short,&(ind_children.smallint),(long)1,(long)1,sizeof(short), ECPGt_EORT);
#line 72 "variable.pgc" #line 74 "variable.pgc"
if (sqlca.sqlcode == ECPG_NOT_FOUND) break; if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
#line 72 "variable.pgc" #line 74 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 72 "variable.pgc" #line 74 "variable.pgc"
printf("%8.8s", personal.name.arr); printf("%8.8s", personal.name.arr);
if (i->ind_birth.born >= 0) if (i->ind_birth.born >= 0)
...@@ -242,35 +250,42 @@ if (sqlca.sqlcode < 0) exit (1);} ...@@ -242,35 +250,42 @@ if (sqlca.sqlcode < 0) exit (1);}
strcpy(msg, "close"); strcpy(msg, "close");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT);
#line 89 "variable.pgc" #line 91 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 89 "variable.pgc" #line 91 "variable.pgc"
strcpy(msg, "drop"); strcpy(msg, "drop");
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table family", ECPGt_EOIT, ECPGt_EORT); { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table family", ECPGt_EOIT, ECPGt_EORT);
#line 92 "variable.pgc" #line 94 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 92 "variable.pgc" #line 94 "variable.pgc"
strcpy(msg, "commit"); strcpy(msg, "commit");
{ ECPGtrans(__LINE__, NULL, "commit"); { ECPGtrans(__LINE__, NULL, "commit");
#line 95 "variable.pgc" #line 97 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 95 "variable.pgc" #line 97 "variable.pgc"
strcpy(msg, "disconnect"); strcpy(msg, "disconnect");
{ ECPGdisconnect(__LINE__, "CURRENT"); { ECPGdisconnect(__LINE__, "CURRENT");
#line 98 "variable.pgc" #line 100 "variable.pgc"
if (sqlca.sqlcode < 0) exit (1);} if (sqlca.sqlcode < 0) exit (1);}
#line 98 "variable.pgc" #line 100 "variable.pgc"
/* this just to silence unused-variable warnings: */
vc1.len = vc2.len = vc3.len = 0;
i1 = i2 = i3 = 0;
printf("%d %d %d %d %d %d\n",
vc1.len, vc2.len, vc3.len,
i1, i2, i3);
return 0; return 0;
} }
...@@ -3,3 +3,4 @@ Dad , born 19610721, married 1987-07-14, children = 3 ...@@ -3,3 +3,4 @@ Dad , born 19610721, married 1987-07-14, children = 3
Child 1 , age = 16 Child 1 , age = 16
Child 2 , age = 14 Child 2 , age = 14
Child 3 , age = 9 Child 3 , age = 9
0 0 0 0 0 0
...@@ -30,6 +30,8 @@ exec sql begin declare section; ...@@ -30,6 +30,8 @@ exec sql begin declare section;
} ind_personal, *i; } ind_personal, *i;
ind ind_children; ind ind_children;
struct t1 { str name; }; struct t2 { str name; }; struct t1 { str name; }; struct t2 { str name; };
static varchar vc1[50], vc2[50], vc3[255];
static int i1, i2, i3;
exec sql end declare section; exec sql end declare section;
exec sql char *married = NULL; exec sql char *married = NULL;
...@@ -97,5 +99,12 @@ exec sql end declare section; ...@@ -97,5 +99,12 @@ exec sql end declare section;
strcpy(msg, "disconnect"); strcpy(msg, "disconnect");
exec sql disconnect; exec sql disconnect;
/* this just to silence unused-variable warnings: */
vc1.len = vc2.len = vc3.len = 0;
i1 = i2 = i3 = 0;
printf("%d %d %d %d %d %d\n",
vc1.len, vc2.len, vc3.len,
i1, i2, i3);
return 0; return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment