diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index 5f9a3d4604f..3ec774ca6d0 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -455,6 +455,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, { char *str = (char *) (var + offset * act_tuple); + /* + * If varcharsize is unknown and the offset is that of + * char *, then this variable represents the array of + * character pointers. So, use extra indirection. + */ + if (varcharsize == 0 && offset == sizeof(char *)) + str = *(char **)str; + if (varcharsize == 0 || varcharsize > size) { strncpy(str, pval, size + 1); diff --git a/src/interfaces/ecpg/ecpglib/execute.c b/src/interfaces/ecpg/ecpglib/execute.c index 1a7876ecf2d..4acb345972c 100644 --- a/src/interfaces/ecpg/ecpglib/execute.c +++ b/src/interfaces/ecpg/ecpglib/execute.c @@ -1850,7 +1850,14 @@ ECPGdo(const int lineno, const int compat, const int force_indicator, const char var->arrsize = va_arg(args, long); var->offset = va_arg(args, long); - if (var->arrsize == 0 || var->varcharsize == 0) + /* + * Unknown array size means pointer to an array. + * Unknown varcharsize usually also means pointer. But if the + * type is character and the array size is known, it is an + * array of pointers to char, so use var->pointer as it is. + */ + if (var->arrsize == 0 || + (var->varcharsize == 0 && ((var->type != ECPGt_char && var->type != ECPGt_unsigned_char) || (var->arrsize <= 1)))) var->value = *((char **) (var->pointer)); else var->value = var->pointer; diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index 64e8361f1f4..9fb979febb0 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -410,7 +410,8 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, case ECPGt_unsigned_char: case ECPGt_char_variable: case ECPGt_string: - + { + char *sizeof_name = "char"; /* * we have to use the pointer except for arrays with given * bounds, ecpglib will distinguish between * and [] @@ -420,12 +421,24 @@ ECPGdump_a_simple(FILE *o, const char *name, enum ECPGttype type, (atoi(varcharsize) == 0 && strcmp(varcharsize, "0") != 0) || (atoi(arrsize) == 0 && strcmp(arrsize, "0") != 0)) && siz == NULL) + { sprintf(variable, "(%s%s)", prefix ? prefix : "", name); + if ((type == ECPGt_char || type == ECPGt_unsigned_char) && + strcmp(varcharsize, "0") == 0) + { + /* + * If this is an array of char *, the offset would be + * sizeof(char *) and not sizeof(char). + */ + sizeof_name = "char *"; + } + } else sprintf(variable, "&(%s%s)", prefix ? prefix : "", name); - sprintf(offset, "(%s)*sizeof(char)", strcmp(varcharsize, "0") == 0 ? "1" : varcharsize); + sprintf(offset, "(%s)*sizeof(%s)", strcmp(varcharsize, "0") == 0 ? "1" : varcharsize, sizeof_name); break; + } case ECPGt_numeric: /*