Hi All,
I tried to use pointer to array to fetch results of a query. The test case
test_select.pgc is attached. Changes specific to one's environment are
needed before that test can be tried. Otherwise, you may try file
pointer_to_struct.pgc in the patch attached, by putting it ecpg/test
directory.

The file test_select.pgc compiles fine but when run it produces error -203
and produces garbage because the result of FETCH was not saved in the array
pointed by pointer.

./test_select
SQL error: SQL error -203 on line 40
empno=-163754450, ename=, job=
empno=634004672, ename=�, job=
empno=634004624, ename=�, job=

This happens because of two problems
1. When dumping individual members of structure emp in test_select.pgc,
when a pointer to that structure is dumped, its array size is dumped as "1"
instead of "0" or a negative number like scalar variable pointers.

2. As discussed in other thread "using arrays within structure in ECPG",
the offsets of members of structures are not dumped correctly for an
unbounded array.

Problem 1 reason:
-------------------------
When dumping individual members of structure emp in test_select.pgc, when a
pointer to that structure is dumped, the call is routed through code path
as shown below

*#0*  *ECPGdump_a_type* (o=0x6cc4f0, *name=0x6d2190 "empno"*,
type=0x6d2130, brace_level=-1, ind_name=0x4c0ae8 "no_indicator",
ind_type=0x6c8260, ind_brace_l
evel=-1, *prefix=0x6d1a20 "emp2->"*, ind_prefix=0x0, *arr_str_siz=0x6d2070
"0",* *struct_sizeof=0x6d0c60 "sizeof( struct employee )"*,
ind_struct_sizeof=0x0)
 at type.c:247
*#1*  0x000000000042f21d in *ECPGdump_a_struct* (o=0x6cc4f0, *name=0x6d20b0
"emp2"*, ind_name=0x435c20 "no_indicator", *arrsiz=0x6d2070 "0"*,
type=0x6d20d0, in
d_type=0x6c8260, *prefix=0x6d1a20 "emp2->"*, ind_prefix=0x0) at type.c:572
*#2*  0x000000000042e2cc in *ECPGdump_a_type *(o=0x6cc4f0, *name=0x6d20b0
"emp2"*, type=0x6d22b0, brace_level=1, ind_name=0x435c20 "no_indicator",
ind_type=0
x6c8260, ind_brace_level=0, prefix=0x0, ind_prefix=0x0, *arr_str_siz=0x6d1e60
"0"*, *struct_sizeof=0x0*, ind_struct_sizeof=0x0) at type.c:293
*#3*  0x000000000043335d in *dump_variables* (list=0x6d2310, mode=1) at
variable.c:452

ECPGdump_a_type() at frame #3, then calls ECPGdump_a_simple() as follows
#0  *ECPGdump_a_simple* (o=0x6cc4f0, *name=0x6d2190 "empno"*,
type=ECPGt_int, varcharsize=0x6d0f70 "1",* arrsize=0x6d2360 "-1"*,
*siz=0x6d0c60 "sizeof( struct employee )"*, prefix=0x6d1a20 "emp2->",
counter=0) at type.c:405

ECPGdump_a_simple() while dumping the member (here empno) dumps with
arrsize = "1" instead of "-1" because of code at line
523│                 if (atoi(arrsize) < 0)
524│                         strcpy(arrsize, "1");

In ECPG run time library when reading this variable, it is read with array
size 1 and is falsely interpreted as an array with size 1 instead of an
unbounded array (which are read with arrsize < 0). Hence giving error -203.

ECPGdump_a_struct has correctly called ECPGdump_a_type with arrsize "0" to
mean an unbounded array, and ECPGdump_a_type() has correctly converted it
to "-1" again to differentiate between pointer to struct from pointer to
scalar variable. This differentiation is important to dump pointer to
struct and pointer to scalar variable differently in ECPGdump_a_simple().
So, in ECPGdump_a_simple() we should dump the variable with arrsize "-1" if
it's part of an outer structure.

