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