mysql> select '9223372036854775809' + 0; +---------------------------+ | '9223372036854775809' + 0 | +---------------------------+ | 9.2233720368548e+18 | +---------------------------+
mysql> select CAST('9223372036854775809' AS UNSIGNED INTEGER); +-------------------------------------------------+ | CAST('9223372036854775809' AS UNSIGNED INTEGER) | +-------------------------------------------------+ | 9223372036854775807 | +-------------------------------------------------+
mysql> select CONVERT('9223372036854775809', UNSIGNED INTEGER); +--------------------------------------------------+ | CONVERT('9223372036854775809', UNSIGNED INTEGER) | +--------------------------------------------------+ | 9223372036854775807 | +--------------------------------------------------+
mysql> select 9223372036854775807 & 127; +---------------------------+ | 9223372036854775807 & 127 | +---------------------------+ | 127 | +---------------------------+
See, the & works correctly. It's the conversion of '9223372036854775809' to a number which causes your problem. I expect the warnings about the range of BIGINT in the manual <http://www.mysql.com/doc/en/Column_types.html> apply here. It says
...All arithmetic is done using signed BIGINT or DOUBLE values, so you shouldn't use unsigned big integers larger than 9223372036854775807 (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting the BIGINT to a DOUBLE.
`-', `+', and `*' will use BIGINT arithmetic when both arguments are integer values! This means that if you multiply two big integers (or results from functions that return integers) you may get unexpected results when the result is larger than 9223372036854775807.
Of course, it's not clear that CAST and CONVERT shouldn't have worked.
Meanwhile, perhaps a simpler workaround would be to change how you build the query in Perl so as to avoid the quotes.
Michael
Stefan Traby wrote:
WOW !!
The story goes on:
I wrote the UDF-Functions (and64/or64) and while and it seems to work:
mysql> select and64('9223372036854775809',127); +----------------------------------+ | and64('9223372036854775809',127) | +----------------------------------+ | 1 | +----------------------------------+ 1 row in set (0.00 sec)
I noted that mysql can't really dial with unsigned: (you can't even declare it unsigned)
mysql> select or64('9223372036854775809',127); +---------------------------------+ | or64('9223372036854775809',127) | +---------------------------------+ | -9223372036854775681 | +---------------------------------+ 1 row in set (0.00 sec)
On Sun, Feb 01, 2004 at 01:09:34AM +0100, Stefan Traby wrote:
Hi !
select 129 & 127; -- ok(1) select '129' & 127; -- ok(1) select (0+'129') & 127; -- ok(1) select CAST('129' AS UNSIGNED INTEGER) & 127; -- ok(1) select CONVERT('129', UNSIGNED INTEGER) & 127;-- ok(1)
Doing the same with 64 bit values gives strange results:
select 9223372036854775809 & 127; -- returns 1, correct select '9223372036854775809' & 127; -- ERROR: returns 127 select (0+'9223372036854775809') & 127; -- ERROR: returns 0 select CAST('9223372036854775809' AS UNSIGNED INTEGER) & 127; -- ERROR: returns 127 select CONVERT('9223372036854775809', UNSIGNED INTEGER) & 127;-- ERROR: returns 127
So please tell me how to perform a bitwise 64bit-AND if a value is quoted.
Never seen such a strange bug for a long time.
Well, I just found it because DBD::mysql quotes large integer bind-variables even on perl int64...
So do I need to write an UDF-Function to get the correct behavior or is there another work-arround to fix this?
--
ciao - Stefan
-- MySQL General Mailing List For list archives: http://lists.mysql.com/mysql To unsubscribe: http://lists.mysql.com/[EMAIL PROTECTED]
-- MySQL General Mailing List For list archives: http://lists.mysql.com/mysql To unsubscribe: http://lists.mysql.com/[EMAIL PROTECTED]