Applied patch by Boszormenyi Zoltan <zb@cybertec.at> to add DESCRIBE [OUTPUT] stateme...
authorMichael Meskes <meskes@postgresql.org>
Fri, 15 Jan 2010 10:44:39 +0000 (10:44 +0000)
committerMichael Meskes <meskes@postgresql.org>
Fri, 15 Jan 2010 10:44:39 +0000 (10:44 +0000)
22 files changed:
src/interfaces/ecpg/ecpglib/descriptor.c
src/interfaces/ecpg/ecpglib/extern.h
src/interfaces/ecpg/ecpglib/prepare.c
src/interfaces/ecpg/include/ecpglib.h
src/interfaces/ecpg/preproc/ecpg.addons
src/interfaces/ecpg/preproc/ecpg.trailer
src/interfaces/ecpg/preproc/ecpg.type
src/interfaces/ecpg/test/compat_informix/Makefile
src/interfaces/ecpg/test/compat_informix/describe.pgc [new file with mode: 0644]
src/interfaces/ecpg/test/ecpg_schedule
src/interfaces/ecpg/test/ecpg_schedule_tcp
src/interfaces/ecpg/test/expected/compat_informix-describe.c [new file with mode: 0644]
src/interfaces/ecpg/test/expected/compat_informix-describe.stderr [new file with mode: 0644]
src/interfaces/ecpg/test/expected/compat_informix-describe.stdout [new file with mode: 0644]
src/interfaces/ecpg/test/expected/preproc-describe.c [new file with mode: 0644]
src/interfaces/ecpg/test/expected/preproc-describe.stderr [new file with mode: 0644]
src/interfaces/ecpg/test/expected/preproc-describe.stdout [new file with mode: 0644]
src/interfaces/ecpg/test/expected/sql-describe.c [new file with mode: 0644]
src/interfaces/ecpg/test/expected/sql-describe.stderr [new file with mode: 0644]
src/interfaces/ecpg/test/expected/sql-describe.stdout [new file with mode: 0644]
src/interfaces/ecpg/test/sql/Makefile
src/interfaces/ecpg/test/sql/describe.pgc [new file with mode: 0644]

index 0712e0ba9b6ed3eb91ce6d7058c770c4faa3032d..367081a684d56838be4222ab4875b6e4d0c86cda 100644 (file)
@@ -1,6 +1,6 @@
 /* dynamic SQL support routines
  *
- * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.33 2009/08/07 10:51:20 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.34 2010/01/15 10:44:34 meskes Exp $
  */
 
 #define POSTGRES_ECPG_INTERNAL
@@ -13,6 +13,7 @@
 #include "ecpgerrno.h"
 #include "extern.h"
 #include "sqlca.h"
+#include "sqlda.h"
 #include "sql3types.h"
 
 static void descriptor_free(struct descriptor * desc);
@@ -226,6 +227,12 @@ get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int va
    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,...)
 {
@@ -244,11 +251,6 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
        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))
    {
@@ -283,6 +285,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
        switch (type)
        {
            case (ECPGd_indicator):
+               RETURN_IF_NO_DATA;
                data_var.ind_type = vartype;
                data_var.ind_pointer = var;
                data_var.ind_varcharsize = varcharsize;
@@ -295,6 +298,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
                break;
 
            case ECPGd_data:
+               RETURN_IF_NO_DATA;
                data_var.type = vartype;
                data_var.pointer = var;
                data_var.varcharsize = varcharsize;
@@ -377,6 +381,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
            case ECPGd_ret_length:
            case ECPGd_ret_octet:
 
+               RETURN_IF_NO_DATA;
                /*
                 * this is like ECPGstore_result
                 */
@@ -480,6 +485,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
    sqlca->sqlerrd[2] = ntuples;
    return (true);
 }
+#undef RETURN_IF_NO_DATA
 
 bool
 ECPGset_desc_header(int lineno, const char *desc_name, int count)
@@ -723,8 +729,140 @@ ecpg_find_desc(int line, const char *name)
 }
 
 bool
