Re: Split-up ECPG patches - Mailing list pgsql-hackers
From | Boszormenyi Zoltan |
---|---|
Subject | Re: Split-up ECPG patches |
Date | |
Msg-id | 4A892354.8010502@cybertec.at Whole thread Raw |
In response to | Re: Split-up ECPG patches (Michael Meskes <meskes@postgresql.org>) |
List | pgsql-hackers |
Michael Meskes írta: > On Sun, Aug 16, 2009 at 05:59:46PM +0200, Boszormenyi Zoltan wrote: > >>> What heppens if the sqlda is incompatible? >>> >> Returns false? >> > > I wasn't talking about this one function but about the flow of the resulting > program. How can it happen that sqlda is incompatible and what happens then? > Hm. The following may occur. One may pass the same sqlda ptr to two different cursors in DECLARE or FETCH in the same loop. In this case it's wrong to not process the "incompatible" call. Modified patch is attached: - fixed flow, frees up the "incompatible" sqlda and creates a new one - added ecpg_log() calls - no more realloc(), an "empty" sqlda is allocated for full size. realloc() can destroy internal pointers (like the ones pointing to field names and ->sqlvar.) The previous pg85-describe-5-ctxdiff.patch still applies cleanly. 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-17 11:13:42.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,1453 ---- } 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 we are passed in a non-compatible sqlda then free it. */ + if (sqlda) + { + int compat_sqlda; + compat_sqlda = 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, compat_sqlda); + if (!compat_sqlda) + { + free(sqlda); + sqlda = NULL; + } + } + /* Build a new sqlda structure */ + if (!sqlda) + { + sqlda = ecpg_build_sqlda_for_PGresult(stmt->lineno, results); + ecpg_log("ecpg_execute on line %d: new sqlda was built\n", stmt->lineno); + if (!sqlda) + status = false; + *_sqlda = sqlda; + } + /* If the sqlda was allocated then fill it. */ + if (status == true) + { + ecpg_set_sqlda_from_PGresult(stmt->lineno, _sqlda, results); + ecpg_log("ecpg_execute on line %d: putting result (1 tuple %d fields) into sqlda descriptor\n", + stmt->lineno, PQnfields(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-17 11:10:32.000000000 +0200 *************** *** 0 **** --- 1,329 ---- + /* + * 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" + + /* + * Compute the next variable's offset with + * the current variable's size and alignment. + */ + static long + ecpg_sqlda_size_round_align(long offset, int alignment, int size) + { + if (offset % alignment) + offset += alignment - (offset % alignment); + offset += size; + return offset; + } + + /* + * Compute the current variable's offset with alignment. + */ + static long + ecpg_sqlda_size_align(long offset, int alignment) + { + if (offset % alignment) + offset += alignment - (offset % alignment); + return offset; + } + + static long + ecpg_sqlda_empty_size(const PGresult *res) + { + long size; + int i; + int sqld = PQnfields(res); + + + /* Initial size to store main structure and field structures */ + size = sizeof(pg_sqlda_t) + sqld * sizeof(pg_sqlvar_t); + + /* Add space for field names */ + for (i = 0; i < sqld; i++) + size += strlen(PQfname(res, i)) + 1; + + /* Add padding to the first field value */ + size = ecpg_sqlda_size_align(size, sizeof(int)); + + return size; + } + + static long + ecpg_sqlda_total_size(const PGresult *res) + { + int i; + int sqld = PQnfields(res); + long size; + + size = ecpg_sqlda_empty_size(res); + + /* Add space for the field values */ + for (i = 0; i < sqld; i++) + { + switch (ecpg_to_sqlda_type(PQftype(res, i))) + { + 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 + * as is from the PGresult 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; + } + } + return size; + } + + /* + * 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 sqld; + int i; + + size = ecpg_sqlda_total_size(res); + sqlda = (pg_sqlda_t *)ecpg_alloc(size, line); + if (!sqlda) + return NULL; + + memset(sqlda, 0, size); + sqlvar = (pg_sqlvar_t *)(sqlda + 1); + sqld = PQnfields(res); + fname = (char *)(sqlvar + sqld); + + sqlda->sqld = sqld; + 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; + long size; + + if (sqlda->sqld != PQnfields(res)) + { + ecpg_log("ecpg_compare_sqlda_with_PGresult: sqld differ %d %d\n", + sqlda->sqld, PQnfields(res)); + return false; + } + + size = ecpg_sqlda_total_size(res); + if (sqlda->desc_occ != size) + { + ecpg_log("ecpg_compare_sqlda_with_PGresult: structure size differ %d %d\n", + sqlda->desc_occ, size); + 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 (strncmp(sqlda->sqlvar[i].sqlname, PQfname(res, i), strlen(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; + } + + /* + * Sets values from PGresult. + */ + 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; + + /* Offset for the first field value */ + size = ecpg_sqlda_empty_size(res); + + /* + * Set sqlvar[i]->sqldata pointers and convert values to correct format + */ + 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-17 11:22:46.000000000 +0200 *************** *** 0 **** --- 1,224 ---- + [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_execute on line 111: new sqlda was built + [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 tuple 5 fields) 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 tuple 5 fields) 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 tuple 5 fields) 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 tuple 5 fields) 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_execute on line 148: new sqlda was built + [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 tuple 5 fields) 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 tuple 5 fields) 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 tuple 5 fields) 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 tuple 5 fields) 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_execute on line 186: new sqlda was built + [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 tuple 5 fields) 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 '
pgsql-hackers by date: