BUG #17128: minimum numeric 'integer' is -2147483647 not -2147483648 as documented

Started by PG Bug reporting formover 4 years ago6 messagesbugs
Jump to latest
#1PG Bug reporting form
noreply@postgresql.org

The following bug has been logged on the website:

Bug reference: 17128
Logged by: Kevin Sweet
Email address: kjs@teews.com
PostgreSQL version: 13.2
Operating system: RHEL6, RHEL7, Solaris11
Description:

I submitted a similar report to the documentation mailing list so you can
decide whether to update the documentation or the code.
The PGTYPESnumeric_to_int function deems -2147483648 to be invalid even
though it is a perfectly valid 32-bit integer because the code compares to
-INT_MAX which resolves to -2147483647 on the Fedora/Red Hat and Solaris
versions I have available to check against.

diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml
index 7266e229a4..0e89f23c73 100644
--- a/doc/src/sgml/ecpg.sgml
+++ b/doc/src/sgml/ecpg.sgml
@@ -8666,7 +8666,7 @@ int dectoint(decimal *np, int *ip);
         Note that the ECPG implementation differs from the
<productname>Informix</productname>
         implementation. <productname>Informix</productname> limits an
integer to the range from -32767 to
         32767, while the limits in the ECPG implementation depend on the
-        architecture (<literal>-INT_MAX .. INT_MAX</literal>).
+        architecture (<literal>(-INT_MAX - 1) .. INT_MAX</literal>).
        </para>
       </listitem>
      </varlistentry>
diff --git a/src/interfaces/ecpg/pgtypeslib/numeric.c
b/src/interfaces/ecpg/pgtypeslib/numeric.c
index 060fad7867..4e6c9910dc 100644
--- a/src/interfaces/ecpg/pgtypeslib/numeric.c
+++ b/src/interfaces/ecpg/pgtypeslib/numeric.c
@@ -1505,7 +1505,7 @@ PGTYPESnumeric_to_int(numeric *nv, int *ip)
    if ((i = PGTYPESnumeric_to_long(nv, &l)) != 0)
        return i;
-   if (l < -INT_MAX || l > INT_MAX)
+   if (l < (-INT_MAX - 1) || l > INT_MAX)
    {
        errno = PGTYPES_NUM_OVERFLOW;
        return -1;
#2John Naylor
john.naylor@enterprisedb.com
In reply to: PG Bug reporting form (#1)
Re: BUG #17128: minimum numeric 'integer' is -2147483647 not -2147483648 as documented

On Fri, Jul 30, 2021 at 7:53 AM PG Bug reporting form <
noreply@postgresql.org> wrote:

The PGTYPESnumeric_to_int function deems -2147483648 to be invalid even
though it is a perfectly valid 32-bit integer because the code compares to
-INT_MAX which resolves to -2147483647 on the Fedora/Red Hat and Solaris
versions I have available to check against.

-   if (l < -INT_MAX || l > INT_MAX)
+   if (l < (-INT_MAX - 1) || l > INT_MAX)

Yeah, that looks like it should be INT_MIN instead. I'll see about making
that happen. Thanks for the report!

--
John Naylor
EDB: http://www.enterprisedb.com

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: John Naylor (#2)
Re: BUG #17128: minimum numeric 'integer' is -2147483647 not -2147483648 as documented

John Naylor <john.naylor@enterprisedb.com> writes:

On Fri, Jul 30, 2021 at 7:53 AM PG Bug reporting form <
noreply@postgresql.org> wrote:

-   if (l < -INT_MAX || l > INT_MAX)
+   if (l < (-INT_MAX - 1) || l > INT_MAX)

Yeah, that looks like it should be INT_MIN instead. I'll see about making
that happen. Thanks for the report!

The whole stanza perhaps ought to be within

#if SIZEOF_LONG > SIZEOF_INT

otherwise some compilers will bleat about useless tests.

(I looked at PGTYPESnumeric_to_long and it seems like it will do
the right thing for 32-bit long, assuming strtol does.)

regards, tom lane

#4John Naylor
john.naylor@enterprisedb.com
In reply to: Tom Lane (#3)
Re: BUG #17128: minimum numeric 'integer' is -2147483647 not -2147483648 as documented

On Fri, Jul 30, 2021 at 11:14 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:

John Naylor <john.naylor@enterprisedb.com> writes:

On Fri, Jul 30, 2021 at 7:53 AM PG Bug reporting form <
noreply@postgresql.org> wrote:

-   if (l < -INT_MAX || l > INT_MAX)
+   if (l < (-INT_MAX - 1) || l > INT_MAX)

Yeah, that looks like it should be INT_MIN instead. I'll see about

making

that happen. Thanks for the report!

The whole stanza perhaps ought to be within

#if SIZEOF_LONG > SIZEOF_INT

otherwise some compilers will bleat about useless tests.

Here's a draft fix for master, with regression tests. It will need a bit of
massaging for the back branches -- the problem goes back at least to 9.6.

--
John Naylor
EDB: http://www.enterprisedb.com

Attachments:

v1-0001-Fix-range-check-in-ECPG-numeric-to-int-conversion.patchapplication/x-patch; name=v1-0001-Fix-range-check-in-ECPG-numeric-to-int-conversion.patchDownload+38-10
#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: John Naylor (#4)
Re: BUG #17128: minimum numeric 'integer' is -2147483647 not -2147483648 as documented

John Naylor <john.naylor@enterprisedb.com> writes:

Here's a draft fix for master, with regression tests.

Passes an eyeball check, though I didn't run the test.

It will need a bit of
massaging for the back branches -- the problem goes back at least to 9.6.

I'm sure it's quite ancient ... ecpg hasn't changed much in a Long Time.

regards, tom lane

#6John Naylor
john.naylor@enterprisedb.com
In reply to: Tom Lane (#5)
Re: BUG #17128: minimum numeric 'integer' is -2147483647 not -2147483648 as documented

On Fri, Jul 30, 2021 at 3:22 PM Tom Lane <tgl@sss.pgh.pa.us> wrote:

John Naylor <john.naylor@enterprisedb.com> writes:

Here's a draft fix for master, with regression tests.

Passes an eyeball check, though I didn't run the test.

Pushed, thanks for looking! I'll keep an eye on the build farm.

--
John Naylor
EDB: http://www.enterprisedb.com