-ECPGdescribe(int line, bool input, const char *statement,...)
+ECPGdescribe(int line, int compat, bool input, const char *connection_name, const char *stmt_name, ...)
 {
-   ecpg_log("ECPGdescribe called on line %d for %s: %s\n", line, input ? "input" : "output", statement);
-   return false;
+   bool        ret = false;
+   struct connection *con;
+   struct prepared_statement *prep;
+   PGresult   *res;
+   va_list     args;
+
+   /* DESCRIBE INPUT is not yet supported */
+   if (input)
+       return ret;
+
+   con = ecpg_get_connection(connection_name);
+   if (!con)
+       return false;
+   prep = ecpg_find_prepared_statement(stmt_name, con, NULL);
+   if (!prep)
+       return ret;
+
+   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 descriptor *desc = ecpg_find_desc(line, name);
+
+               if (desc == NULL)
+                   break;
+
+               res = PQdescribePrepared(con->connection, stmt_name);
+               if (!ecpg_check_PQresult(res, line, con->connection, compat))
+                   break;
+
+               if (desc->result != NULL)
+                   PQclear(desc->result);
+
+               desc->result = res;
+               ret = true;
+               break;
+           }
+           case ECPGt_sqlda:
+           {
+               if (INFORMIX_MODE(compat))
+               {
+                   struct sqlda_compat **_sqlda = ptr;
+                   struct sqlda_compat *sqlda;
+
+                   res = PQdescribePrepared(con->connection, stmt_name);
+                   if (!ecpg_check_PQresult(res, line, con->connection, compat))
+                       break;
+
+                   sqlda = ecpg_build_compat_sqlda(line, res, -1, compat);
+                   if (sqlda)
+                   {
+                       struct sqlda_compat *sqlda_old = *_sqlda;
+                       struct sqlda_compat *sqlda_old1;
+
+                       while (sqlda_old)
+                       {
+                           sqlda_old1 = sqlda_old->desc_next;
+                           free(sqlda_old);
+                           sqlda_old = sqlda_old1;
+                       }
+
+                       *_sqlda = sqlda;
+                       ret = true;
+                   }
+
+                   PQclear(res);
+               }
+               else
+               {
+                   struct sqlda_struct **_sqlda = ptr;
+                   struct sqlda_struct *sqlda;
+
+                   res = PQdescribePrepared(con->connection, stmt_name);
+                   if (!ecpg_check_PQresult(res, line, con->connection, compat))
+                       break;
+
+                   sqlda = ecpg_build_native_sqlda(line, res, -1, compat);
+                   if (sqlda)
+                   {
+                       struct sqlda_struct *sqlda_old = *_sqlda;
+                       struct sqlda_struct *sqlda_old1;
+
+                       while (sqlda_old)
+                       {
+                           sqlda_old1 = sqlda_old->desc_next;
+                           free(sqlda_old);
+                           sqlda_old = sqlda_old1;
+                       }
+
+                       *_sqlda = sqlda;
+                       ret = true;
+                   }
+
+                   PQclear(res);
+               }
+               break;
+           }
+           default:
+               /* nothing else may come */
+               ;
+       }
+   }
+
+   va_end(args);
+
+   return ret;
 }
index 6a68bc9f155f9984842640d604d2292ff225d02e..a07bf406b142575451ae1bd71de6580679a222f8 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.36 2010/01/05 16:38:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/extern.h,v 1.37 2010/01/15 10:44:34 meskes Exp $ */
 
 #ifndef _ECPG_LIB_EXTERN_H
 #define _ECPG_LIB_EXTERN_H
@@ -60,6 +60,15 @@ struct statement
    struct variable *outlist;
 };
 
