Обсуждение: using array of char pointers gives wrong results
Hi,
When array of char * is used as target for the FETCH statement returning more than one row, it tries to store all the result in the first element. PFA test_char_select.pgc, which fetches first 3 relnames from pg_class ordered by relname. The program prints following result
steps to compile and build the program
ecpg -c -I<ecpg_include_dir> test_char_select.pgc
cc -I<pg installation include dir> -g -c -o test_char_select.o test_char_select.c
cc -g test_char_select.o -L<pg installation lib dir> -lecpg -lpq -lpgtypes -o test_char_select
steps to compile and build the program
ecpg -c -I<ecpg_include_dir> test_char_select.pgc
cc -I<pg installation include dir> -g -c -o test_char_select.o test_char_select.c
cc -g test_char_select.o -L<pg installation lib dir> -lecpg -lpq -lpgtypes -o test_char_select
output
./test_char_select
relname=___pg_foreign_table_columns
relname=
relname=
relname=___pg_foreign_table_columns
relname=
relname=
The first three relnames should have been
postgres=# select relname from pg_class order by relname limit 3;
relname
---------------------------
_pg_foreign_data_wrappers
_pg_foreign_servers
_pg_foreign_table_columns
postgres=# select relname from pg_class order by relname limit 3;
relname
---------------------------
_pg_foreign_data_wrappers
_pg_foreign_servers
_pg_foreign_table_columns
It's obvious that the first element of the array is being overwritten with an offset of 1.
This happens because, the array of char pointer is dumped as
/* Fetch multiple columns into one structure. */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 3 from cur1", ECPGt_EOIT,
ECPGt_char,(strings),(long)0,(long)3,(1)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
/* Fetch multiple columns into one structure. */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 3 from cur1", ECPGt_EOIT,
ECPGt_char,(strings),(long)0,(long)3,(1)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
Since the offset is 1, the next result overwrites the previous result except for the first byte.
PFA patch ecpg_char_ptr_arr.patch to fix this issue. It has changes as follows
1. Dump array of char pointer with right offset i.e. sizeof(char *)
2. While reading array of char pointer in ecpg_do_prologue(), use the address instead of the value at that address
3. The pointer arithmetic should treat such variable as char **, instead of char *
ECPG regression tests do not show any failures with this patch.
--
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
Вложения
Let me bring the bug fix again to the surface. Is anybody looking at this fix?
On Tue, Apr 29, 2014 at 2:25 PM, Ashutosh Bapat <ashutosh.bapat@enterprisedb.com> wrote:
Hi,When array of char * is used as target for the FETCH statement returning more than one row, it tries to store all the result in the first element. PFA test_char_select.pgc, which fetches first 3 relnames from pg_class ordered by relname. The program prints following result
steps to compile and build the program
ecpg -c -I<ecpg_include_dir> test_char_select.pgc
cc -I<pg installation include dir> -g -c -o test_char_select.o test_char_select.c
cc -g test_char_select.o -L<pg installation lib dir> -lecpg -lpq -lpgtypes -o test_char_selectoutput./test_char_select
relname=___pg_foreign_table_columns
relname=
relname=The first three relnames should have been
postgres=# select relname from pg_class order by relname limit 3;
relname
---------------------------
_pg_foreign_data_wrappers
_pg_foreign_servers
_pg_foreign_table_columnsIt's obvious that the first element of the array is being overwritten with an offset of 1.This happens because, the array of char pointer is dumped as
/* Fetch multiple columns into one structure. */
{ ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch 3 from cur1", ECPGt_EOIT,
ECPGt_char,(strings),(long)0,(long)3,(1)*sizeof(char),
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);Since the offset is 1, the next result overwrites the previous result except for the first byte.PFA patch ecpg_char_ptr_arr.patch to fix this issue. It has changes as follows1. Dump array of char pointer with right offset i.e. sizeof(char *)2. While reading array of char pointer in ecpg_do_prologue(), use the address instead of the value at that address3. The pointer arithmetic should treat such variable as char **, instead of char *ECPG regression tests do not show any failures with this patch.--Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
--
Best Wishes,
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
Ashutosh Bapat
EnterpriseDB Corporation
The Postgres Database Company
> PFA patch ecpg_char_ptr_arr.patch to fix this issue. It has changes as > follows > ... Thanks for finding and fixing the problem. Patch applied to complete 9 series with only a minor change. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Michael at BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org Jabber: michael.meskes at gmail dot com VfL Borussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL
<div dir="ltr">Thanks Michael.<br /><br /></div><div class="gmail_extra"><br /><br /><div class="gmail_quote">On Tue, May6, 2014 at 5:01 PM, Michael Meskes <span dir="ltr"><<a href="mailto:meskes@postgresql.org" target="_blank">meskes@postgresql.org</a>></span>wrote:<br /><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px#ccc solid;padding-left:1ex"><div class="">> PFA patch ecpg_char_ptr_arr.patch to fix this issue.It has changes as<br /> > follows<br /></div>> ...<br /><br /> Thanks for finding and fixing the problem. Patchapplied to complete 9 series with only a minor change.<br /><span class="HOEnZb"><font color="#888888"><br /> Michael<br/> --<br /> Michael Meskes<br /> Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org)<br /> Michaelat BorussiaFan dot De, Meskes at (Debian|Postgresql) dot Org<br /> Jabber: michael.meskes at gmail dot com<br /> VfLBorussia! Força Barça! Go SF 49ers! Use Debian GNU/Linux, PostgreSQL<br /></font></span></blockquote></div><br /><br clear="all"/><br />-- <br /><div dir="ltr">Best Wishes,<br />Ashutosh Bapat<br />EnterpriseDB Corporation<br />The PostgresDatabase Company<br /></div></div>