Thread: 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 ---------------------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
> 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, Pennsylvania19026
> 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
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