===========================================================================
POSTGRESQL BUG REPORT TEMPLATE
============================================================================
Your name : Caroline Hebert
Your email address : caroline.hebert@eds.com
System Configuration
---------------------
Architecture (example: Intel Pentium) : Pentium Celeron
Operating System (example: Linux 2.0.26 ELF) : RedHat 7.2 + Linux Kernel
2.4.20
PostgreSQL version (example: PostgreSQL-7.4) : PostgreSQL-7.4.2 / ECPG
3.1.1
Compiler used (example: gcc 2.95.2) : gcc 2.96
Short Description : ECPG doesn't return the correct length for an empty
VARCHAR
Please enter a FULL description of your problem:
------------------------------------------------
When recovering VARCHAR data from a PostGreSQL Database through the ECPG
interface client, the 'length' field of the 'VARCHAR' C structure is not set
to 0 for an empty string.
Indeed, ECPG converts a VARCHAR variable like this :
VARCHAR var [180]
into
struct varchar_var { int len; char arr[180]; } var;
When data recovered are not empty, the 'arr' field contains the returned
string and the 'len' field contains its length.
If the string recovered is empty, the 'arr' is empty, but the 'len' field is
not set to 0 and keeps its prior value.
Please describe a way to repeat the problem. Please try to provide a
concise reproducible example, if at all possible:
----------------------------------------------------------------------
#include <stdio.h>
int
main (void)
{
EXEC SQL BEGIN DECLARE SECTION;
varchar text[10];
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE sqlca.h;
EXEC SQL CONNECT TO ... USER ... IDENTIFIED BY ...;
EXEC SQL CREATE TABLE MYTABLE (COL1 VARCHAR (10), COL2 VARCHAR (10),
COL3 VARCHAR (10));
EXEC SQL INSERT INTO MYTABLE (COL1, COL2, COL3) VALUES ('HELLO', 'WORLD',
'!!!');
/* (1) PUT AN EMPTY STRING INTO COL2 */
strcpy (text.arr, "");
text.len = 0;
EXEC SQL UPDATE MYTABLE SET COL2 = :text WHERE COL1 = 'HELLO';
/* (2) SELECT VALUE FROM COL3 */
EXEC SQL SELECT COL3 INTO :text FROM MYTABLE WHERE COL1 = 'HELLO';
printf ("(2) text.arr=[%s] text.len=[%d]\n", text.arr, text.len);
/* (3) SELECT VALUE FROM COL 2 (EMPTY STRING) */
EXEC SQL SELECT COL2 INTO :text FROM MYTABLE WHERE COL1 = 'HELLO';
printf ("(3) text.arr=[%s] text.len=[%d]\n", text.arr, text.len);
EXEC SQL DROP TABLE MYTABLE;
EXEC SQL DISCONNECT SIG;
return (0);
}
I compiled with :
* /usr/local/pgsql/bin/ecpg -r no_indicator pg_empty_varchar.pgc
* gcc -g pg_empty_varchar.c -o pg_empty_varchar -I/usr/local/pgsql/include
-L/usr/local/pgsql/lib -lecpg
Results :
(2) text.arr=[!!!] text.len=[3]
(3) text.arr=[] text.len=[3]
If you know how this problem might be fixed, list the solution below:
---------------------------------------------------------------------
Bug description :
In misc.c::ECPGset_informix_null(enum ECPGttype type, void *ptr), the
variable contained in 'ptr' is set to null (or zero depending on its type).
In case of a 'ECPGt_varchar' variable, the 'arr' field is set to "\0", but
the 'len' field is not set to zero.
Patch :
diff -c -r postgresql-7.4.2/src/interfaces/ecpg/ecpglib
postgresql-7.4.2p1/src/interfaces/ecpg/ecpglib --exclude="*.o"
*** postgresql-7.4.2/src/interfaces/ecpg/ecpglib/misc.c Mon Nov 24 13:11:27
2003
--- postgresql-7.4.2p1/src/interfaces/ecpg/ecpglib/misc.c Fri May 7
09:38:37 2004
***************
*** 296,301 ****
--- 296,302 ----
break;
case ECPGt_varchar:
*(((struct ECPGgeneric_varchar *) ptr)->arr) = 0x00;
+ ((struct ECPGgeneric_varchar *) ptr)->len = 0;
break;
case ECPGt_decimal:
memset((char *) ptr, 0, sizeof(decimal));