The patch attached, includes solutions to both the problems and also a
testcase preproc/pointer_to_struct.pgc. This test is a copy of test
preproc/array_of_struct.pgc with the structure arrays replaced by pointers
to structures and memory allocations.

The patch is based on development head. Please consider this to be
backpatched to 9.3 as well.

-- 
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company

Attachment: test_select.pgc
Description: Binary data

diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c
index 2982cb6..dbe2d7e 100644
--- a/src/interfaces/ecpg/preproc/type.c
+++ b/src/interfaces/ecpg/preproc/type.c
@@ -512,25 +512,33 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type,
 				if (((atoi(arrsize) > 0) ||
 					 (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) &&
 					siz == NULL)
 					sprintf(variable, "(%s%s)", prefix ? prefix : "", name);
 				else
 					sprintf(variable, "&(%s%s)", prefix ? prefix : "", name);
 
 				sprintf(offset, "sizeof(%s)", ecpg_type_name(type));
 				break;
 		}
-
-		if (atoi(arrsize) < 0)
+		
+		/*
+		 * Array size would be -1 for addresses of members within structure,
+		 * when pointer to structure is being dumped.
+		 */
+		if (atoi(arrsize) < 0 && !siz)
 			strcpy(arrsize, "1");
 
-		if (siz == NULL || strlen(siz) == 0 || strcmp(arrsize, "0") == 0 || strcmp(arrsize, "1") == 0)
+		/*
+		 * If siz i.e. the size of structure of which this variable is part of,
+		 * that gives the offset to the next element, if required 
+		 */
+		if (siz == NULL || strlen(siz) == 0)
 			fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, offset);
 		else
 			fprintf(o, "\n\t%s,%s,(long)%s,(long)%s,%s, ", get_type(type), variable, varcharsize, arrsize, siz);
 
 		free(variable);
 		free(offset);
 	}
 }
 
 
diff --git a/src/interfaces/ecpg/test/ecpg_schedule b/src/interfaces/ecpg/test/ecpg_schedule
index c07ea93..c3ec125 100644
--- a/src/interfaces/ecpg/test/ecpg_schedule
+++ b/src/interfaces/ecpg/test/ecpg_schedule
@@ -10,20 +10,21 @@ test: compat_informix/test_informix2
 test: connect/test2
 test: connect/test3
 test: connect/test4
 test: connect/test5
 test: pgtypeslib/dt_test
 test: pgtypeslib/dt_test2
 test: pgtypeslib/num_test
 test: pgtypeslib/num_test2
 test: pgtypeslib/nan_test
 test: preproc/array_of_struct
+test: preproc/pointer_to_struct
 test: preproc/autoprep
 test: preproc/comment
 test: preproc/cursor
 test: preproc/define
 test: preproc/init
 test: preproc/strings
 test: preproc/type
 test: preproc/variable
 test: preproc/outofscope
 test: preproc/whenever
diff --git a/src/interfaces/ecpg/test/expected/preproc-array_of_struct.c b/src/interfaces/ecpg/test/expected/preproc-array_of_struct.c
index 9bb09cc..216f234 100644
--- a/src/interfaces/ecpg/test/expected/preproc-array_of_struct.c
+++ b/src/interfaces/ecpg/test/expected/preproc-array_of_struct.c
@@ -228,24 +228,24 @@ if (sqlca.sqlcode < 0) sqlprint();}
 #line 72 "array_of_struct.pgc"
 
     printf("\ncusts3:\n");
     for (r = 0; r < 2; r++)
     {
 	    printf( "name  - %s\n", custs3[r].name.arr );
 	    printf( "phone - %d\n", custs3[r].phone );
     }
 
     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select * from customers limit 1", ECPGt_EOIT, 
