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

Reply via email to