Hello, we encountered unexpected behavior from an ECPG program
complied with the -C ORACLE option. The program executes the
following query:
SELECT 123::numeric(3,0), 't'::char(2)";
Compilation and execution steps:
$ ecpg -C ORACLE ecpgtest.pgc (attached)
$ gcc -g -o ecpgtest ecpgtest.c -L `pg_config --libdir` -I `pg_config --includedir` -lecpg -lpgtypes
$ ./ecpgtest
type: numeric : data: "120"
type: bpchar : data: "t"
The expected numeric value is "123".
The code below is the direct cause of the unanticipated data
modification.
interfaces/ecpg/ecpglib/data.c:581 (whitespaces are swueezed)
> if (varcharsize == 0 || varcharsize > size)
> {
> /*
> * 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';
This results in overwriting str[-1], the last byte of the preceding
numeric in this case, with 0x00, representing the digit '0'. When
callers of ecpg_get_data() explicitly pass zero as varcharsize, they
provide storage that precisely fitting the data. However, it remains
uncertain if this assumption is valid when ecpg_store_result() passes
var->varcharsize which is also zero. Consequently, the current fix
presumes exact-fit storage when varcharsize is zero.
I haven't fully checked, but at least back to 10 have this issue.
Thoughts?
regards.
--
Kyotaro Horiguchi
NTT Open Source Software Center