More informix fixes.
authorMichael Meskes
Tue, 8 Jul 2003 12:11:35 +0000 (12:11 +0000)
committerMichael Meskes
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 2b33f1f487d421d6b22afb8290d0652cdea12307..c42a6b2599f241aa405ed699b160124347c21888 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 157809de22f87e690c1c6cffdf015e09c4f44027..985704393c9e27ccd9621e1c9fd29f6674fe87d3 100644 (file)
@@ -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;
    
index c9da13794df65a16c4121e1fe3f2dfc17fc0a9b3..011b5a6b29d3cf13030a85199bbe2c29d2f4e5cb 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 255b9040339853ea5e3477275493600a1b492404..0115362a0fff40d7504de5dc8772b6d8c7e3fda2 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 a4aa18e50cebec1c7d2e1745549b7998d2df423b..ad9bfba17c93f884d09dd991761a09393049b52f 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()" */
        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"));
     }
 
index 58ef58af985ce75ff3da6d5009589d94f6b355ee..ee4bac58598ad1af4061eaf413c4b2929f4653bd 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 8e2160a0ec8ef60c42068e6bcc24e5a1209867b5..f16eb0921eeddb7102a9de984ad31786de6dd2cf 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;