Re: using arrays within structure in ECPG

From: Ashutosh Bapat <ashutosh(dot)bapat(at)enterprisedb(dot)com>
To: Boszormenyi Zoltan <zboszor(at)pr(dot)hu>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: using arrays within structure in ECPG
Date: 2014-03-25 05:05:05
Message-ID: CAFjFpRdeSi=5oN1Z7J+Pdha_ovLk2Mb26WAHmA+XWmTEPmda_Q@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Mar 24, 2014 at 3:40 PM, Boszormenyi Zoltan <zboszor(at)pr(dot)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(at)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(at)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

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Heikki Linnakangas 2014-03-25 07:30:22 Re: Only first XLogRecData is visible to rm_desc with WAL_DEBUG
Previous Message Craig Ringer 2014-03-25 04:10:15 Re: About adding an attribute to pg_attibute