Bug #47963 Wrong results when index is used
| Submitted: | 9 Oct 2009 23:07 | Modified: | 12 Mar 2010 17:17 |
|---|---|---|---|
| Reporter: | Todd Farmer (OCA) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: Optimizer | Severity: | S1 (Critical) |
| Version: | 5.1.39, 5.1.41 | OS: | Any |
| Assigned to: | Ramil Kalimullin | CPU Architecture: | Any |
| Tags: | regression | ||
[9 Oct 2009 23:16]
Todd Farmer
Not limited to composite indexes:
mysql> DROP TABLE IF EXISTS not_found;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE `not_found` (
-> `col1` varchar(5) NOT NULL DEFAULT '',
-> `col2` varchar(15) NOT NULL DEFAULT '',
-> `col3` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
-> KEY `col3` (`col3`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> INSERT INTO not_found (col1, col2, col3) VALUES
-> ('TEST', 'TEST', '2009-10-09 00:00:00');
Query OK, 1 row affected (0.00 sec)
mysql> -- not found!
mysql> SELECT * FROM not_found
-> WHERE col1 = 'TEST'
-> AND col3 >= '2009-10-09 00:00:00.0'
-> AND col3 <= '2009-10-09 00:00:00.0';
Empty set (0.00 sec)
mysql>
mysql> SELECT * FROM not_found
-> WHERE col1 = 'TEST'
-> AND col3 + INTERVAL 0 SECOND >= '2009-10-09 00:00:00.0'
-> AND col3 + INTERVAL 0 SECOND <= '2009-10-09 00:00:00.0';
+------+------+---------------------+
| col1 | col2 | col3 |
+------+------+---------------------+
| TEST | TEST | 2009-10-09 00:00:00 |
+------+------+---------------------+
1 row in set (0.00 sec)
[11 Oct 2009 8:53]
Calvin Sun
This appears to be a server bug. There is no change in the InnoDB from 5.1.38 to 5.1.39. And I use the latest InnoDB 5.1 repo with 5.1.38, the result is correct.
[11 Oct 2009 9:37]
Valeriy Kravchuk
Verified with recent 5.1.41 from bzr also. Indeed, repeatable only with InnoDB tables, but this is an optimizer bug for sure. Look:
mysql> explain SELECT * FROM not_found WHERE col1 = 'TEST' AND col3 >= '2009-10-09 00:00:00.0' AND col3 <= '2009-10-09 00:00:00.0'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Impossible WHERE noticed after reading const tables
1 row in set (0.00 sec)
mysql> explain SELECT * FROM not_found IGNORE INDEX(col2) WHERE col1 = 'TEST' AND col3 >= '2009-10-09 00:00:00.0' AND col3 <= '2009-10-09 00:00:00.0'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: not_found
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1
Extra: Using where
1 row in set (0.00 sec)
mysql> SELECT * FROM not_found IGNORE INDEX(col2) WHERE col1 = 'TEST' AND col3 >= '2009-10-09 00:00:00.0' AND col3 <= '2009-10-09 00:00:00.0'\G
*************************** 1. row ***************************
col1: TEST
col2: TEST
col3: 2009-10-09 00:00:00
1 row in set (0.00 sec)
mysql> select version();
+--------------+
| version() |
+--------------+
| 5.1.41-debug |
+--------------+
1 row in set (0.00 sec)
mysql> alter table not_found engine=MyISAM;
Query OK, 1 row affected (0.41 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM not_found WHERE col1 = 'TEST' AND col3 >= '2009-10-09 00:00:00.0' AND col3 <= '2009-10-09 00:00:00.0'\G
*************************** 1. row ***************************
col1: TEST
col2: TEST
col3: 2009-10-09 00:00:00
1 row in set (0.00 sec)
mysql> explain SELECT * FROM not_found WHERE col1 = 'TEST' AND col3 >= '2009-10-09 00:00:00.0' AND col3 <= '2009-10-09 00:00:00.0'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: not_found
type: system
possible_keys: col2
key: NULL
key_len: NULL
ref: NULL
rows: 1
Extra:
1 row in set (0.00 sec)
[12 Oct 2009 18:41]
Ramil Kalimullin
The regression was introduced by fix for bug#46362. Looks like it doesn't take into account milliseconds component somehow.
[13 Oct 2009 4:43]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/86638 3163 Ramil Kalimullin 2009-10-13 Fix for bug#47963: Wrong results when index is used Problem: using null microsecond part (e.g. "YYYY-MM-DD HH:MM:SS.0000") in a WHERE condition may lead to wrong results due to improper DATETIMEs comparison in some cases. Fix: as we compare DATETIMEs as strings we must trim trailing 0's in such cases. @ mysql-test/r/innodb_mysql.result Fix for bug#47963: Wrong results when index is used - test result. @ mysql-test/t/innodb_mysql.test Fix for bug#47963: Wrong results when index is used - test case. @ sql/item.cc Fix for bug#47963: Wrong results when index is used - comparing DATETIMEs trim trailing 0's in the microsecond part.
[18 Oct 2009 16:27]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/87243 3182 Ramil Kalimullin 2009-10-18 [merge] Fix for bug#47963: Wrong results when index is used Problem: using null microsecond part in a WHERE condition (e.g. WHERE date_time_field <= "YYYY-MM-DD HH:MM:SS.0000") may lead to wrong results due to improper DATETIMEs comparison in some cases. Fix: comparing DATETIMEs as strings we must trim trailing 0's in such cases. @ mysql-test/r/innodb_mysql.result Fix for bug#47963: Wrong results when index is used - test result. @ mysql-test/t/innodb_mysql.test Fix for bug#47963: Wrong results when index is used - test case. @ sql/item.cc Fix for bug#47963: Wrong results when index is used - comparing DATETIMEs as strings we must trim trailing 0's in the microsecond part to ensure 'YYYY-MM-DD HH:MM:SS.000' == 'YYYY-MM-DD HH:MM:SS'
[4 Nov 2009 9:25]
Bugs System
Pushed into 5.1.41 (revid:joro@sun.com-20091104092152-qz96bzlf2o1japwc) (version source revid:ramil@mysql.com-20091018162655-z4dlolfx5s0zem8l) (merge vers: 5.1.41) (pib:13)
[11 Nov 2009 6:53]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091110093407-rw5g8dys2baqkt67) (version source revid:alik@sun.com-20091109080109-7dxapd5y5pxlu08w) (merge vers: 6.0.14-alpha) (pib:13)
[11 Nov 2009 6:58]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091109115615-nuohp02h8mdrz8m2) (version source revid:alik@sun.com-20091105090203-cls5j6k3ohu04xpt) (merge vers: 5.5.0-beta) (pib:13)
[17 Nov 2009 16:48]
Paul DuBois
Noted in 5.1.41, 5.5.0, 6.0.14 changelogs. In some cases, using a null microsecond part in a WHERE condition (for example, WHERE date_time_field <= 'YYYY-MM-DD HH:MM:SS.0000') could lead to incorrect results due to improper DATETIME comparison.
[7 Dec 2009 16:44]
Paul DuBois
Noted in 5.1.40sp1 changelog.
[8 Dec 2009 9:29]
Bugs System
Pushed into 5.1.43 (revid:build@mysql.com-20091208092611-pbno5awyb0v38hs7) (version source revid:build@mysql.com-20091208092611-pbno5awyb0v38hs7) (merge vers: 5.1.43) (pib:13)
[16 Dec 2009 8:39]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091216083311-xorsasf5kopjxshf) (version source revid:alik@sun.com-20091215065750-5m04ogppd5l0pol5) (merge vers: 6.0.14-alpha) (pib:14)
[16 Dec 2009 8:46]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091216082430-s0gtzibcgkv4pqul) (version source revid:alik@sun.com-20091211070127-kl8uvlrv9cr11kva) (merge vers: 5.5.0-beta) (pib:14)
[16 Dec 2009 8:53]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20091216083231-rp8ecpnvkkbhtb27) (version source revid:alik@sun.com-20091212203859-fx4rx5uab47wwuzd) (merge vers: 5.6.0-beta) (pib:14)
[18 Dec 2009 10:34]
Bugs System
Pushed into 5.1.41-ndb-7.1.0 (revid:jonas@mysql.com-20091218102229-64tk47xonu3dv6r6) (version source revid:jonas@mysql.com-20091218095730-26gwjidfsdw45dto) (merge vers: 5.1.41-ndb-7.1.0) (pib:15)
[18 Dec 2009 10:50]
Bugs System
Pushed into 5.1.41-ndb-6.2.19 (revid:jonas@mysql.com-20091218100224-vtzr0fahhsuhjsmt) (version source revid:jonas@mysql.com-20091217101452-qwzyaig50w74xmye) (merge vers: 5.1.41-ndb-6.2.19) (pib:15)
[18 Dec 2009 11:05]
Bugs System
Pushed into 5.1.41-ndb-6.3.31 (revid:jonas@mysql.com-20091218100616-75d9tek96o6ob6k0) (version source revid:jonas@mysql.com-20091217154335-290no45qdins5bwo) (merge vers: 5.1.41-ndb-6.3.31) (pib:15)
[18 Dec 2009 11:19]
Bugs System
Pushed into 5.1.41-ndb-7.0.11 (revid:jonas@mysql.com-20091218101303-ga32mrnr15jsa606) (version source revid:jonas@mysql.com-20091218064304-ezreonykd9f4kelk) (merge vers: 5.1.41-ndb-7.0.11) (pib:15)
[1 Feb 2010 8:59]
Tonci Grgin
Bug#50710 was marked as duplicate of this report.
[11 Feb 2010 19:49]
Mike Hoeffner
As Todd mentioned this is particularly problematic due to how C/J formats times but only actually newer versions as I recently got bitten by: http://forums.mysql.com/read.php?39,353773,353773 I'm a big fan of MySQL, but this is what we'd refer to as a head-shaving bug on our dev team. ;-)
[12 Mar 2010 14:14]
Bugs System
Pushed into 5.1.44-ndb-7.0.14 (revid:jonas@mysql.com-20100312135944-t0z8s1da2orvl66x) (version source revid:jonas@mysql.com-20100312115609-woou0te4a6s4ae9y) (merge vers: 5.1.44-ndb-7.0.14) (pib:16)
[12 Mar 2010 14:30]
Bugs System
Pushed into 5.1.44-ndb-6.2.19 (revid:jonas@mysql.com-20100312134846-tuqhd9w3tv4xgl3d) (version source revid:jonas@mysql.com-20100312060623-mx6407w2vx76h3by) (merge vers: 5.1.44-ndb-6.2.19) (pib:16)
[12 Mar 2010 14:46]
Bugs System
Pushed into 5.1.44-ndb-6.3.33 (revid:jonas@mysql.com-20100312135724-xcw8vw2lu3mijrhn) (version source revid:jonas@mysql.com-20100312103652-snkltsd197l7q2yg) (merge vers: 5.1.44-ndb-6.3.33) (pib:16)
[22 Mar 2010 16:52]
Tonci Grgin
Bug#52277 was marked as duplicate of this report.
[1 Nov 2010 0:54]
Roel Van de Paar
See bug #50774
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.100 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
Description: Beginning in 5.1.39, queries against InnoDB tables with certain composite keys can produce incorrect results: mysql> SELECT VERSION(); +----------------------+ | VERSION() | +----------------------+ | 5.1.39-community-log | +----------------------+ 1 row in set (0.00 sec) mysql> mysql> DROP TABLE IF EXISTS not_found; Query OK, 0 rows affected (0.00 sec) mysql> CREATE TABLE `not_found` ( -> `col1` varchar(5) NOT NULL DEFAULT '', -> `col2` varchar(15) NOT NULL DEFAULT '', -> `col3` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', -> KEY `col2` (`col1`, `col2`, `col3`) -> ) ENGINE=InnoDB DEFAULT CHARSET=latin1; Query OK, 0 rows affected (0.01 sec) mysql> mysql> INSERT INTO not_found (col1, col2, col3) VALUES -> ('TEST', 'TEST', '2009-10-09 00:00:00'); Query OK, 1 row affected (0.00 sec) mysql> -- not found! mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00.0' -> AND col3 <= '2009-10-09 00:00:00.0'; Empty set (0.00 sec) mysql> mysql> -- equivalent logic finds row: mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 = '2009-10-09 00:00:00.0'; +------+------+---------------------+ | col1 | col2 | col3 | +------+------+---------------------+ | TEST | TEST | 2009-10-09 00:00:00 | +------+------+---------------------+ 1 row in set (0.00 sec) mysql> mysql> -- dropping the key finds it mysql> ALTER TABLE not_found DROP KEY `col2`; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00.0' -> AND col3 <= '2009-10-09 00:00:00.0'; +------+------+---------------------+ | col1 | col2 | col3 | +------+------+---------------------+ | TEST | TEST | 2009-10-09 00:00:00 | +------+------+---------------------+ 1 row in set (0.00 sec) mysql> mysql> -- an index on just col1 and col2 doesn't cause the problem: mysql> ALTER TABLE not_found ADD KEY `col2` (`col1`,`col2`); Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00.0' -> AND col3 <= '2009-10-09 00:00:00.0'; +------+------+---------------------+ | col1 | col2 | col3 | +------+------+---------------------+ | TEST | TEST | 2009-10-09 00:00:00 | +------+------+---------------------+ 1 row in set (0.00 sec) mysql> -- but an index on all three does: mysql> ALTER TABLE not_found DROP KEY `col2`; Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE not_found ADD KEY `col2` (`col1`,`col2`, `col3`); Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00.0' -> AND col3 <= '2009-10-09 00:00:00.0'; Empty set (0.00 sec) mysql> mysql> -- so does an index on first and third columns: mysql> ALTER TABLE not_found DROP KEY `col2`; Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> ALTER TABLE not_found ADD KEY `col2` (`col1`, `col3`); Query OK, 1 row affected (0.01 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00.0' -> AND col3 <= '2009-10-09 00:00:00.0'; Empty set (0.00 sec) mysql> mysql> EXPLAIN SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00' -> AND col3 <= '2009-10-09 00:00:00.0'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: not_found type: range possible_keys: col2 key: col2 key_len: 15 ref: NULL rows: 1 Extra: Using where 1 row in set (0.03 sec) mysql> mysql> -- eliminating the milliseconds component eliminates problem: mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00' -> AND col3 <= '2009-10-09 00:00:00'; +------+------+---------------------+ | col1 | col2 | col3 | +------+------+---------------------+ | TEST | TEST | 2009-10-09 00:00:00 | +------+------+---------------------+ 1 row in set (0.03 sec) mysql> mysql> -- MyISAM isn't affected: mysql> ALTER TABLE not_found ENGINE = MyISAM; Query OK, 1 row affected (0.06 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM not_found -> WHERE col1 = 'TEST' -> AND col3 >= '2009-10-09 00:00:00.0' -> AND col3 <= '2009-10-09 00:00:00.0'; +------+------+---------------------+ | col1 | col2 | col3 | +------+------+---------------------+ | TEST | TEST | 2009-10-09 00:00:00 | +------+------+---------------------+ 1 row in set (0.00 sec) This is particularly problematic because C/J (and perhaps other drivers) explicitly add the millisecond component when converting java.sql.Timestamp objects to strings. How to repeat: DROP TABLE IF EXISTS not_found; CREATE TABLE `not_found` ( `col1` varchar(5) NOT NULL DEFAULT '', `col2` varchar(15) NOT NULL DEFAULT '', `col3` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', KEY `col2` (`col1`, `col2`, `col3`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO not_found (col1, col2, col3) VALUES ('TEST', 'TEST', '2009-10-09 00:00:00'); -- not found! SELECT * FROM not_found WHERE col1 = 'TEST' AND col3 >= '2009-10-09 00:00:00.0' AND col3 <= '2009-10-09 00:00:00.0'; Suggested fix: Produce correct results.