-	ECPGt_varchar,&(custs4.name),(long)50,(long)1,sizeof(struct varchar_4), 
-	ECPGt_short,&(inds[0].name_ind),(long)1,(long)1,sizeof(short), 
-	ECPGt_int,&(custs4.phone),(long)1,(long)1,sizeof(int), 
-	ECPGt_short,&(inds[0].phone_ind),(long)1,(long)1,sizeof(short), ECPGt_EORT);
+	ECPGt_varchar,&(custs4.name),(long)50,(long)1,sizeof( struct customer4 ), 
+	ECPGt_short,&(inds[0].name_ind),(long)1,(long)1,sizeof( struct ind ), 
+	ECPGt_int,&(custs4.phone),(long)1,(long)1,sizeof( struct customer4 ), 
+	ECPGt_short,&(inds[0].phone_ind),(long)1,(long)1,sizeof( struct ind ), ECPGt_EORT);
 #line 80 "array_of_struct.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
 #line 80 "array_of_struct.pgc"
 
 if (sqlca.sqlwarn[0] == 'W') sqlprint();
 #line 80 "array_of_struct.pgc"
 
 if (sqlca.sqlcode < 0) sqlprint();}
 #line 80 "array_of_struct.pgc"
diff --git a/src/interfaces/ecpg/test/expected/preproc-outofscope.c b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
index 2438911..475f6e7 100644
--- a/src/interfaces/ecpg/test/expected/preproc-outofscope.c
+++ b/src/interfaces/ecpg/test/expected/preproc-outofscope.c
@@ -195,54 +195,54 @@ get_var1(MYTYPE **myvar0, MYNULLTYPE **mynullvar0)
 		exit(1);
 
 	*myvar0 = myvar;
 	*mynullvar0 = mynullvar;
 }
 
 static void
 open_cur1(void)
 {
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "declare mycur cursor for select * from a1", ECPGt_EOIT, 
-	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
-	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).t),(long)1,(long)1,sizeof(int), 
-	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d1),(long)1,(long)1,sizeof(double), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d1),(long)1,(long)1,sizeof(int), 
-	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d2),(long)1,(long)1,sizeof(double), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d2),(long)1,(long)1,sizeof(int), 
-	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).c),(long)30,(long)1,(30)*sizeof(char), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).c),(long)1,(long)1,sizeof(int), ECPGt_EORT);
+	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).t),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d1),(long)1,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d1),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d2),(long)1,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d2),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).c),(long)30,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).c),(long)1,(long)1,sizeof( struct mynulltype ), ECPGt_EORT);
 #line 40 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
 #line 40 "outofscope.pgc"
 
 
 	if (sqlca.sqlcode != 0)
 		exit(1);
 }
 
 static void
 get_record1(void)
 {
 	{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch mycur", ECPGt_EOIT, 
-	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof(int), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof(int), 
-	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,(64)*sizeof(char), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).t),(long)1,(long)1,sizeof(int), 
-	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d1),(long)1,(long)1,sizeof(double), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d1),(long)1,(long)1,sizeof(int), 
-	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d2),(long)1,(long)1,sizeof(double), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d2),(long)1,(long)1,sizeof(int), 
-	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).c),(long)30,(long)1,(30)*sizeof(char), 
-	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).c),(long)1,(long)1,sizeof(int), ECPGt_EORT);
+	ECPGt_int,&((*( MYTYPE  *)(ECPGget_var( 0)) ).id),(long)1,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).id),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).t),(long)64,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).t),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d1),(long)1,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d1),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_double,&((*( MYTYPE  *)(ECPGget_var( 0)) ).d2),(long)1,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).d2),(long)1,(long)1,sizeof( struct mynulltype ), 
+	ECPGt_char,&((*( MYTYPE  *)(ECPGget_var( 0)) ).c),(long)30,(long)1,sizeof( struct mytype ), 
+	ECPGt_int,&((*( MYNULLTYPE  *)(ECPGget_var( 1)) ).c),(long)1,(long)1,sizeof( struct mynulltype ), ECPGt_EORT);
 #line 49 "outofscope.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
 #line 49 "outofscope.pgc"
 
 
 	if (sqlca.sqlcode != 0 && sqlca.sqlcode != ECPG_NOT_FOUND)
 		exit(1);
 }
 
