Skip site navigation (1) Skip section navigation (2)

Re: Integer parsing bug?

From: Steve Atkins <steve(at)blighty(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: Re: Integer parsing bug?
Date: 2004-03-03 17:41:41
Message-ID: 20040303174141.GH17410@gp.word-to-the-wise.com (view raw or flat)
Thread:
Lists: pgsql-bugs
On Wed, Mar 03, 2004 at 12:31:47PM -0500, Bruce Momjian wrote:

> Yep, it definately looks weird:
> 	
> 	test=> select '-2147483648'::int;
> 	    int4
> 	-------------
> 	 -2147483648
> 	(1 row)
> 	
> 	test=> select -2147483648::int;
> 	ERROR:  integer out of range
> 	test=> select -2147483647::int;
> 	  ?column?
> 	-------------
> 	 -2147483647
> 	(1 row)
> 	
> 	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:

I traced through that far and managed to convince myself that the
problem was that it was considering a -...48 to be an int8, rather
than an int4, so was hitting int84() when it shouldn't have been - and
the input values for int84() looked very, very broken.

Specifically, a breakpoint on int84() fires on -..48 and -..49, but
not on -..47, suggesting that the problem is somewhere in the parsing
before it reaches int84().

I'm happy to take a look at it, but got very lost in the maze of twisty
parse routines, all alike, when I tried to track back further. Is there
any overview documentation on that end of the code?

> I see in the freebsd machine/limits.h file:
> 
>  * According to ANSI (section 2.2.4.2), 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 3.1.3.2).
>  * 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.

I don't read it that way. INT_MIN is correctly read as a signed int,
but it can't be defined as -0x8000000 as that would be parsed as
-(0x80000000) and the constant 0x80000000 is unsigned.

Cheers,
  Steve

In response to

Responses

pgsql-bugs by date

Next:From: Suresh Babu.A.GDate: 2004-03-03 20:23:39
Subject: Re: BUG #1090: initdb does not work
Previous:From: Bruce MomjianDate: 2004-03-03 17:31:47
Subject: Re: Integer parsing bug?

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group