+/* structure to store prepared statements for a connection */
+struct prepared_statement
+{
+   char       *name;
+   bool        prepared;
+   struct statement *stmt;
+   struct prepared_statement *next;
+};
+
 /* structure to store connections */
 struct connection
 {
@@ -139,6 +148,9 @@ struct descriptor *ecpggetdescp(int, char *);
 
 struct descriptor *ecpg_find_desc(int line, const char *name);
 
+struct prepared_statement *ecpg_find_prepared_statement(const char *,
+                 struct connection *, struct prepared_statement **);
+
 bool ecpg_store_result(const PGresult *results, int act_field,
                  const struct statement * stmt, struct variable * var);
 bool       ecpg_store_input(const int, const bool, const struct variable *, char **, bool);
index 17b2cc05b1edefda1a1d0f78e71af74dfdc506b8..6be062f4d8fa7b8f5ac07ba918221bbf85cdcb6a 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.33 2009/10/15 10:20:15 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/prepare.c,v 1.34 2010/01/15 10:44:34 meskes Exp $ */
 
 #define POSTGRES_ECPG_INTERNAL
 #include "postgres_fe.h"
 #include "extern.h"
 #include "sqlca.h"
 
-struct prepared_statement
-{
-   char       *name;
-   bool        prepared;
-   struct statement *stmt;
-   struct prepared_statement *next;
-};
-
 #define STMTID_SIZE 32
 
 typedef struct
@@ -35,8 +27,6 @@ static const int stmtCacheNBuckets = 2039;        /* # buckets - a prime # */
 static const int stmtCacheEntPerBucket = 8;        /* # entries/bucket     */
 static stmtCacheEntry stmtCacheEntries[16384] = {{0, {0}, 0, 0, 0}};
 
-static struct prepared_statement *find_prepared_statement(const char *name,
-                struct connection * con, struct prepared_statement ** prev);
 static bool deallocate_one(int lineno, enum COMPAT_MODE c, struct connection * con,
         struct prepared_statement * prev, struct prepared_statement * this);
 
@@ -126,7 +116,7 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, c
        return false;
 
    /* check if we already have prepared this statement */
-   this = find_prepared_statement(name, con, &prev);
+   this = ecpg_find_prepared_statement(name, con, &prev);
    if (this && !deallocate_one(lineno, ECPG_COMPAT_PGSQL, con, prev, this))
        return false;
 
@@ -179,8 +169,8 @@ ECPGprepare(int lineno, const char *connection_name, const bool questionmarks, c
    return true;
 }
 
-static struct prepared_statement *
-find_prepared_statement(const char *name,
+struct prepared_statement *
+ecpg_find_prepared_statement(const char *name,
                 struct connection * con, struct prepared_statement ** prev_)
 {
    struct prepared_statement *this,
@@ -262,7 +252,7 @@ ECPGdeallocate(int lineno, int c, const char *connection_name, const char *name)
    if (!ecpg_init(con, connection_name, lineno))
        return false;
 
-   this = find_prepared_statement(name, con, &prev);
+   this = ecpg_find_prepared_statement(name, con, &prev);
    if (this)
        return deallocate_one(lineno, c, con, prev, this);
 
@@ -297,7 +287,7 @@ ecpg_prepared(const char *name, struct connection * con)
 {
    struct prepared_statement *this;
 
-   this = find_prepared_statement(name, con, NULL);
+   this = ecpg_find_prepared_statement(name, con, NULL);
    return this ? this->stmt->command : NULL;
 }
 
@@ -394,7 +384,7 @@ ecpg_freeStmtCacheEntry(int lineno, int compat, int entNo)      /* entry # to free *
    con = ecpg_get_connection(entry->connection);
 
    /* free the 'prepared_statement' list entry       */
-   this = find_prepared_statement(entry->stmtID, con, &prev);
+   this = ecpg_find_prepared_statement(entry->stmtID, con, &prev);
    if (this && !deallocate_one(lineno, compat, con, prev, this))
        return (-1);
 
index bbb817830510648d282dea1b8ecf64d8cabfb422..f301de986ade3b29492358162348af3288e9ad09 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * this is a small part of c.h since we don't want to leak all postgres
  * definitions into ecpg programs
- * $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.80 2009/09/18 13:13:32 meskes Exp $
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/include/ecpglib.h,v 1.81 2010/01/15 10:44:36 meskes Exp $
  */
 
 #ifndef _ECPGLIB_H
@@ -83,7 +83,7 @@ bool      ECPGset_desc(int, const char *, int,...);
 
 void       ECPGset_noind_null(enum ECPGttype, void *);
 bool       ECPGis_noind_null(enum ECPGttype, void *);
-bool       ECPGdescribe(int, bool, const char *,...);
+bool       ECPGdescribe(int, int, bool, const char *, const char *, ...);
 
 /* dynamic result allocation */
 void       ECPGfree_auto_mem(void);
index 15548e81500fa72c6c37966ae8a3ad649e985cef..283826799101dd4a3b7198b70288ae5e55c36fdb 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.13 2010/01/05 16:38:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.addons,v 1.14 2010/01/15 10:44:37 meskes Exp $ */
 ECPG: stmtClosePortalStmt block
    {
        if (INFORMIX_MODE)
@@ -84,7 +84,7 @@ ECPG: stmtViewStmt rule
    }
    | ECPGDescribe
    {
-       fprintf(yyout, "{ ECPGdescribe(__LINE__, %s,", $1);
+       fprintf(yyout, "{ ECPGdescribe(__LINE__, %d, %s,", compat, $1);
        dump_variables(argsresult, 1);
        fputs("ECPGt_EORT);", yyout);
        fprintf(yyout, "}");
index d4f25b25fbec4ca80d91504bf070012a2b9c0c02..f372c7dcd8a25cf1ced8e37b4333e635ec7bee2f 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.trailer,v 1.17 2010/01/05 16:38:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.trailer,v 1.18 2010/01/15 10:44:37 meskes Exp $ */
 
 statements: /*EMPTY*/
                 | statements statement
@@ -994,6 +994,13 @@ into_descriptor: INTO SQL_SQL SQL_DESCRIPTOR quoted_ident_stringvar
        }
        ;
 
+into_sqlda: INTO name
+       {
+           add_variable_to_head(&argsresult, sqlda_variable($2), &no_indicator);
+           $$ = EMPTY;
+       }
+       ;
+
 using_list: UsingValue | UsingValue ',' using_list;
 
 UsingValue: UsingConst
@@ -1019,28 +1026,45 @@ UsingConst: Iconst          { $$ = $1; }
        ;
 
 /*
- * We accept descibe but do nothing with it so far.
+ * We accept DESCRIBE [OUTPUT] but do nothing with DESCRIBE INPUT so far.
  */
-ECPGDescribe: SQL_DESCRIBE INPUT_P name using_descriptor
+ECPGDescribe: SQL_DESCRIBE INPUT_P prepared_name using_descriptor
    {
        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);
+       $$ = (char *) mm_alloc(sizeof("1, ") + strlen(con) + strlen($3));
+       sprintf($$, "1, %s, %s", con, $3);
    }
-   | SQL_DESCRIBE opt_output name using_descriptor
+   | SQL_DESCRIBE opt_output prepared_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);
+       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
+   | SQL_DESCRIBE opt_output prepared_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 prepared_name into_sqlda
    {
        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);
+       $$ = (char *) mm_alloc(sizeof("1, , ") + strlen(con) + strlen($3));
+       sprintf($$, "1, %s, %s", con, $3);
+   }
+   | SQL_DESCRIBE opt_output prepared_name into_sqlda
+   {
+       const char *con = connection ? connection : "NULL";
+       $$ = (char *) mm_alloc(sizeof("0, , ") + strlen(con) + strlen($3));
+       sprintf($$, "0, %s, %s", con, $3);
    }
    ;
 
