OSDN Git Service

More informix fixes.
authorMichael Meskes <meskes@postgresql.org>
Tue, 8 Jul 2003 12:11:35 +0000 (12:11 +0000)
committerMichael Meskes <meskes@postgresql.org>
Tue, 8 Jul 2003 12:11:35 +0000 (12:11 +0000)
src/interfaces/ecpg/ChangeLog
src/interfaces/ecpg/compatlib/informix.c
src/interfaces/ecpg/ecpglib/data.c
src/interfaces/ecpg/ecpglib/execute.c
src/interfaces/ecpg/preproc/preproc.y
src/interfaces/ecpg/preproc/type.c
src/interfaces/ecpg/test/test2.pgc

index 2b33f1f..c42a6b2 100644 (file)
@@ -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
index 157809d..9857043 100644 (file)
@@ -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;
        
index c9da137..011b5a6 100644 (file)
@@ -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
        {
index 255b904..0115362 100644 (file)
@@ -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);
 
index a4aa18e..ad9bfba 100644 (file)
@@ -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"));
         }
 
index 58ef58a..ee4bac5 100644 (file)
@@ -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) ||
index 8e2160a..f16eb09 100644 (file)
@@ -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;