Bug #24759 | WHERE IN(CONV(), ...) fails to match some BIGINT values | ||
---|---|---|---|
Submitted: | 1 Dec 2006 20:02 | Modified: | 7 Dec 2006 16:28 |
Reporter: | Jamie McCarthy | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server | Severity: | S2 (Serious) |
Version: | 5.0.26 | OS: | Linux (CentOS 4.4 Linux) |
Assigned to: | CPU Architecture: | Any |
[1 Dec 2006 20:02]
Jamie McCarthy
[1 Dec 2006 23:34]
Jamie McCarthy
Forgot to include this info before... The tests were run on an Opteron. We have not attempted to reproduce the problem on any 32-bit machines. vendor_id : AuthenticAMD cpu family : 15 model : 33 model name : Dual Core AMD Opteron(tm) Processor 270 # rpm -qa|grep -i 'mysql\|glibc' glibc-2.3.4-2.25 MySQL-client-5.0.26-0.glibc23 glibc-common-2.3.4-2.25 MySQL-shared-5.0.26-0.glibc23 MySQL-devel-5.0.26-0.glibc23 glibc-kernheaders-2.4-9.1.98.EL glibc-devel-2.3.4-2.25 glibc-2.3.4-2.25 glibc-headers-2.3.4-2.25 MySQL-server-5.0.26-0.glibc23
[3 Dec 2006 9:50]
Valeriy Kravchuk
Thank you for a problem report. Sorry, but I was not able to repeat the behaviour described with latest 5.0.32-BK on Linux (32-bit): mysql> create table test1 (id bigint unsigned not null default '0', primary key (id)) engine=InnoDB; Query OK, 0 rows affected (0.06 sec) mysql> INSERT INTO test1 VALUES ('2332785242394147927'), -> ('2332785242394237927'), ('2332785242394247937'); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select id, conv(id, 10, 16) from test1; +---------------------+------------------+ | id | conv(id, 10, 16) | +---------------------+------------------+ | 2332785242394147927 | 205FB7D17E2D3C57 | | 2332785242394237927 | 205FB7D17E2E9BE7 | | 2332785242394247937 | 205FB7D17E2EC301 | +---------------------+------------------+ 3 rows in set (0.01 sec) mysql> select * from test1 where id=2332785242394237927; +---------------------+ | id | +---------------------+ | 2332785242394237927 | +---------------------+ 1 row in set (0.01 sec) mysql> select * from test1 where id='2332785242394237927'; +---------------------+ | id | +---------------------+ | 2332785242394237927 | +---------------------+ 1 row in set (0.00 sec) mysql> select * from test1 where id=CONV('205FB7D17E2E9BE7', 16, 10); +---------------------+ | id | +---------------------+ | 2332785242394237927 | +---------------------+ 1 row in set (0.00 sec) mysql> select * from test1 where id IN (CONV('205FB7D17E2E9BE7', 16, 10)); +---------------------+ | id | +---------------------+ | 2332785242394237927 | +---------------------+ 1 row in set (0.00 sec) mysql> select * from test1 where id IN (CONV('205FB7D17E2E9BE7', 16, 10), 1); +---------------------+ | id | +---------------------+ | 2332785242394237927 | +---------------------+ 1 row in set (0.01 sec) mysql> select version(); +--------------+ | version() | +--------------+ | 5.0.32-debug | +--------------+ 1 row in set (0.00 sec)
[3 Dec 2006 18:04]
Brian Aker
I just tried this on 5.1 BK on my 64bit AMD withe a debug build. For Valerity's results I got this: mysql> select * from test1 where id IN (CONV('205FB7D17E2E9BE7', 16, 10), 1); Empty set (0.00 sec) My results for Jamie's queries were the same. Someone with access to a 64bit machine needs to look at this.
[4 Dec 2006 16:28]
Sebastian Goth
Hi there, i have a similar problem without CONV(). create table test (token bigint(20)); insert into test values('3232933621568372736'),('5174632569486238062'),('5860192774298853742'),('8787532532089676142'),('8029914733239132526') select token from test where token in('3232933621568372736','8787532532089676142','8029914733239132526','5174632569486238062','5860192774298853742'); This gives 3 results with following versions: 4.1.20 (source) 4.1.22 (source) 4.1.22 (mysql-standard-4.1.22-unknown-linux-gnu-x86_64-glibc23.tar.gz) 5.0.27 (source) 5.0.27-1 (debian etch amd64 binary) And I get only 1 result with: 5.0.27 (mysql-standard-5.0.27-linux-x86_64-icc-glibc23.tar.gz) The correct 5 results are shown if I write the query without quotes or with "when token='3232933621568372736' or token='8787532532089676142'..." This happens on: vendor_id : AuthenticAMD cpu family : 15 model : 35 model name : AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ with the debian stable amd64 port (unofficial) _and_ debian etch amd64. Tested kernels: 2.6.16-2-amd64-k8-smp from debian backports 2.6.19 vanilla In contrast my kubuntu 5.0.24a build on AMD Athlon 2400+ (32bit) does NOT have this bug.
[6 Dec 2006 11:05]
Sergei Golubchik
This is expected. 1. CONV() function returns a string, not a number. http://dev.mysql.com/doc/refman/5.0/en/string-functions.html 2. When a number is compared to a string, both are converted to a floating point number (double). http://dev.mysql.com/doc/refman/5.0/en/type-conversion.html 3. Converting of a BIGINT to a DOUBLE is lossy.
[6 Dec 2006 12:46]
Sebastian Goth
Is it also expected that it behaves really inconsitent? If ... in('[bigint1]','[bigint2]','[bigint3]'); can't find [bigint1] because of conversion loss, shouldn't ... in('[bigint1]'); return no result, either? This is what i can't explain to myself. Ask for 5 quoted bigints and you get 3 for example. Ask for one of the missing bigints explicitly but also in quotes and you get a result. Sebastian
[7 Dec 2006 16:28]
Jamie McCarthy
I think this is my bad, I'd assumed that "CONV(constant, constant, constant)" would return a constant value when it does not. The description for "expr IN (val,val)" reads: "if all values are constants, they are evaluated according to the type of expr" so I was assuming the CONV would be evaluated as a BIGINT. Since it's not a constant, the type conversion rules Sergei pointed out apply, namely the conversion of the CONV's string and expr's BIGINT into floating-point. So without the CAST this was never guaranteed to work and the question becomes why it ever did... my assumption is that "expr IN (singleval)" is special-cased, at which point I can imagine a bunch of reasons why that would work differently. So at this point I'm inclined to agree this is not a bug.