Thread: int8 bug on Alpha

int8 bug on Alpha

From
Adriaan Joubert
Date:
Hi,
int8 is not handled correctly on Alpha. Inserting 2^63-1, 2^63-2 and
2^61
into 

create table lint (i int8);

gives

test=# select * from lint;i  
-----1-2 0
(3 rows)

On linux it gives the correct values:

test=# select * from lint;         i          
---------------------922337203685477580792233720368547758062305843009213693952
(3 rows)

This is postgres 7.1b4, compiled with native cc on Tru64 4.0G. I seem to
recall running the regression tests, so perhaps this is not checked?
(just looked at int8.sql, and it is not checked.)

I'm swamped, so cannot look at it right now. If nobody else can look at
it, I will get back to it in about a fortnight.

Adriaan


Re: int8 bug on Alpha

From
Thomas Lockhart
Date:
> int8 is not handled correctly on Alpha. Inserting 2^63-1, 2^63-2 and
> 2^61...

How are you doing the inserts? If you aren't coercing the "2" to be an
int8, then (afaik) the math will be done in int4, then upconverted. So,
can you confirm that your inserts look like:

insert into lint values ('9223372036854775807');

or

insert into lint select (int8 '2') ^ 61;
                        - Thomas


Re: int8 bug on Alpha

From
Adriaan Joubert
Date:
Thomas Lockhart wrote:
> 
> > int8 is not handled correctly on Alpha. Inserting 2^63-1, 2^63-2 and
> > 2^61...
> 
> How are you doing the inserts? If you aren't coercing the "2" to be an
> int8, then (afaik) the math will be done in int4, then upconverted. So,
> can you confirm that your inserts look like:
> 
> insert into lint values ('9223372036854775807');

OK, that was it. I  inserted without quotes. If I insert the quotes it
works. So why does it work correctly on linux without quotes?

and 
insert into lint values ('9223372036854775807'::int8);

works, but
insert into lint values (9223372036854775807::int8);

doesn't. I guess in the second case it converts it to an int4 and then
recasts to an int8?

Cheers,

Adriaan


Re: int8 bug on Alpha

From
Thomas Lockhart
Date:
> > How are you doing the inserts? If you aren't coercing the "2" to be an
> > int8, then (afaik) the math will be done in int4, then upconverted. So,
> > can you confirm that your inserts look like:
> > insert into lint values ('9223372036854775807');
> OK, that was it. I  inserted without quotes. If I insert the quotes it
> works. So why does it work correctly on linux without quotes?

For integers (optional sign and all digits), the code in
src/backend/parser/scan.l uses strtol() to read the string, then checks
for failure. If it fails, the number is interpreted as a double float on
the assumption that if it could hold more digits it would succeed!

Anyway, either strtol() thinks it *should* be able to read a 64 bit
integer, or your machine is silently overflowing. I used to have a bunch
of these boxes, and I recall spending quite a bit of time discovering
that Alphas have some explicit flags which can be set at compile time
which affect run-time detection of floating point and (perhaps) integer
overflow behavior.

Can you check these possibilities? I'd look at strtol() first, then the
overflow/underflow flags second...
                       - Thomas


Re: Re: int8 bug on Alpha

From
Bruce Momjian
Date:
> For integers (optional sign and all digits), the code in
> src/backend/parser/scan.l uses strtol() to read the string, then checks
> for failure. If it fails, the number is interpreted as a double float on
> the assumption that if it could hold more digits it would succeed!
> 
> Anyway, either strtol() thinks it *should* be able to read a 64 bit
> integer, or your machine is silently overflowing. I used to have a bunch
> of these boxes, and I recall spending quite a bit of time discovering
> that Alphas have some explicit flags which can be set at compile time
> which affect run-time detection of floating point and (perhaps) integer
> overflow behavior.
> 
> Can you check these possibilities? I'd look at strtol() first, then the
> overflow/underflow flags second...

Intersting that the lack of strtol() failure on Alpha is causing the
problem.


--  Bruce Momjian                        |  http://candle.pha.pa.us pgman@candle.pha.pa.us               |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: int8 bug on Alpha

From
Adriaan Joubert
Date:
> Anyway, either strtol() thinks it *should* be able to read a 64 bit
> integer, or your machine is silently overflowing. I used to have a bunch
> of these boxes, and I recall spending quite a bit of time discovering
> that Alphas have some explicit flags which can be set at compile time
> which affect run-time detection of floating point and (perhaps) integer
> overflow behavior.
> 
> Can you check these possibilities? I'd look at strtol() first, then the
> overflow/underflow flags second...

Hmm, I wrote a trivial programme parsing long ints and get the following

#include <errno.h>

main (int argc, char *argv[]) {   long int a = strtol(argv[1], (char **) 0, 10);   printf("input='%s' ld=%ld (errno
%d)\n",argv[1],a,errno);
}

emily:~/Tmp/C++$ a.out 9223372036854775807
input='9223372036854775807' ld=9223372036854775807 (errno 0)
emily:~/Tmp/C++$ a.out 9223372036854775808
input='9223372036854775808' ld=9223372036854775807 (errno 34)
emily:~/Tmp/C++$ a.out 9223372036854775806
input='9223372036854775806' ld=9223372036854775806 (errno 0)
emily:~/Tmp/C++$ a.out -9223372036854775808
input='-9223372036854775808' ld=-9223372036854775808 (errno 0)


so that seems to work correctly. And I compiled with the same compiler
flags with which postgres was compiled. Apparently long is defined as
'long long int' on alpha, and I tried it with that and it works as well.

I'll have to debug this properly, but first I need to get Friday out of
the way ;-)

Adriaan


Re: Re: int8 bug on Alpha

From
Tom Lane
Date:
Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
> For integers (optional sign and all digits), the code in
> src/backend/parser/scan.l uses strtol() to read the string, then checks
> for failure. If it fails, the number is interpreted as a double float on
> the assumption that if it could hold more digits it would succeed!

Ohhhh....

This is an Alpha, remember?  long *is* 64 bits on that machine,
therefore strtol is correct to accept the number.  Unfortunately,
later in the parser we assign the datatype int4, not int8, to the
"integer" constant, and so it gets truncated.  make_const is making
an unwarranted assumption that T_Integer is the same as int4 --- or,
if you prefer, make_const is OK and scan.l is erroneous to use
node type T_Integer for ints that exceed 32 bits.

This is a portability bug, no question.  But I'd expect it to fail
like that on all Alpha-based platforms.  Adriaan, when you say it
works on Linux, are you talking about Linux/Alpha or some other
hardware?
        regards, tom lane


Re: Re: int8 bug on Alpha

From
Adriaan Joubert
Date:
> This is a portability bug, no question.  But I'd expect it to fail
> like that on all Alpha-based platforms.  Adriaan, when you say it
> works on Linux, are you talking about Linux/Alpha or some other
> hardware?

No, PC Linux. I run a database on my laptop as well.

Adriaan


Re: Re: int8 bug on Alpha

From
Tom Lane
Date:
Adriaan Joubert <a.joubert@albourne.com> writes:
>  insert into lint values ('9223372036854775807'::int8);
> works, but
>  insert into lint values (9223372036854775807::int8);
> doesn't.

Fixed, and checked on Debian Alpha.
        regards, tom lane