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
#include <ecpg_informix.h>
#include <pgtypes_error.h>
#include <pgtypes_date.h>
+#include <sqltypes.h>
char * ECPGalloc(long, int);
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
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;
-/* $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"
{
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);
/* 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
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
{
-/* $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.
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 *);
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);
-/* $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 */
%{
/* 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"));
}
{
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:
/*
/*
* 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) ||
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;