From 1a321fea71db878755a4a2c00d45b98e10842a92 Mon Sep 17 00:00:00 2001 From: Michael Meskes Date: Wed, 11 Feb 2015 11:13:11 +0100 Subject: Fixed array handling in ecpg. 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. --- src/interfaces/ecpg/ecpglib/execute.c | 265 ++++++++++++++++------------------ 1 file changed, 121 insertions(+), 144 deletions(-) (limited to 'src/interfaces/ecpg/ecpglib/execute.c') diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 4acb345972c..9854a57ed3e 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -505,16 +505,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 @@ -572,12 +566,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)); @@ -610,12 +604,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)); @@ -629,12 +623,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)); @@ -648,12 +642,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)); @@ -667,12 +661,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)); @@ -686,12 +680,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)); @@ -705,12 +699,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)); @@ -724,12 +718,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), ""); @@ -743,12 +737,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), ""); @@ -757,27 +751,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 { @@ -853,63 +847,59 @@ 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++) - { - nval = PGTYPESnumeric_new(); - if (!nval) - return false; - - if (var->type == ECPGt_numeric) - PGTYPESnumeric_copy((numeric *) ((var + var->offset * element)->value), nval); - else - PGTYPESnumeric_from_decimal((decimal *) ((var + var->offset * element)->value), nval); - - 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) - PGTYPESnumeric_copy((numeric *) (var->value), nval); + result = PGTYPESnumeric_copy(&(((numeric *) (var->value))[element]), nval); else - 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; + } str = PGTYPESnumeric_to_asc(nval, nval->dscale); 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; @@ -920,47 +910,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; @@ -971,47 +957,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; @@ -1022,48 +1004,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) - 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; -- cgit v1.2.3