Hi, 
Currently our customer uses PostgreSQL 9.6 and hits ECPG's bug during using 
numeric data type by SQLDA. 
I confirmed that this problem is occurred on master and 9.6 latest branch. 

PROBLEM
---------------------------------------
When the integer part of numeric data type is "0", cancellation of significant 
digits is occurred. 
For example, I expect "0.12345", but I got "0.12340". When I expect "0.01234", 
I got "0.01200"
I attached the sample application code to reproduce this problem. 

CAUSE
---------------------------------------
When copy the data of numeric data, the size is wrong. 
"src/interfaces/ecpg/ecpglib/sqlda.c" has problem. 

ecpg_set_native_sqlda(int lineno, struct sqlda_struct ** _sqlda, const PGresult 
*res, int row, enum COMPAT_MODE compat)
{
...
    if (num->ndigits)
    {
        ecpg_sqlda_align_add_size(next_offset, sizeof(int), num->ndigits + 1, 
&offset, &next_offset);
        memcpy((char *) sqlda + offset, num->buf, num->ndigits + 1);

        ((numeric *) sqlda->sqlvar[i].sqldata)->buf = (NumericDigit *) sqlda + 
offset;
        ((numeric *) sqlda->sqlvar[i].sqldata)->digits = (NumericDigit *) sqlda 
+ offset + (num->digits - num->buf);
    }
...

When numeric data is "0.12345", num->buf has "0 0 1 2 3 4 5" and num->digits 
has "1 2 3 4 5". 
num->ndigits has the number of digits which is or later "1", it means 5.

In this code, currently copy "num->ndigits + 1" as size of numeric data. 
As a result, (char *) sqlda + offset has "0 0 1 2 3 4", not "0 0 1 2 3 4 5". 
So, "num->digits - num->buf + num->ndigits" should be copied. 

FIX
---------------------------------------
Above source code should be fixed and other similar bugs are fixed too.
I attached patches for bug fix and regression test for master branch. 
I hope this bug fix will be backport to other versions. 

Regards, 
Daisuke Higuchi

Attachment: 001_ecpg_numeric_bugfix_v1.patch
Description: 001_ecpg_numeric_bugfix_v1.patch

Attachment: numeric_sample_test.pgc
Description: numeric_sample_test.pgc

Attachment: 002_ecpg_numeric_test_v1.patch
Description: 002_ecpg_numeric_test_v1.patch

Reply via email to