diff options
Diffstat (limited to 'src/interfaces/ecpg/ecpglib')
-rw-r--r-- | src/interfaces/ecpg/ecpglib/data.c | 49 | ||||
-rw-r--r-- | src/interfaces/ecpg/ecpglib/extern.h | 3 |
2 files changed, 49 insertions, 3 deletions
diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c index 871e2011f3e..bb2bef1afff 100644 --- a/src/interfaces/ecpg/ecpglib/data.c +++ b/src/interfaces/ecpg/ecpglib/data.c @@ -464,7 +464,45 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, if (varcharsize == 0 || varcharsize > size) { - strncpy(str, pval, size + 1); + /* compatibility mode, blank pad and null terminate char array */ + if (ORACLE_MODE(compat) && (type == ECPGt_char || type == ECPGt_unsigned_char)) + { + memset(str, ' ', varcharsize); + memcpy(str, pval, size); + str[varcharsize-1] = '\0'; + + /* compatiblity mode empty string gets -1 indicator but no warning */ + if (size == 0) { + /* truncation */ + 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; + #ifdef HAVE_LONG_LONG_INT + case ECPGt_long_long: + case ECPGt_unsigned_long_long: + *((long long int *) (ind + ind_offset * act_tuple)) = -1; + break; + #endif /* HAVE_LONG_LONG_INT */ + default: + break; + } + } + } + else + { + strncpy(str, pval, size + 1); + } /* do the rtrim() */ if (type == ECPGt_string) { @@ -481,7 +519,14 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno, { strncpy(str, pval, varcharsize); - if (varcharsize < size) + /* compatibility mode, null terminate char array */ + if (ORACLE_MODE(compat) && (varcharsize - 1) < size) + { + if (type == ECPGt_char || type == ECPGt_unsigned_char) + str[varcharsize-1] = '\0'; + } + + if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size)) { /* truncation */ switch (ind_type) diff --git a/src/interfaces/ecpg/ecpglib/extern.h b/src/interfaces/ecpg/ecpglib/extern.h index 91c7367b8b0..a88f34106cc 100644 --- a/src/interfaces/ecpg/ecpglib/extern.h +++ b/src/interfaces/ecpg/ecpglib/extern.h @@ -15,12 +15,13 @@ enum COMPAT_MODE { - ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE + ECPG_COMPAT_PGSQL = 0, ECPG_COMPAT_INFORMIX, ECPG_COMPAT_INFORMIX_SE, ECPG_COMPAT_ORACLE }; extern bool ecpg_internal_regression_mode; #define INFORMIX_MODE(X) ((X) == ECPG_COMPAT_INFORMIX || (X) == ECPG_COMPAT_INFORMIX_SE) +#define ORACLE_MODE(X) ((X) == ECPG_COMPAT_ORACLE) enum ARRAY_TYPE { |