using arrays within structure in ECPG - Mailing list pgsql-hackers
From | Ashutosh Bapat |
---|---|
Subject | using arrays within structure in ECPG |
Date | |
Msg-id | CAFjFpRdwCZ+0tiJg1iRXG4d=ehVDHPTyooM6Ra6aFff-VADpaA@mail.gmail.com Whole thread Raw |
Responses |
Re: using arrays within structure in ECPG
Re: using arrays within structure in ECPG |
List | pgsql-hackers |
Hi,
I tried using integer array within a structure array in ECPG code. But it resulted in some garbage values being printed from the table. Here are the details,
The ECPG program is attached (array_test.pgc). It tries to read the contents of table emp, whose structure and contents are as follows
postgres=# \d+ emp
Table "public.emp"
Column | Type | Modifiers | Storage | Stats target | Description
---------+-------------------+-----------+----------+--------------+-------------
empno | numeric(4,0) | | main | |
ename | character varying | | extended | |
job | character varying | | extended | |
arr_col | integer[] | | extended | |
Has OIDs: no
postgres=# select * from emp;
empno | ename | job | arr_col
-------+--------+---------+------------
7900 | JAMES | CLERK | {1,2,7900}
7902 | FORD | ANALYST | {1,2,7902}
7934 | MILLER | CLERK | {1,2,7934}
(3 rows)
postgres=# \d+ emp
Table "public.emp"
Column | Type | Modifiers | Storage | Stats target | Description
---------+-------------------+-----------+----------+--------------+-------------
empno | numeric(4,0) | | main | |
ename | character varying | | extended | |
job | character varying | | extended | |
arr_col | integer[] | | extended | |
Has OIDs: no
postgres=# select * from emp;
empno | ename | job | arr_col
-------+--------+---------+------------
7900 | JAMES | CLERK | {1,2,7900}
7902 | FORD | ANALYST | {1,2,7902}
7934 | MILLER | CLERK | {1,2,7934}
(3 rows)
You will notice that the last element of the arr_col array is same as the empno of that row.
The ECPG program tries to read the rows using FETCH in a structure emp defined as
15 struct employee {
16 int empno;
17 char ename[11];
18 char job[15];
19 int arr_col[3];
20 };
15 struct employee {
16 int empno;
17 char ename[11];
18 char job[15];
19 int arr_col[3];
20 };
and then print the read contents as
39 /* Print members of the structure. */
40 for ( i = 0 ;i < 3; i++){
41 printf("empno=%d, ename=%s, job=%s, arr_col[2]=%d\n", emp[i].empno, emp[i].ename, emp[i].job, emp[i].arr_col[2]);
42
43 }
39 /* Print members of the structure. */
40 for ( i = 0 ;i < 3; i++){
41 printf("empno=%d, ename=%s, job=%s, arr_col[2]=%d\n", emp[i].empno, emp[i].ename, emp[i].job, emp[i].arr_col[2]);
42
43 }
But garbage values are printed
[ashutosh@ubuntu repro]./array_test
+++++++++++++++++++++++++++++++++++++++++++++++
empno=7900, ename=JAMES, job=CLERK, arr_col[2]=1
empno=2, ename=�, job=ANALYST, arr_col[2]=32767
empno=7934, ename=MILLER, job=CLERK, arr_col[2]=1719202336
[ashutosh@ubuntu repro]./array_test
+++++++++++++++++++++++++++++++++++++++++++++++
empno=7900, ename=JAMES, job=CLERK, arr_col[2]=1
empno=2, ename=�, job=ANALYST, arr_col[2]=32767
empno=7934, ename=MILLER, job=CLERK, arr_col[2]=1719202336
Here are steps I have used to compile the ECPG program
[ashutosh@ubuntu repro]make array_test
ecpg -c -I/work/pg_head/build/include array_test.pgc
cc -I/work/pg_head/build/include -g -c -o array_test.o array_test.c
cc -g array_test.o -L/work/pg_head/build/lib -lecpg -lpq -o array_test
rm array_test.o array_test.c
[ashutosh@ubuntu repro]make array_test
ecpg -c -I/work/pg_head/build/include array_test.pgc
cc -I/work/pg_head/build/include -g -c -o array_test.o array_test.c
cc -g array_test.o -L/work/pg_head/build/lib -lecpg -lpq -o array_test
rm array_test.o array_test.c
where /work/pg_head/build is the directory containing the postgresql build (essentially argument to the --prefix option to configure).
The programs compiles and links fine.
Without the arr_col member, the program works fine. So, it seems to be a problem with array within structure array.
In array_test.c I see that the ECPGdo statement corresponding to the FETCH command is as follows
87 /* Fetch multiple columns into one structure. */
88 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 3 from cur1", ECPGt_EOIT,
89 ECPGt_int,&(emp->empno),(long)1,(long)14,sizeof( struct employee ),
90 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
91 ECPGt_char,&(emp->ename),(long)11,(long)14,sizeof( struct employee ),
92 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
93 ECPGt_char,&(emp->job),(long)15,(long)14,sizeof( struct employee ),
94 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
95 ECPGt_int,(emp->arr_col),(long)1,(long)3,sizeof(int),
96 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
87 /* Fetch multiple columns into one structure. */
88 { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 3 from cur1", ECPGt_EOIT,
89 ECPGt_int,&(emp->empno),(long)1,(long)14,sizeof( struct employee ),
90 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
91 ECPGt_char,&(emp->ename),(long)11,(long)14,sizeof( struct employee ),
92 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
93 ECPGt_char,&(emp->job),(long)15,(long)14,sizeof( struct employee ),
94 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
95 ECPGt_int,(emp->arr_col),(long)1,(long)3,sizeof(int),
96 ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
For all the members of struct employee, except arr_col, the size of array is set to 14 and next member offset is set of sizeof (struct employee). But for arr_col they are set to 3 and sizeof(int) resp. So, for the next row onwards, the calculated offset of arr_col member would not coincide with the real arr_col member's address.
Am I missing something here?
--
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
Attachment
pgsql-hackers by date: