Thread: ECPG doesn't return the correct length for an empty

ECPG doesn't return the correct length for an empty

From
"Hebert, Caroline"
Date:
===========================================================================
                        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));

Re: ECPG doesn't return the correct length for an empty

From
Michael Meskes
Date:
On Mon, Jun 21, 2004 at 08:18:07AM +0100, Hebert, Caroline wrote:
>   Short Description : ECPG doesn't return the correct length for an empty
> VARCHAR

I'm sorry, but this is not a bug but an incorrectly used feature.

> I compiled with :
> * /usr/local/pgsql/bin/ecpg -r no_indicator pg_empty_varchar.pgc

When using "-r no_indicator" an empty string in a varchar is considered
a NULL value.  So you essantially put a NULL value in the database and
then read it and try to use it as if it was not NULL.

If you remove this option it works fine.

As an explanation, this option came in as a compatibility option to
Informix. But it can also be used without Informix as you see. I wonder
if I should make this option only callable in compatibility mode.

Michael
--
Michael Meskes
Email: Michael at Fam-Meskes dot De
ICQ: 179140304, AIM/Yahoo: michaelmeskes, Jabber: meskes@jabber.org
Go SF 49ers! Go Rhein Fire! Use Debian GNU/Linux! Use PostgreSQL!