diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 2b33f1f487..c42a6b2599 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -1558,6 +1558,11 @@ Mon Jul 7 14:13:43 CEST 2003 Tue Jul 8 09:04:31 CEST 2003 - Fixed segfault in ECPGconnect in Informix mode. + +Tue Jul 8 12:34:00 CEST 2003 + + - Made Informix decimal-ascii conversion honor Informix NULLs. + - Informix variable handling didn't cope well with arrays. - Set ecpg version to 3.0.0 - Set ecpg library to 4.0.0 - Set pgtypes library to 1.0.0 diff --git a/src/interfaces/ecpg/compatlib/informix.c b/src/interfaces/ecpg/compatlib/informix.c index 157809de22..985704393c 100644 --- a/src/interfaces/ecpg/compatlib/informix.c +++ b/src/interfaces/ecpg/compatlib/informix.c @@ -8,6 +8,7 @@ #include #include #include +#include char * ECPGalloc(long, int); @@ -147,8 +148,13 @@ deccvasc(char *cp, int len, Decimal *np) char *str = strndup(cp, len); /* Decimal_in always converts the complete string */ int ret = 0; Numeric *result; - - + + if (risnull(CSTRINGTYPE, cp)) + { + rsetnull(CDECIMALTYPE, (char *)np); + return 0; + } + if (!str) ret = -1201; else @@ -292,6 +298,12 @@ dectoasc(Decimal *np, char *cp, int len, int right) if (nres == NULL) return -1211; + if (risnull(CDECIMALTYPE, (char *)np)) + { + rsetnull(CSTRINGTYPE, (char *)cp); + return 0; + } + if (PGTYPESnumeric_from_decimal(np, nres) != 0) return -1211; diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index c9da13794d..011b5a6b29 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.10 2003/07/01 12:40:51 meskes Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/data.c,v 1.11 2003/07/08 12:11:28 meskes Exp $ */ #define POSTGRES_ECPG_INTERNAL #include "postgres_fe.h" @@ -24,6 +24,7 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, { struct sqlca_t *sqlca = ECPGget_sqlca(); char *pval = (char *) PQgetvalue(results, act_tuple, act_field); + int value_for_indicator = 0; ECPGlog("ECPGget_data line %d: RESULT: %s offset: %ld\n", lineno, pval ? pval : "", offset); @@ -53,31 +54,34 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, /* We will have to decode the value */ /* - * check for null value and set indicator accordingly + * check for null value and set indicator accordingly, i.e. -1 if NULL and 0 if not */ if (PQgetisnull(results, act_tuple, act_field)) + value_for_indicator = -1; + + switch (ind_type) { - switch (ind_type) - { - case ECPGt_short: - case ECPGt_unsigned_short: - *((short *) (ind + ind_offset * act_tuple)) = -1; - break; - case ECPGt_int: - case ECPGt_unsigned_int: - *((int *) (ind + ind_offset * act_tuple)) = -1; - break; - case ECPGt_long: - case ECPGt_unsigned_long: - *((long *) (ind + ind_offset * act_tuple)) = -1; - break; + case ECPGt_short: + case ECPGt_unsigned_short: + *((short *) (ind + ind_offset * act_tuple)) = value_for_indicator; + break; + case ECPGt_int: + case ECPGt_unsigned_int: + *((int *) (ind + ind_offset * act_tuple)) = value_for_indicator; + break; + case ECPGt_long: + case ECPGt_unsigned_long: + *((long *) (ind + ind_offset * act_tuple)) = value_for_indicator; + break; #ifdef HAVE_LONG_LONG_INT_64 - case ECPGt_long_long: - case ECPGt_unsigned_long_long: - *((long long int *) (ind + ind_offset * act_tuple)) = -1; - break; + case ECPGt_long_long: + case ECPGt_unsigned_long_long: + *((long long int *) (ind + ind_offset * act_tuple)) = value_for_indicator; + break; #endif /* HAVE_LONG_LONG_INT_64 */ - case ECPGt_NO_INDICATOR: + case ECPGt_NO_INDICATOR: + if (value_for_indicator == -1) + { if (force_indicator == false) { /* Informix has an additional way to specify NULLs @@ -89,16 +93,17 @@ ECPGget_data(const PGresult *results, int act_tuple, int act_field, int lineno, ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL); return (false); } - break; - default: - ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(ind_type)); - return (false); - break; - } - - return (true); + } + break; + default: + ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(ind_type)); + return (false); + break; } + if (value_for_indicator == -1) + return (true); + do { switch (type) diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 255b904033..0115362a0f 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.17 2003/07/07 12:15:33 meskes Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.18 2003/07/08 12:11:29 meskes Exp $ */ /* * The aim is to get a simpler inteface to the database routines. @@ -144,7 +144,6 @@ create_statement(int lineno, int compat, int force_indicator, struct connection var->arrsize = 0; if (var->varcharsize < 0) var->varcharsize = 0; - var->ind_type = va_arg(ap, enum ECPGttype); var->ind_pointer = va_arg(ap, char *); @@ -158,6 +157,13 @@ create_statement(int lineno, int compat, int force_indicator, struct connection var->ind_value = *((char **) (var->ind_pointer)); else var->ind_value = var->ind_pointer; + + /* negative values are used to indicate an array without given bounds */ + /* reset to zero for us */ + if (var->ind_arrsize < 0) + var->ind_arrsize = 0; + if (var->ind_varcharsize < 0) + var->ind_varcharsize = 0; for (ptr = *list; ptr && ptr->next; ptr = ptr->next); diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index a4aa18e50c..ad9bfba17c 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.244 2003/07/01 12:40:51 meskes Exp $ */ +/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.245 2003/07/08 12:11:32 meskes Exp $ */ /* Copyright comment */ %{ @@ -208,10 +208,18 @@ adjust_informix(struct arguments *list) /* change variable name to "ECPG_informix_get_var()" */ original_var = ptr->variable->name; sprintf(temp, "%d))", ecpg_informix_var); - ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0); /* create call to "ECPG_informix_set_var(, . )" */ - sprintf(temp, "%d, &(", ecpg_informix_var++); + if (atoi(ptr->variable->type->size) > 1) + { + ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0); + sprintf(temp, "%d, (", ecpg_informix_var++); + } + else + { + ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0); + sprintf(temp, "%d, &(", ecpg_informix_var++); + } result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n")); } diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index 58ef58af98..ee4bac5859 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -318,9 +318,13 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, { char *variable = (char *) mm_alloc(strlen(name) + ((prefix == NULL) ? 0 : strlen(prefix)) + 4); char *offset = (char *) mm_alloc(strlen(name) + strlen("sizeof(struct varchar_)") + 1); - + switch (type) { + /* + * we have to use the & operator except for arrays and pointers + */ + case ECPGt_varchar: /* @@ -342,7 +346,7 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, /* * we have to use the pointer except for arrays with given - * bounds + * bounds, ecpglib will distinguish between * and [] */ if ((atoi(varcharsize) > 1 || (atoi(arrsize) > 0) || diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc index 8e2160a0ec..f16eb0921e 100644 --- a/src/interfaces/ecpg/test/test2.pgc +++ b/src/interfaces/ecpg/test/test2.pgc @@ -65,6 +65,7 @@ exec sql end declare section; p=&personal; i=&ind_personal; + memset(i, 0, sizeof(ind_personal)); while (1) { strcpy(msg, "fetch"); exec sql fetch cur into :p:i, :married:ind_married, :children.integer:ind_children.smallint;