index 419a565ce3f6a47cabb0b01ebd9deb412f7952cd..dbcd3e81106cd89da3947bc20508f586b997d7bb 100644 (file)
@@ -1,4 +1,4 @@
-/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.type,v 1.5 2010/01/05 16:38:23 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/ecpg.type,v 1.6 2010/01/15 10:44:37 meskes Exp $ */
 %type <str> ECPGAllocateDescr
 %type <str> ECPGCKeywords
 %type <str> ECPGColId
@@ -72,6 +72,7 @@
 %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
index fadc081a6437a3a3f1421c2bf067818742b3132c..a8e2ca972ece17ff2069561a08d2ea2f8e4207e7 100644 (file)
@@ -17,6 +17,7 @@ TESTS = test_informix test_informix.c \
         rfmtlong rfmtlong.c \
         rnull rnull.c \
         sqlda sqlda.c \
+        describe describe.c \
         charfuncs charfuncs.c
 
 all: $(TESTS)
diff --git a/src/interfaces/ecpg/test/compat_informix/describe.pgc b/src/interfaces/ecpg/test/compat_informix/describe.pgc
new file mode 100644 (file)
index 0000000..b0f9a3d
--- /dev/null
@@ -0,0 +1,199 @@
+#include <stdlib.h>
+#include <string.h>
+
+exec sql include ../regression;
+exec sql include sqlda.h;
+
+exec sql whenever sqlerror stop;
+
+sqlda_t    *sqlda1, *sqlda2, *sqlda3;
+
+int
+main (void)
+{
+exec sql begin declare section;
+   char    *stmt1 = "SELECT id, t FROM descr_t1";
+   char    *stmt2 = "SELECT id, t FROM descr_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 descr_t1(id serial primary key, t text);
+
+   strcpy(msg, "insert");
+   exec sql insert into descr_t1(id, t) values (default, 'a');
+   exec sql insert into descr_t1(id, t) values (default, 'b');
+   exec sql insert into descr_t1(id, t) values (default, 'c');
+   exec sql insert into descr_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)
+   {
+       printf("sqlda1 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda2 == NULL)
+   {
+       printf("sqlda2 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda3 == NULL)
+   {
+       printf("sqlda3 NULL\n");
+       exit(1);
+   }
+
+   strcpy(msg, "get descriptor");
+   exec sql get descriptor desc1 :count1 = count;
+   exec sql get descriptor desc1 :count2 = count;
+
+   if (count1 != count2)
+   {
+       printf("count1 (%d) != count2 (%d)\n", count1, count2);
+       exit(1);
+   }
+
+   if (count1 != sqlda1->sqld)
+   {
+       printf("count1 (%d) != sqlda1->sqld (%d)\n", count1, sqlda1->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda2->sqld)
+   {
+       printf("count1 (%d) != sqlda2->sqld (%d)\n", count1, sqlda2->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda3->sqld)
+   {
+       printf("count1 (%d) != sqlda3->sqld (%d)\n", 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 descr_t1;
+
+   strcpy(msg, "commit");
+   exec sql commit;
+
+   strcpy(msg, "disconnect"); 
+   exec sql disconnect;
+
+   return (0);
+}
index f79d76b3dd9a2f9c35d63c7b4fbac125655c8038..2bf1e0243ef347ffad7d9423d38192b69d975606 100644 (file)
@@ -4,6 +4,7 @@ test: compat_informix/rfmtdate
 test: compat_informix/rfmtlong
 test: compat_informix/rnull
 test: compat_informix/sqlda
+test: compat_informix/describe
 test: compat_informix/test_informix
 test: compat_informix/test_informix2
 test: connect/test2
@@ -31,6 +32,7 @@ test: sql/copystdout
 test: sql/define
 test: sql/desc
 test: sql/sqlda
+test: sql/describe
 test: sql/dynalloc
 test: sql/dynalloc2
 test: sql/dyntest
index f55e97c2622457693fb7f256a22680d7ff09cea8..9df75aba21b644547ffa2c72cc37728dddb7f5a5 100644 (file)
@@ -4,6 +4,7 @@ test: compat_informix/rfmtdate
 test: compat_informix/rfmtlong
 test: compat_informix/rnull
 test: compat_informix/sqlda
+test: compat_informix/describe
 test: compat_informix/test_informix
 test: compat_informix/test_informix2
 test: connect/test2
@@ -31,6 +32,7 @@ test: sql/copystdout
 test: sql/define
 test: sql/desc
 test: sql/sqlda
+test: sql/describe
 test: sql/dynalloc
 test: sql/dynalloc2
 test: sql/dyntest
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-describe.c b/src/interfaces/ecpg/test/expected/compat_informix-describe.c
new file mode 100644 (file)
index 0000000..6aa534f
--- /dev/null
@@ -0,0 +1,467 @@
+/* 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"
+#ifndef ECPG_SQLDA_H
+#define ECPG_SQLDA_H
+
+#ifdef _ECPG_INFORMIX_H
+
+#include "sqlda-compat.h"
+typedef struct sqlvar_compat   sqlvar_t;
+typedef struct sqlda_compat    sqlda_t;
+
+#else
+
+#include "sqlda-native.h"
+typedef struct sqlvar_struct   sqlvar_t;
+typedef struct sqlda_struct    sqlda_t;
+
+#endif
+
+#endif /* ECPG_SQLDA_H */
+
+#line 5 "describe.pgc"
+
+
+/* exec sql whenever sqlerror  stop ; */
+#line 7 "describe.pgc"
+
+
+sqlda_t    *sqlda1, *sqlda2, *sqlda3;
+
+int
+main (void)
+{
+/* exec sql begin declare section */
+         
+         
+         
+         
+         
+
+#line 15 "describe.pgc"
+ char * stmt1 = "SELECT id, t FROM descr_t1" ;
+#line 16 "describe.pgc"
+ char * stmt2 = "SELECT id, t FROM descr_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 descr_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 descr_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 descr_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 descr_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 descr_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__, 1, 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__, 1, 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__, 1, 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__, 1, 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__, 1, 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)
+   {
+       printf("sqlda1 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda2 == NULL)
+   {
+       printf("sqlda2 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda3 == NULL)
+   {
+       printf("sqlda3 NULL\n");
+       exit(1);
+   }
+
+   strcpy(msg, "get descriptor");
+   { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+#line 86 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 86 "describe.pgc"
+
+   { ECPGget_desc_header(__LINE__, "desc1", &(count2));
+
+#line 87 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 87 "describe.pgc"
+
+
+   if (count1 != count2)
+   {
+       printf("count1 (%d) != count2 (%d)\n", count1, count2);
+       exit(1);
+   }
+
+   if (count1 != sqlda1->sqld)
+   {
+       printf("count1 (%d) != sqlda1->sqld (%d)\n", count1, sqlda1->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda2->sqld)
+   {
+       printf("count1 (%d) != sqlda2->sqld (%d)\n", count1, sqlda2->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda3->sqld)
+   {
+       printf("count1 (%d) != sqlda3->sqld (%d)\n", 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 115 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 115 "describe.pgc"
+
+       { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+   ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+#line 116 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 116 "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 126 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 126 "describe.pgc"
+
+   ECPGdeallocate_desc(__LINE__, "desc2");
+#line 127 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 127 "describe.pgc"
+
+   free(sqlda1);
+   free(sqlda2);
+   free(sqlda3);
+
+   { ECPGdeallocate(__LINE__, 1, NULL, "st_id1");
+#line 132 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 132 "describe.pgc"
+
+
+   /* Test DESCRIBE with a query not producing tuples */
+
+   strcpy(msg, "allocate");
+   ECPGallocate_desc(__LINE__, "desc1");
+#line 137 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 137 "describe.pgc"
+
+   ECPGallocate_desc(__LINE__, "desc2");
+#line 138 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 138 "describe.pgc"
+
+
+   strcpy(msg, "prepare");
+   { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt2);
+#line 141 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 141 "describe.pgc"
+
+
+   sqlda1 = sqlda2 = sqlda3 = NULL;
+
+   strcpy(msg, "describe");
+   { ECPGdescribe(__LINE__, 1, 0, NULL, "st_id2",
+   ECPGt_descriptor, "desc1", 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 146 "describe.pgc"
+
+   { ECPGdescribe(__LINE__, 1, 0, NULL, "st_id2",
+   ECPGt_descriptor, "desc2", 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 147 "describe.pgc"
+
+
+   { ECPGdescribe(__LINE__, 1, 0, NULL, "st_id2",
+   ECPGt_sqlda, &sqlda1, 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 149 "describe.pgc"
+
+   { ECPGdescribe(__LINE__, 1, 0, NULL, "st_id2",
+   ECPGt_sqlda, &sqlda2, 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 150 "describe.pgc"
+
+   { ECPGdescribe(__LINE__, 1, 0, NULL, "st_id2",
+   ECPGt_sqlda, &sqlda3, 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 151 "describe.pgc"
+
+
+   if (sqlda1 == NULL || sqlda1 == NULL || sqlda2 == NULL)
+       exit(1);
+
+   strcpy(msg, "get descriptor");
+   { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+#line 157 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 157 "describe.pgc"
+
+   { ECPGget_desc_header(__LINE__, "desc1", &(count2));
+
+#line 158 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 158 "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 168 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 168 "describe.pgc"
+
+       { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+   ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+#line 169 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 169 "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 179 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 179 "describe.pgc"
+
+   ECPGdeallocate_desc(__LINE__, "desc2");
+#line 180 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 180 "describe.pgc"
+
+   free(sqlda1);
+   free(sqlda2);
+   free(sqlda3);
+
+   { ECPGdeallocate(__LINE__, 1, NULL, "st_id2");
+#line 185 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 185 "describe.pgc"
+
+
+   /* End test */
+
+   strcpy(msg, "drop");
+   { ECPGdo(__LINE__, 1, 1, NULL, 0, ECPGst_normal, "drop table descr_t1", ECPGt_EOIT, ECPGt_EORT);
+#line 190 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 190 "describe.pgc"
+
+
+   strcpy(msg, "commit");
+   { ECPGtrans(__LINE__, NULL, "commit");
+#line 193 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 193 "describe.pgc"
+
+
+   strcpy(msg, "disconnect"); 
+   { ECPGdisconnect(__LINE__, "CURRENT");
+#line 196 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 196 "describe.pgc"
+
+
+   return (0);
+}
diff --git a/src/interfaces/ecpg/test/expected/compat_informix-describe.stderr b/src/interfaces/ecpg/test/expected/compat_informix-describe.stderr
new file mode 100644 (file)
index 0000000..3be0a65
--- /dev/null
@@ -0,0 +1,112 @@
+[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 descr_t1 ( id serial primary key , t text ); with 0 parameter(s) on connection regress1
+[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 descr_t1 ( id , t ) values ( default , 'a' ); with 0 parameter(s) on connection regress1
+[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 descr_t1 ( id , t ) values ( default , 'b' ); with 0 parameter(s) on connection regress1
+[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 descr_t1 ( id , t ) values ( default , 'c' ); with 0 parameter(s) on connection regress1
+[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 descr_t1 ( id , t ) values ( default , 'd' ); with 0 parameter(s) on connection regress1
+[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 descr_t1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_compat_sqlda on line 63 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_compat_sqlda on line 64 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_compat_sqlda on line 65 sqld = 2
+[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 132: name st_id1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 141: name st_id2; query: "SELECT id, t FROM descr_t1 WHERE id = -1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_compat_sqlda on line 149 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_compat_sqlda on line 150 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_compat_sqlda on line 151 sqld = 2
+[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 185: name st_id2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 190: query: drop table descr_t1; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 190: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 190: OK: DROP TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 193: 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 --git a/src/interfaces/ecpg/test/expected/compat_informix-describe.stdout b/src/interfaces/ecpg/test/expected/compat_informix-describe.stdout
new file mode 100644 (file)
index 0000000..1e3fe10
--- /dev/null
@@ -0,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 --git a/src/interfaces/ecpg/test/expected/preproc-describe.c b/src/interfaces/ecpg/test/expected/preproc-describe.c
new file mode 100644 (file)
index 0000000..4c397e0
--- /dev/null
@@ -0,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 --git a/src/interfaces/ecpg/test/expected/preproc-describe.stderr b/src/interfaces/ecpg/test/expected/preproc-describe.stderr
new file mode 100644 (file)
index 0000000..999cac6
--- /dev/null
@@ -0,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 connection regress1
+[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 connection regress1
+[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 connection regress1
+[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 connection regress1
+[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 connection regress1
+[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 --git a/src/interfaces/ecpg/test/expected/preproc-describe.stdout b/src/interfaces/ecpg/test/expected/preproc-describe.stdout
new file mode 100644 (file)
index 0000000..d27324e
--- /dev/null
@@ -0,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 --git a/src/interfaces/ecpg/test/expected/sql-describe.c b/src/interfaces/ecpg/test/expected/sql-describe.c
new file mode 100644 (file)
index 0000000..7a5ab02
--- /dev/null
@@ -0,0 +1,465 @@
+/* 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"
+
+
+#line 1 "sqlda.h"
+#ifndef ECPG_SQLDA_H
+#define ECPG_SQLDA_H
+
+#ifdef _ECPG_INFORMIX_H
+
+#include "sqlda-compat.h"
+typedef struct sqlvar_compat   sqlvar_t;
+typedef struct sqlda_compat    sqlda_t;
+
+#else
+
+#include "sqlda-native.h"
+typedef struct sqlvar_struct   sqlvar_t;
+typedef struct sqlda_struct    sqlda_t;
+
+#endif
+
+#endif /* ECPG_SQLDA_H */
+
+#line 5 "describe.pgc"
+
+
+/* exec sql whenever sqlerror  stop ; */
+#line 7 "describe.pgc"
+
+
+sqlda_t    *sqlda1, *sqlda2, *sqlda3;
+
+int
+main (void)
+{
+/* exec sql begin declare section */
+         
+         
+         
+         
+         
+
+#line 15 "describe.pgc"
+ char * stmt1 = "SELECT id, t FROM descr_t2" ;
+#line 16 "describe.pgc"
+ char * stmt2 = "SELECT id, t FROM descr_t2 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__, 0, "regress1" , NULL, NULL , NULL, 0); 
+#line 27 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 27 "describe.pgc"
+
+
+   strcpy(msg, "set");
+   { ECPGdo(__LINE__, 0, 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__, 0, 1, NULL, 0, ECPGst_normal, "create table descr_t2 ( 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__, 0, 1, NULL, 0, ECPGst_normal, "insert into descr_t2 ( 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__, 0, 1, NULL, 0, ECPGst_normal, "insert into descr_t2 ( 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__, 0, 1, NULL, 0, ECPGst_normal, "insert into descr_t2 ( 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__, 0, 1, NULL, 0, ECPGst_normal, "insert into descr_t2 ( 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, 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, 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, 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, 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, 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)
+   {
+       printf("sqlda1 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda2 == NULL)
+   {
+       printf("sqlda2 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda3 == NULL)
+   {
+       printf("sqlda3 NULL\n");
+       exit(1);
+   }
+
+   strcpy(msg, "get descriptor");
+   { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+#line 86 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 86 "describe.pgc"
+
+   { ECPGget_desc_header(__LINE__, "desc1", &(count2));
+
+#line 87 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 87 "describe.pgc"
+
+
+   if (count1 != count2)
+   {
+       printf("count1 (%d) != count2 (%d)\n", count1, count2);
+       exit(1);
+   }
+
+   if (count1 != sqlda1->sqld)
+   {
+       printf("count1 (%d) != sqlda1->sqld (%d)\n", count1, sqlda1->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda2->sqld)
+   {
+       printf("count1 (%d) != sqlda2->sqld (%d)\n", count1, sqlda2->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda3->sqld)
+   {
+       printf("count1 (%d) != sqlda3->sqld (%d)\n", 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 115 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 115 "describe.pgc"
+
+       { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+   ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+#line 116 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 116 "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.data,
+           sqlda2->sqlvar[i-1].sqlname.data,
+           sqlda3->sqlvar[i-1].sqlname.data);
+   }
+
+   strcpy(msg, "deallocate");
+   ECPGdeallocate_desc(__LINE__, "desc1");
+#line 126 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 126 "describe.pgc"
+
+   ECPGdeallocate_desc(__LINE__, "desc2");
+#line 127 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 127 "describe.pgc"
+
+   free(sqlda1);
+   free(sqlda2);
+   free(sqlda3);
+
+   { ECPGdeallocate(__LINE__, 0, NULL, "st_id1");
+#line 132 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 132 "describe.pgc"
+
+
+   /* Test DESCRIBE with a query not producing tuples */
+
+   strcpy(msg, "allocate");
+   ECPGallocate_desc(__LINE__, "desc1");
+#line 137 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 137 "describe.pgc"
+
+   ECPGallocate_desc(__LINE__, "desc2");
+#line 138 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 138 "describe.pgc"
+
+
+   strcpy(msg, "prepare");
+   { ECPGprepare(__LINE__, NULL, 0, "st_id2", stmt2);
+#line 141 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 141 "describe.pgc"
+
+
+   sqlda1 = sqlda2 = sqlda3 = NULL;
+
+   strcpy(msg, "describe");
+   { ECPGdescribe(__LINE__, 0, 0, NULL, "st_id2",
+   ECPGt_descriptor, "desc1", 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 146 "describe.pgc"
+
+   { ECPGdescribe(__LINE__, 0, 0, NULL, "st_id2",
+   ECPGt_descriptor, "desc2", 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 147 "describe.pgc"
+
+
+   { ECPGdescribe(__LINE__, 0, 0, NULL, "st_id2",
+   ECPGt_sqlda, &sqlda1, 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 149 "describe.pgc"
+
+   { ECPGdescribe(__LINE__, 0, 0, NULL, "st_id2",
+   ECPGt_sqlda, &sqlda2, 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 150 "describe.pgc"
+
+   { ECPGdescribe(__LINE__, 0, 0, NULL, "st_id2",
+   ECPGt_sqlda, &sqlda3, 0L, 0L, 0L, 
+   ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);}
+#line 151 "describe.pgc"
+
+
+   if (sqlda1 == NULL || sqlda1 == NULL || sqlda2 == NULL)
+       exit(1);
+
+   strcpy(msg, "get descriptor");
+   { ECPGget_desc_header(__LINE__, "desc1", &(count1));
+
+#line 157 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 157 "describe.pgc"
+
+   { ECPGget_desc_header(__LINE__, "desc1", &(count2));
+
+#line 158 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 158 "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 168 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 168 "describe.pgc"
+
+       { ECPGget_desc(__LINE__, "desc2", i,ECPGd_name,
+   ECPGt_char,(field_name2),(long)30,(long)1,(30)*sizeof(char), ECPGd_EODT);
+
+#line 169 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 169 "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.data,
+           sqlda2->sqlvar[i-1].sqlname.data,
+           sqlda3->sqlvar[i-1].sqlname.data);
+   }
+
+   strcpy(msg, "deallocate");
+   ECPGdeallocate_desc(__LINE__, "desc1");
+#line 179 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 179 "describe.pgc"
+
+   ECPGdeallocate_desc(__LINE__, "desc2");
+#line 180 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);
+#line 180 "describe.pgc"
+
+   free(sqlda1);
+   free(sqlda2);
+   free(sqlda3);
+
+   { ECPGdeallocate(__LINE__, 0, NULL, "st_id2");
+#line 185 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 185 "describe.pgc"
+
+
+   /* End test */
+
+   strcpy(msg, "drop");
+   { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop table descr_t2", ECPGt_EOIT, ECPGt_EORT);
+#line 190 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 190 "describe.pgc"
+
+
+   strcpy(msg, "commit");
+   { ECPGtrans(__LINE__, NULL, "commit");
+#line 193 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 193 "describe.pgc"
+
+
+   strcpy(msg, "disconnect"); 
+   { ECPGdisconnect(__LINE__, "CURRENT");
+#line 196 "describe.pgc"
+
+if (sqlca.sqlcode < 0) exit (1);}
+#line 196 "describe.pgc"
+
+
+   return (0);
+}
diff --git a/src/interfaces/ecpg/test/expected/sql-describe.stderr b/src/interfaces/ecpg/test/expected/sql-describe.stderr
new file mode 100644 (file)
index 0000000..64f0e03
--- /dev/null
@@ -0,0 +1,112 @@
+[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 descr_t2 ( id serial primary key , t text ); with 0 parameter(s) on connection regress1
+[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 descr_t2 ( id , t ) values ( default , 'a' ); with 0 parameter(s) on connection regress1
+[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 descr_t2 ( id , t ) values ( default , 'b' ); with 0 parameter(s) on connection regress1
+[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 descr_t2 ( id , t ) values ( default , 'c' ); with 0 parameter(s) on connection regress1
+[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 descr_t2 ( id , t ) values ( default , 'd' ); with 0 parameter(s) on connection regress1
+[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 descr_t2"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_native_sqlda on line 63 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_native_sqlda on line 64 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_native_sqlda on line 65 sqld = 2
+[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 132: name st_id1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGprepare on line 141: name st_id2; query: "SELECT id, t FROM descr_t2 WHERE id = -1"
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_native_sqlda on line 149 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_native_sqlda on line 150 sqld = 2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_build_native_sqlda on line 151 sqld = 2
+[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 185: name st_id2
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 190: query: drop table descr_t2; with 0 parameter(s) on connection regress1
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 190: using PQexec
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ecpg_execute on line 190: OK: DROP TABLE
+[NO_PID]: sqlca: code: 0, state: 00000
+[NO_PID]: ECPGtrans on line 193: 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 --git a/src/interfaces/ecpg/test/expected/sql-describe.stdout b/src/interfaces/ecpg/test/expected/sql-describe.stdout
new file mode 100644 (file)
index 0000000..1e3fe10
--- /dev/null
@@ -0,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'
index 45893d39cc1ad217721be6143d418bbc54542cfc..1cd2217ed72acff098474879ab746215167a1df3 100644 (file)
@@ -9,6 +9,8 @@ TESTS = array array.c \
         copystdout copystdout.c \
    define define.c \
         desc desc.c \
+        sqlda sqlda.c \
+        describe describe.c \
         dyntest dyntest.c \
         dynalloc dynalloc.c \
         dynalloc2 dynalloc2.c \
@@ -20,7 +22,6 @@ TESTS = array array.c \
         parser parser.c \
         quote quote.c \
         show show.c \
-        sqlda sqlda.c \
         insupd insupd.c 
 
 all: $(TESTS)
diff --git a/src/interfaces/ecpg/test/sql/describe.pgc b/src/interfaces/ecpg/test/sql/describe.pgc
new file mode 100644 (file)
index 0000000..80361cb
--- /dev/null
@@ -0,0 +1,199 @@
+#include <stdlib.h>
+#include <string.h>
+
+exec sql include ../regression;
+exec sql include sqlda.h;
+
+exec sql whenever sqlerror stop;
+
+sqlda_t    *sqlda1, *sqlda2, *sqlda3;
+
+int
+main (void)
+{
+exec sql begin declare section;
+   char    *stmt1 = "SELECT id, t FROM descr_t2";
+   char    *stmt2 = "SELECT id, t FROM descr_t2 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 descr_t2(id serial primary key, t text);
+
+   strcpy(msg, "insert");
+   exec sql insert into descr_t2(id, t) values (default, 'a');
+   exec sql insert into descr_t2(id, t) values (default, 'b');
+   exec sql insert into descr_t2(id, t) values (default, 'c');
+   exec sql insert into descr_t2(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)
+   {
+       printf("sqlda1 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda2 == NULL)
+   {
+       printf("sqlda2 NULL\n");
+       exit(1);
+   }
+
+   if (sqlda3 == NULL)
+   {
+       printf("sqlda3 NULL\n");
+       exit(1);
+   }
+
+   strcpy(msg, "get descriptor");
+   exec sql get descriptor desc1 :count1 = count;
+   exec sql get descriptor desc1 :count2 = count;
+
+   if (count1 != count2)
+   {
+       printf("count1 (%d) != count2 (%d)\n", count1, count2);
+       exit(1);
+   }
+
+   if (count1 != sqlda1->sqld)
+   {
+       printf("count1 (%d) != sqlda1->sqld (%d)\n", count1, sqlda1->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda2->sqld)
+   {
+       printf("count1 (%d) != sqlda2->sqld (%d)\n", count1, sqlda2->sqld);
+       exit(1);
+   }
+
+   if (count1 != sqlda3->sqld)
+   {
+       printf("count1 (%d) != sqlda3->sqld (%d)\n", 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.data,
+           sqlda2->sqlvar[i-1].sqlname.data,
+           sqlda3->sqlvar[i-1].sqlname.data);
+   }
+
+   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.data,
+           sqlda2->sqlvar[i-1].sqlname.data,
+           sqlda3->sqlvar[i-1].sqlname.data);
+   }
+
+   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 descr_t2;
+
+   strcpy(msg, "commit");
+   exec sql commit;
+
+   strcpy(msg, "disconnect"); 
+   exec sql disconnect;
+
+   return (0);
+}