]> granicus.if.org Git - postgresql/commitdiff
Fixed array handling in ecpg.
authorMichael Meskes <meskes@postgresql.org>
Wed, 11 Feb 2015 09:45:46 +0000 (10:45 +0100)
committerMichael Meskes <meskes@postgresql.org>
Wed, 11 Feb 2015 09:57:02 +0000 (10:57 +0100)
When ecpg was rewritten to the new protocol version not all variable types
were corrected. This patch rewrites the code for these types to fix that. It
also fixes the documentation to correctly tell the status of array handling.

doc/src/sgml/ecpg.sgml
src/interfaces/ecpg/ecpglib/data.c
src/interfaces/ecpg/ecpglib/execute.c

index f9536ee1e49fefab605e022f290b6a22a8a5a48b..47857890e9c33340c206dcf2d36281440dabbdd8 100644 (file)
@@ -1377,10 +1377,13 @@ EXEC SQL END DECLARE SECTION;
     <title>Arrays</title>
 
     <para>
-     SQL-level arrays are not directly supported in ECPG.  It is not
-     possible to simply map an SQL array into a C array host variable.
-     This will result in undefined behavior.  Some workarounds exist,
-     however.
+     Multi-dimensional SQL-level arrays are not directly supported in ECPG.
+     One-dimensional SQL-level arrays can be mapped into C array host
+     variables and vice-versa.  However, when creating a statement ecpg does
+     not know the types of the columns, so that it cannot check if a C array
+     is input into a corresponding SQL-level array.  When processing the
+     output of a SQL statement, ecpg has the necessary information and thus
+     checks if both are arrays.
     </para>
 
     <para>
index 28b1be758afa19d040f99d62eda934b2fbaf16d4..2d0c1180a3c189effa278f89cb394a039e42d6b5 100644 (file)
@@ -291,6 +291,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        date            ddres;
                                        timestamp       tres;
                                        interval   *ires;
+                                       char *endptr, endchar;
 
                                case ECPGt_short:
                                case ECPGt_int:
@@ -564,10 +565,11 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 
                                case ECPGt_decimal:
                                case ECPGt_numeric:
-                                       if (isarray && *pval == '"')
-                                               nres = PGTYPESnumeric_from_asc(pval + 1, &scan_length);
-                                       else
-                                               nres = PGTYPESnumeric_from_asc(pval, &scan_length);
+                                       for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
+                                       endchar = *endptr;
+                                       *endptr = '\0';
+                                       nres = PGTYPESnumeric_from_asc(pval, &scan_length);
+                                       *endptr = endchar;
 
                                        /* did we get an error? */
                                        if (nres == NULL)
