Re: Split-up ECPG patches - Mailing list pgsql-hackers

From Boszormenyi Zoltan
Subject Re: Split-up ECPG patches
Date
Msg-id 4A81961B.6020409@cybertec.at
Whole thread Raw
In response to Re: Split-up ECPG patches  (Boszormenyi Zoltan <zb@cybertec.at>)
List pgsql-hackers
Boszormenyi Zoltan írta:
> But I have the following problem. When this is in ecpg.addon:
> ===============================
> ...
> ECPG: FetchStmtFETCHfetch_args addon
> ECPG: FetchStmtMOVEfetch_args addon
>                 add_additional_variables(current_cursor, false);
>                 free(current_cursor);
>                 current_cursor = NULL;
> ...
> ECPG: FetchStmtMOVEfetch_args rule
>         | FETCH fetch_args ecpg_into
>         {
>                 add_additional_variables(current_cursor, false);
>                 free(current_cursor);
>                 current_cursor = NULL;
>                 $$ = cat2_str(make_str("fetch"), $2);
>         }
> ...
> ===============================
>
> After running parse.pl, I get this in preproc.y for FetchStmt:
>
> ===============================
>   FetchStmt:
>  FETCH fetch_args
>  {
>                 add_additional_variables(current_cursor, false);
>                 free(current_cursor);
>                 current_cursor = NULL;
>
>  $$ = cat_str(2,make_str("fetch"),$2);
> }
> |  MOVE fetch_args
>  {
>                 add_additional_variables(current_cursor, false);
>                 free(current_cursor);
>                 current_cursor = NULL;
>  { // THIS IS AN EXTRA "{"
>  $$ = cat_str(2,make_str("move"),$2);
> }
> ...
> ===============================
>
> With this code, I can prevent the extra "{" emitted:
>
> ===============================
> ECPG: FetchStmtMOVEfetch_args block
>         {
>                 add_additional_variables(current_cursor, false);
>                 free(current_cursor);
>                 current_cursor = NULL;
>                 $$ = cat2_str(make_str("move"), $2);
>         }
>         | FETCH fetch_args ecpg_into
>         {
>                 add_additional_variables(current_cursor, false);
>                 free(current_cursor);
>                 current_cursor = NULL;
>                 $$ = cat2_str(make_str("fetch"), $2);
>         }
> ...
> ===============================
>

Any word on the above? If no, I can accept this construct being legal...

Anyway, I adapted the remaining two patches (SQLDA and
DESCRIBE) to the previously sent dynamic cursor code
and also added regression tests. Please, review.

Best regards,
Zoltán Böszörményi


--
Bible has answers for everything. Proof:
"But let your communication be, Yea, yea; Nay, nay: for whatsoever is more
than these cometh of evil." (Matthew 5:37) - basics of digital technology.
"May your kingdom come" - superficial description of plate tectonics

----------------------------------
Zoltán Böszörményi
Cybertec Schönig & Schönig GmbH
http://www.postgresql.at/

diff -dcrpN pgsql/src/interfaces/ecpg/ecpglib/execute.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c
*** pgsql/src/interfaces/ecpg/ecpglib/execute.c    2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c    2009-08-11 14:23:30.000000000 +0200
***************
*** 25,30 ****
--- 25,31 ----
  #include "ecpgerrno.h"
  #include "extern.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "sql3types.h"
  #include "pgtypes_numeric.h"
  #include "pgtypes_date.h"
*************** ecpg_store_input(const int lineno, const
*** 1033,1038 ****
--- 1034,1040 ----
                  break;

              case ECPGt_descriptor:
+             case ECPGt_sqlda:
                  break;

              default:
*************** ecpg_execute(struct statement * stmt)
*** 1172,1177 ****
--- 1174,1235 ----
              if (desc->count == desc_counter)
                  desc_counter = 0;
          }
+         else if (var->type == ECPGt_sqlda)
+         {
+             pg_sqlda_t      **_sqlda = (pg_sqlda_t **)var->pointer;
+             pg_sqlda_t       *sqlda = *_sqlda;
+             struct variable    desc_inlist;
+             int        i;
+
+             if (sqlda == NULL)
+                 return false;
+
+             desc_counter++;
+             for (i = 0; i < sqlda->sqld; i++)
+             {
+                 if (i + 1 == desc_counter)
+                 {
+                     desc_inlist.type = ecpg_sqlda_type(sqlda->sqlvar[i].sqltype);
+                     desc_inlist.value = sqlda->sqlvar[i].sqldata;
+                     desc_inlist.pointer = &(sqlda->sqlvar[i].sqldata);
+                     switch (desc_inlist.type)
+                     {
+                         case ECPGt_char:
+                         case ECPGt_varchar:
+                             desc_inlist.varcharsize = strlen(sqlda->sqlvar[i].sqldata);
+                             break;
+                         default:
+                             desc_inlist.varcharsize = 0;
+                             break;
+                     }
+                     desc_inlist.arrsize = 1;
+                     desc_inlist.offset = 0;
+                     if (sqlda->sqlvar[i].sqlind)
+                     {
+                         desc_inlist.ind_type = ECPGt_short;
+                         /* ECPG expects indicator value < 0 */
+                         if (*(sqlda->sqlvar[i].sqlind))
+                             *(sqlda->sqlvar[i].sqlind) = -1;
+                         desc_inlist.ind_value = sqlda->sqlvar[i].sqlind;
+                         desc_inlist.ind_pointer = &(sqlda->sqlvar[i].sqlind);
+                         desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = 1;
+                         desc_inlist.ind_offset = 0;
+                     }
+                     else
+                     {
+                         desc_inlist.ind_type = ECPGt_NO_INDICATOR;
+                         desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
+                         desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
+                     }
+                     if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, &desc_inlist, &tobeinserted, false))
+                         return false;
+
+                     break;
+                 }
+             }
+             if (sqlda->sqld == desc_counter)
+                 desc_counter = 0;
+         }
          else
          {
              if (!ecpg_store_input(stmt->lineno, stmt->force_indicator, var, &tobeinserted, false))
*************** ecpg_execute(struct statement * stmt)
*** 1353,1358 ****
--- 1411,1445 ----
                  }
                  var = var->next;
              }
+             else if (var != NULL && var->type == ECPGt_sqlda)
+             {
+                 pg_sqlda_t      **_sqlda = (pg_sqlda_t **)var->pointer;
+                 pg_sqlda_t       *sqlda = *_sqlda;
+
+                 if (!sqlda)
+                 {
+                     sqlda = ecpg_build_sqlda_for_PGresult(stmt->lineno, results);
+                     if (!sqlda)
+                         status = false;
+                     else
+                         *_sqlda = sqlda;
+                 }
+                 else
+                 {
+                     status = ecpg_compare_sqlda_with_PGresult(sqlda, results);
+                     ecpg_log("ecpg_execute on line %d: called ecpg_compare_sqlda_with_PGresult, status %d\n",
+                             stmt->lineno, status);
+                 }
+
+                 if (status == true)
+                 {
+                     ecpg_set_sqlda_from_PGresult(stmt->lineno, _sqlda, results);
+                     ecpg_log("ecpg_execute on line %d: putting result (%d tuples) into sqlda descriptor\n",
+                             stmt->lineno, PQntuples(results));
+                 }
+
+                 var = var->next;
+             }
              else
                  for (act_field = 0; act_field < nfields && status; act_field++)
                  {
diff -dcrpN pgsql/src/interfaces/ecpg/ecpglib/extern.h pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h
*** pgsql/src/interfaces/ecpg/ecpglib/extern.h    2009-05-25 12:08:48.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/extern.h    2009-08-11 10:32:34.000000000 +0200
***************
*** 6,11 ****
--- 6,12 ----
  #include "postgres_fe.h"
  #include "libpq-fe.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "ecpg_config.h"
  #ifndef CHAR_BIT
  #include <limits.h>
*************** bool        ecpg_init(const struct connection
*** 129,134 ****
--- 130,137 ----
  char       *ecpg_strdup(const char *, int);
  const char *ecpg_type_name(enum ECPGttype);
  int            ecpg_dynamic_type(Oid);
+ int            ecpg_sqlda_type(int);
+ int            ecpg_to_sqlda_type(Oid);
  void        ecpg_free_auto_mem(void);
  void        ecpg_clear_auto_mem(void);

*************** void        ecpg_log(const char *format,...);
*** 149,154 ****
--- 152,161 ----
  bool        ecpg_auto_prepare(int, const char *, const int, char **, const char *);
  void        ecpg_init_sqlca(struct sqlca_t * sqlca);

+ pg_sqlda_t *ecpg_build_sqlda_for_PGresult(int, PGresult *);
+ bool        ecpg_compare_sqlda_with_PGresult(pg_sqlda_t *sqlda, const PGresult *results);
+ void        ecpg_set_sqlda_from_PGresult(int, pg_sqlda_t **, const PGresult *);
+
  /* SQLSTATE values generated or processed by ecpglib (intentionally
   * not exported -- users should refer to the codes directly) */

diff -dcrpN pgsql/src/interfaces/ecpg/ecpglib/Makefile pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile
*** pgsql/src/interfaces/ecpg/ecpglib/Makefile    2009-07-13 11:16:41.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/Makefile    2009-08-11 10:32:34.000000000 +0200
*************** override CFLAGS += $(PTHREAD_CFLAGS)
*** 24,30 ****
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))

! OBJS= execute.o typename.o descriptor.o data.o error.o prepare.o memory.o \
      connect.o misc.o path.o pgstrcasecmp.o \
      $(filter snprintf.o strlcpy.o, $(LIBOBJS))

--- 24,30 ----
  # Need to recompile any libpgport object files
  LIBS := $(filter-out -lpgport, $(LIBS))

! OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
      connect.o misc.o path.o pgstrcasecmp.o \
      $(filter snprintf.o strlcpy.o, $(LIBOBJS))

