On Mon, Mar 24, 2014 at 3:40 PM, Boszormenyi Zoltan <zbos...@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

Reply via email to