diff --git a/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.c b/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.c
new file mode 100644
index 0000000..2e4418a
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.c
@@ -0,0 +1,293 @@
+/* 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 "pointer_to_struct.pgc"
+#include <stdio.h>
+#include <stdlib.h>
+
+
+#line 1 "regression.h"
+
+
+
+
+
+
+#line 4 "pointer_to_struct.pgc"
+
+
+/* exec sql whenever sqlerror  sqlprint ; */
+#line 6 "pointer_to_struct.pgc"
+
+/* exec sql whenever sql_warning  sqlprint ; */
+#line 7 "pointer_to_struct.pgc"
+
+/* exec sql whenever not found  sqlprint ; */
+#line 8 "pointer_to_struct.pgc"
+
+
+typedef  struct { 
+#line 13 "pointer_to_struct.pgc"
+  struct varchar_1  { int len; char arr[ 50 ]; }  name ;
+ 
+#line 14 "pointer_to_struct.pgc"
+ int phone ;
+ } customer ;
+#line 15 "pointer_to_struct.pgc"
+
+
+typedef  struct ind { 
+#line 20 "pointer_to_struct.pgc"
+ short name_ind ;
+ 
+#line 21 "pointer_to_struct.pgc"
+ short phone_ind ;
+ } cust_ind ;
+#line 22 "pointer_to_struct.pgc"
+
+
+int main()
+{
+    /* exec sql begin declare section */
+              
+              
+       
+      
+         
+             
+       typedef struct { 
+#line 31 "pointer_to_struct.pgc"
+  struct varchar_2  { int len; char arr[ 50 ]; }  name ;
+ 
+#line 32 "pointer_to_struct.pgc"
+ int phone ;
+ }  customer2 ;
+
+#line 33 "pointer_to_struct.pgc"
+
+              
+
+       
+      
+         
+             
+               
+
+       
+      
+         
+             
+             
+
+       
+       
+    
+#line 27 "pointer_to_struct.pgc"
+ customer * custs1 = ( customer * ) malloc ( sizeof ( customer ) * 10 ) ;
+ 
+#line 28 "pointer_to_struct.pgc"
+ cust_ind * inds = ( cust_ind * ) malloc ( sizeof ( cust_ind ) * 10 ) ;
+ 
+#line 34 "pointer_to_struct.pgc"
+ customer2 * custs2 = ( customer2 * ) malloc ( sizeof ( customer2 ) * 10 ) ;
+ 
+#line 40 "pointer_to_struct.pgc"
+ struct customer3 { 
+#line 38 "pointer_to_struct.pgc"
+ char name [ 50 ] ;
+ 
+#line 39 "pointer_to_struct.pgc"
+ int phone ;
+ } * custs3 = ( struct customer3 * ) malloc ( sizeof ( struct customer3 ) * 10 ) ;
+ 
+#line 46 "pointer_to_struct.pgc"
+ struct customer4 { 
+#line 44 "pointer_to_struct.pgc"
+  struct varchar_3  { int len; char arr[ 50 ]; }  name ;
+ 
+#line 45 "pointer_to_struct.pgc"
+ int phone ;
+ } * custs4 = ( struct customer4 * ) malloc ( sizeof ( struct customer4 ) ) ;
+ 
+#line 48 "pointer_to_struct.pgc"
+ int r ;
+ 
+#line 49 "pointer_to_struct.pgc"
+  struct varchar_4  { int len; char arr[ 50 ]; }  onlyname [ 2 ] ;
+/* exec sql end declare section */
+#line 50 "pointer_to_struct.pgc"
+
+
+    ECPGdebug(1, stderr);
+
+    { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0); 
+#line 54 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 54 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 54 "pointer_to_struct.pgc"
+
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table customers ( c varchar ( 50 ) , p int )", ECPGt_EOIT, ECPGt_EORT);
+#line 56 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 56 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 56 "pointer_to_struct.pgc"
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into customers values ( 'John Doe' , '12345' )", ECPGt_EOIT, ECPGt_EORT);
+#line 57 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 57 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 57 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 57 "pointer_to_struct.pgc"
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into customers values ( 'Jane Doe' , '67890' )", ECPGt_EOIT, ECPGt_EORT);
+#line 58 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 58 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 58 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 58 "pointer_to_struct.pgc"
+
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select * from customers limit 2", ECPGt_EOIT, 
+	ECPGt_varchar,&(custs1->name),(long)50,(long)-1,sizeof( customer ), 
+	ECPGt_short,&(inds->name_ind),(long)1,(long)-1,sizeof( struct ind ), 
+	ECPGt_int,&(custs1->phone),(long)1,(long)-1,sizeof( customer ), 
+	ECPGt_short,&(inds->phone_ind),(long)1,(long)-1,sizeof( struct ind ), ECPGt_EORT);
+#line 60 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 60 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 60 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 60 "pointer_to_struct.pgc"
+
+    printf("custs1:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", custs1[r].name.arr );
+	    printf( "phone - %d\n", custs1[r].phone );
+    }
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select * from customers limit 2", ECPGt_EOIT, 
+	ECPGt_varchar,&(custs2->name),(long)50,(long)-1,sizeof( customer2 ), 
+	ECPGt_short,&(inds->name_ind),(long)1,(long)-1,sizeof( struct ind ), 
+	ECPGt_int,&(custs2->phone),(long)1,(long)-1,sizeof( customer2 ), 
+	ECPGt_short,&(inds->phone_ind),(long)1,(long)-1,sizeof( struct ind ), ECPGt_EORT);
+#line 68 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 68 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 68 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 68 "pointer_to_struct.pgc"
+
+    printf("\ncusts2:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", custs2[r].name.arr );
+	    printf( "phone - %d\n", custs2[r].phone );
+    }
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select * from customers limit 2", ECPGt_EOIT, 
+	ECPGt_char,&(custs3->name),(long)50,(long)-1,sizeof( struct customer3 ), 
+	ECPGt_short,&(inds->name_ind),(long)1,(long)-1,sizeof( struct ind ), 
+	ECPGt_int,&(custs3->phone),(long)1,(long)-1,sizeof( struct customer3 ), 
+	ECPGt_short,&(inds->phone_ind),(long)1,(long)-1,sizeof( struct ind ), ECPGt_EORT);
+#line 76 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 76 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 76 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 76 "pointer_to_struct.pgc"
+
+    printf("\ncusts3:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", custs3[r].name );
+	    printf( "phone - %d\n", custs3[r].phone );
+    }
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select * from customers limit 1", ECPGt_EOIT, 
+	ECPGt_varchar,&(custs4->name),(long)50,(long)-1,sizeof( struct customer4 ), 
+	ECPGt_short,&(inds->name_ind),(long)1,(long)-1,sizeof( struct ind ), 
+	ECPGt_int,&(custs4->phone),(long)1,(long)-1,sizeof( struct customer4 ), 
+	ECPGt_short,&(inds->phone_ind),(long)1,(long)-1,sizeof( struct ind ), ECPGt_EORT);
+#line 84 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 84 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 84 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 84 "pointer_to_struct.pgc"
+
+    printf("\ncusts4:\n");
+    printf( "name  - %s\n", custs4->name.arr );
+    printf( "phone - %d\n", custs4->phone );
+
+    { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select c from customers limit 2", ECPGt_EOIT, 
+	ECPGt_varchar,(onlyname),(long)50,(long)2,sizeof(struct varchar_4), 
+	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+#line 89 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode == ECPG_NOT_FOUND) sqlprint();
+#line 89 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 89 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 89 "pointer_to_struct.pgc"
+
+    printf("\nname:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", onlyname[r].arr );
+    }
+
+    { ECPGdisconnect(__LINE__, "ALL");
+#line 96 "pointer_to_struct.pgc"
+
+if (sqlca.sqlwarn[0] == 'W') sqlprint();
+#line 96 "pointer_to_struct.pgc"
+
+if (sqlca.sqlcode < 0) sqlprint();}
+#line 96 "pointer_to_struct.pgc"
+
+
+	/* All the memory will anyway be freed at the end */
+    return( 0 );
+}
diff --git a/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stderr b/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stderr
new file mode 100644
index 0000000..b011737
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stderr
@@ -0,0 +1,86 @@
+[NO_PID]: ECPGdebug: set to 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>  
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 56: query: create table customers ( c varchar ( 50 ) , p int ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 56: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 56: OK: CREATE TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 57: query: insert into customers values ( 'John Doe' , '12345' ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 57: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 57: OK: INSERT 0 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 58: query: insert into customers values ( 'Jane Doe' , '67890' ); with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 58: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 58: OK: INSERT 0 1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 60: query: select * from customers limit 2; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 60: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 60: correctly got 2 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 60: RESULT: John Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 60: RESULT: Jane Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 60: RESULT: 12345 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 60: RESULT: 67890 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 68: query: select * from customers limit 2; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 68: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 68: correctly got 2 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 68: RESULT: John Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 68: RESULT: Jane Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 68: RESULT: 12345 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 68: RESULT: 67890 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 76: query: select * from customers limit 2; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 76: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 76: correctly got 2 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 76: RESULT: John Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 76: RESULT: Jane Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 76: RESULT: 12345 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 76: RESULT: 67890 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 84: query: select * from customers limit 1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 84: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 84: correctly got 1 tuples with 2 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 84: RESULT: John Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 84: RESULT: 12345 offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 89: query: select c from customers limit 2; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 89: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_process_output on line 89: correctly got 2 tuples with 1 fields
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 89: RESULT: John Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_get_data on line 89: RESULT: Jane Doe offset: -1; array: no
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_finish: connection regress1 closed
+[NO_PID]: sqlca: code: 0, state: 00000
diff --git a/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stdout b/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stdout
new file mode 100644
index 0000000..23f41ff
--- /dev/null
+++ b/src/interfaces/ecpg/test/expected/preproc-pointer_to_struct.stdout
@@ -0,0 +1,25 @@
+custs1:
+name  - John Doe
+phone - 12345
+name  - Jane Doe
+phone - 67890
+
+custs2:
+name  - John Doe
+phone - 12345
+name  - Jane Doe
+phone - 67890
+
+custs3:
+name  - John Doe
+phone - 12345
+name  - Jane Doe
+phone - 67890
+
+custs4:
+name  - John Doe
+phone - 12345
+
+name:
+name  - John Doe
+name  - Jane Doe
diff --git a/src/interfaces/ecpg/test/expected/preproc-type.c b/src/interfaces/ecpg/test/expected/preproc-type.c
index 540770f..1df633e 100644
--- a/src/interfaces/ecpg/test/expected/preproc-type.c
+++ b/src/interfaces/ecpg/test/expected/preproc-type.c
@@ -133,25 +133,25 @@ main (void)
 
   if (sqlca.sqlcode)
     {
       printf ("insert error = %ld\n", sqlca.sqlcode);
       exit (sqlca.sqlcode);
     }
 
   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "select idnum , name , accs , string1 , string2 , string3 from empl where idnum = $1 ", 
 	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, 
-	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof(long), 
+	ECPGt_long,&(empl.idnum),(long)1,(long)1,sizeof( struct TBempl ), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
-	ECPGt_char,&(empl.name),(long)21,(long)1,(21)*sizeof(char), 
+	ECPGt_char,&(empl.name),(long)21,(long)1,sizeof( struct TBempl ), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
-	ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof(short), 
+	ECPGt_short,&(empl.accs),(long)1,(long)1,sizeof( struct TBempl ), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,(str),(long)11,(long)1,(11)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_char,&(ptr),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, 
 	ECPGt_varchar,&(vc),(long)10,(long)1,sizeof(struct varchar), 
 	ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
 #line 68 "type.pgc"
 
   if (sqlca.sqlcode)
diff --git a/src/interfaces/ecpg/test/expected/preproc-variable.c b/src/interfaces/ecpg/test/expected/preproc-variable.c
index 32e9778..a93af97 100644
--- a/src/interfaces/ecpg/test/expected/preproc-variable.c
+++ b/src/interfaces/ecpg/test/expected/preproc-variable.c
@@ -200,26 +200,26 @@ if (sqlca.sqlcode < 0) exit (1);}
 	/* exec sql whenever not found  break ; */
 #line 65 "variable.pgc"
 
 
 	p=&personal;
 	i=&ind_personal;
 	memset(i, 0, sizeof(ind_personal));
 	while (1) {
 		strcpy(msg, "fetch");
 		{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch cur", ECPGt_EOIT, 
-	ECPGt_varchar,&(p->name),(long)BUFFERSIZ,(long)1,sizeof(struct varchar_1), 
-	ECPGt_int,&(i->ind_name),(long)1,(long)1,sizeof(int), 
-	ECPGt_long,&(p->birth.born),(long)1,(long)1,sizeof(long), 
-	ECPGt_long,&(i->ind_birth.born),(long)1,(long)1,sizeof(long), 
-	ECPGt_short,&(p->birth.age),(long)1,(long)1,sizeof(short), 
-	ECPGt_short,&(i->ind_birth.age),(long)1,(long)1,sizeof(short), 
+	ECPGt_varchar,&(p->name),(long)BUFFERSIZ,(long)-1,sizeof( struct birthinfo ), 
+	ECPGt_int,&(i->ind_name),(long)1,(long)-1,sizeof( struct birthinfo ), 
+	ECPGt_long,&(p->birth.born),(long)1,(long)1,sizeof( struct birthinfo ), 
+	ECPGt_long,&(i->ind_birth.born),(long)1,(long)1,sizeof( struct birthinfo ), 
+	ECPGt_short,&(p->birth.age),(long)1,(long)1,sizeof( struct birthinfo ), 
+	ECPGt_short,&(i->ind_birth.age),(long)1,(long)1,sizeof( struct birthinfo ), 
 	ECPGt_char,&(married),(long)0,(long)1,(1)*sizeof(char), 
 	ECPGt_long,&(ind_married),(long)1,(long)1,sizeof(long), 
 	ECPGt_int,&(children.integer),(long)1,(long)1,sizeof(int), 
 	ECPGt_short,&(ind_children.smallint),(long)1,(long)1,sizeof(short), ECPGt_EORT);
 #line 72 "variable.pgc"
 
 if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
 #line 72 "variable.pgc"
 
 if (sqlca.sqlcode < 0) exit (1);}
diff --git a/src/interfaces/ecpg/test/preproc/Makefile b/src/interfaces/ecpg/test/preproc/Makefile
index 3bcb63a..95eb154 100644
--- a/src/interfaces/ecpg/test/preproc/Makefile
+++ b/src/interfaces/ecpg/test/preproc/Makefile
@@ -7,22 +7,26 @@ include $(top_srcdir)/$(subdir)/../Makefile.regress
 TESTS = array_of_struct array_of_struct.c \
 	autoprep autoprep.c \
 	comment comment.c \
 	cursor cursor.c \
 	define define.c \
 	init init.c \
 	strings strings.c \
 	outofscope outofscope.c \
 	type type.c \
 	variable variable.c \
-	whenever whenever.c
+	whenever whenever.c \
+	pointer_to_struct pointer_to_struct.c
 
 all: $(TESTS)
 
 array_of_struct.c:	array_of_struct.pgc ../regression.h
 	$(ECPG) -c -o $@ -I$(srcdir) $<
 
+pointer_to_struct.c:	pointer_to_struct.pgc ../regression.h
+	$(ECPG) -c -o $@ -I$(srcdir) $<
+
 autoprep.c:     autoprep.pgc ../regression.h
 	$(ECPG) -r prepare -o $@ -I$(srcdir) $<
 
 strings.c:     strings.pgc strings.h ../regression.h
 	$(ECPG) -i -o $@ -I$(srcdir) $<
diff --git a/src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc b/src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc
new file mode 100644
index 0000000..ec94273
--- /dev/null
+++ b/src/interfaces/ecpg/test/preproc/pointer_to_struct.pgc
@@ -0,0 +1,100 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+exec sql include ../regression;
+
+EXEC SQL WHENEVER sqlerror sqlprint;
+EXEC SQL WHENEVER sqlwarning sqlprint;
+EXEC SQL WHENEVER not found sqlprint;
+
+EXEC SQL TYPE customer IS
+    struct
+    {
+        varchar name[50];
+        int     phone;
+    };
+
+EXEC SQL TYPE cust_ind IS
+    struct ind
+    {
+        short   name_ind;
+        short   phone_ind;
+    };
+
+int main()
+{
+    EXEC SQL begin declare section;
+      customer  *custs1 = (customer *) malloc(sizeof(customer) * 10);
+      cust_ind  *inds = (cust_ind *) malloc(sizeof(cust_ind) * 10);
+      typedef struct
+      {
+        varchar name[50];
+        int     phone;
+      } customer2;
+      customer2  *custs2 = (customer2 *) malloc(sizeof(customer2) * 10);
+
+      struct customer3
+      {
+        char name[50];
+        int     phone;
+      } *custs3 = (struct customer3 *) malloc(sizeof(struct customer3) * 10);
+
+      struct customer4
+      {
+        varchar name[50];
+        int     phone;
+      } *custs4 = (struct customer4 *) malloc(sizeof(struct customer4));
+
+      int r;
+      varchar onlyname[2][50];
+    EXEC SQL end declare section;
+
+    ECPGdebug(1, stderr);
+
+    EXEC SQL connect to REGRESSDB1;
+
+    EXEC SQL create table customers (c varchar(50), p int);
+    EXEC SQL insert into customers values ('John Doe', '12345');
+    EXEC SQL insert into customers values ('Jane Doe', '67890');
+
+    EXEC SQL select * INTO :custs1:inds from customers limit 2;
+    printf("custs1:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", custs1[r].name.arr );
+	    printf( "phone - %d\n", custs1[r].phone );
+    }
+
+    EXEC SQL select * INTO :custs2:inds from customers limit 2;
+    printf("\ncusts2:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", custs2[r].name.arr );
+	    printf( "phone - %d\n", custs2[r].phone );
+    }
+
+    EXEC SQL select * INTO :custs3:inds from customers limit 2;
+    printf("\ncusts3:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", custs3[r].name );
+	    printf( "phone - %d\n", custs3[r].phone );
+    }
+
+    EXEC SQL select * INTO :custs4:inds from customers limit 1;
+    printf("\ncusts4:\n");
+    printf( "name  - %s\n", custs4->name.arr );
+    printf( "phone - %d\n", custs4->phone );
+
+    EXEC SQL select c INTO :onlyname from customers limit 2;
+    printf("\nname:\n");
+    for (r = 0; r < 2; r++)
+    {
+	    printf( "name  - %s\n", onlyname[r].arr );
+    }
+
+    EXEC SQL disconnect all;
+
+	/* All the memory will anyway be freed at the end */
+    return( 0 );
+}
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to