Re: BUG #14986: -2147483648 is minimum value of integer but-2147483648::integer fails (out of range). - Mailing list pgsql-bugs

From Greg Stark
Subject Re: BUG #14986: -2147483648 is minimum value of integer but-2147483648::integer fails (out of range).
Date
Msg-id CAM-w4HNudmE0OReuV7YCAkO2=0rgxNGC_43G-R8oKXRnJTUNKw@mail.gmail.com
Whole thread Raw
In response to Re: BUG #14986: -2147483648 is minimum value of integer but-2147483648::integer fails (out of range).  (Magnus Hagander <magnus@hagander.net>)
Responses Re: BUG #14986: -2147483648 is minimum value of integer but-2147483648::integer fails (out of range).  (Andres Freund <andres@anarazel.de>)
Re: BUG #14986: -2147483648 is minimum value of integer but-2147483648::integer fails (out of range).  (Alvaro Herrera <alvherre@alvh.no-ip.org>)
List pgsql-bugs
On 20 December 2017 at 12:25, Magnus Hagander <magnus@hagander.net> wrote:
> In the first query, you are casting  2147483648 to integer, and then
> applying the minus. So it overflows the positive integer.  You need () around
> it:
>
> postgres=# select (-2147483648)::integer;
>     int4
> -------------
>  -2147483648
> (1 row)

Note that -2147483648 is already an integer constant so the ::integer
doesn't actually do anything here. It gets removed during query
preparation (parse analysis? Not sure). It doesn't appear in the final
plan at all.

But even if you do arrange for the cast to be called (as it is in the
original query) it happens during constant folding preparing the plan
(again parse analysis?):

=# explain select '-2147483648'::bigint::integer;
LOG:  00000: plan:
DETAIL:     {PLANNEDSTMT
...
      :targetlist (
         {TARGETENTRY
         :expr
            {CONST
            :consttype 23


You can see this by running EXPLAIN on the original query. It
overflows even though the query is never run:

=# explain select -2147483648::integer;
ERROR:  22003: integer out of range
LOCATION:  int84, int8.c:1298
Time: 0.393 ms

The LOCATION line even gives a hint what's going on. 2147483648 was
read as an int8 constant and the - operator returned an int8 and then
the cast (being run during explain as part of preparing the plan)
overflowed.

I wonder why the "out of range" error doesn't print the actual value
it's trying to cast. That would help the user here...

-- 
greg


pgsql-bugs by date:

Previous
From: PG Bug reporting form
Date:
Subject: BUG #14988: application server couldnot contacted
Next
From: Andres Freund
Date:
Subject: Re: BUG #14986: -2147483648 is minimum value of integer but-2147483648::integer fails (out of range).