1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-17 06:41:24 +03:00

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.
This commit is contained in:
Michael Meskes 2015-02-11 11:13:11 +01:00
parent a4e871caad
commit 1a321fea71
3 changed files with 174 additions and 183 deletions

View File

@ -1375,10 +1375,13 @@ EXEC SQL END DECLARE SECTION;
<title>Arrays</title> <title>Arrays</title>
<para> <para>
SQL-level arrays are not directly supported in ECPG. It is not Multi-dimensional SQL-level arrays are not directly supported in ECPG.
possible to simply map an SQL array into a C array host variable. One-dimensional SQL-level arrays can be mapped into C array host
This will result in undefined behavior. Some workarounds exist, variables and vice-versa. However, when creating a statement ecpg does
however. 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>
<para> <para>

View File

@ -291,6 +291,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
date ddres; date ddres;
timestamp tres; timestamp tres;
interval *ires; interval *ires;
char *endptr, endchar;
case ECPGt_short: case ECPGt_short:
case ECPGt_int: 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_decimal:
case ECPGt_numeric: case ECPGt_numeric:
if (isarray && *pval == '"') for (endptr = pval; *endptr && *endptr != ',' && *endptr != '}'; endptr++);
nres = PGTYPESnumeric_from_asc(pval + 1, &scan_length); endchar = *endptr;
else *endptr = '\0';
nres = PGTYPESnumeric_from_asc(pval, &scan_length); nres = PGTYPESnumeric_from_asc(pval, &scan_length);
*endptr = endchar;
/* did we get an error? */ /* did we get an error? */
if (nres == NULL) if (nres == NULL)
@ -600,10 +602,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
} }
else else
{ {
if (isarray && *scan_length == '"') if (!isarray && garbage_left(isarray, scan_length, compat))
scan_length++;
if (garbage_left(isarray, scan_length, compat))
{ {
free(nres); free(nres);
ecpg_raise(lineno, ECPG_NUMERIC_FORMAT, 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; break;
case ECPGt_interval: case ECPGt_interval:
if (isarray && *pval == '"') if (*pval == '"')
ires = PGTYPESinterval_from_asc(pval + 1, &scan_length); pval++;
else
ires = PGTYPESinterval_from_asc(pval, &scan_length); 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? */ /* did we get an error? */
if (ires == NULL) if (ires == NULL)
@ -654,10 +657,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
} }
else else
{ {
if (isarray && *scan_length == '"') if (*scan_length == '"')
scan_length++; scan_length++;
if (garbage_left(isarray, scan_length, compat)) if (!isarray && garbage_left(isarray, scan_length, compat))
{ {
free(ires); free(ires);
ecpg_raise(lineno, ECPG_INTERVAL_FORMAT, 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; break;
case ECPGt_date: case ECPGt_date:
if (isarray && *pval == '"') if (*pval == '"')
ddres = PGTYPESdate_from_asc(pval + 1, &scan_length); pval++;
else
ddres = PGTYPESdate_from_asc(pval, &scan_length); 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? */ /* did we get an error? */
if (errno != 0) if (errno != 0)
@ -700,10 +707,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
} }
else else
{ {
if (isarray && *scan_length == '"') if (*scan_length == '"')
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_raise(lineno, ECPG_DATE_FORMAT,
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);
@ -716,10 +723,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
break; break;
case ECPGt_timestamp: case ECPGt_timestamp:
if (isarray && *pval == '"') if (*pval == '"')
tres = PGTYPEStimestamp_from_asc(pval + 1, &scan_length); pval++;
else
tres = PGTYPEStimestamp_from_asc(pval, &scan_length); 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? */ /* did we get an error? */
if (errno != 0) if (errno != 0)
@ -744,10 +755,10 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
} }
else else
{ {
if (isarray && *scan_length == '"') if (*scan_length == '"')
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_raise(lineno, ECPG_TIMESTAMP_FORMAT,
ECPG_SQLSTATE_DATATYPE_MISMATCH, pval); ECPG_SQLSTATE_DATATYPE_MISMATCH, pval);

View File

@ -505,16 +505,10 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
char *newcopy = NULL; char *newcopy = NULL;
/* /*
* arrays are not possible unless the attribute is an array too FIXME: we * arrays are not possible unless the column is an array, too
* do not know if the attribute is an array here * 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 * 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%hd,", ((short *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%hd", *((short *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%hu,", ((unsigned short *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%hu", *((unsigned short *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%u,", ((unsigned int *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%u", *((unsigned int *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%ld,", ((long *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%ld", *((long *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%lu,", ((unsigned long *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%lu", *((unsigned long *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%lld,", ((long long int *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%lld", *((long long int *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]); sprintf(mallocedval + strlen(mallocedval), "%llu,", ((unsigned long long int *) var->value)[element]);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf(mallocedval, "%llu", *((unsigned long long int *) var->value)); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf_float_value(mallocedval + strlen(mallocedval), ((float *) var->value)[element], ","); sprintf_float_value(mallocedval + strlen(mallocedval), ((float *) var->value)[element], ",");
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf_float_value(mallocedval, *((float *) var->value), ""); 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) if (asize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
for (element = 0; element < asize; element++) for (element = 0; element < asize; element++)
sprintf_double_value(mallocedval + strlen(mallocedval), ((double *) var->value)[element], ","); sprintf_double_value(mallocedval + strlen(mallocedval), ((double *) var->value)[element], ",");
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
sprintf_double_value(mallocedval, *((double *) var->value), ""); 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; break;
case ECPGt_bool: case ECPGt_bool:
if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("array []"), lineno))) if (!(mallocedval = ecpg_alloc(var->arrsize + sizeof("{}"), lineno)))
return false; return false;
if (var->arrsize > 1) if (var->arrsize > 1)
{ {
strcpy(mallocedval, "array ["); strcpy(mallocedval, "{");
if (var->offset == sizeof(char)) 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'); sprintf(mallocedval + strlen(mallocedval), "%c,", (((char *) var->value)[element]) ? 't' : 'f');
/* /*
* this is necessary since sizeof(C++'s bool)==sizeof(int) * this is necessary since sizeof(C++'s bool)==sizeof(int)
*/ */
else if (var->offset == 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'); sprintf(mallocedval + strlen(mallocedval), "%c,", (((int *) var->value)[element]) ? 't' : 'f');
else else
ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL); ecpg_raise(lineno, ECPG_CONVERT_BOOL, ECPG_SQLSTATE_DATATYPE_MISMATCH, NULL);
strcpy(mallocedval + strlen(mallocedval) - 1, "]"); strcpy(mallocedval + strlen(mallocedval) - 1, "}");
} }
else else
{ {
@ -853,63 +847,59 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
numeric *nval; numeric *nval;
if (var->arrsize > 1) if (var->arrsize > 1)
{ mallocedval = ecpg_strdup("{", lineno);
if (!(mallocedval = ecpg_strdup("array [", lineno))) else
mallocedval = ecpg_strdup("", lineno);
if (!mallocedval)
return false; return false;
for (element = 0; element < var->arrsize; element++) for (element = 0; element < asize; 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);
if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
{
ecpg_free(str);
return false;
}
strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
strcpy(mallocedval + strlen(mallocedval), ",");
ecpg_free(str);
}
strcpy(mallocedval + strlen(mallocedval) - 1, "]");
}
else
{ {
int result;
nval = PGTYPESnumeric_new(); nval = PGTYPESnumeric_new();
if (!nval) if (!nval)
{
ecpg_free(mallocedval);
return false; return false;
}
if (var->type == ECPGt_numeric) if (var->type == ECPGt_numeric)
PGTYPESnumeric_copy((numeric *) (var->value), nval); result = PGTYPESnumeric_copy(&(((numeric *) (var->value))[element]), nval);
else 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); str = PGTYPESnumeric_to_asc(nval, nval->dscale);
slen = strlen(str); slen = strlen(str);
PGTYPESnumeric_free(nval); 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; 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); ecpg_free(str);
} }
if (var->arrsize > 1)
strcpy(mallocedval + strlen(mallocedval) - 1, "}");
*tobeinserted_p = mallocedval; *tobeinserted_p = mallocedval;
} }
break; break;
@ -920,47 +910,43 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
int slen; int slen;
if (var->arrsize > 1) if (var->arrsize > 1)
{ mallocedval = ecpg_strdup("{", lineno);
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);
if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
{
ecpg_free(str);
return false;
}
strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
strcpy(mallocedval + strlen(mallocedval), ",");
ecpg_free(str);
}
strcpy(mallocedval + strlen(mallocedval) - 1, "]");
}
else else
{ mallocedval = ecpg_strdup("", lineno);
str = quote_postgres(PGTYPESinterval_to_asc((interval *) (var->value)), quote, lineno);
if (!str) if (!mallocedval)
return false; return false;
for (element = 0; element < asize; element++)
{
str = quote_postgres(PGTYPESinterval_to_asc(&(((interval *) (var->value))[element])), quote, lineno);
if (!str)
{
ecpg_free(mallocedval);
return false;
}
slen = strlen(str); 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); ecpg_free(str);
return false; return false;
} }
mallocedval = newcopy;
/* also copy trailing '\0' */ /* 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); ecpg_free(str);
} }
if (var->arrsize > 1)
strcpy(mallocedval + strlen(mallocedval) - 1, "}");
*tobeinserted_p = mallocedval; *tobeinserted_p = mallocedval;
} }
break; break;
@ -971,47 +957,43 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
int slen; int slen;
if (var->arrsize > 1) if (var->arrsize > 1)
{ mallocedval = ecpg_strdup("{", lineno);
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);
if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
{
ecpg_free(str);
return false;
}
strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
strcpy(mallocedval + strlen(mallocedval), ",");
ecpg_free(str);
}
strcpy(mallocedval + strlen(mallocedval) - 1, "]");
}
else else
{ mallocedval = ecpg_strdup("", lineno);
str = quote_postgres(PGTYPESdate_to_asc(*(date *) (var->value)), quote, lineno);
if (!str) if (!mallocedval)
return false; return false;
for (element = 0; element < asize; element++)
{
str = quote_postgres(PGTYPESdate_to_asc(((date *) (var->value))[element]), quote, lineno);
if (!str)
{
ecpg_free(mallocedval);
return false;
}
slen = strlen(str); 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); ecpg_free(str);
return false; return false;
} }
mallocedval = newcopy;
/* also copy trailing '\0' */ /* 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); ecpg_free(str);
} }
if (var->arrsize > 1)
strcpy(mallocedval + strlen(mallocedval) - 1, "}");
*tobeinserted_p = mallocedval; *tobeinserted_p = mallocedval;
} }
break; break;
@ -1022,48 +1004,43 @@ ecpg_store_input(const int lineno, const bool force_indicator, const struct vari
int slen; int slen;
if (var->arrsize > 1) if (var->arrsize > 1)
{ mallocedval = ecpg_strdup("{", lineno);
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);
if (!(mallocedval = ecpg_realloc(mallocedval, strlen(mallocedval) + slen + 2, lineno)))
{
ecpg_free(str);
return false;
}
strncpy(mallocedval + strlen(mallocedval), str, slen + 1);
strcpy(mallocedval + strlen(mallocedval), ",");
ecpg_free(str);
}
strcpy(mallocedval + strlen(mallocedval) - 1, "]");
}
else else
{ mallocedval = ecpg_strdup("", lineno);
str = quote_postgres(PGTYPEStimestamp_to_asc(*(timestamp *) (var->value)), quote, lineno);
if (!str) if (!mallocedval)
return false; return false;
for (element = 0; element < asize; element++)
{
str = quote_postgres(PGTYPEStimestamp_to_asc(((timestamp *) (var->value))[element]), quote, lineno);
if (!str)
{
ecpg_free(mallocedval);
return false;
}
slen = strlen(str); 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); ecpg_free(str);
return false; return false;
} }
mallocedval = newcopy;
/* also copy trailing '\0' */ /* 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); ecpg_free(str);
} }
if (var->arrsize > 1)
strcpy(mallocedval + strlen(mallocedval) - 1, "}");
*tobeinserted_p = mallocedval; *tobeinserted_p = mallocedval;
} }
break; break;