@@ -600,10 +602,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        }
                                        else
                                        {
-                                               if (isarray && *scan_length == '"')
-                                                       scan_length++;
-
-                                               if (garbage_left(isarray, scan_length, compat))
+                                               if (!isarray && garbage_left(isarray, scan_length, compat))
                                                {
                                                        free(nres);
                                                        ecpg_raise(lineno, ECPG_NUMERIC_FORMAT,
@@ -622,10 +621,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        break;
 
                                case ECPGt_interval:
-                                       if (isarray && *pval == '"')
-                                               ires = PGTYPESinterval_from_asc(pval + 1, &scan_length);
-                                       else
-                                               ires = PGTYPESinterval_from_asc(pval, &scan_length);
+                                       if (*pval == '"')
+                                               pval++;
+
+                                       for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
+                                       endchar = *endptr;
+                                       *endptr = '\0';
+                                       ires = PGTYPESinterval_from_asc(pval, &scan_length);
+                                       *endptr = endchar;
 
                                        /* did we get an error? */
                                        if (ires == NULL)
@@ -654,10 +657,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        }
                                        else
                                        {
-                                               if (isarray && *scan_length == '"')
+                                               if (*scan_length == '"')
                                                        scan_length++;
 
-                                               if (garbage_left(isarray, scan_length, compat))
+                                               if (!isarray && garbage_left(isarray, scan_length, compat))
                                                {
                                                        free(ires);
                                                        ecpg_raise(lineno, ECPG_INTERVAL_FORMAT,
@@ -672,10 +675,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        break;
 
                                case ECPGt_date:
-                                       if (isarray && *pval == '"')
-                                               ddres = PGTYPESdate_from_asc(pval + 1, &scan_length);
-                                       else
-                                               ddres = PGTYPESdate_from_asc(pval, &scan_length);
+                                       if (*pval == '"')
+                                               pval++;
+
+                                       for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
+                                       endchar = *endptr;
+                                       *endptr = '\0';
+                                       ddres = PGTYPESdate_from_asc(pval, &scan_length);
+                                       *endptr = endchar;
 
                                        /* did we get an error? */
                                        if (errno != 0)
@@ -700,10 +707,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        }
                                        else
                                        {
-                                               if (isarray && *scan_length == '"')
+                                               if (*scan_length == '"')
                                                        scan_length++;
 
-                                               if (garbage_left(isarray, scan_length, compat))
+                                               if (!isarray && garbage_left(isarray, scan_length, compat))
                                                {
                                                        ecpg_raise(lineno, ECPG_DATE_FORMAT,
                                                                           ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@@ -716,10 +723,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        break;
 
                                case ECPGt_timestamp:
-                                       if (isarray && *pval == '"')
-                                               tres = PGTYPEStimestamp_from_asc(pval + 1, &scan_length);
-                                       else
-                                               tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
+                                       if (*pval == '"')
+                                               pval++;
+
+                                       for (endptr = pval; *endptr && *endptr != ',' && *endptr != '"' && *endptr != '}'; endptr++);
+                                       endchar = *endptr;
+                                       *endptr = '\0';
+                                       tres = PGTYPEStimestamp_from_asc(pval, &scan_length);
+                                       *endptr = endchar;
 
                                        /* did we get an error? */
                                        if (errno != 0)
@@ -744,10 +755,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
                                        }
                                        else
                                        {
-                                               if (isarray && *scan_length == '"')
+                                               if (*scan_length == '"')
                                                        scan_length++;
 
-                                               if (garbage_left(isarray, scan_length, compat))
+                                               if (!isarray && garbage_left(isarray, scan_length, compat))
                                                {
                                                        ecpg_raise(lineno, ECPG_TIMESTAMP_FORMAT,
                                                                           ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
index a4c7151f9a3a3731dd40f06c72675a2c9a94f134..c5f1c16510551ef364300beee8cac2dff0981fc4 100644 (file)
@@ -501,16 +501,10 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
        char       *newcopy = NULL;
 
        /*
-        * arrays are not possible unless the attribute is an array too FIXME: we
-        * do not know if the attribute is an array here
+        * arrays are not possible unless the column is an array, too
+        * FIXME: we do not know if the column is an array here
+        * array input to singleton column will result in a runtime error
         */
-#if 0
-       if (var->arrsize > 1 &&...)
-       {
-               ecpg_raise(lineno, ECPG_ARRAY_INSERT, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
-               return false;
-       }
-#endif
 
        /*
         * Some special treatment is needed for records since we want their
@@ -568,12 +562,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%hd", *((short *) var->value));
@@ -606,12 +600,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%hu", *((unsigned short *) var->value));
@@ -625,12 +619,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%u", *((unsigned int *) var->value));
@@ -644,12 +638,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%ld", *((long *) var->value));
@@ -663,12 +657,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%lu", *((unsigned long *) var->value));
@@ -682,12 +676,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%lld", *((long long int *) var->value));
@@ -701,12 +695,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf(mallocedval, "%llu", *((unsigned long long int *) var->value));
@@ -720,12 +714,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf_float_value(mallocedval + strlen(mallocedval), ((float *) var->value)[element], ",");
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf_float_value(mallocedval, *((float *) var->value), "");
@@ -739,12 +733,12 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
 
                                if (asize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        for (element = 0; element < asize; element++)
                                                sprintf_double_value(mallocedval + strlen(mallocedval), ((double *) var->value)[element], ",");
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                        sprintf_double_value(mallocedval, *((double *) var->value), "");
@@ -753,27 +747,27 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                break;
 
                        case ECPGt_bool:
-                               if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("array []"), lineno)))
+                               if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("{}"), lineno)))
                                        return false;
 
                                if (var->arrsize > 1)
                                {
-                                       strcpy(mallocedval, "array [");
+                                       strcpy(mallocedval, "{");
 
                                        if (var->offset == sizeof(char))
-                                               for (element = 0; element < var->arrsize; element++)
+                                               for (element = 0; element < asize; element++)
                                                        sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
 
                                        /*
                                         * this is necessary since sizeof(C++'s bool)==sizeof(int)
                                         */
                                        else if (var->offset == sizeof(int))
-                                               for (element = 0; element < var->arrsize; element++)
+                                               for (element = 0; element < asize; element++)
                                                        sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
                                        else
                                                ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
 
-                                       strcpy(mallocedval + strlen(mallocedval) - 1, "]");
+                                       strcpy(mallocedval + strlen(mallocedval) - 1, "}");
                                }
                                else
                                {
@@ -849,61 +843,33 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                        numeric    *nval;
 
                                        if (var->arrsize > 1)
-                                       {
-                                               if (!(mallocedval = ecpg_strdup("array [", lineno)))
-                                                       return false;
-
-                                               for (element = 0; element < var->arrsize; element++)
-                                               {
-                                                       int                     result;
-
-                                                       nval = PGTYPESnumeric_new();
-                                                       if (!nval)
-                                                               return false;
-
-                                                       if (var->type == ECPGt_numeric)
-                                                               result = PGTYPESnumeric_copy((numeric *) ((var + var->offset * element)->value), nval);
-                                                       else
-                                                               result = PGTYPESnumeric_from_decimal((decimal *) ((var + var->offset * element)->value), nval);
-
-                                                       if (result != 0)
-                                                       {
-                                                               PGTYPESnumeric_free(nval);
-                                                               return false;
-                                                       }
-
-                                                       str = PGTYPESnumeric_to_asc(nval, nval->dscale);
-                                                       slen = strlen(str);
-                                                       PGTYPESnumeric_free(nval);
+                                               mallocedval = ecpg_strdup("{", lineno);
+                                       else
+                                               mallocedval = ecpg_strdup("", lineno);
 
-                                                       if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
-                                                       {
-                                                               ecpg_free(str);
-                                                               return false;
-                                                       }
+                                       if (!mallocedval)
+                                                       return false;
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
-                                                       strcpy(mallocedval + strlen(mallocedval), ",");
-                                                       ecpg_free(str);
-                                               }
-                                               strcpy(mallocedval + strlen(mallocedval) - 1, "]");
-                                       }
-                                       else
+                                       for (element = 0; element < asize; element++)
                                        {
                                                int                     result;
 
                                                nval = PGTYPESnumeric_new();
                                                if (!nval)
+                                               {
+                                                       ecpg_free(mallocedval);
                                                        return false;
+                                               }
 
                                                if (var->type == ECPGt_numeric)
-                                                       result = PGTYPESnumeric_copy((numeric *) (var->value), nval);
+                                                       result = PGTYPESnumeric_copy(&(((numeric *) (var->value))[element]), nval);
                                                else
-                                                       result = PGTYPESnumeric_from_decimal((decimal *) (var->value), nval);
+                                                       result = PGTYPESnumeric_from_decimal(&(((decimal *) (var->value))[element]), nval);
 
                                                if (result != 0)
                                                {
                                                        PGTYPESnumeric_free(nval);
+                                                       ecpg_free(mallocedval);
                                                        return false;
                                                }
 
@@ -911,17 +877,25 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                                slen = strlen(str);
                                                PGTYPESnumeric_free(nval);
 
-                                               if (!(mallocedval = ecpg_alloc(slen + 1, lineno)))
+                                               if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                                                {
-                                                       free(str);
+                                                       ecpg_free(mallocedval);
+                                                       ecpg_free(str);
                                                        return false;
                                                }
+                                               mallocedval = newcopy;
+
+                                               /* also copy trailing '\0' */
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               if (var->arrsize > 1)
+                                                       strcpy(mallocedval + strlen(mallocedval), ",");
 
-                                               strncpy(mallocedval, str, slen);
-                                               mallocedval[slen] = '\0';
                                                ecpg_free(str);
                                        }
 
+                                       if (var->arrsize > 1)
+                                               strcpy(mallocedval + strlen(mallocedval) - 1, "}");
+
                                        *tobeinserted_p = mallocedval;
                                }
                                break;
@@ -932,47 +906,43 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                        int                     slen;
 
                                        if (var->arrsize > 1)
-                                       {
-                                               if (!(mallocedval = ecpg_strdup("array [", lineno)))
-                                                       return false;
-
-                                               for (element = 0; element < var->arrsize; element++)
-                                               {
-                                                       str = quote_postgres(PGTYPESinterval_to_asc((interval *) ((var + var->offset * element)->value)), quote, lineno);
-                                                       if (!str)
-                                                               return false;
-                                                       slen = strlen(str);
+                                               mallocedval = ecpg_strdup("{", lineno);
+                                       else
+                                               mallocedval = ecpg_strdup("", lineno);
 
-                                                       if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
-                                                       {
-                                                               ecpg_free(str);
-                                                               return false;
-                                                       }
+                                       if (!mallocedval)
+                                                       return false;
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
-                                                       strcpy(mallocedval + strlen(mallocedval), ",");
-                                                       ecpg_free(str);
-                                               }
-                                               strcpy(mallocedval + strlen(mallocedval) - 1, "]");
-                                       }
-                                       else
+                                       for (element = 0; element < asize; element++)
                                        {
-                                               str = quote_postgres(PGTYPESinterval_to_asc((interval *) (var->value)), quote, lineno);
+                                               str = quote_postgres(PGTYPESinterval_to_asc(&(((interval *) (var->value))[element])), quote, lineno);
                                                if (!str)
+                                               {
+                                                       ecpg_free(mallocedval);
                                                        return false;
+                                               }
+
                                                slen = strlen(str);
 
-                                               if (!(mallocedval = ecpg_alloc(slen + sizeof("interval ") + 1, lineno)))
+                                               if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                                                {
+                                                       ecpg_free(mallocedval);
                                                        ecpg_free(str);
                                                        return false;
                                                }
+                                               mallocedval = newcopy;
 
                                                /* also copy trailing '\0' */
-                                               strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               if (var->arrsize > 1)
+                                                       strcpy(mallocedval + strlen(mallocedval), ",");
+
                                                ecpg_free(str);
                                        }
 
+                                       if (var->arrsize > 1)
+                                               strcpy(mallocedval + strlen(mallocedval) - 1, "}");
+
                                        *tobeinserted_p = mallocedval;
                                }
                                break;
@@ -983,47 +953,43 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                        int                     slen;
 
                                        if (var->arrsize > 1)
-                                       {
-                                               if (!(mallocedval = ecpg_strdup("array [", lineno)))
-                                                       return false;
-
-                                               for (element = 0; element < var->arrsize; element++)
-                                               {
-                                                       str = quote_postgres(PGTYPESdate_to_asc(*(date *) ((var + var->offset * element)->value)), quote, lineno);
-                                                       if (!str)
-                                                               return false;
-                                                       slen = strlen(str);
+                                               mallocedval = ecpg_strdup("{", lineno);
+                                       else
+                                               mallocedval = ecpg_strdup("", lineno);
 
-                                                       if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
-                                                       {
-                                                               ecpg_free(str);
-                                                               return false;
-                                                       }
+                                       if (!mallocedval)
+                                                       return false;
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
-                                                       strcpy(mallocedval + strlen(mallocedval), ",");
-                                                       ecpg_free(str);
-                                               }
-                                               strcpy(mallocedval + strlen(mallocedval) - 1, "]");
-                                       }
-                                       else
+                                       for (element = 0; element < asize; element++)
                                        {
-                                               str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), quote, lineno);
+                                               str = quote_postgres(PGTYPESdate_to_asc(((date *) (var->value))[element]), quote, lineno);
                                                if (!str)
+                                               {
+                                                       ecpg_free(mallocedval);
                                                        return false;
+                                               }
+
                                                slen = strlen(str);
 
-                                               if (!(mallocedval = ecpg_alloc(slen + sizeof("date ") + 1, lineno)))
+                                               if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                                                {
+                                                       ecpg_free(mallocedval);
                                                        ecpg_free(str);
                                                        return false;
                                                }
+                                               mallocedval = newcopy;
 
                                                /* also copy trailing '\0' */
-                                               strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               if (var->arrsize > 1)
+                                                       strcpy(mallocedval + strlen(mallocedval), ",");
+
                                                ecpg_free(str);
                                        }
 
+                                       if (var->arrsize > 1)
+                                               strcpy(mallocedval + strlen(mallocedval) - 1, "}");
+
                                        *tobeinserted_p = mallocedval;
                                }
                                break;
@@ -1034,51 +1000,43 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
                                        int                     slen;
 
                                        if (var->arrsize > 1)
-                                       {
-                                               if (!(mallocedval = ecpg_strdup("array [", lineno)))
-                                                       return false;
-
-                                               for (element = 0; element < var->arrsize; element++)
-                                               {
-                                                       str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) ((var + var->offset * element)->value)), quote, lineno);
-                                                       if (!str)
-                                                       {
-                                                               ecpg_free(mallocedval);
-                                                               return false;
-                                                       }
-
-                                                       slen = strlen(str);
+                                               mallocedval = ecpg_strdup("{", lineno);
+                                       else
+                                               mallocedval = ecpg_strdup("", lineno);
 
-                                                       if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
-                                                       {
-                                                               ecpg_free(str);
-                                                               return false;
-                                                       }
+                                       if (!mallocedval)
+                                                       return false;
 
-                                                       strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
-                                                       strcpy(mallocedval + strlen(mallocedval), ",");
-                                                       ecpg_free(str);
-                                               }
-                                               strcpy(mallocedval + strlen(mallocedval) - 1, "]");
-                                       }
-                                       else
+                                       for (element = 0; element < asize; element++)
                                        {
-                                               str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), quote, lineno);
+                                               str = quote_postgres(PGTYPEStimestamp_to_asc(((timestamp *) (var->value))[element]), quote, lineno);
                                                if (!str)
+                                               {
+                                                       ecpg_free(mallocedval);
                                                        return false;
+                                               }
+
                                                slen = strlen(str);
 
-                                               if (!(mallocedval = ecpg_alloc(slen + sizeof("timestamp") + 1, lineno)))
+                                               if (!(newcopy = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
                                                {
+                                                       ecpg_free(mallocedval);
                                                        ecpg_free(str);
                                                        return false;
                                                }
+                                               mallocedval = newcopy;
 
                                                /* also copy trailing '\0' */
-                                               strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               memcpy(mallocedval + strlen(mallocedval), str, slen + 1);
+                                               if (var->arrsize > 1)
+                                                       strcpy(mallocedval + strlen(mallocedval), ",");
+
                                                ecpg_free(str);
                                        }
 
+                                       if (var->arrsize > 1)
+                                               strcpy(mallocedval + strlen(mallocedval) - 1, "}");
+
                                        *tobeinserted_p = mallocedval;
                                }
                                break;