diff -dcrpN pgsql/src/interfaces/ecpg/ecpglib/sqlda.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c
*** pgsql/src/interfaces/ecpg/ecpglib/sqlda.c    1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/sqlda.c    2009-08-11 17:41:47.000000000 +0200
***************
*** 0 ****
--- 1,300 ----
+ /*
+  * Crude SQLDA support routines
+  * Only supports fetching 1 record at a time
+  *
+  * The allocated memory area pointed by an sqlda pointer
+  * contains both the metadata and the data, so freeing up
+  * is a simple free(sqlda) as expected by the ESQL/C examples.
+  */
+
+ #define POSTGRES_ECPG_INTERNAL
+ #include "postgres_fe.h"
+ #include "pg_type.h"
+
+ #include <inttypes.h>
+ #include <dlfcn.h>
+
+ #include "ecpg-pthread-win32.h"
+ #include "decimal.h"
+ #include "ecpgtype.h"
+ #include "ecpglib.h"
+ #include "ecpgerrno.h"
+ #include "extern.h"
+ #include "sqlca.h"
+ #include "sqlda.h"
+ #include "sqltypes.h"
+
+ /*
+  * Build pg_sqlda_t (metadata only) from PGresult
+  */
+ pg_sqlda_t *
+ ecpg_build_sqlda_for_PGresult(int line, PGresult *res)
+ {
+     pg_sqlda_t *sqlda;
+     pg_sqlvar_t*sqlvar;
+     char       *fname;
+     long        size;
+     int        i;
+
+     size = sizeof(pg_sqlda_t) + PQnfields(res) * sizeof(pg_sqlvar_t);
+     for (i = 0; i < PQnfields(res); i++)
+         size += strlen(PQfname(res, i)) + 1;
+     /* round allocated size up to the next multiple of 8 */
+     if (size % 8)
+         size += 8 - (size % 8);
+
+     sqlda = (pg_sqlda_t *)ecpg_alloc(size, line);
+     if (!sqlda)
+     {
+         ecpg_raise(line, ECPG_OUT_OF_MEMORY, ECPG_SQLSTATE_ECPG_OUT_OF_MEMORY, NULL);
+         return NULL;
+     }
+     memset(sqlda, 0, size);
+     sqlvar = (pg_sqlvar_t *)(sqlda + 1);
+     fname = (char *)(sqlvar + PQnfields(res));
+
+     sqlda->sqld = PQnfields(res);
+     sqlda->desc_occ = size; /* cheat here, keep the full allocated size */
+     sqlda->sqlvar = sqlvar;
+
+     for (i = 0; i < sqlda->sqld; i++)
+     {
+         sqlda->sqlvar[i].sqltype = ecpg_to_sqlda_type(PQftype(res, i));
+         strcpy(fname, PQfname(res, i));
+         sqlda->sqlvar[i].sqlname = fname;
+         fname += strlen(sqlda->sqlvar[i].sqlname) + 1;
+         sqlda->sqlvar[i].sqlformat = (char *)(long)PQfformat(res, i);
+         sqlda->sqlvar[i].sqlxid = PQftype(res, i);
+         sqlda->sqlvar[i].sqltypelen = PQfsize(res, i);
+     }
+
+     return sqlda;
+ }
+
+ /*
+  * Check whether the supplied sqlda and PGresult
+  * both has the same metadata
+  */
+ bool
+ ecpg_compare_sqlda_with_PGresult(pg_sqlda_t *sqlda, const PGresult *res)
+ {
+     int    i;
+
+     if (sqlda->sqld != PQnfields(res))
+     {
+         ecpg_log("ecpg_compare_sqlda_with_PGresult: sqld differ %d %d\n",
+                                                 sqlda->sqld, PQnfields(res));
+         return false;
+     }
+
+     for (i = 0; i < sqlda->sqld; i++)
+     {
+         if (sqlda->sqlvar[i].sqltype != ecpg_to_sqlda_type(PQftype(res, i)))
+         {
+             ecpg_log("ecpg_compare_sqlda_with_PGresult: field %d sqltype differ %d %d\n",
+                     i, sqlda->sqlvar[i].sqltype, ecpg_to_sqlda_type(PQftype(res, i)));
+             return false;
+         }
+         if (strcmp(sqlda->sqlvar[i].sqlname, PQfname(res, i)))
+         {
+             ecpg_log("ecpg_compare_sqlda_with_PGresult: field %d sqlname differ '%s' '%s'\n",
+                     i, sqlda->sqlvar[i].sqlname, PQfname(res, i));
+             return false;
+         }
+         if (sqlda->sqlvar[i].sqlformat != (char *)(long)PQfformat(res, i))
+         {
+             ecpg_log("ecpg_compare_sqlda_with_PGresult: field %d sqlformat differ %d %d\n",
+                     i, sqlda->sqlvar[i].sqlformat, PQfformat(res, i));
+             return false;
+         }
+         if (sqlda->sqlvar[i].sqlxid != PQftype(res, i))
+         {
+             ecpg_log("ecpg_compare_sqlda_with_PGresult: field %d sqlxid differ %d %d\n",
+                     i, sqlda->sqlvar[i].sqlxid, PQftype(res, i));
+             return false;
+         }
+         if (sqlda->sqlvar[i].sqltypelen != PQfsize(res, i))
+         {
+             ecpg_log("ecpg_compare_sqlda_with_PGresult: field %d sqltypelen differ %d %d\n",
+                     i, sqlda->sqlvar[i].sqltypelen, PQfsize(res, i));
+             return false;
+         }
+     }
+
+     return true;
+ }
+
+ static long
+ ecpg_sqlda_size_round_align(long size, int alignment, int round)
+ {
+     if (size % alignment)
+         size += alignment - (size % alignment);
+     size += round;
+     return size;
+ }
+
+ static long
+ ecpg_sqlda_size_align(long size, int alignment)
+ {
+     if (size % alignment)
+         size += alignment - (size % alignment);
+     return size;
+ }
+
+ /*
+  * Sets values from PGresult.
+  * Reallocates the memory area pointed by *_sqlda if needed
+  */
+ void
+ ecpg_set_sqlda_from_PGresult(int lineno, pg_sqlda_t **_sqlda, const PGresult *res)
+ {
+     pg_sqlda_t *sqlda = (*_sqlda);
+     int        i;
+     long        size;
+     static    int2    value_is_null = -1;
+     static    int2    value_is_not_null = 0;
+
+     /* Compute new structure size for allocation */
+     size = sizeof(pg_sqlda_t) + sqlda->sqld * sizeof(pg_sqlvar_t);
+     for (i = 0; i < PQnfields(res); i++)
+         size += strlen(PQfname(res, i)) + 1;
+
+     for (i = 0; i < sqlda->sqld; i++)
+     {
+         switch (sqlda->sqlvar[i].sqltype)
+         {
+             case SQLSMINT:
+                 size = ecpg_sqlda_size_round_align(size, sizeof(short), sizeof(short));
+                 break;
+             case SQLINT:
+             case SQLSERIAL:
+                 size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(int));
+                 break;
+             case SQLFLOAT:
+                 size = ecpg_sqlda_size_round_align(size, sizeof(double), sizeof(double));
+                 break;
+             case SQLSMFLOAT:
+                 size = ecpg_sqlda_size_round_align(size, sizeof(float), sizeof(float));
+                 break;
+             case SQLDECIMAL:
+                 size = ecpg_sqlda_size_round_align(size, sizeof(int), sizeof(decimal));
+                 break;
+             case SQLINT8:
+             case SQLSERIAL8:
+                 size = ecpg_sqlda_size_round_align(size, sizeof(int64_t), sizeof(int64_t));
+                 break;
+
+             /*
+              * These types will be passed as character strings
+              * until we know what to do with them.
+              */
+             case SQLCHAR:
+             case SQLTEXT:
+             case SQLVCHAR:
+             case SQLNCHAR:
+             case SQLNVCHAR:
+             case SQLMONEY:
+             case SQLDATE:
+             case SQLDTIME:
+             case SQLINTERVAL:
+             default:
+                 break;
+         }
+     }
+
+     if (sqlda->desc_occ < size)
+     {
+         sqlda = realloc(sqlda, size);
+         *_sqlda = sqlda;
+         sqlda->desc_occ = size;
+     }
+
+     /*
+      * Set sqlvar[i]->sqldata pointers and convert values to correct format
+      */
+     size = sizeof(pg_sqlda_t) + sqlda->sqld * sizeof(pg_sqlvar_t);
+     for (i = 0; i < PQnfields(res); i++)
+         size += strlen(PQfname(res, i)) + 1;
+
+     for (i = 0; i < sqlda->sqld; i++)
+     {
+         int type = -1, isnull;
+         int use_getdata = true;
+
+         switch (sqlda->sqlvar[i].sqltype)
+         {
+             case SQLSMINT:
+                 size = ecpg_sqlda_size_align(size, sizeof(short));
+                 sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+                 size += sizeof(short);
+                 type = ECPGt_short;
+                 break;
+             case SQLINT:
+             case SQLSERIAL:
+                 size = ecpg_sqlda_size_align(size, sizeof(int));
+                 sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+                 size += sizeof(int);
+                 type = ECPGt_int;
+                 break;
+             case SQLFLOAT:
+                 size = ecpg_sqlda_size_align(size, sizeof(double));
+                 sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+                 size += sizeof(double);
+                 type = ECPGt_double;
+                 break;
+             case SQLSMFLOAT:
+                 size = ecpg_sqlda_size_align(size, sizeof(float));
+                 sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+                 size += sizeof(float);
+                 type = ECPGt_float;
+                 break;
+             case SQLDECIMAL:
+             {
+                 size = ecpg_sqlda_size_align(size, sizeof(int));
+                 sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+                 size += sizeof(decimal);
+                 type = ECPGt_decimal;
+                 break;
+             }
+             case SQLINT8:
+             case SQLSERIAL8:
+                 size = ecpg_sqlda_size_align(size, sizeof(int64_t));
+                 sqlda->sqlvar[i].sqldata = (char *)sqlda + size;
+                 size += sizeof(int64_t);
+                 type = ECPGt_long_long;
+                 break;
+
+             /*
+              * These types will be passed as character strings until
+              * it's known what to do with them. We use sqlvar->sqldata
+              * in all cases regardless of length, don't care about
+              * sqlvar->sqlilongdata.
+              */
+             case SQLCHAR:
+             case SQLTEXT:
+             case SQLVCHAR:
+             case SQLNCHAR:
+             case SQLNVCHAR:
+             case SQLMONEY:
+             case SQLDATE:
+             case SQLDTIME:
+             case SQLINTERVAL:
+             default:
+                 use_getdata = false;
+                 break;
+         }
+
+         isnull = PQgetisnull(res, 0, i);
+         sqlda->sqlvar[i].sqlind = isnull ? &value_is_null : &value_is_not_null;
+         if (!isnull)
+         {
+             if (use_getdata)
+                 ecpg_get_data(res, 0, i, lineno,
+                         type, ECPGt_NO_INDICATOR,
+                         sqlda->sqlvar[i].sqldata, NULL, 0, 0, 0,
+                         ECPG_ARRAY_NONE, ECPG_COMPAT_INFORMIX, false);
+             else
+                 sqlda->sqlvar[i].sqldata = PQgetvalue(res, 0, i);
+         }
+     }
+ }
diff -dcrpN pgsql/src/interfaces/ecpg/ecpglib/typename.c pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c
*** pgsql/src/interfaces/ecpg/ecpglib/typename.c    2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/ecpglib/typename.c    2009-08-11 10:32:34.000000000 +0200
***************
*** 7,12 ****
--- 7,13 ----
  #include "ecpgtype.h"
  #include "ecpglib.h"
  #include "extern.h"
+ #include "sqltypes.h"
  #include "sql3types.h"
  #include "pg_type.h"

*************** ecpg_dynamic_type(Oid type)
*** 100,102 ****
--- 101,190 ----
              return -(int) type;
      }
  }
+
+ int
+ ecpg_sqlda_type(int type)
+ {
+     switch (type)
+     {
+         case SQLCHAR:
+         case SQLNCHAR:
+             return ECPGt_char;
+         case SQLSMINT:
+             return ECPGt_short;
+         case SQLINT:
+             return ECPGt_int;
+         case SQLFLOAT:
+             return ECPGt_double;
+         case SQLSMFLOAT:
+             return ECPGt_float;
+         case SQLDECIMAL:
+             return ECPGt_decimal;
+         case SQLSERIAL:
+             return ECPGt_int;
+         case SQLDATE:
+             return ECPGt_date;
+ #if 0
+         case SQLMONEY:
+             return ???;
+         case SQLNULL:
+             return ???;
+ #endif
+         case SQLDTIME:
+             return ECPGt_timestamp;
+ #if 0
+         case SQLBYTES:
+             return ???;
+ #endif
+         case SQLTEXT:
+             return ECPGt_char;
+         case SQLVCHAR:
+         case SQLNVCHAR:
+             return ECPGt_varchar;
+         case SQLINTERVAL:
+             return ECPGt_interval;
+         case SQLINT8:
+         case SQLSERIAL8:
+             return ECPGt_long_long;
+         default:
+             return (-type);
+     }
+ }
+
+ int
+ ecpg_to_sqlda_type(Oid type)
+ {
+     switch (type)
+     {
+         case CHAROID:
+         case BPCHAROID:
+             return SQLCHAR;
+         case INT2OID:
+             return SQLSMINT;
+         case INT4OID:
+             return SQLINT;
+         case FLOAT8OID:
+             return SQLFLOAT;
+         case FLOAT4OID:
+             return SQLSMFLOAT;
+         case NUMERICOID:
+             return SQLDECIMAL;
+         case DATEOID:
+             return SQLDATE;
+         case CASHOID:
+             return SQLMONEY;
+         case TIMESTAMPOID:
+         case TIMESTAMPTZOID:
+             return SQLDTIME;
+         case TEXTOID:
+             return SQLTEXT;
+         case VARCHAROID:
+             return SQLVCHAR;
+         case INTERVALOID:
+             return SQLINTERVAL;
+         case INT8OID:
+             return SQLINT8;
+         default:
+             return (-type);
+     }
+ }
diff -dcrpN pgsql/src/interfaces/ecpg/include/ecpgtype.h pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h
*** pgsql/src/interfaces/ecpg/include/ecpgtype.h    2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/ecpgtype.h    2009-08-11 10:34:24.000000000 +0200
*************** enum ECPGttype
*** 62,68 ****
      ECPGt_EOIT,                    /* End of insert types. */
      ECPGt_EORT,                    /* End of result types. */
      ECPGt_NO_INDICATOR,            /* no indicator */
!     ECPGt_string                            /* trimmed (char *) type */
  };

   /* descriptor items */
--- 62,69 ----
      ECPGt_EOIT,                    /* End of insert types. */
      ECPGt_EORT,                    /* End of result types. */
      ECPGt_NO_INDICATOR,            /* no indicator */
!     ECPGt_string,                /* trimmed (char *) type */
!     ECPGt_sqlda                /* C struct descriptor */
  };

   /* descriptor items */
diff -dcrpN pgsql/src/interfaces/ecpg/include/sqlda.h pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h
*** pgsql/src/interfaces/ecpg/include/sqlda.h    2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqlda.h    2009-08-11 10:32:34.000000000 +0200
***************
*** 1,3 ****
--- 1,74 ----
  /*
   * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
   */
+
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int        int4;
+ typedef    short        int2;
+ #endif
+ typedef    char        int1;
+
+ typedef    int        mint;
+ typedef    long        mlong;
+
+ typedef    short        MSHORT;
+ typedef    char        MCHAR;
+
+ typedef    unsigned int    uint4;
+ typedef    unsigned short    uint2;
+ typedef    unsigned char    uint1;
+
+ typedef    unsigned int    muint;
+ typedef    unsigned long    mulong;
+
+ typedef    unsigned short    MUSHORT;
+ typedef    unsigned char    MUCHAR;
+
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+
+ typedef struct sqlvar_struct
+ {
+     int2    sqltype;        /* variable type                */
+     int4    sqllen;            /* length in bytes              */
+     char       *sqldata;        /* pointer to data              */
+     int2       *sqlind;        /* pointer to indicator         */
+     char       *sqlname;        /* variable name                */
+     char       *sqlformat;        /* reserved for future use      */
+     int2    sqlitype;        /* ind variable type            */
+     int2    sqlilen;        /* ind length in bytes          */
+     char       *sqlidata;        /* ind data pointer             */
+     int4    sqlxid;            /* extended id type             */
+     char       *sqltypename;    /* extended type name           */
+     int2    sqltypelen;        /* length of extended type name */
+     int2    sqlownerlen;        /* length of owner name         */
+     int2    sqlsourcetype;        /* source type for distinct of built-ins */
+     char       *sqlownername;    /* owner name                   */
+     int4    sqlsourceid;        /* extended id of source type   */
+
+     /*
+      * sqlilongdata is new.  It supports data that exceeds the 32k
+      * limit.  sqlilen and sqlidata are for backward compatibility
+      * and they have maximum value of <32K.
+      */
+     char       *sqlilongdata;    /* for data field beyond 32K    */
+     int4    sqlflags;        /* for internal use only        */
+     void       *sqlreserved;    /* reserved for future use      */
+ } pg_sqlvar_t;
+
+ typedef struct sqlda
+ {
+     int2        sqld;
+     pg_sqlvar_t       *sqlvar;
+     char        desc_name[19];    /* descriptor name              */
+     int2        desc_occ;    /* size of sqlda structure      */
+     struct sqlda       *desc_next;    /* pointer to next sqlda struct */
+     void           *reserved;    /* reserved for future use */
+ } pg_sqlda_t;
+
+ #endif /* POSTGRES_SQLDA_H */
diff -dcrpN pgsql/src/interfaces/ecpg/include/sqltypes.h pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h
*** pgsql/src/interfaces/ecpg/include/sqltypes.h    2009-06-13 18:25:05.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/include/sqltypes.h    2009-08-11 10:32:34.000000000 +0200
***************
*** 30,33 ****
--- 30,55 ----
  #define CLVCHARPTRTYPE    124
  #define CTYPEMAX    25

