int8 bug on Alpha
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
---------------------
9223372036854775807
9223372036854775806
2305843009213693952
(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
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
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
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
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, Pennsylvania 19026
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
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
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