Re: using arrays within structure in ECPG

Поиск
Список
Период
Сортировка
От Ashutosh Bapat
Тема Re: using arrays within structure in ECPG
Дата
Msg-id CAFjFpRdeSi=5oN1Z7J+Pdha_ovLk2Mb26WAHmA+XWmTEPmda_Q@mail.gmail.com
обсуждение исходный текст
Ответ на Re: using arrays within structure in ECPG  (Boszormenyi Zoltan <zboszor@pr.hu>)
Список pgsql-hackers



On Mon, Mar 24, 2014 at 3:40 PM, Boszormenyi Zoltan <zboszor@pr.hu> wrote:
2014-03-24 07:22 keltezéssel, Ashutosh Bapat írta:
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)

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     };

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     }

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

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

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);

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?

ECPG (I think intentionally) doesn't interpret or parse array fields.
You need to pass a character array and parse the contents by yourself.


That doesn't seem to be the case with bare arrays (not included in anything else). I added following lines to the program attached in my first mail, and they worked perfectly fine.

 47     /* Test only arrays */
 48     EXEC SQL DECLARE cur2 CURSOR FOR select arr_col from emp;
 49
 50     EXEC SQL OPEN cur2;
 51
 52     EXEC SQL FETCH 1 FROM cur2 into :emp[0].arr_col;
 53
 54     printf("\n+++++++++++++++++++++++++++++++++++++++++++++++\n");
 55
 56     /* Print members of the array fetched. */
 57     for ( i = 0 ;i < 3; i++)
 58     {
 59         printf("arr_col[%d] = %d\n", i, emp[0].arr_col[i]);
 60     }
 61     EXEC SQL CLOSE cur2;

Anyway, if that's a restriction, shouldn't there be an error during compilation?
Best regards,
Zoltán Böszörményi


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






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

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Craig Ringer
Дата:
Сообщение: Re: About adding an attribute to pg_attibute
Следующее
От: Heikki Linnakangas
Дата:
Сообщение: Re: Only first XLogRecData is visible to rm_desc with WAL_DEBUG