+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define    SQLCHAR        0
+ #define    SQLSMINT    1
+ #define    SQLINT        2
+ #define    SQLFLOAT    3
+ #define    SQLSMFLOAT    4
+ #define    SQLDECIMAL    5
+ #define    SQLSERIAL    6
+ #define    SQLDATE        7
+ #define    SQLMONEY    8
+ #define    SQLDTIME    10
+ #define    SQLBYTES    11
+ #define    SQLTEXT        12
+ #define    SQLVCHAR    13
+ #define    SQLINTERVAL    14
+ #define    SQLNCHAR    15
+ #define    SQLNVCHAR    16
+ #define    SQLINT8        17
+ #define    SQLSERIAL8    18
+
  #endif   /* ndef ECPG_SQLTYPES_H */
diff -dcrpN pgsql/src/interfaces/ecpg/preproc/descriptor.c pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c
*** pgsql/src/interfaces/ecpg/preproc/descriptor.c    2009-01-30 17:28:46.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/preproc/descriptor.c    2009-08-11 10:32:34.000000000 +0200
*************** descriptor_variable(const char *name, in
*** 326,328 ****
--- 326,347 ----
      strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
      return (struct variable *) & varspace[input];
  }
+
+ struct variable *
+ sqlda_variable(const char *name)
+ {
+     struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
+
+     p->name = mm_strdup(name);
+     p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
+     p->type->type = ECPGt_sqlda;
+     p->type->size = NULL;
+     p->type->struct_sizeof = NULL;
+     p->type->u.element = NULL;
+     p->type->lineno = 0;
+     p->brace_level = 0;
+     p->next = NULL;
+
+     return p;
+ }
+
diff -dcrpN pgsql/src/interfaces/ecpg/preproc/ecpg.addons pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons
*** pgsql/src/interfaces/ecpg/preproc/ecpg.addons    2009-08-10 15:18:04.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.addons    2009-08-11 10:42:00.000000000 +0200
*************** ECPG: FetchStmtMOVEfetch_args block
*** 405,424 ****
          current_cursor = NULL;
          $$ = cat2_str(make_str("move"), $2);
      }
!     | FETCH fetch_args ecpg_into
      {
          add_additional_variables(current_cursor, false);
          free(current_cursor);
          current_cursor = NULL;
          $$ = cat2_str(make_str("fetch"), $2);
      }
!     | FETCH FORWARD cursor_name opt_ecpg_into
      {
          char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
          add_additional_variables($3, false);
          $$ = cat_str(2, make_str("fetch forward"), cursor_marker);
      }
!     | FETCH FORWARD from_in cursor_name opt_ecpg_into
      {
          char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
          add_additional_variables($4, false);
--- 405,424 ----
          current_cursor = NULL;
          $$ = cat2_str(make_str("move"), $2);
      }
!     | FETCH fetch_args ecpg_fetch_into
      {
          add_additional_variables(current_cursor, false);
          free(current_cursor);
          current_cursor = NULL;
          $$ = cat2_str(make_str("fetch"), $2);
      }
!     | FETCH FORWARD cursor_name opt_ecpg_fetch_into
      {
          char *cursor_marker = $3[0] == ':' ? make_str("$0") : $3;
          add_additional_variables($3, false);
          $$ = cat_str(2, make_str("fetch forward"), cursor_marker);
      }
