Steve Atkins wrote:
> Section 8.1 of the manual gives the range of an integer
> as -2147483648 to +2147483647.
> template1=# select '-2147483648'::int;
> (1 row)
> template1=# select -2147483648::int;
> ERROR: integer out of range
> template1=# select version();
> PostgreSQL 7.4.1 on i686-pc-linux-gnu, compiled by GCC 2.96
> (1 row)
> Completely vanilla build - no options other than --prefix to
> configure. Clean installation, this is immediately after an initdb.
> I see the same bug on Solaris, built with Forte C in 64 bit mode.
Yep, it definately looks weird:
test=> select '-2147483648'::int;
test=> select -2147483648::int;
ERROR: integer out of range
test=> select -2147483647::int;
test=> select '-2147483649'::int;
ERROR: value "-2147483649" is out of range for type integer
The non-quoting works only for *47, and the quoting works for *48, but
both fail for *49.
I looked at libc's strtol(), and that works fine, as does our existing
parser checks. The error is coming from int84, a comparison function
called from the executor. Here is a test program:
int main(int argc, char *argv)
long long l = -2147483648;
int i = l;
if (i != l)
A compile generates the following warning:
tst1.c:6: warning: decimal constant is so large that it is unsigned
and reports "not equal".
I see in the freebsd machine/limits.h file:
* According to ANSI (section 220.127.116.11), the values below must be usable by
* #if preprocessing directives. Additionally, the expression must have the
* same type as would an expression that is an object of the corresponding
* type converted according to the integral promotions. The subtraction for
* INT_MIN, etc., is so the value is not unsigned; e.g., 0x80000000 is an
* unsigned int for 32-bit two's complement ANSI compilers (section 18.104.22.168).
* These numbers are for the default configuration of gcc. They work for
* some other compilers as well, but this should not be depended on.
#define INT_MAX 0x7fffffff /* max value for an int */
#define INT_MIN (-0x7fffffff - 1) /* min value for an int */
Basically, what is happening is that the special value -INT_MAX-1 is
being converted to an int value, and the compiler is casting it to an
unsigned. Seems this is a known C issue and I can't see a good fix for
it except perhaps check for INT_MIN int he int84 function, but I ran
some tests and that didn't work either.
Bruce Momjian | http://candle.pha.pa.us
pgman(at)candle(dot)pha(dot)pa(dot)us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
In response to
pgsql-bugs by date
|Next:||From: Steve Atkins||Date: 2004-03-03 17:41:41|
|Subject: Re: Integer parsing bug?|
|Previous:||From: evanm||Date: 2004-03-03 12:46:31|
|Subject: initdb could use some lower default settings (trivial patch)|