05.09.2022, 11:12, "Kyotaro Horiguchi" <horikyota....@gmail.com>:
About the test, don't we need the test for non-varchar/bytea static
variables like "static int inta, intb, intc;"?
Good idea, thanks. I have added tests for static int and bytea. The new patch is in the attachment and here https://github.com/andr-sokolov/postgresql/commit/5a4adc1b5a2a0adfc152debcaf825e7a95a47450
From 5a4adc1b5a2a0adfc152debcaf825e7a95a47450 Mon Sep 17 00:00:00 2001 From: Andrey Sokolov <a.soko...@arenadata.io> Date: Sun, 4 Sep 2022 12:48:22 +0300 Subject: [PATCH v2] Fix storage declaration in ECPG
The ECPG preprocessor converted the code "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 ;". Storage declaration applied only to the first structure. Now storage declaration is repeated before each structure. --- src/interfaces/ecpg/preproc/ecpg.trailer | 4 +- src/interfaces/ecpg/preproc/type.h | 1 + src/interfaces/ecpg/test/ecpg_schedule | 1 + .../test/expected/preproc-static_variables.c | 215 ++++++++++++++++++ .../expected/preproc-static_variables.stderr | 150 ++++++++++++ .../expected/preproc-static_variables.stdout | 12 + src/interfaces/ecpg/test/preproc/.gitignore | 2 + src/interfaces/ecpg/test/preproc/Makefile | 1 + .../ecpg/test/preproc/static_variables.pgc | 118 ++++++++++ 9 files changed, 503 insertions(+), 1 deletion(-) create mode 100644 src/interfaces/ecpg/test/expected/preproc-static_variables.c create mode 100644 src/interfaces/ecpg/test/expected/preproc-static_variables.stderr create mode 100644 src/interfaces/ecpg/test/expected/preproc-static_variables.stdout create mode 100644 src/interfaces/ecpg/test/preproc/static_variables.pgc diff --git a/src/interfaces/ecpg/preproc/ecpg.trailer b/src/interfaces/ecpg/preproc/ecpg.trailer index 0b100b9b04..54254e2f97 100644 --- a/src/interfaces/ecpg/preproc/ecpg.trailer +++ b/src/interfaces/ecpg/preproc/ecpg.trailer @@ -479,6 +479,7 @@ type_declaration: S_TYPEDEF var_declaration: 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_str = $2.type_str; actual_type[struct_level].type_dimension = $2.type_dimension; @@ -493,6 +494,7 @@ var_declaration: storage_declaration } | var_type { + actual_type[struct_level].type_storage = EMPTY; actual_type[struct_level].type_enum = $1.type_enum; actual_type[struct_level].type_str = $1.type_str; actual_type[struct_level].type_dimension = $1.type_dimension; @@ -949,7 +951,7 @@ variable_list: variable | variable_list ',' variable { 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 $$ = cat_str(3, $1, mm_strdup(","), $3); } diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index fb20be53e0..08b739e5f3 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -114,6 +114,7 @@ struct exec struct this_type { + char *type_storage; enum ECPGttype type_enum; char *type_str; char *type_dimension; diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule index e034c5a420..d594c4d9b0 100644 --- a/src/interfaces/ecpg/test/ecpg_schedule +++ b/src/interfaces/ecpg/test/ecpg_schedule @@ -24,6 +24,7 @@ test: preproc/comment test: preproc/cursor test: preproc/define test: preproc/init +test: preproc/static_variables test: preproc/strings test: preproc/type test: preproc/variable diff --git a/src/interfaces/ecpg/test/expected/preproc-static_variables.c b/src/interfaces/ecpg/test/expected/preproc-static_variables.c new file mode 100644 index 0000000000..5a6bcee666 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/preproc-static_variables.c @@ -0,0 +1,215 @@ +/* Processed by ecpg (regression mode) */ +/* These include files are added by the preprocessor */ +#include <ecpglib.h> +#include <ecpgerrno.h> +#include <sqlca.h> +/* End of automatic include section */ +#define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y)) + +#line 1 "static_variables.pgc" +#include <stdlib.h> + + +#line 1 "regression.h" + + + + + + +#line 3 "static_variables.pgc" + + +/* exec sql whenever sqlerror stop ; */ +#line 5 "static_variables.pgc" + + +/* declare cur cursor for select firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 from persons */ +#line 11 "static_variables.pgc" + + +/* exec sql begin declare section */ + + + + + +#line 14 "static_variables.pgc" + static struct varchar_1 { int len; char arr[ 50 ]; } firstname ; static struct varchar_2 { int len; char arr[ 50 ]; } lastname ; static struct varchar_3 { int len; char arr[ 255 ]; } address ; + +#line 15 "static_variables.pgc" + static int year_of_birth , height_in_sm , weight_in_kg ; + +#line 16 "static_variables.pgc" + static struct bytea_1 { int len; char arr[ 5 ]; } data1 ; static struct bytea_2 { int len; char arr[ 8 ]; } data2 ; static struct bytea_3 { int len; char arr[ 12 ]; } data3 ; static struct bytea_4 { int len; char arr[ 5 ]; } data1_2 ; static struct bytea_5 { int len; char arr[ 8 ]; } data2_2 ; static struct bytea_6 { int len; char arr[ 12 ]; } data3_2 ; +/* exec sql end declare section */ +#line 18 "static_variables.pgc" + + +static void +dump_binary(char *buf, int len) +{ + int i; + + printf("len=%d, data=0x", len); + for (i = 0; i < len; ++i) + printf("%02x", buf[i]); + printf("\n"); +} + +int +main (void) +{ + int loopcount; + + ECPGdebug(1, stderr); + + { ECPGconnect(__LINE__, 0, "ecpg1_regression" , NULL, NULL , NULL, 0); +#line 38 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 38 "static_variables.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table persons ( firstname varchar ( 50 ) not null , lastname varchar ( 50 ) not null , address varchar ( 255 ) not null , year_of_birth int not null , height_in_sm int not null , weight_in_kg int not null , data1 bytea not null , data2 bytea not null , data3 bytea not null )", ECPGt_EOIT, ECPGt_EORT); +#line 50 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 50 "static_variables.pgc" + + + data1.len = 5; + for (loopcount = 0; loopcount < data1.len; loopcount++) + data1.arr[loopcount] = 1; + + data2.len = 8; + for (loopcount = 0; loopcount < data2.len; loopcount++) + data2.arr[loopcount] = 2; + + data3.len = 12; + for (loopcount = 0; loopcount < data3.len; loopcount++) + data3.arr[loopcount] = 3; + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into persons ( firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 ) values ( 'firstname1' , 'lastname1' , 'address1' , 1985 , 180 , 70 , $1 , $2 , $3 )", + ECPGt_bytea,&(data1),(long)5,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data2),(long)8,(long)1,sizeof(struct bytea_2), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data3),(long)12,(long)1,sizeof(struct bytea_3), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 71 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 71 "static_variables.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into persons ( firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 ) values ( 'firstname2' , 'lastname2' , 'address2' , 1995 , 170 , 65 , $1 , $2 , $3 )", + ECPGt_bytea,&(data1),(long)5,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data2),(long)8,(long)1,sizeof(struct bytea_2), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data3),(long)12,(long)1,sizeof(struct bytea_3), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 80 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 80 "static_variables.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into persons ( firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 ) values ( 'firstname3' , 'lastname3' , 'address3' , 2000 , 172 , 80 , $1 , $2 , $3 )", + ECPGt_bytea,&(data1),(long)5,(long)1,sizeof(struct bytea_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data2),(long)8,(long)1,sizeof(struct bytea_2), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data3),(long)12,(long)1,sizeof(struct bytea_3), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT); +#line 89 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 89 "static_variables.pgc" + + + { ECPGtrans(__LINE__, NULL, "commit"); +#line 91 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 91 "static_variables.pgc" + + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare cur cursor for select firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 from persons", ECPGt_EOIT, ECPGt_EORT); +#line 93 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 93 "static_variables.pgc" + + + /* exec sql whenever not found break ; */ +#line 95 "static_variables.pgc" + + + for (loopcount = 0; loopcount < 100; loopcount++) + { + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur", ECPGt_EOIT, + ECPGt_varchar,&(firstname),(long)50,(long)1,sizeof(struct varchar_1), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_varchar,&(lastname),(long)50,(long)1,sizeof(struct varchar_2), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_varchar,&(address),(long)255,(long)1,sizeof(struct varchar_3), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(year_of_birth),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(height_in_sm),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_int,&(weight_in_kg),(long)1,(long)1,sizeof(int), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data1_2),(long)5,(long)1,sizeof(struct bytea_4), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data2_2),(long)8,(long)1,sizeof(struct bytea_5), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, + ECPGt_bytea,&(data3_2),(long)12,(long)1,sizeof(struct bytea_6), + ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT); +#line 101 "static_variables.pgc" + +if (sqlca.sqlcode == ECPG_NOT_FOUND) break; +#line 101 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 101 "static_variables.pgc" + + + printf("%.*s\t%.*s\t%.*s\t%i\t%i\t%i\n", + firstname.len, firstname.arr, + lastname.len, lastname.arr, + address.len, address.arr, + year_of_birth, height_in_sm, weight_in_kg); + dump_binary(data1_2.arr, data1_2.len); + dump_binary(data2_2.arr, data2_2.len); + dump_binary(data3_2.arr, data3_2.len); + } + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "close cur", ECPGt_EOIT, ECPGt_EORT); +#line 113 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 113 "static_variables.pgc" + + { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table persons", ECPGt_EOIT, ECPGt_EORT); +#line 114 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 114 "static_variables.pgc" + + { ECPGtrans(__LINE__, NULL, "commit"); +#line 115 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 115 "static_variables.pgc" + + { ECPGdisconnect(__LINE__, "CURRENT"); +#line 116 "static_variables.pgc" + +if (sqlca.sqlcode < 0) exit (1);} +#line 116 "static_variables.pgc" + + return 0; +} diff --git a/src/interfaces/ecpg/test/expected/preproc-static_variables.stderr b/src/interfaces/ecpg/test/expected/preproc-static_variables.stderr new file mode 100644 index 0000000000..b3e94f1c52 --- /dev/null +++ b/src/interfaces/ecpg/test/expected/preproc-static_variables.stderr @@ -0,0 +1,150 @@ +[NO_PID]: ECPGdebug: set to 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGconnect: opening database ecpg1_regression on <DEFAULT> port <DEFAULT> +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 40: query: create table persons ( firstname varchar ( 50 ) not null , lastname varchar ( 50 ) not null , address varchar ( 255 ) not null , year_of_birth int not null , height_in_sm int not null , weight_in_kg int not null , data1 bytea not null , data2 bytea not null , data3 bytea not null ); with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 40: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 40: OK: CREATE TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 64: query: insert into persons ( firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 ) values ( 'firstname1' , 'lastname1' , 'address1' , 1985 , 180 , 70 , $1 , $2 , $3 ); with 3 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 64: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 64: parameter 1 = 0101010101 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 64: parameter 2 = 0202020202020202 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 64: parameter 3 = 030303030303030303030303 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 64: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 73: query: insert into persons ( firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 ) values ( 'firstname2' , 'lastname2' , 'address2' , 1995 , 170 , 65 , $1 , $2 , $3 ); with 3 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 73: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 73: parameter 1 = 0101010101 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 73: parameter 2 = 0202020202020202 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 73: parameter 3 = 030303030303030303030303 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 73: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: query: insert into persons ( firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 ) values ( 'firstname3' , 'lastname3' , 'address3' , 2000 , 172 , 80 , $1 , $2 , $3 ); with 3 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 82: using PQexecParams +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 82: parameter 1 = 0101010101 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 82: parameter 2 = 0202020202020202 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_free_params on line 82: parameter 3 = 030303030303030303030303 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 82: OK: INSERT 0 1 +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 91: action "commit"; connection "ecpg1_regression" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 93: query: declare cur cursor for select firstname , lastname , address , year_of_birth , height_in_sm , weight_in_kg , data1 , data2 , data3 from persons; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 93: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 93: OK: DECLARE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: query: fetch cur; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 99: correctly got 1 tuples with 9 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: firstname1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: lastname1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: address1 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 1985 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 180 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 70 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x0101010101 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x0202020202020202 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x030303030303030303030303 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: query: fetch cur; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 99: correctly got 1 tuples with 9 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: firstname2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: lastname2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: address2 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 1995 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 170 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 65 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x0101010101 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x0202020202020202 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x030303030303030303030303 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: query: fetch cur; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 99: correctly got 1 tuples with 9 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: firstname3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: lastname3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: address3 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 2000 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 172 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: 80 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x0101010101 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x0202020202020202 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_get_data on line 99: RESULT: \x030303030303030303030303 offset: -1; array: no +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: query: fetch cur; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 99: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 99: correctly got 0 tuples with 9 fields +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: raising sqlcode 100 on line 99: no data found on line 99 +[NO_PID]: sqlca: code: 100, state: 02000 +[NO_PID]: ecpg_execute on line 113: query: close cur; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 113: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 113: OK: CLOSE CURSOR +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 114: query: drop table persons; with 0 parameter(s) on connection ecpg1_regression +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_execute on line 114: using PQexec +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_process_output on line 114: OK: DROP TABLE +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ECPGtrans on line 115: action "commit"; connection "ecpg1_regression" +[NO_PID]: sqlca: code: 0, state: 00000 +[NO_PID]: ecpg_finish: connection ecpg1_regression closed +[NO_PID]: sqlca: code: 0, state: 00000 diff --git a/src/interfaces/ecpg/test/expected/preproc-static_variables.stdout b/src/interfaces/ecpg/test/expected/preproc-static_variables.stdout new file mode 100644 index 0000000000..d5148f78fa --- /dev/null +++ b/src/interfaces/ecpg/test/expected/preproc-static_variables.stdout @@ -0,0 +1,12 @@ +firstname1 lastname1 address1 1985 180 70 +len=5, data=0x0101010101 +len=8, data=0x0202020202020202 +len=12, data=0x030303030303030303030303 +firstname2 lastname2 address2 1995 170 65 +len=5, data=0x0101010101 +len=8, data=0x0202020202020202 +len=12, data=0x030303030303030303030303 +firstname3 lastname3 address3 2000 172 80 +len=5, data=0x0101010101 +len=8, data=0x0202020202020202 +len=12, data=0x030303030303030303030303 diff --git a/src/interfaces/ecpg/test/preproc/.gitignore b/src/interfaces/ecpg/test/preproc/.gitignore index fd63e645a3..831accc526 100644 --- a/src/interfaces/ecpg/test/preproc/.gitignore +++ b/src/interfaces/ecpg/test/preproc/.gitignore @@ -14,6 +14,8 @@ /outofscope.c /pointer_to_struct /pointer_to_struct.c +/static_variables +/static_variables.c /strings /strings.c /type diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile index 39b1974f5f..a3cfe6533f 100644 --- a/src/interfaces/ecpg/test/preproc/Makefile +++ b/src/interfaces/ecpg/test/preproc/Makefile @@ -10,6 +10,7 @@ TESTS = array_of_struct array_of_struct.c \ cursor cursor.c \ define define.c \ init init.c \ + static_variables static_variables.c \ strings strings.c \ outofscope outofscope.c \ type type.c \ diff --git a/src/interfaces/ecpg/test/preproc/static_variables.pgc b/src/interfaces/ecpg/test/preproc/static_variables.pgc new file mode 100644 index 0000000000..05be898e01 --- /dev/null +++ b/src/interfaces/ecpg/test/preproc/static_variables.pgc @@ -0,0 +1,118 @@ +#include <stdlib.h> + +exec sql include ../regression; + +exec sql whenever sqlerror stop; + +exec sql declare cur cursor for + select firstname, lastname, address, + year_of_birth, height_in_sm, weight_in_kg, + data1, data2, data3 + from persons; + +exec sql begin declare section; + static varchar firstname[50], lastname[50], address[255]; + static int year_of_birth, height_in_sm, weight_in_kg; + static bytea data1[5], data2[8], data3[12], + data1_2[5], data2_2[8], data3_2[12]; +exec sql end declare section; + +static void +dump_binary(char *buf, int len) +{ + int i; + + printf("len=%d, data=0x", len); + for (i = 0; i < len; ++i) + printf("%02x", buf[i]); + printf("\n"); +} + +int +main (void) +{ + int loopcount; + + ECPGdebug(1, stderr); + + exec sql connect to REGRESSDB1; + + exec sql create table persons ( + firstname varchar(50) not null, + lastname varchar(50) not null, + address varchar(255) not null, + year_of_birth int not null, + height_in_sm int not null, + weight_in_kg int not null, + data1 bytea not null, + data2 bytea not null, + data3 bytea not null + ); + + data1.len = 5; + for (loopcount = 0; loopcount < data1.len; loopcount++) + data1.arr[loopcount] = 1; + + data2.len = 8; + for (loopcount = 0; loopcount < data2.len; loopcount++) + data2.arr[loopcount] = 2; + + data3.len = 12; + for (loopcount = 0; loopcount < data3.len; loopcount++) + data3.arr[loopcount] = 3; + + exec sql insert into persons ( + firstname, lastname, address, + year_of_birth, height_in_sm, weight_in_kg, + data1, data2, data3) + values ( + 'firstname1', 'lastname1', 'address1', + 1985, 180, 70, + :data1, :data2, :data3); + + exec sql insert into persons ( + firstname, lastname, address, + year_of_birth, height_in_sm, weight_in_kg, + data1, data2, data3) + values ( + 'firstname2', 'lastname2', 'address2', + 1995, 170, 65, + :data1, :data2, :data3); + + exec sql insert into persons ( + firstname, lastname, address, + year_of_birth, height_in_sm, weight_in_kg, + data1, data2, data3) + values ( + 'firstname3', 'lastname3', 'address3', + 2000, 172, 80, + :data1, :data2, :data3); + + exec sql commit; + + exec sql open cur; + + exec sql whenever not found do break; + + for (loopcount = 0; loopcount < 100; loopcount++) + { + exec sql fetch cur into :firstname, :lastname, :address, + :year_of_birth, :height_in_sm, :weight_in_kg, + :data1_2, :data2_2, :data3_2; + + printf("%.*s\t%.*s\t%.*s\t%i\t%i\t%i\n", + firstname.len, firstname.arr, + lastname.len, lastname.arr, + address.len, address.arr, + year_of_birth, height_in_sm, weight_in_kg); + dump_binary(data1_2.arr, data1_2.len); + dump_binary(data2_2.arr, data2_2.len); + dump_binary(data3_2.arr, data3_2.len); + } + + exec sql close cur; + exec sql drop table persons; + exec sql commit; + exec sql disconnect; + return 0; +} -- 2.33.3