!     | FETCH FORWARD from_in cursor_name opt_ecpg_fetch_into
      {
          char *cursor_marker = $4[0] == ':' ? make_str("$0") : $4;
          add_additional_variables($4, false);
diff -dcrpN pgsql/src/interfaces/ecpg/preproc/ecpg.trailer pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql/src/interfaces/ecpg/preproc/ecpg.trailer    2009-08-10 18:01:47.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer    2009-08-11 10:41:02.000000000 +0200
*************** ecpg_using:    USING using_list     { $$ = EMP
*** 1014,1032 ****

  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
          {
!             add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
              $$ = EMPTY;
          }
          ;

  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
          {
!             add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
              $$ = EMPTY;
          }
          ;

! opt_sql: /*EMPTY*/ | SQL_SQL;

  using_list: UsingValue | UsingValue ',' using_list;

--- 1014,1062 ----

  using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
          {
!             if (strlen($2) || !(INFORMIX_MODE))
!                 add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
!             else
!             {
!                 if ($4[0] == '\"')
!                 {
!                     char *pos;
!
!                     $4[0] = ' ';
!                     for (pos = $4; *pos; pos++)
!                         if (*pos == '\"')
!                             *pos = ' ';
!                 }
!                 add_variable_to_head(&argsinsert, sqlda_variable($4), &no_indicator);
!             }
              $$ = EMPTY;
          }
          ;

  into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
          {
!             if (strlen($2) || !(INFORMIX_MODE))
!                 add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
!             else
!             {
!                 if ($4[0] == '\"')
!                 {
!                     char *pos;
!
!                     $4[0] = ' ';
!                     for (pos = $4; *pos; pos++)
!                         if (*pos == '\"')
!                             *pos = ' ';
!                 }
!                 add_variable_to_head(&argsresult, sqlda_variable($4), &no_indicator);
!             }
              $$ = EMPTY;
          }
          ;

! opt_sql: /*EMPTY*/        { $$ = EMPTY; }
!         | SQL_SQL    { $$ = make_str("sql"); }
!         ;

  using_list: UsingValue | UsingValue ',' using_list;

*************** ecpg_into: INTO into_list    { $$ = EMPTY;
*** 2050,2057 ****
      ;


! opt_ecpg_into:    /* EMPTY */    { $$ = EMPTY; }
!     | ecpg_into        { $$ = $1; }

  %%

--- 2080,2103 ----
      ;


! ecpg_fetch_into: ecpg_into    { $$ = $1; }
!     | using_descriptor
!     {
!         struct variable *var;
!
!         if (!INFORMIX_MODE)
!             mmerror(PARSE_ERROR, ET_ERROR, "Not in Informix compatibility mode");
!
!         var = argsinsert->variable;
!         remove_variable_from_list(&argsinsert, var);
!         add_variable_to_head(&argsresult, var, &no_indicator);
!         $$ = $1;
!     }
!     ;
!
! opt_ecpg_fetch_into: /* EMPTY */    { $$ = EMPTY; }
!     | ecpg_fetch_into        { $$ = $1; }
!     ;

  %%

diff -dcrpN pgsql/src/interfaces/ecpg/preproc/ecpg.type pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type
*** pgsql/src/interfaces/ecpg/preproc/ecpg.type    2009-08-10 18:02:24.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type    2009-08-11 10:44:52.000000000 +0200
***************
*** 62,67 ****
--- 62,68 ----
  %type <str> ecpg_ident
  %type <str> ecpg_interval
  %type <str> ecpg_into
+ %type <str> ecpg_fetch_into
  %type <str> ecpg_param
  %type <str> ecpg_sconst
  %type <str> ecpg_using
***************
*** 77,83 ****
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
--- 78,84 ----
  %type <str> opt_bit_field
  %type <str> opt_connection_name
  %type <str> opt_database_name
! %type <str> opt_ecpg_fetch_into
  %type <str> opt_ecpg_using
  %type <str> opt_initializer
  %type <str> opt_options
***************
*** 87,92 ****
--- 88,94 ----
  %type <str> opt_reference
  %type <str> opt_scale
  %type <str> opt_server
+ %type <str> opt_sql
  %type <str> opt_user
  %type <str> opt_opt_value
  %type <str> ora_user
diff -dcrpN pgsql/src/interfaces/ecpg/preproc/extern.h pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h
*** pgsql/src/interfaces/ecpg/preproc/extern.h    2009-08-09 18:13:31.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/extern.h    2009-08-11 10:32:34.000000000 +0200
*************** extern void add_descriptor(char *, char
*** 90,95 ****
--- 90,96 ----
  extern void drop_descriptor(char *, char *);
  extern struct descriptor *lookup_descriptor(char *, char *);
  extern struct variable *descriptor_variable(const char *name, int input);
+ extern struct variable *sqlda_variable(const char *name);
  extern void add_variable_to_head(struct arguments **, struct variable *, struct variable *);
  extern void add_variable_to_tail(struct arguments **, struct variable *, struct variable *);
  extern void remove_variable_from_list(struct arguments ** list, struct variable * var);
diff -dcrpN pgsql/src/interfaces/ecpg/preproc/type.c pgsql.sqlda/src/interfaces/ecpg/preproc/type.c
*** pgsql/src/interfaces/ecpg/preproc/type.c    2009-08-07 13:06:28.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/preproc/type.c    2009-08-11 11:46:04.000000000 +0200
*************** get_type(enum ECPGttype type)
*** 194,199 ****
--- 194,202 ----
          case ECPGt_descriptor:
              return ("ECPGt_descriptor");
              break;
+         case ECPGt_sqlda:
+             return ("ECPGt_sqlda");
+             break;
          case ECPGt_date:
              return ("ECPGt_date");
              break;
*************** ECPGdump_a_simple(FILE *o, const char *n
*** 328,333 ****
--- 331,338 ----
      else if (type == ECPGt_descriptor)
          /* remember that name here already contains quotes (if needed) */
          fprintf(o, "\n\tECPGt_descriptor, %s, 0L, 0L, 0L, ", name);
+     else if (type == ECPGt_sqlda)
+         fprintf(o, "\n\tECPGt_sqlda, &%s, 0L, 0L, 0L, ", name);
      else
      {
          char       *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4);
diff -dcrpN pgsql/src/interfaces/ecpg/test/compat_informix/Makefile
pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile
*** pgsql/src/interfaces/ecpg/test/compat_informix/Makefile    2009-08-10 18:05:33.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile    2009-08-11 10:51:42.000000000 +0200
*************** TESTS = test_informix test_informix.c \
*** 17,22 ****
--- 17,23 ----
          rfmtdate rfmtdate.c \
          rfmtlong rfmtlong.c \
          rnull rnull.c \
+         sqlda sqlda.c \
          charfuncs charfuncs.c

  all: $(TESTS)
*************** test_informix2.c: test_informix2.pgc ../
*** 30,35 ****
--- 31,39 ----
  cursor.c: cursor.pgc ../regression.h
      $(ECPG) -o $@ -I$(srcdir) $<

+ sqlda.c: sqlda.pgc ../regression.h
+     $(ECPG) -o $@ -I$(srcdir) $<
+
  dec_test.c: dec_test.pgc ../regression.h
      $(ECPG) -o $@ -I$(srcdir) $<

diff -dcrpN pgsql/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc
*** pgsql/src/interfaces/ecpg/test/compat_informix/sqlda.pgc    1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/sqlda.pgc    2009-08-11 13:44:07.000000000 +0200
***************
*** 0 ****
--- 1,207 ----
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.h>
+
+ exec sql include ../regression;
+
+ exec sql include sqlda.h;
+ exec sql include sqltypes.h;
+
+ exec sql whenever sqlerror stop;
+
+ /* These shouldn't be under DECLARE SECTION */
+ pg_sqlda_t    *inp_sqlda, *outp_sqlda;
+
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+     int    i;
+
+     for (i = 0; i < sqlda->sqld; i++)
+     {
+         if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+             printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+         else
+         switch (sqlda->sqlvar[i].sqltype)
+         {
+         case SQLCHAR:
+         case SQLVCHAR:
+         case SQLTEXT:
+             printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLSERIAL:
+         case SQLINT:
+             printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int
*)sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLSERIAL8:
+         case SQLINT8:
+             printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t
*)sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLFLOAT:
+             printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double
*)sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLDECIMAL:
+             {
+                 char    val[64];
+                 dectoasc((dec_t *)sqlda->sqlvar[i].sqldata, val, 64, -1);
+                 printf("name sqlda descriptor: '%s' value DECIMAL '%s'\n", sqlda->sqlvar[i].sqlname, val);
+                 break;
+             }
+         }
+     }
+ }
+
+ int
+ main (void)
+ {
+ exec sql begin declare section;
+     char    *stmt1 = "SELECT * FROM t1";
+     char    *stmt2 = "SELECT * FROM t1 WHERE id = ?";
+     int    rec;
+     int    id;
+ exec sql end declare section;
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     exec sql connect to REGRESSDB1;
+
+     strcpy(msg, "set");
+     exec sql set datestyle to iso;
+
+     strcpy(msg, "create");
+     exec sql create table t1(
+         id integer,
+         t text,
+         d1 numeric,
+         d2 float8,
+         c char(10));
+
+     strcpy(msg, "insert");
+     exec sql insert into t1 values
+         (1, 'a', 1.0, 1, 'a'),
+         (2, null, null, null, null),
+         (3, '"c"', -3, 'nan'::float8, 'c'),
+         (4, 'd', 4.0, 4, 'd');
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     /* SQLDA test for getting all records from a table */
+
+     outp_sqlda = NULL;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id1 from :stmt1;
+
+     strcpy(msg, "declare");
+     exec sql declare mycur1 cursor for st_id1;
+
+     strcpy(msg, "open");
+     exec sql open mycur1;
+
+     exec sql whenever not found do break;
+
+     rec = 0;
+     while (1)
+     {
+         strcpy(msg, "fetch");
+         exec sql fetch 1 from mycur1 into descriptor outp_sqlda;
+
+         printf("FETCH RECORD %d\n", ++rec);
+         dump_sqlda(outp_sqlda);
+     }
+
+     exec sql whenever not found continue;
+
+     strcpy(msg, "close");
+     exec sql close mycur1;
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate prepare st_id1;
+
+     free(outp_sqlda);
+
+     /* SQLDA test for getting all records from a table
+        using the Informix-specific FETCH ... USING DESCRIPTOR
+      */
+
+     outp_sqlda = NULL;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id2 from :stmt1;
+
+     strcpy(msg, "declare");
+     exec sql declare mycur2 cursor for st_id2;
+
+     strcpy(msg, "open");
+     exec sql open mycur2;
+
+     exec sql whenever not found do break;
+
+     rec = 0;
+     while (1)
+     {
+         strcpy(msg, "fetch");
+         exec sql fetch from mycur2 using descriptor outp_sqlda;
+
+         printf("FETCH RECORD %d\n", ++rec);
+         dump_sqlda(outp_sqlda);
+     }
+
+     exec sql whenever not found continue;
+
+     strcpy(msg, "close");
+     exec sql close mycur2;
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate prepare st_id2;
+
+     free(outp_sqlda);
+
+     /* SQLDA test for getting one record using an input descriptor */
+
+     /* Input sqlda has to be built manually */
+     inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+     memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+     inp_sqlda->sqld = 1;
+     inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+     memset(inp_sqlda->sqlvar, 0, sizeof(pg_sqlvar_t));
+
+     inp_sqlda->sqlvar[0].sqltype = SQLINT;
+     inp_sqlda->sqlvar[0].sqldata = (char *)&id;
+
+     printf("EXECUTE RECORD 4\n");
+
+     id = 4;
+
+     outp_sqlda = NULL;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id3 FROM :stmt2;
+
+     strcpy(msg, "execute");
+     exec sql execute st_id3 using descriptor inp_sqlda into descriptor outp_sqlda;
+
+     dump_sqlda(outp_sqlda);
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate prepare st_id3;
+
+     free(outp_sqlda);
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     exec sql drop table t1;
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     strcpy(msg, "disconnect");
+     exec sql disconnect;
+
+     return (0);
+ }
diff -dcrpN pgsql/src/interfaces/ecpg/test/ecpg_schedule pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule
*** pgsql/src/interfaces/ecpg/test/ecpg_schedule    2009-08-10 18:06:06.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule    2009-08-11 11:19:52.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql/src/interfaces/ecpg/test/ecpg_schedule_tcp pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp
*** pgsql/src/interfaces/ecpg/test/ecpg_schedule_tcp    2009-08-10 18:06:11.000000000 +0200
--- pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp    2009-08-11 11:19:59.000000000 +0200
*************** test: compat_informix/rfmtdate
*** 4,9 ****
--- 4,10 ----
  test: compat_informix/rfmtlong
  test: compat_informix/rnull
  test: compat_informix/cursor
+ test: compat_informix/sqlda
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
diff -dcrpN pgsql/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c
*** pgsql/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c    1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.c    2009-08-11 14:24:20.000000000 +0200
***************
*** 0 ****
--- 1,506 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+ #line 1 "sqlda.pgc"
+ #include <stdlib.h>
+ #include <string.h>
+ #include <inttypes.h>
+
+
+ #line 1 "regression.h"
+
+
+
+
+
+
+ #line 5 "sqlda.pgc"
+
+
+
+ #line 1 "sqlda.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
+  */
+
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int        int4;
+ typedef    short        int2;
+ #endif
+ typedef    char        int1;
+
+ typedef    int        mint;
+ typedef    long        mlong;
+
+ typedef    short        MSHORT;
+ typedef    char        MCHAR;
+
+ typedef    unsigned int    uint4;
+ typedef    unsigned short    uint2;
+ typedef    unsigned char    uint1;
+
+ typedef    unsigned int    muint;
+ typedef    unsigned long    mulong;
+
+ typedef    unsigned short    MUSHORT;
+ typedef    unsigned char    MUCHAR;
+
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+
+ typedef struct sqlvar_struct
+ {
+     int2    sqltype;        /* variable type                */
+     int4    sqllen;            /* length in bytes              */
+     char       *sqldata;        /* pointer to data              */
+     int2       *sqlind;        /* pointer to indicator         */
+     char       *sqlname;        /* variable name                */
+     char       *sqlformat;        /* reserved for future use      */
+     int2    sqlitype;        /* ind variable type            */
+     int2    sqlilen;        /* ind length in bytes          */
+     char       *sqlidata;        /* ind data pointer             */
+     int4    sqlxid;            /* extended id type             */
+     char       *sqltypename;    /* extended type name           */
+     int2    sqltypelen;        /* length of extended type name */
+     int2    sqlownerlen;        /* length of owner name         */
+     int2    sqlsourcetype;        /* source type for distinct of built-ins */
+     char       *sqlownername;    /* owner name                   */
+     int4    sqlsourceid;        /* extended id of source type   */
+
+     /*
+      * sqlilongdata is new.  It supports data that exceeds the 32k
+      * limit.  sqlilen and sqlidata are for backward compatibility
+      * and they have maximum value of <32K.
+      */
+     char       *sqlilongdata;    /* for data field beyond 32K    */
+     int4    sqlflags;        /* for internal use only        */
+     void       *sqlreserved;    /* reserved for future use      */
+ } pg_sqlvar_t;
+
+ typedef struct sqlda
+ {
+     int2        sqld;
+     pg_sqlvar_t       *sqlvar;
+     char        desc_name[19];    /* descriptor name              */
+     int2        desc_occ;    /* size of sqlda structure      */
+     struct sqlda       *desc_next;    /* pointer to next sqlda struct */
+     void           *reserved;    /* reserved for future use */
+ } pg_sqlda_t;
+
+ #endif /* POSTGRES_SQLDA_H */
+
+ #line 7 "sqlda.pgc"
+
+
+ #line 1 "sqltypes.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqltypes.h,v 1.9 2009/06/11 14:49:13 momjian Exp $
+  */
+ #ifndef ECPG_SQLTYPES_H
+ #define ECPG_SQLTYPES_H
+
+ #define CCHARTYPE    ECPGt_char
+ #define CSHORTTYPE    ECPGt_short
+ #define CINTTYPE    ECPGt_int
+ #define CLONGTYPE    ECPGt_long
+ #define CFLOATTYPE    ECPGt_float
+ #define CDOUBLETYPE ECPGt_double
+ #define CDECIMALTYPE    ECPGt_decimal
+ #define CFIXCHARTYPE    108
+ #define CSTRINGTYPE ECPGt_char
+ #define CDATETYPE    ECPGt_date
+ #define CMONEYTYPE    111
+ #define CDTIMETYPE    ECPGt_timestamp
+ #define CLOCATORTYPE    113
+ #define CVCHARTYPE    ECPGt_varchar
+ #define CINVTYPE    115
+ #define CFILETYPE    116
+ #define CINT8TYPE    ECPGt_long_long
+ #define CCOLLTYPE        118
+ #define CLVCHARTYPE        119
+ #define CFIXBINTYPE        120
+ #define CVARBINTYPE        121
+ #define CBOOLTYPE        ECPGt_bool
+ #define CROWTYPE        123
+ #define CLVCHARPTRTYPE    124
+ #define CTYPEMAX    25
+
+ /*
+  * Values used in sqlda->sqlvar[i]->sqltype
+  */
+ #define    SQLCHAR        0
+ #define    SQLSMINT    1
+ #define    SQLINT        2
+ #define    SQLFLOAT    3
+ #define    SQLSMFLOAT    4
+ #define    SQLDECIMAL    5
+ #define    SQLSERIAL    6
+ #define    SQLDATE        7
+ #define    SQLMONEY    8
+ #define    SQLDTIME    10
+ #define    SQLBYTES    11
+ #define    SQLTEXT        12
+ #define    SQLVCHAR    13
+ #define    SQLINTERVAL    14
+ #define    SQLNCHAR    15
+ #define    SQLNVCHAR    16
+ #define    SQLINT8        17
+ #define    SQLSERIAL8    18
+
+ #endif   /* ndef ECPG_SQLTYPES_H */
+
+ #line 8 "sqlda.pgc"
+
+
+ /* exec sql whenever sqlerror  stop ; */
+ #line 10 "sqlda.pgc"
+
+
+ /* These shouldn't be under DECLARE SECTION */
+ pg_sqlda_t    *inp_sqlda, *outp_sqlda;
+
+ static void
+ dump_sqlda(pg_sqlda_t *sqlda)
+ {
+     int    i;
+
+     for (i = 0; i < sqlda->sqld; i++)
+     {
+         if (outp_sqlda->sqlvar[i].sqlind && *(outp_sqlda->sqlvar[i].sqlind) == -1)
+             printf("name sqlda descriptor: '%s' value NULL'\n", outp_sqlda->sqlvar[i].sqlname);
+         else
+         switch (sqlda->sqlvar[i].sqltype)
+         {
+         case SQLCHAR:
+         case SQLVCHAR:
+         case SQLTEXT:
+             printf("name sqlda descriptor: '%s' value '%s'\n", sqlda->sqlvar[i].sqlname, sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLSERIAL:
+         case SQLINT:
+             printf("name sqlda descriptor: '%s' value %d\n", sqlda->sqlvar[i].sqlname, *(int
*)sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLSERIAL8:
+         case SQLINT8:
+             printf("name sqlda descriptor: '%s' value %" PRId64 "\n", sqlda->sqlvar[i].sqlname, *(int64_t
*)sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLFLOAT:
+             printf("name sqlda descriptor: '%s' value %lf\n", sqlda->sqlvar[i].sqlname, *(double
*)sqlda->sqlvar[i].sqldata);
+             break;
+         case SQLDECIMAL:
+             {
+                 char    val[64];
+                 dectoasc((decimal *)sqlda->sqlvar[i].sqldata, val, 64, -1);
+                 printf("name sqlda descriptor: '%s' value DECIMAL '%s'\n", sqlda->sqlvar[i].sqlname, val);
+                 break;
+             }
+         }
+     }
+ }
+
+ int
+ main (void)
+ {
+ /* exec sql begin declare section */
+
+
+
+
+
+ #line 58 "sqlda.pgc"
+  char * stmt1 = "SELECT * FROM t1" ;
+
+ #line 59 "sqlda.pgc"
+  char * stmt2 = "SELECT * FROM t1 WHERE id = ?" ;
+
+ #line 60 "sqlda.pgc"
+  int rec ;
+
+ #line 61 "sqlda.pgc"
+  int id ;
+ /* exec sql end declare section */
+ #line 62 "sqlda.pgc"
+
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     { ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , NULL, 0);
+ #line 69 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 69 "sqlda.pgc"
+
+
+     strcpy(msg, "set");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 72 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 72 "sqlda.pgc"
+
+
+     strcpy(msg, "create");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table t1 ( id integer , t text , d1 numeric , d2 float8
,c char ( 10 ) )", ECPGt_EOIT, ECPGt_EORT); 
+ #line 80 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 80 "sqlda.pgc"
+
+
+     strcpy(msg, "insert");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null
,null , null , null ) , ( 3 , '\"c\"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' )", ECPGt_EOIT,
ECPGt_EORT);
+ #line 87 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 87 "sqlda.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 90 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 90 "sqlda.pgc"
+
+
+     /* SQLDA test for getting all records from a table */
+
+     outp_sqlda = NULL;
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
+ #line 97 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 97 "sqlda.pgc"
+
+
+     strcpy(msg, "declare");
+     /* declare mycur1 cursor for $1 */
+ #line 100 "sqlda.pgc"
+
+
+     strcpy(msg, "open");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur1 cursor for $1",
+     ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id1", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 103 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 103 "sqlda.pgc"
+
+
+     /* exec sql whenever not found  break ; */
+ #line 105 "sqlda.pgc"
+
+
+     rec = 0;
+     while (1)
+     {
+         strcpy(msg, "fetch");
+         { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch 1 from mycur1", ECPGt_EOIT,
+     ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 111 "sqlda.pgc"
+
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 111 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 111 "sqlda.pgc"
+
+
+         printf("FETCH RECORD %d\n", ++rec);
+         dump_sqlda(outp_sqlda);
+     }
+
+     /* exec sql whenever not found  continue ; */
+ #line 117 "sqlda.pgc"
+
+
+     strcpy(msg, "close");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur1", ECPGt_EOIT, ECPGt_EORT);
+ #line 120 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 120 "sqlda.pgc"
+
+
+     strcpy(msg, "deallocate");
+     { ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
+ #line 123 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 123 "sqlda.pgc"
+
+
+     free(outp_sqlda);
+
+     /* SQLDA test for getting all records from a table
+        using the Informix-specific FETCH ... USING DESCRIPTOR
+      */
+
+     outp_sqlda = NULL;
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt1);
+ #line 134 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 134 "sqlda.pgc"
+
+
+     strcpy(msg, "declare");
+     /* declare mycur2 cursor for $1 */
+ #line 137 "sqlda.pgc"
+
+
+     strcpy(msg, "open");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "declare mycur2 cursor for $1",
+     ECPGt_char_variable,(ECPGprepared_statement(NULL, "st_id2", __LINE__)),(long)1,(long)1,(1)*sizeof(char),
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT, ECPGt_EORT);
+ #line 140 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 140 "sqlda.pgc"
+
+
+     /* exec sql whenever not found  break ; */
+ #line 142 "sqlda.pgc"
+
+
+     rec = 0;
+     while (1)
+     {
+         strcpy(msg, "fetch");
+         { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "fetch from mycur2", ECPGt_EOIT,
+     ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 148 "sqlda.pgc"
+
+ if (sqlca.sqlcode == ECPG_NOT_FOUND) break;
+ #line 148 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 148 "sqlda.pgc"
+
+
+         printf("FETCH RECORD %d\n", ++rec);
+         dump_sqlda(outp_sqlda);
+     }
+
+     /* exec sql whenever not found  continue ; */
+ #line 154 "sqlda.pgc"
+
+
+     strcpy(msg, "close");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "close mycur2", ECPGt_EOIT, ECPGt_EORT);
+ #line 157 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 157 "sqlda.pgc"
+
+
+     strcpy(msg, "deallocate");
+     { ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
+ #line 160 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 160 "sqlda.pgc"
+
+
+     free(outp_sqlda);
+
+     /* SQLDA test for getting one record using an input descriptor */
+
+     /* Input sqlda has to be built manually */
+     inp_sqlda = (pg_sqlda_t *)malloc(sizeof(pg_sqlda_t));
+     memset(inp_sqlda, 0, sizeof(pg_sqlda_t));
+     inp_sqlda->sqld = 1;
+     inp_sqlda->sqlvar = malloc(sizeof(pg_sqlvar_t));
+     memset(inp_sqlda->sqlvar, 0, sizeof(pg_sqlvar_t));
+
+     inp_sqlda->sqlvar[0].sqltype = SQLINT;
+     inp_sqlda->sqlvar[0].sqldata = (char *)&id;
+
+     printf("EXECUTE RECORD 4\n");
+
+     id = 4;
+
+     outp_sqlda = NULL;
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id3", stmt2);
+ #line 183 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 183 "sqlda.pgc"
+
+
+     strcpy(msg, "execute");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, 1, "st_id3",
+     ECPGt_sqlda, & inp_sqlda , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
+     ECPGt_sqlda, & outp_sqlda , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
+ #line 186 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 186 "sqlda.pgc"
+
+
+     dump_sqlda(outp_sqlda);
+
+     strcpy(msg, "deallocate");
+     { ECPGdeallocate(__LINE__, 1, NULL, "st_id3");
+ #line 191 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 191 "sqlda.pgc"
+
+
+     free(outp_sqlda);
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+ #line 198 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 198 "sqlda.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 201 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 201 "sqlda.pgc"
+
+
+     strcpy(msg, "disconnect");
+     { ECPGdisconnect(__LINE__, "CURRENT");
+ #line 204 "sqlda.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 204 "sqlda.pgc"
+
+
+     return (0);
+ }
diff -dcrpN pgsql/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr
*** pgsql/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr    1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stderr    2009-08-11 14:24:21.000000000 +0200
***************
*** 0 ****
--- 1,218 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 72: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: query: create table t1 ( id integer , t text , d1 numeric , d2 float8 , c char (
10) ); with 0 parameter(s) on connection regress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 75: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: query: insert into t1 values ( 1 , 'a' , 1.0 , 1 , 'a' ) , ( 2 , null , null ,
null, null ) , ( 3 , '"c"' , - 3 , 'nan' :: float8 , 'c' ) , ( 4 , 'd' , 4.0 , 4 , 'd' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 83: OK: INSERT 0 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 90: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 97: name st_id1; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: query: declare mycur1 cursor for SELECT * FROM t1; with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 103: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: called ecpg_compare_sqlda_with_PGresult, status 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: called ecpg_compare_sqlda_with_PGresult, status 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: called ecpg_compare_sqlda_with_PGresult, status 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 111: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: query: fetch 1 from mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 111: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 111: no data found on line 111
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 120: query: close mycur1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 120: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 123: name st_id1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 134: name st_id2; query: "SELECT * FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: query: declare mycur2 cursor for SELECT * FROM t1; with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 140: OK: DECLARE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 1 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: called ecpg_compare_sqlda_with_PGresult, status 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 2 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: called ecpg_compare_sqlda_with_PGresult, status 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: -3 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: NaN offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: called ecpg_compare_sqlda_with_PGresult, status 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 148: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: query: fetch from mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 148: correctly got 0 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: raising sqlcode 100 on line 148: no data found on line 148
+ [NO_PID]: sqlca: code: 100, state: 02000
+ [NO_PID]: ecpg_execute on line 157: query: close mycur2; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: OK: CLOSE CURSOR
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 160: name st_id2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 183: name st_id3; query: "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: query: SELECT * FROM t1 WHERE id = $1; with 1 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: using PQexecPrepared for "SELECT * FROM t1 WHERE id = $1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: free_params on line 186: parameter 1 = 4
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: correctly got 1 tuples with 5 fields
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4.0 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_get_data on line 186: RESULT: 4 offset: -1; array: yes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 186: putting result (1 tuples) into sqlda descriptor
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 191: name st_id3
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 198: query: drop table t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 198: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 198: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 201: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout
pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout
*** pgsql/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout    1970-01-01 01:00:00.000000000 +0100
--- pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-sqlda.stdout    2009-08-11 14:24:21.000000000 +0200
***************
*** 0 ****
--- 1,54 ----
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ FETCH RECORD 1
+ name sqlda descriptor: 'id' value 1
+ name sqlda descriptor: 't' value 'a'
+ name sqlda descriptor: 'd1' value DECIMAL '1.0'
+ name sqlda descriptor: 'd2' value 1.000000
+ name sqlda descriptor: 'c' value 'a         '
+ FETCH RECORD 2
+ name sqlda descriptor: 'id' value 2
+ name sqlda descriptor: 't' value NULL'
+ name sqlda descriptor: 'd1' value NULL'
+ name sqlda descriptor: 'd2' value NULL'
+ name sqlda descriptor: 'c' value NULL'
+ FETCH RECORD 3
+ name sqlda descriptor: 'id' value 3
+ name sqlda descriptor: 't' value '"c"'
+ name sqlda descriptor: 'd1' value DECIMAL '-3'
+ name sqlda descriptor: 'd2' value nan
+ name sqlda descriptor: 'c' value 'c         '
+ FETCH RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
+ EXECUTE RECORD 4
+ name sqlda descriptor: 'id' value 4
+ name sqlda descriptor: 't' value 'd'
+ name sqlda descriptor: 'd1' value DECIMAL '4.0'
+ name sqlda descriptor: 'd2' value 4.000000
+ name sqlda descriptor: 'c' value 'd         '
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/ecpglib/descriptor.c
pgsql.describe/src/interfaces/ecpg/ecpglib/descriptor.c
*** pgsql.sqlda/src/interfaces/ecpg/ecpglib/descriptor.c    2009-08-07 13:06:28.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/ecpglib/descriptor.c    2009-08-11 14:34:03.000000000 +0200
***************
*** 13,18 ****
--- 13,19 ----
  #include "ecpgerrno.h"
  #include "extern.h"
  #include "sqlca.h"
+ #include "sqlda.h"
  #include "sql3types.h"

  static void descriptor_free(struct descriptor * desc);
*************** get_char_item(int lineno, void *var, enu
*** 226,231 ****
--- 227,238 ----
      return (true);
  }

+ #define RETURN_IF_NO_DATA    if (ntuples < 1) \
+                 { \
+                     ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); \
+                     return (false); \
+                 }
+
  bool
  ECPGget_desc(int lineno, const char *desc_name, int index,...)
  {
*************** ECPGget_desc(int lineno, const char *des
*** 244,254 ****
          return (false);

      ntuples = PQntuples(ECPGresult);
-     if (ntuples < 1)
-     {
-         ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL);
-         return (false);
-     }

      if (index < 1 || index > PQnfields(ECPGresult))
      {
--- 251,256 ----
*************** ECPGget_desc(int lineno, const char *des
*** 283,288 ****
--- 285,291 ----
          switch (type)
          {
              case (ECPGd_indicator):
+                 RETURN_IF_NO_DATA;
                  data_var.ind_type = vartype;
                  data_var.ind_pointer = var;
                  data_var.ind_varcharsize = varcharsize;
*************** ECPGget_desc(int lineno, const char *des
*** 295,300 ****
--- 298,304 ----
                  break;

              case ECPGd_data:
+                 RETURN_IF_NO_DATA;
                  data_var.type = vartype;
                  data_var.pointer = var;
                  data_var.varcharsize = varcharsize;
*************** ECPGget_desc(int lineno, const char *des
*** 377,382 ****
--- 381,387 ----
              case ECPGd_ret_length:
              case ECPGd_ret_octet:

+                 RETURN_IF_NO_DATA;
                  /*
                   * this is like ECPGstore_result
                   */
*************** ECPGget_desc(int lineno, const char *des
*** 480,485 ****
--- 485,491 ----
      sqlca->sqlerrd[2] = ntuples;
      return (true);
  }
+ #undef RETURN_IF_NO_DATA

  bool
  ECPGset_desc_header(int lineno, const char *desc_name, int count)
*************** ecpg_find_desc(int line, const char *nam
*** 722,730 ****
      return NULL;                /* not found */
  }

  bool
! ECPGdescribe(int line, bool input, const char *statement,...)
  {
!     ecpg_log("ECPGdescribe called on line %d for %s: %s\n", line, input ? "input" : "output", statement);
!     return false;
  }
--- 728,841 ----
      return NULL;                /* not found */
  }

+ static pg_sqlda_t*
+ build_sqlda(int lineno, bool input, const char *connection_name, const char *stmt_name)
+ {
+     struct connection *con;
+     PGresult    *res;
+     pg_sqlda_t    *sqlda = NULL;
+
+     con = ecpg_get_connection(connection_name);
+     res = PQdescribePrepared(con->connection, stmt_name);
+     if (!ecpg_check_PQresult(res, lineno, con->connection, ECPG_COMPAT_INFORMIX))
+         return NULL;
+
+     sqlda = ecpg_build_sqlda_for_PGresult(lineno, res);
+
+     PQclear(res);
+     return sqlda;
+ }
+
  bool
! ECPGdescribe(int line, bool input, const char *connection_name, const char *stmt_name, ...)
  {
!     bool        ret = false;
!     va_list        args;
!
!     /* DESCRIBE INPUT is not yet supported */
!     if (input)
!         return false;
!
!     va_start(args, stmt_name);
!
!     for (;;)
!     {
!         enum ECPGttype    type, dummy_type;
!         void        *ptr, *dummy_ptr;
!         long        dummy;
!
!         /* variable type */
!         type = va_arg(args, enum ECPGttype);
!
!         if (type == ECPGt_EORT)
!             break;
!
!         /* rest of variable parameters*/
!         ptr = va_arg(args, void *);
!         dummy = va_arg(args, long);
!         dummy = va_arg(args, long);
!         dummy = va_arg(args, long);
!
!         /* variable indicator */
!         dummy_type = va_arg(args, enum ECPGttype);
!         dummy_ptr = va_arg(args, void *);
!         dummy = va_arg(args, long);
!         dummy = va_arg(args, long);
!         dummy = va_arg(args, long);
!
!         switch (type)
!         {
!             case ECPGt_descriptor:
!             {
!                 char    *name = ptr;
!                 struct connection *con = ecpg_get_connection(connection_name);
!                 struct descriptor *desc = ecpg_find_desc(line, name);
!                 PGresult    *res;
!                 ExecStatusType  ret;
!
!                 if (con == NULL)
!                     break;
!                 if (desc == NULL)
!                     break;
!
!                 res = PQdescribePrepared(con->connection, stmt_name);
!                 ret = PQresultStatus(res);
!                 if (ecpg_check_PQresult(res, line, con->connection, ECPG_COMPAT_PGSQL))
!                 {
!                     if (desc->result != NULL)
!                         PQclear(desc->result);
!                     desc->result = res;
!                     ret = true;
!                 }
!                 break;
!             }
!             case ECPGt_sqlda:
!             {
!                 pg_sqlda_t **sqlda_ptr = ptr;
!                 pg_sqlda_t *sqlda_new;
!
!                 sqlda_new = build_sqlda(line, input, connection_name, stmt_name);
!                 if (sqlda_new)
!                 {
! #if 0
!                     /*
!                      * We should free the old pointer but we can't be sure
!                      * if the pointer is valid. Only the calling application can.
!                      */
!                     pg_sqlda_t *sqlda_old = *sqlda_ptr;
!                     if (sqlda_old)
!                         free(sqlda_old);
! #endif
!                     *sqlda_ptr = sqlda_new;
!                     ret = true;
!                 }
!                 break;
!             }
!             default:
!                 /* nothing else may come */
!                 ;
!         }
!     }
!
!     return ret;
  }
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c pgsql.describe/src/interfaces/ecpg/ecpglib/execute.c
*** pgsql.sqlda/src/interfaces/ecpg/ecpglib/execute.c    2009-08-11 14:23:30.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/ecpglib/execute.c    2009-08-11 14:34:03.000000000 +0200
*************** ecpg_store_input(const int lineno, const
*** 1034,1039 ****
--- 1034,1041 ----
                  break;

              case ECPGt_descriptor:
+                 break;
+
              case ECPGt_sqlda:
                  break;

diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/include/ecpglib.h pgsql.describe/src/interfaces/ecpg/include/ecpglib.h
*** pgsql.sqlda/src/interfaces/ecpg/include/ecpglib.h    2009-06-13 18:25:05.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/include/ecpglib.h    2009-08-11 14:34:03.000000000 +0200
*************** bool        ECPGset_desc(int, const char *, in
*** 83,89 ****

  void        ECPGset_noind_null(enum ECPGttype, void *);
  bool        ECPGis_noind_null(enum ECPGttype, void *);
! bool        ECPGdescribe(int, bool, const char *,...);

  /* dynamic result allocation */
  void        ECPGfree_auto_mem(void);
--- 83,89 ----

  void        ECPGset_noind_null(enum ECPGttype, void *);
  bool        ECPGis_noind_null(enum ECPGttype, void *);
! bool        ECPGdescribe(int, bool, const char *, const char *, ...);

  /* dynamic result allocation */
  void        ECPGfree_auto_mem(void);
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer
pgsql.describe/src/interfaces/ecpg/preproc/ecpg.trailer
*** pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.trailer    2009-08-11 10:41:02.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/preproc/ecpg.trailer    2009-08-11 17:18:31.000000000 +0200
*************** ECPGCursorStmt:  DECLARE cursor_name cur
*** 354,360 ****
                  add_variable_to_head(&(this->argsinsert), var, &no_indicator);
              }
              add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
-
              cur = this;

              $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
--- 354,359 ----
*************** into_descriptor: INTO opt_sql SQL_DESCRI
*** 1054,1059 ****
--- 1053,1065 ----
          }
          ;

+ into_sqlda: INTO name
+         {
+             add_variable_to_head(&argsresult, sqlda_variable($2), &no_indicator);
+             $$ = EMPTY;
+         }
+         ;
+
  opt_sql: /*EMPTY*/        { $$ = EMPTY; }
          | SQL_SQL    { $$ = make_str("sql"); }
          ;
*************** ECPGDescribe: SQL_DESCRIBE INPUT_P name
*** 1089,1110 ****
      {
          const char *con = connection ? connection : "NULL";
          mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
!         $$ = (char *) mm_alloc(sizeof("1, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
!         sprintf($$, "1, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
      }
      | SQL_DESCRIBE opt_output name using_descriptor
      {
          const char *con = connection ? connection : "NULL";
!         mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
!         $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
!         sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
      }
      | SQL_DESCRIBE opt_output name into_descriptor
      {
          const char *con = connection ? connection : "NULL";
          mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
!         $$ = (char *) mm_alloc(sizeof("0, ECPGprepared_statement(, \"\", __LINE__)") + strlen(con) + strlen($3));
!         sprintf($$, "0, ECPGprepared_statement(%s, \"%s\", __LINE__)", con, $3);
      }
      ;

--- 1095,1137 ----
      {
          const char *con = connection ? connection : "NULL";
          mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
!         $$ = (char *) mm_alloc(sizeof("1, , \"\"") + strlen(con) + strlen($3));
!         sprintf($$, "1, %s, \"%s\"", con, $3);
      }
      | SQL_DESCRIBE opt_output name using_descriptor
      {
          const char *con = connection ? connection : "NULL";
!         struct variable *var;
!
!         var = argsinsert->variable;
!         remove_variable_from_list(&argsinsert, var);
!         add_variable_to_head(&argsresult, var, &no_indicator);
!
!         $$ = (char *) mm_alloc(sizeof("0, , \"\"") + strlen(con) + strlen($3));
!         sprintf($$, "0, %s, \"%s\"", con, $3);
      }
      | SQL_DESCRIBE opt_output name into_descriptor
      {
          const char *con = connection ? connection : "NULL";
+         $$ = (char *) mm_alloc(sizeof("0, , \"\"") + strlen(con) + strlen($3));
+         sprintf($$, "0, %s, \"%s\"", con, $3);
+     }
+     | SQL_DESCRIBE INPUT_P name into_sqlda
+     {
+         const char *con = connection ? connection : "NULL";
          mmerror(PARSE_ERROR, ET_WARNING, "using unsupported DESCRIBE statement");
!         if (!INFORMIX_MODE)
!             mmerror(PARSE_ERROR, ET_ERROR, "Not in Informix compatibility mode");
!         $$ = (char *) mm_alloc(sizeof("1, , \"\"") + strlen(con) + strlen($3));
!         sprintf($$, "1, %s, \"%s\"", con, $3);
!     }
!     | SQL_DESCRIBE opt_output name into_sqlda
!     {
!         const char *con = connection ? connection : "NULL";
!         if (!INFORMIX_MODE)
!             mmerror(PARSE_ERROR, ET_ERROR, "Not in Informix compatibility mode");
!         $$ = (char *) mm_alloc(sizeof("0, , \"\"") + strlen(con) + strlen($3));
!         sprintf($$, "0, %s, \"%s\"", con, $3);
      }
      ;

diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type pgsql.describe/src/interfaces/ecpg/preproc/ecpg.type
*** pgsql.sqlda/src/interfaces/ecpg/preproc/ecpg.type    2009-08-11 10:44:52.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/preproc/ecpg.type    2009-08-11 14:34:03.000000000 +0200
***************
*** 73,78 ****
--- 73,79 ----
  %type <str> execute_rest
  %type <str> indicator
  %type <str> into_descriptor
+ %type <str> into_sqlda
  %type <str> Iresult
  %type <str> on_off
  %type <str> opt_bit_field
***************
*** 88,94 ****
  %type <str> opt_reference
  %type <str> opt_scale
  %type <str> opt_server
! %type <str> opt_sql
  %type <str> opt_user
  %type <str> opt_opt_value
  %type <str> ora_user
--- 89,95 ----
  %type <str> opt_reference
  %type <str> opt_scale
  %type <str> opt_server
! %type <str> opt_sql
  %type <str> opt_user
  %type <str> opt_opt_value
  %type <str> ora_user
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/describe.pgc
pgsql.describe/src/interfaces/ecpg/test/compat_informix/describe.pgc
*** pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/describe.pgc    1970-01-01 01:00:00.000000000 +0100
--- pgsql.describe/src/interfaces/ecpg/test/compat_informix/describe.pgc    2009-08-11 17:13:35.000000000 +0200
***************
*** 0 ****
--- 1,166 ----
+ #include <stdlib.h>
+ #include <string.h>
+
+ exec sql include ../regression;
+ exec sql include sqlda.h;
+
+ exec sql whenever sqlerror stop;
+
+ pg_sqlda_t    *sqlda1, *sqlda2, *sqlda3;
+
+ int
+ main (void)
+ {
+ exec sql begin declare section;
+     char    *stmt1 = "SELECT id, t FROM t1";
+     char    *stmt2 = "SELECT id, t FROM t1 WHERE id = -1";
+     int    i, count1, count2;
+     char    field_name1[30] = "not set";
+     char    field_name2[30] = "not set";
+ exec sql end declare section;
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     exec sql connect to REGRESSDB1;
+
+     strcpy(msg, "set");
+     exec sql set datestyle to iso;
+
+     strcpy(msg, "create");
+     exec sql create table t1(id serial primary key, t text);
+
+     strcpy(msg, "insert");
+     exec sql insert into t1(id, t) values (default, 'a');
+     exec sql insert into t1(id, t) values (default, 'b');
+     exec sql insert into t1(id, t) values (default, 'c');
+     exec sql insert into t1(id, t) values (default, 'd');
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     /*
+      * Test DESCRIBE with a query producing tuples.
+      * DESCRIPTOR and SQL DESCRIPTOR are NOT the same in
+      * Informix-compat mode.
+      */
+
+     strcpy(msg, "allocate");
+     exec sql allocate descriptor desc1;
+     exec sql allocate descriptor desc2;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id1 FROM :stmt1;
+
+     sqlda1 = sqlda2 = sqlda3 = NULL;
+
+     strcpy(msg, "describe");
+     exec sql describe st_id1 into sql descriptor desc1;
+     exec sql describe st_id1 using sql descriptor desc2;
+
+     exec sql describe st_id1 into descriptor sqlda1;
+     exec sql describe st_id1 using descriptor sqlda2;
+     exec sql describe st_id1 into sqlda3;
+
+     if (sqlda1 == NULL || sqlda1 == NULL || sqlda2 == NULL)
+         exit(1);
+
+     strcpy(msg, "get descriptor");
+     exec sql get descriptor desc1 :count1 = count;
+     exec sql get descriptor desc1 :count2 = count;
+
+     if (!(    count1 == count2 &&
+         count1 == sqlda1->sqld &&
+         count1 == sqlda2->sqld &&
+         count1 == sqlda3->sqld))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         exec sql get descriptor desc1 value :i :field_name1 = name;
+         exec sql get descriptor desc2 value :i :field_name2 = name;
+         printf("%d\n\tfield_name1 '%s'\n\tfield_name2 '%s'\n\t"
+             "sqlda1 '%s'\n\tsqlda2 '%s'\n\tsqlda3 '%s'\n",
+             i, field_name1, field_name2,
+             sqlda1->sqlvar[i-1].sqlname,
+             sqlda2->sqlvar[i-1].sqlname,
+             sqlda3->sqlvar[i-1].sqlname);
+     }
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate descriptor desc1;
+     exec sql deallocate descriptor desc2;
+     free(sqlda1);
+     free(sqlda2);
+     free(sqlda3);
+
+     exec sql deallocate prepare st_id1;
+
+     /* Test DESCRIBE with a query not producing tuples */
+
+     strcpy(msg, "allocate");
+     exec sql allocate descriptor desc1;
+     exec sql allocate descriptor desc2;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id2 FROM :stmt2;
+
+     sqlda1 = sqlda2 = sqlda3 = NULL;
+
+     strcpy(msg, "describe");
+     exec sql describe st_id2 into sql descriptor desc1;
+     exec sql describe st_id2 using sql descriptor desc2;
+
+     exec sql describe st_id2 into descriptor sqlda1;
+     exec sql describe st_id2 using descriptor sqlda2;
+     exec sql describe st_id2 into sqlda3;
+
+     if (sqlda1 == NULL || sqlda1 == NULL || sqlda2 == NULL)
+         exit(1);
+
+     strcpy(msg, "get descriptor");
+     exec sql get descriptor desc1 :count1 = count;
+     exec sql get descriptor desc1 :count2 = count;
+
+     if (!(    count1 == count2 &&
+         count1 == sqlda1->sqld &&
+         count1 == sqlda2->sqld &&
+         count1 == sqlda3->sqld))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         exec sql get descriptor desc1 value :i :field_name1 = name;
+         exec sql get descriptor desc2 value :i :field_name2 = name;
+         printf("%d\n\tfield_name1 '%s'\n\tfield_name2 '%s'\n\t"
+             "sqlda1 '%s'\n\tsqlda2 '%s'\n\tsqlda3 '%s'\n",
+             i, field_name1, field_name2,
+             sqlda1->sqlvar[i-1].sqlname,
+             sqlda2->sqlvar[i-1].sqlname,
+             sqlda3->sqlvar[i-1].sqlname);
+     }
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate descriptor desc1;
+     exec sql deallocate descriptor desc2;
+     free(sqlda1);
+     free(sqlda2);
+     free(sqlda3);
+
+     exec sql deallocate prepare st_id2;
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     exec sql drop table t1;
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     strcpy(msg, "disconnect");
+     exec sql disconnect;
+
+     return (0);
+ }
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile
pgsql.describe/src/interfaces/ecpg/test/compat_informix/Makefile
*** pgsql.sqlda/src/interfaces/ecpg/test/compat_informix/Makefile    2009-08-11 10:51:42.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/test/compat_informix/Makefile    2009-08-11 16:56:15.000000000 +0200
*************** override LIBS := -lecpg_compat $(LIBS)
*** 13,18 ****
--- 13,19 ----
  TESTS = test_informix test_informix.c \
          test_informix2 test_informix2.c \
          cursor cursor.c \
+         describe describe.c \
          dec_test dec_test.c \
          rfmtdate rfmtdate.c \
          rfmtlong rfmtlong.c \
*************** test_informix2.c: test_informix2.pgc ../
*** 31,36 ****
--- 32,40 ----
  cursor.c: cursor.pgc ../regression.h
      $(ECPG) -o $@ -I$(srcdir) $<

+ describe.c: describe.pgc ../regression.h
+     $(ECPG) -o $@ -I$(srcdir) $<
+
  sqlda.c: sqlda.pgc ../regression.h
      $(ECPG) -o $@ -I$(srcdir) $<

diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule pgsql.describe/src/interfaces/ecpg/test/ecpg_schedule
*** pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule    2009-08-11 11:19:52.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/test/ecpg_schedule    2009-08-11 17:00:27.000000000 +0200
*************** test: compat_informix/rfmtlong
*** 5,10 ****
--- 5,11 ----
  test: compat_informix/rnull
  test: compat_informix/cursor
  test: compat_informix/sqlda
+ test: compat_informix/describe
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
*************** test: preproc/array_of_struct
*** 19,24 ****
--- 20,26 ----
  test: preproc/autoprep
  test: preproc/comment
  test: preproc/cursor
+ test: preproc/describe
  test: preproc/define
  test: preproc/init
  test: preproc/strings
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp
pgsql.describe/src/interfaces/ecpg/test/ecpg_schedule_tcp
*** pgsql.sqlda/src/interfaces/ecpg/test/ecpg_schedule_tcp    2009-08-11 11:19:59.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/test/ecpg_schedule_tcp    2009-08-11 17:00:33.000000000 +0200
*************** test: compat_informix/rfmtlong
*** 5,10 ****
--- 5,11 ----
  test: compat_informix/rnull
  test: compat_informix/cursor
  test: compat_informix/sqlda
+ test: compat_informix/describe
  test: compat_informix/test_informix
  test: compat_informix/test_informix2
  test: connect/test2
*************** test: preproc/array_of_struct
*** 19,24 ****
--- 20,26 ----
  test: preproc/autoprep
  test: preproc/comment
  test: preproc/cursor
+ test: preproc/describe
  test: preproc/define
  test: preproc/init
  test: preproc/strings
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-describe.c
pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-describe.c
*** pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-describe.c    1970-01-01 01:00:00.000000000 +0100
--- pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-describe.c    2009-08-11 17:23:04.000000000 +0200
***************
*** 0 ****
--- 1,490 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* Needed for informix compatibility */
+ #include <ecpg_informix.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+ #line 1 "describe.pgc"
+ #include <stdlib.h>
+ #include <string.h>
+
+
+ #line 1 "regression.h"
+
+
+
+
+
+
+ #line 4 "describe.pgc"
+
+
+ #line 1 "sqlda.h"
+ /*
+  * $PostgreSQL: pgsql/src/interfaces/ecpg/include/sqlda.h,v 1.4 2009/06/11 14:49:13 momjian Exp $
+  */
+
+ #ifndef POSTGRES_SQLDA_H
+ #define POSTGRES_SQLDA_H
+
+ /* Define Informix "standard" types */
+ #ifndef C_H
+ typedef int        int4;
+ typedef    short        int2;
+ #endif
+ typedef    char        int1;
+
+ typedef    int        mint;
+ typedef    long        mlong;
+
+ typedef    short        MSHORT;
+ typedef    char        MCHAR;
+
+ typedef    unsigned int    uint4;
+ typedef    unsigned short    uint2;
+ typedef    unsigned char    uint1;
+
+ typedef    unsigned int    muint;
+ typedef    unsigned long    mulong;
+
+ typedef    unsigned short    MUSHORT;
+ typedef    unsigned char    MUCHAR;
+
+ #define MI_INT_SIZE     (sizeof(int)    * 8)
+ #define MI_LONG_SIZE    (sizeof(long)   * 8)
+ #define MI_PTR_SIZE     (sizeof(char *) * 8)
+
+ typedef struct sqlvar_struct
+ {
+     int2    sqltype;        /* variable type                */
+     int4    sqllen;            /* length in bytes              */
+     char       *sqldata;        /* pointer to data              */
+     int2       *sqlind;        /* pointer to indicator         */
+     char       *sqlname;        /* variable name                */
+     char       *sqlformat;        /* reserved for future use      */
+     int2    sqlitype;        /* ind variable type            */
+     int2    sqlilen;        /* ind length in bytes          */
+     char       *sqlidata;        /* ind data pointer             */
+     int4    sqlxid;            /* extended id type             */
+     char       *sqltypename;    /* extended type name           */
+     int2    sqltypelen;        /* length of extended type name */
+     int2    sqlownerlen;        /* length of owner name         */
+     int2    sqlsourcetype;        /* source type for distinct of built-ins */
+     char       *sqlownername;    /* owner name                   */
+     int4    sqlsourceid;        /* extended id of source type   */
+
+     /*
+      * sqlilongdata is new.  It supports data that exceeds the 32k
+      * limit.  sqlilen and sqlidata are for backward compatibility
+      * and they have maximum value of <32K.
+      */
+     char       *sqlilongdata;    /* for data field beyond 32K    */
+     int4    sqlflags;        /* for internal use only        */
+     void       *sqlreserved;    /* reserved for future use      */
+ } pg_sqlvar_t;
+
+ typedef struct sqlda
+ {
+     int2        sqld;
+     pg_sqlvar_t       *sqlvar;
+     char        desc_name[19];    /* descriptor name              */
+     int2        desc_occ;    /* size of sqlda structure      */
+     struct sqlda       *desc_next;    /* pointer to next sqlda struct */
+     void           *reserved;    /* reserved for future use */
+ } pg_sqlda_t;
+
+ #endif /* POSTGRES_SQLDA_H */
+
+ #line 5 "describe.pgc"
+
+
+ /* exec sql whenever sqlerror  stop ; */
+ #line 7 "describe.pgc"
+
+
+ pg_sqlda_t    *sqlda1, *sqlda2, *sqlda3;
+
+ int
+ main (void)
+ {
+ /* exec sql begin declare section */
+
+
+
+
+
+
+ #line 15 "describe.pgc"
+  char * stmt1 = "SELECT id, t FROM t1" ;
+
+ #line 16 "describe.pgc"
+  char * stmt2 = "SELECT id, t FROM t1 WHERE id = -1" ;
+
+ #line 17 "describe.pgc"
+  int i , count1 , count2 ;
+
+ #line 18 "describe.pgc"
+  char field_name1 [ 30 ] = "not set" ;
+
+ #line 19 "describe.pgc"
+  char field_name2 [ 30 ] = "not set" ;
+ /* exec sql end declare section */
+ #line 20 "describe.pgc"
+
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     { ECPGconnect(__LINE__, 1, "regress1" , NULL, NULL , NULL, 0);
+ #line 27 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 27 "describe.pgc"
+
+
+     strcpy(msg, "set");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 30 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 30 "describe.pgc"
+
+
+     strcpy(msg, "create");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "create table t1 ( id serial primary key , t text )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 33 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 33 "describe.pgc"
+
+
+     strcpy(msg, "insert");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'a' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 36 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 36 "describe.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'b' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 37 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 37 "describe.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'c' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 38 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 38 "describe.pgc"
+
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'd' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 39 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 39 "describe.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 42 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 42 "describe.pgc"
+
+
+     /*
+      * Test DESCRIBE with a query producing tuples.
+      * DESCRIPTOR and SQL DESCRIPTOR are NOT the same in
+      * Informix-compat mode.
+      */
+
+     strcpy(msg, "allocate");
+     ECPGallocate_desc(__LINE__, "desc1");
+ #line 51 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 51 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc2");
+ #line 52 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 52 "describe.pgc"
+
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
+ #line 55 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 55 "describe.pgc"
+
+
+     sqlda1 = sqlda2 = sqlda3 = NULL;
+
+     strcpy(msg, "describe");
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_descriptor, "desc1", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 60 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_descriptor, "desc2", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 61 "describe.pgc"
+
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_sqlda, & sqlda1 , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 63 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_sqlda, & sqlda2 , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 64 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_sqlda, &sqlda3, 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 65 "describe.pgc"
+
+
+     if (sqlda1 == NULL || sqlda1 == NULL || sqlda2 == NULL)
+         exit(1);
+
+     strcpy(msg, "get descriptor");
+     { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+ #line 71 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 71 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc1", &(count2));
+
+ #line 72 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 72 "describe.pgc"
+
+
+     if (!(    count1 == count2 &&
+         count1 == sqlda1->sqld &&
+         count1 == sqlda2->sqld &&
+         count1 == sqlda3->sqld))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         { ECPGget_desc(__LINE__, "desc1", i,ECPGd_name,
+     ECPGt_char,(field_name1),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 82 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 82 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+     ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 83 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 83 "describe.pgc"
+
+         printf("%d\n\tfield_name1 '%s'\n\tfield_name2 '%s'\n\t"
+             "sqlda1 '%s'\n\tsqlda2 '%s'\n\tsqlda3 '%s'\n",
+             i, field_name1, field_name2,
+             sqlda1->sqlvar[i-1].sqlname,
+             sqlda2->sqlvar[i-1].sqlname,
+             sqlda3->sqlvar[i-1].sqlname);
+     }
+
+     strcpy(msg, "deallocate");
+     ECPGdeallocate_desc(__LINE__, "desc1");
+ #line 93 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 93 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc2");
+ #line 94 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 94 "describe.pgc"
+
+     free(sqlda1);
+     free(sqlda2);
+     free(sqlda3);
+
+     { ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
+ #line 99 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 99 "describe.pgc"
+
+
+     /* Test DESCRIBE with a query not producing tuples */
+
+     strcpy(msg, "allocate");
+     ECPGallocate_desc(__LINE__, "desc1");
+ #line 104 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 104 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc2");
+ #line 105 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 105 "describe.pgc"
+
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt2);
+ #line 108 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 108 "describe.pgc"
+
+
+     sqlda1 = sqlda2 = sqlda3 = NULL;
+
+     strcpy(msg, "describe");
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_descriptor, "desc1", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 113 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_descriptor, "desc2", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 114 "describe.pgc"
+
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_sqlda, & sqlda1 , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 116 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_sqlda, & sqlda2 , 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 117 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_sqlda, &sqlda3, 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 118 "describe.pgc"
+
+
+     if (sqlda1 == NULL || sqlda1 == NULL || sqlda2 == NULL)
+         exit(1);
+
+     strcpy(msg, "get descriptor");
+     { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+ #line 124 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 124 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc1", &(count2));
+
+ #line 125 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 125 "describe.pgc"
+
+
+     if (!(    count1 == count2 &&
+         count1 == sqlda1->sqld &&
+         count1 == sqlda2->sqld &&
+         count1 == sqlda3->sqld))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         { ECPGget_desc(__LINE__, "desc1", i,ECPGd_name,
+     ECPGt_char,(field_name1),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 135 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 135 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+     ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 136 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 136 "describe.pgc"
+
+         printf("%d\n\tfield_name1 '%s'\n\tfield_name2 '%s'\n\t"
+             "sqlda1 '%s'\n\tsqlda2 '%s'\n\tsqlda3 '%s'\n",
+             i, field_name1, field_name2,
+             sqlda1->sqlvar[i-1].sqlname,
+             sqlda2->sqlvar[i-1].sqlname,
+             sqlda3->sqlvar[i-1].sqlname);
+     }
+
+     strcpy(msg, "deallocate");
+     ECPGdeallocate_desc(__LINE__, "desc1");
+ #line 146 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 146 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc2");
+ #line 147 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 147 "describe.pgc"
+
+     free(sqlda1);
+     free(sqlda2);
+     free(sqlda3);
+
+     { ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
+ #line 152 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 152 "describe.pgc"
+
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+ #line 157 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 157 "describe.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 160 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 160 "describe.pgc"
+
+
+     strcpy(msg, "disconnect");
+     { ECPGdisconnect(__LINE__, "CURRENT");
+ #line 163 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 163 "describe.pgc"
+
+
+     return (0);
+ }
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-describe.stderr
pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-describe.stderr
*** pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-describe.stderr    1970-01-01 01:00:00.000000000
+0100
--- pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-describe.stderr    2009-08-11 17:23:04.000000000
+0200
***************
*** 0 ****
--- 1,100 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 30: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 30: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 30: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 33: query: create table t1 ( id serial primary key , t text ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 33: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 33: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: query: insert into t1 ( id , t ) values ( default , 'a' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: query: insert into t1 ( id , t ) values ( default , 'b' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: query: insert into t1 ( id , t ) values ( default , 'c' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 39: query: insert into t1 ( id , t ) values ( default , 'd' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 39: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 39: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 42: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 55: name st_id1; query: "SELECT id, t FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 99: name st_id1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 108: name st_id2; query: "SELECT id, t FROM t1 WHERE id = -1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 152: name st_id2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: query: drop table t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 157: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 160: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-describe.stdout
pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-describe.stdout
*** pgsql.sqlda/src/interfaces/ecpg/test/expected/compat_informix-describe.stdout    1970-01-01 01:00:00.000000000
+0100
--- pgsql.describe/src/interfaces/ecpg/test/expected/compat_informix-describe.stdout    2009-08-11 17:23:04.000000000
+0200
***************
*** 0 ****
--- 1,24 ----
+ 1
+     field_name1 'id'
+     field_name2 'id'
+     sqlda1 'id'
+     sqlda2 'id'
+     sqlda3 'id'
+ 2
+     field_name1 't'
+     field_name2 't'
+     sqlda1 't'
+     sqlda2 't'
+     sqlda3 't'
+ 1
+     field_name1 'id'
+     field_name2 'id'
+     sqlda1 'id'
+     sqlda2 'id'
+     sqlda3 'id'
+ 2
+     field_name1 't'
+     field_name2 't'
+     sqlda1 't'
+     sqlda2 't'
+     sqlda3 't'
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/expected/preproc-describe.c
pgsql.describe/src/interfaces/ecpg/test/expected/preproc-describe.c
*** pgsql.sqlda/src/interfaces/ecpg/test/expected/preproc-describe.c    1970-01-01 01:00:00.000000000 +0100
--- pgsql.describe/src/interfaces/ecpg/test/expected/preproc-describe.c    2009-08-11 17:29:53.000000000 +0200
***************
*** 0 ****
--- 1,481 ----
+ /* Processed by ecpg (regression mode) */
+ /* These include files are added by the preprocessor */
+ #include <ecpglib.h>
+ #include <ecpgerrno.h>
+ #include <sqlca.h>
+ /* End of automatic include section */
+ #define ECPGdebug(X,Y) ECPGdebug((X)+100,(Y))
+
+ #line 1 "describe.pgc"
+ #include <stdlib.h>
+ #include <string.h>
+
+
+ #line 1 "regression.h"
+
+
+
+
+
+
+ #line 4 "describe.pgc"
+
+
+ /* exec sql whenever sqlerror  stop ; */
+ #line 6 "describe.pgc"
+
+
+ int
+ main (void)
+ {
+ /* exec sql begin declare section */
+
+
+
+
+
+
+
+
+ #line 12 "describe.pgc"
+  char * stmt1 = "SELECT id, t FROM t1" ;
+
+ #line 13 "describe.pgc"
+  char * stmt2 = "SELECT id, t FROM t1 WHERE id = -1" ;
+
+ #line 14 "describe.pgc"
+  int i , count1 , count2 , count3 , count4 ;
+
+ #line 15 "describe.pgc"
+  char field_name1 [ 30 ] = "not set" ;
+
+ #line 16 "describe.pgc"
+  char field_name2 [ 30 ] = "not set" ;
+
+ #line 17 "describe.pgc"
+  char field_name3 [ 30 ] = "not set" ;
+
+ #line 18 "describe.pgc"
+  char field_name4 [ 30 ] = "not set" ;
+ /* exec sql end declare section */
+ #line 19 "describe.pgc"
+
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     { ECPGconnect(__LINE__, 0, "regress1" , NULL, NULL , NULL, 0);
+ #line 26 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 26 "describe.pgc"
+
+
+     strcpy(msg, "set");
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "set datestyle to iso", ECPGt_EOIT, ECPGt_EORT);
+ #line 29 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 29 "describe.pgc"
+
+
+     strcpy(msg, "create");
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create table t1 ( id serial primary key , t text )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 32 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 32 "describe.pgc"
+
+
+     strcpy(msg, "insert");
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'a' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 35 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 35 "describe.pgc"
+
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'b' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 36 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 36 "describe.pgc"
+
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'c' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 37 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 37 "describe.pgc"
+
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into t1 ( id , t ) values ( default , 'd' )",
ECPGt_EOIT,ECPGt_EORT); 
+ #line 38 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 38 "describe.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 41 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 41 "describe.pgc"
+
+
+     /*
+      * Test DESCRIBE with a query producing tuples.
+      * DESCRIPTOR and SQL DESCRIPTOR are the same in native mode.
+      */
+
+     strcpy(msg, "allocate");
+     ECPGallocate_desc(__LINE__, "desc1");
+ #line 49 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 49 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc2");
+ #line 50 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 50 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc3");
+ #line 51 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 51 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc4");
+ #line 52 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 52 "describe.pgc"
+
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id1", stmt1);
+ #line 55 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 55 "describe.pgc"
+
+
+     strcpy(msg, "describe");
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_descriptor, "desc1", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 58 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_descriptor, "desc2", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 59 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_descriptor, "desc3", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 60 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id1",
+     ECPGt_descriptor, "desc4", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 61 "describe.pgc"
+
+
+     strcpy(msg, "get descriptor");
+     { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+ #line 64 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 64 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc2", &(count2));
+
+ #line 65 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 65 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc3", &(count3));
+
+ #line 66 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 66 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc4", &(count4));
+
+ #line 67 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 67 "describe.pgc"
+
+
+     if (!(count1 == count2 && count1 == count3 && count1 == count4))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         { ECPGget_desc(__LINE__, "desc1", i,ECPGd_name,
+     ECPGt_char,(field_name1),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 74 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 74 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+     ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 75 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 75 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc3", i,ECPGd_name,
+     ECPGt_char,(field_name3),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 76 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 76 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc4", i,ECPGd_name,
+     ECPGt_char,(field_name4),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 77 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 77 "describe.pgc"
+
+         printf("field_name 1 '%s' 2 '%s' 3 '%s' 4 '%s'\n",
+             field_name1, field_name2, field_name3, field_name4);
+     }
+
+     strcpy(msg, "deallocate");
+     ECPGdeallocate_desc(__LINE__, "desc1");
+ #line 83 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 83 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc2");
+ #line 84 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 84 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc3");
+ #line 85 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 85 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc4");
+ #line 86 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 86 "describe.pgc"
+
+
+     { ECPGdeallocate(__LINE__, 0, NULL, "st_id1");
+ #line 88 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 88 "describe.pgc"
+
+
+     /* Test DESCRIBE with a query not producing tuples */
+
+     strcpy(msg, "allocate");
+     ECPGallocate_desc(__LINE__, "desc1");
+ #line 93 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 93 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc2");
+ #line 94 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 94 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc3");
+ #line 95 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 95 "describe.pgc"
+
+     ECPGallocate_desc(__LINE__, "desc4");
+ #line 96 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 96 "describe.pgc"
+
+
+     strcpy(msg, "prepare");
+     { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt2);
+ #line 99 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 99 "describe.pgc"
+
+
+     strcpy(msg, "describe");
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_descriptor, "desc1", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 102 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_descriptor, "desc2", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 103 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_descriptor, "desc3", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 104 "describe.pgc"
+
+     { ECPGdescribe(__LINE__, 0, NULL, "st_id2",
+     ECPGt_descriptor, "desc4", 0L, 0L, 0L,
+     ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+ #line 105 "describe.pgc"
+
+
+     strcpy(msg, "get descriptor");
+     { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+ #line 108 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 108 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc2", &(count2));
+
+ #line 109 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 109 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc3", &(count3));
+
+ #line 110 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 110 "describe.pgc"
+
+     { ECPGget_desc_header(__LINE__, "desc4", &(count4));
+
+ #line 111 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 111 "describe.pgc"
+
+
+     if (!(count1 == count2 && count1 == count3 && count1 == count4))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         { ECPGget_desc(__LINE__, "desc1", i,ECPGd_name,
+     ECPGt_char,(field_name1),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 118 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 118 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+     ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 119 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 119 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc3", i,ECPGd_name,
+     ECPGt_char,(field_name3),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 120 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 120 "describe.pgc"
+
+         { ECPGget_desc(__LINE__, "desc4", i,ECPGd_name,
+     ECPGt_char,(field_name4),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+ #line 121 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 121 "describe.pgc"
+
+         printf("field_name 1 '%s' 2 '%s' 3 '%s' 4 '%s'\n",
+             field_name1, field_name2, field_name3, field_name4);
+     }
+
+     strcpy(msg, "deallocate");
+     ECPGdeallocate_desc(__LINE__, "desc1");
+ #line 127 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 127 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc2");
+ #line 128 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 128 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc3");
+ #line 129 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 129 "describe.pgc"
+
+     ECPGdeallocate_desc(__LINE__, "desc4");
+ #line 130 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);
+ #line 130 "describe.pgc"
+
+
+     { ECPGdeallocate(__LINE__, 0, NULL, "st_id2");
+ #line 132 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 132 "describe.pgc"
+
+
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table t1", ECPGt_EOIT, ECPGt_EORT);
+ #line 138 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 138 "describe.pgc"
+
+
+     strcpy(msg, "commit");
+     { ECPGtrans(__LINE__, NULL, "commit");
+ #line 141 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 141 "describe.pgc"
+
+
+     strcpy(msg, "disconnect");
+     { ECPGdisconnect(__LINE__, "CURRENT");
+ #line 144 "describe.pgc"
+
+ if (sqlca.sqlcode < 0) exit (1);}
+ #line 144 "describe.pgc"
+
+
+     return (0);
+ }
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/expected/preproc-describe.stderr
pgsql.describe/src/interfaces/ecpg/test/expected/preproc-describe.stderr
*** pgsql.sqlda/src/interfaces/ecpg/test/expected/preproc-describe.stderr    1970-01-01 01:00:00.000000000 +0100
--- pgsql.describe/src/interfaces/ecpg/test/expected/preproc-describe.stderr    2009-08-11 17:29:53.000000000 +0200
***************
*** 0 ****
--- 1,140 ----
+ [NO_PID]: ECPGdebug: set to 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGconnect: opening database regress1 on <DEFAULT> port <DEFAULT>
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 29: query: set datestyle to iso; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 29: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 29: OK: SET
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 32: query: create table t1 ( id serial primary key , t text ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 32: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 32: OK: CREATE TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: query: insert into t1 ( id , t ) values ( default , 'a' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 35: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: query: insert into t1 ( id , t ) values ( default , 'b' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 36: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: query: insert into t1 ( id , t ) values ( default , 'c' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 37: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: query: insert into t1 ( id , t ) values ( default , 'd' ); with 0 parameter(s) on
connectionregress1 
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 38: OK: INSERT 0 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 41: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 55: name st_id1; query: "SELECT id, t FROM t1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 88: name st_id1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGprepare on line 99: name st_id2; query: "SELECT id, t FROM t1 WHERE id = -1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc_header: found 2 attributes
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = id
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: reading items for tuple 2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGget_desc: NAME = t
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGdeallocate on line 132: name st_id2
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 138: query: drop table t1; with 0 parameter(s) on connection regress1
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 138: using PQexec
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_execute on line 138: OK: DROP TABLE
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ECPGtrans on line 141: action "commit"; connection "regress1"
+ [NO_PID]: sqlca: code: 0, state: 00000
+ [NO_PID]: ecpg_finish: connection regress1 closed
+ [NO_PID]: sqlca: code: 0, state: 00000
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/expected/preproc-describe.stdout
pgsql.describe/src/interfaces/ecpg/test/expected/preproc-describe.stdout
*** pgsql.sqlda/src/interfaces/ecpg/test/expected/preproc-describe.stdout    1970-01-01 01:00:00.000000000 +0100
--- pgsql.describe/src/interfaces/ecpg/test/expected/preproc-describe.stdout    2009-08-11 17:29:53.000000000 +0200
***************
*** 0 ****
--- 1,4 ----
+ field_name 1 'id' 2 'id' 3 'id' 4 'id'
+ field_name 1 't' 2 't' 3 't' 4 't'
+ field_name 1 'id' 2 'id' 3 'id' 4 'id'
+ field_name 1 't' 2 't' 3 't' 4 't'
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/preproc/describe.pgc
pgsql.describe/src/interfaces/ecpg/test/preproc/describe.pgc
*** pgsql.sqlda/src/interfaces/ecpg/test/preproc/describe.pgc    1970-01-01 01:00:00.000000000 +0100
--- pgsql.describe/src/interfaces/ecpg/test/preproc/describe.pgc    2009-08-11 17:26:13.000000000 +0200
***************
*** 0 ****
--- 1,147 ----
+ #include <stdlib.h>
+ #include <string.h>
+
+ exec sql include ../regression;
+
+ exec sql whenever sqlerror stop;
+
+ int
+ main (void)
+ {
+ exec sql begin declare section;
+     char    *stmt1 = "SELECT id, t FROM t1";
+     char    *stmt2 = "SELECT id, t FROM t1 WHERE id = -1";
+     int    i, count1, count2, count3, count4;
+     char    field_name1[30] = "not set";
+     char    field_name2[30] = "not set";
+     char    field_name3[30] = "not set";
+     char    field_name4[30] = "not set";
+ exec sql end declare section;
+
+     char msg[128];
+
+     ECPGdebug(1, stderr);
+
+     strcpy(msg, "connect");
+     exec sql connect to REGRESSDB1;
+
+     strcpy(msg, "set");
+     exec sql set datestyle to iso;
+
+     strcpy(msg, "create");
+     exec sql create table t1(id serial primary key, t text);
+
+     strcpy(msg, "insert");
+     exec sql insert into t1(id, t) values (default, 'a');
+     exec sql insert into t1(id, t) values (default, 'b');
+     exec sql insert into t1(id, t) values (default, 'c');
+     exec sql insert into t1(id, t) values (default, 'd');
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     /*
+      * Test DESCRIBE with a query producing tuples.
+      * DESCRIPTOR and SQL DESCRIPTOR are the same in native mode.
+      */
+
+     strcpy(msg, "allocate");
+     exec sql allocate descriptor desc1;
+     exec sql allocate descriptor desc2;
+     exec sql allocate descriptor desc3;
+     exec sql allocate descriptor desc4;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id1 FROM :stmt1;
+
+     strcpy(msg, "describe");
+     exec sql describe st_id1 into descriptor desc1;
+     exec sql describe st_id1 into sql descriptor desc2;
+     exec sql describe st_id1 using descriptor desc3;
+     exec sql describe st_id1 using sql descriptor desc4;
+
+     strcpy(msg, "get descriptor");
+     exec sql get descriptor desc1 :count1 = count;
+     exec sql get descriptor desc2 :count2 = count;
+     exec sql get descriptor desc3 :count3 = count;
+     exec sql get descriptor desc4 :count4 = count;
+
+     if (!(count1 == count2 && count1 == count3 && count1 == count4))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         exec sql get descriptor desc1 value :i :field_name1 = name;
+         exec sql get descriptor desc2 value :i :field_name2 = name;
+         exec sql get descriptor desc3 value :i :field_name3 = name;
+         exec sql get descriptor desc4 value :i :field_name4 = name;
+         printf("field_name 1 '%s' 2 '%s' 3 '%s' 4 '%s'\n",
+             field_name1, field_name2, field_name3, field_name4);
+     }
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate descriptor desc1;
+     exec sql deallocate descriptor desc2;
+     exec sql deallocate descriptor desc3;
+     exec sql deallocate descriptor desc4;
+
+     exec sql deallocate prepare st_id1;
+
+     /* Test DESCRIBE with a query not producing tuples */
+
+     strcpy(msg, "allocate");
+     exec sql allocate descriptor desc1;
+     exec sql allocate descriptor desc2;
+     exec sql allocate descriptor desc3;
+     exec sql allocate descriptor desc4;
+
+     strcpy(msg, "prepare");
+     exec sql prepare st_id2 FROM :stmt2;
+
+     strcpy(msg, "describe");
+     exec sql describe st_id2 into descriptor desc1;
+     exec sql describe st_id2 into sql descriptor desc2;
+     exec sql describe st_id2 using descriptor desc3;
+     exec sql describe st_id2 using sql descriptor desc4;
+
+     strcpy(msg, "get descriptor");
+     exec sql get descriptor desc1 :count1 = count;
+     exec sql get descriptor desc2 :count2 = count;
+     exec sql get descriptor desc3 :count3 = count;
+     exec sql get descriptor desc4 :count4 = count;
+
+     if (!(count1 == count2 && count1 == count3 && count1 == count4))
+         exit(1);
+
+     for (i = 1; i <= count1; i++)
+     {
+         exec sql get descriptor desc1 value :i :field_name1 = name;
+         exec sql get descriptor desc2 value :i :field_name2 = name;
+         exec sql get descriptor desc3 value :i :field_name3 = name;
+         exec sql get descriptor desc4 value :i :field_name4 = name;
+         printf("field_name 1 '%s' 2 '%s' 3 '%s' 4 '%s'\n",
+             field_name1, field_name2, field_name3, field_name4);
+     }
+
+     strcpy(msg, "deallocate");
+     exec sql deallocate descriptor desc1;
+     exec sql deallocate descriptor desc2;
+     exec sql deallocate descriptor desc3;
+     exec sql deallocate descriptor desc4;
+
+     exec sql deallocate prepare st_id2;
+
+
+     /* End test */
+
+     strcpy(msg, "drop");
+     exec sql drop table t1;
+
+     strcpy(msg, "commit");
+     exec sql commit;
+
+     strcpy(msg, "disconnect");
+     exec sql disconnect;
+
+     return (0);
+ }
diff -dcrpN pgsql.sqlda/src/interfaces/ecpg/test/preproc/Makefile
pgsql.describe/src/interfaces/ecpg/test/preproc/Makefile
*** pgsql.sqlda/src/interfaces/ecpg/test/preproc/Makefile    2009-08-09 23:14:23.000000000 +0200
--- pgsql.describe/src/interfaces/ecpg/test/preproc/Makefile    2009-08-11 15:30:38.000000000 +0200
*************** TESTS = array_of_struct array_of_struct.
*** 8,13 ****
--- 8,14 ----
      autoprep autoprep.c \
      comment comment.c \
      cursor cursor.c \
+     describe describe.c \
      define define.c \
      init init.c \
      strings strings.c \

pgsql-hackers by date:

Previous
From: "Joshua D. Drake"
Date:
Subject: Re: "Hot standby"?
Next
From: David Fetter
Date:
Subject: Re: "Hot standby"?