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: