diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 2b33f1f487d421d6b22afb8290d0652cdea12307..c42a6b2599f241aa405ed699b160124347c21888 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 157809de22f87e690c1c6cffdf015e09c4f44027..985704393c9e27ccd9621e1c9fd29f6674fe87d3 100644 --- a/src/interfaces/ecpg/compatlib/informix.c +++ b/src/interfaces/ecpg/compatlib/informix.c @@ -8,6 +8,7 @@ #include <ecpg_informix.h> #include <pgtypes_error.h> #include <pgtypes_date.h> +#include <sqltypes.h> 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 c9da13794df65a16c4121e1fe3f2dfc17fc0a9b3..011b5a6b29d3cf13030a85199bbe2c29d2f4e5cb 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,15 +93,16 @@ 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; - } + } + break; + default: + ECPGraise(lineno, ECPG_UNSUPPORTED, ECPGtype_name(ind_type)); + return (false); + break; + } + if (value_for_indicator == -1) return (true); - } do { diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 255b9040339853ea5e3477275493600a1b492404..0115362a0fff40d7504de5dc8772b6d8c7e3fda2 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 a4aa18e50cebec1c7d2e1745549b7998d2df423b..ad9bfba17c93f884d09dd991761a09393049b52f 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(<counter>)" */ 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(<counter>, <pointer>. <linen number>)" */ - 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 58ef58af985ce75ff3da6d5009589d94f6b355ee..ee4bac58598ad1af4061eaf413c4b2929f4653bd 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 8e2160a0ec8ef60c42068e6bcc24e5a1209867b5..f16eb0921eeddb7102a9de984ad31786de6dd2cf 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;