Bug #42760 | Select doesn't return desired results when we have null values | ||
---|---|---|---|
Submitted: | 11 Feb 2009 12:57 | Modified: | 12 Mar 2010 17:43 |
Reporter: | Josep Maria Pons Roca | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Optimizer | Severity: | S2 (Serious) |
Version: | 5.0.67, 5.0.74, 5.0.79-bzr, 5.1.32-bzr, 6.0.10 | OS: | Linux |
Assigned to: | Georgi Kodinov | CPU Architecture: | Any |
Tags: | ref_or_null, regression |
[11 Feb 2009 12:57]
Josep Maria Pons Roca
[11 Feb 2009 13:21]
Valeriy Kravchuk
Thank you for the bug report. Verified just as described: openxs@suse:/home2/openxs/dbs/5.0> bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.0.79-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> drop table test; ERROR 1051 (42S02): Unknown table 'test' mysql> CREATE TABLE `test` ( -> `id_test` int(11) unsigned NOT NULL auto_increment, -> `a` int(11) unsigned NOT NULL default '0', -> `b` varchar(100) NOT NULL default '', -> `c` int(11) unsigned default NULL, -> PRIMARY KEY (`id_test`), -> UNIQUE KEY `index_a_c` (`a`,`c`), -> KEY `index_a` (`a`) -> ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.06 sec) mysql> insert into test values (null, 1, "a", 10); Query OK, 1 row affected (0.01 sec) mysql> insert into test values (null, 2, "b", null); Query OK, 1 row affected (0.00 sec) mysql> select * from test where a=2 and (c=10 or c is null) order by c desc limit 1; Empty set (0.03 sec) mysql> select * from test where a=2 and (c is null) order by c desc limit 1; +---------+---+---+------+ | id_test | a | b | c | +---------+---+---+------+ | 4 | 2 | b | NULL | +---------+---+---+------+ 1 row in set (0.00 sec) Looks like ref_or_null access path is broken: mysql> explain select * from test where a=2 and (c=10 or c is null) order by c desc limit 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ref_or_null possible_keys: index_a_c,index_a key: index_a_c key_len: 9 ref: const,const rows: 1 Extra: Using where 1 row in set (0.00 sec) mysql> explain select * from test where a=2 and (c is null) order by c desc limit 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ref possible_keys: index_a_c,index_a key: index_a_c key_len: 9 ref: const,const rows: 1 Extra: Using where; Using filesort 1 row in set (0.00 sec)
[11 Feb 2009 13:24]
Valeriy Kravchuk
5.1 is also affected: openxs@suse:/home2/openxs/dbs/5.1> bin/mysql -uroot test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1 Server version: 5.1.32-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE TABLE `test` ( `id_test` int(11) unsigned NOT NULL auto_increment, `a` int(11) unsigned NOT NULL default '0', `b` varchar(100) NOT NULL default '', `c` int(11) unsigned default NULL, PRIMARY KEY (`id_test`), UNIQUE KEY `index_a_c` (`a`,`c`), KEY `index_a` (`a`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.03 sec) mysql> insert into test values (null, 1, "a", 10); Query OK, 1 row affected (0.01 sec) mysql> insert into test values (null, 2, "b", null); Query OK, 1 row affected (0.00 sec) mysql> select * from test where a=2 and (c=10 or c is null) order by c desc limit 1; Empty set (0.03 sec) mysql> select * from test where a=2 and (c is null) order by c desc limit 1; +---------+---+---+------+ | id_test | a | b | c | +---------+---+---+------+ | 4 | 2 | b | NULL | +---------+---+---+------+ 1 row in set (0.01 sec)
[11 Feb 2009 13:40]
Alexander Keremidarski
Engine independent. Same with MyISAM Both ORDER BY ASC and DESC trigger the bug. Interesting enough both IGNORE and FORCE INDEX (index_a_c) produce correct result. index_a_c is the one the optimizer uses without hints when the result set is empty according to the explain. Tested with both MyISAM and InnoDB on 5.0.79 from bzr revno: 2741 Doesn't make any sense to me: mysql> SELECT VERSION(); +------------------+ | VERSION() | +------------------+ | 5.0.79-debug-log | +------------------+ 1 row in set (0.00 sec) mysql> SELECT * FROM test WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; Empty set (0.00 sec) mysql> SELECT * FROM test IGNORE INDEX (index_a_c) WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; +---------+---+---+------+ | id_test | a | b | c | +---------+---+---+------+ | 4 | 2 | b | NULL | +---------+---+---+------+ 1 row in set (0.00 sec) mysql> SELECT * FROM test FORCE INDEX (index_a_c) WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; +---------+---+---+------+ | id_test | a | b | c | +---------+---+---+------+ | 4 | 2 | b | NULL | +---------+---+---+------+ 1 row in set (0.00 sec)
[11 Feb 2009 15:44]
Josep Maria Pons Roca
With force key (index_a_c) I can see some strange differences, in extra col: mysql> explain select * from test force key (index_a_c) where a=2 and (c=10 or c is null) order by c desc limit 1; +----+-------------+-------+-------------+---------------+-----------+---------+-------------+------+-----------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------------+---------------+-----------+---------+-------------+------+-----------------------------+ | 1 | SIMPLE | test | ref_or_null | index_a_c | index_a_c | 9 | const,const | 2 | Using where; Using filesort | +----+-------------+-------+-------------+---------------+-----------+---------+-------------+------+-----------------------------+ 1 row in set (0.00 sec) mysql> explain select * from test where a=2 and (c=10 or c is null) order by c desc limit 1; +----+-------------+-------+-------------+-------------------+-----------+---------+-------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+-------------+-------------------+-----------+---------+-------------+------+-------------+ | 1 | SIMPLE | test | ref_or_null | index_a_c,index_a | index_a_c | 9 | const,const | 1 | Using where | +----+-------------+-------+-------------+-------------------+-----------+---------+-------------+------+-------------+ 1 row in set (0.00 sec) I'm not sure, but... can it be some kind of query parsing error?
[11 Feb 2009 16:44]
Valeriy Kravchuk
This is a regression bug happened some time in between 5.0.51 and 5.0.67. 5.0.51 works OK: C:\work\mysql-5.0.51a-win32\bin>mysql -uroot test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.0.51a-community MySQL Community Edition (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE TABLE `test` ( -> `id_test` int(11) unsigned NOT NULL auto_increment, -> `a` int(11) unsigned NOT NULL default '0', -> `b` varchar(100) NOT NULL default '', -> `c` int(11) unsigned default NULL, -> PRIMARY KEY (`id_test`), -> UNIQUE KEY `index_a_c` (`a`,`c`), -> KEY `index_a` (`a`) -> ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8; Query OK, 0 rows affected (0.03 sec) mysql> mysql> insert into test values (null, 1, "a", 10); Query OK, 1 row affected (0.01 sec) mysql> insert into test values (null, 2, "b", null); Query OK, 1 row affected (0.00 sec) mysql> select * from test where a=2 and (c=10 or c is null) order by c desc limi t 1; +---------+---+---+------+ | id_test | a | b | c | +---------+---+---+------+ | 4 | 2 | b | NULL | +---------+---+---+------+ 1 row in set (0.05 sec) mysql> explain select * from test where a=2 and (c=10 or c is null) order by c d esc limit 1\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: test type: ref possible_keys: index_a_c,index_a key: index_a key_len: 4 ref: const rows: 1 Extra: Using where; Using filesort 1 row in set (0.00 sec)
[22 Oct 2009 16:39]
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/87793 2823 Georgi Kodinov 2009-10-22 Bug #42760: Select doesn't return desired results when we have null values We should re-set the access method functions when changing the access method when switching to another index to avoid sorting. Fixed by doing a little re-engineering : encapsulating all the function assignment into a special function and calling it when flipping the indexes.
[6 Nov 2009 13:25]
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/89592 2823 Georgi Kodinov 2009-11-06 Bug #42760: Select doesn't return desired results when we have null values We should re-set the access method functions when changing the access method when switching to another index to avoid sorting. Fixed by doing a little re-engineering : encapsulating all the function assignment into a special function and calling it when flipping the indexes.
[9 Nov 2009 17:23]
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/89842 2843 Georgi Kodinov 2009-11-06 Bug #42760: Select doesn't return desired results when we have null values We should re-set the access method functions when changing the access method when switching to another index to avoid sorting. Fixed by doing a little re-engineering : encapsulating all the function assignment into a special function and calling it when flipping the indexes.
[10 Nov 2009 8:22]
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/89887 2843 Georgi Kodinov 2009-11-10 Bug #42760: Select doesn't return desired results when we have null values We should re-set the access method functions when changing the access method when switching to another index to avoid sorting. Fixed by doing a little re-engineering : encapsulating all the function assignment into a special function and calling it when flipping the indexes.
[2 Dec 2009 8:01]
Bugs System
Pushed into 5.0.89 (revid:joro@sun.com-20091202075830-mzl79q7mc1v72pf1) (version source revid:joro@sun.com-20091110082141-ldr8p6s1joczve2j) (merge vers: 5.0.88) (pib:13)
[2 Dec 2009 8:04]
Bugs System
Pushed into 5.1.42 (revid:joro@sun.com-20091202080033-mndu4sxwx19lz2zs) (version source revid:joro@sun.com-20091110085843-uiz4zu251q16v5nt) (merge vers: 5.1.41) (pib:13)
[6 Dec 2009 17:15]
Elena Stepanova
On the current mysql-5.1 tree: Test case provided in 'How to repeat section' still does not work -- with the same structure and data, the same SELECT returns an empty result set. In regard to the test added with this bugfix, the test itself passes: DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( a INT, c INT, UNIQUE KEY a_c (a,c), KEY (a)); INSERT INTO t1 VALUES (1, 10), (2, NULL); EXPLAIN SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c; #+-----+ #| col | #+-----+ #| 1 | #+-----+ # But the same select with ORDER BY c DESC returns an empty set: SELECT 1 AS col FROM t1 WHERE a=2 AND (c=10 OR c IS NULL) ORDER BY c DESC; # Empty set (0.00 sec) Additional note: I'm observing a slight change in behavior in regard to NULL values, which is not explicitly mentioned in this bug, but I suppose might be related to the bugfix: DROP TABLE IF EXISTS t3; CREATE TABLE t3(c1 TIME NOT NULL, c2 TIME NULL); INSERT INTO t3 VALUES ('123456',null); #In the current version, the following SELECT returns the row from the table: SELECT * FROM t3 WHERE c2 < '-838:59:59'; #+----------+------+ #| c1 | c2 | #+----------+------+ #| 12:34:56 | NULL | #+----------+------+ #1 row in set (0.00 sec) #In previous versions, it would return an empty result set: SELECT * FROM t3 WHERE c2 < '-838:59:59'; #Empty set (0.00 sec) It seems OK as long as it is expected/planned.
[6 Dec 2009 18:05]
Elena Stepanova
In regard to the note about comparing to NULL -- the behavior is not quite consistent when it comes to integer types, e.g.: DROP TABLE IF EXISTS t3; CREATE TABLE t3(c1 BIGINT UNSIGNED NOT NULL, c2 BIGINT NULL, c3 INT NULL); INSERT INTO t3 VALUES(105,NULL,NULL); SELECT * FROM t3 WHERE c2 < -102; #+-----+------+------+ #| c1 | c2 | c3 | #+-----+------+------+ #| 105 | NULL | NULL | #+-----+------+------+ #1 row in set (0.00 sec) SELECT * FROM t3 WHERE c3 < -102; # Empty set (0.00 sec) That is, for BIGINT <NULL> < <NUMBER> returns true, while for INT (SMALLINT, TINYINT) it does not.
[7 Dec 2009 11:48]
Georgi Kodinov
My fix was only fixing the case when the ORDER BY was not descending. Re-opening the bug.
[7 Dec 2009 14:39]
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/93074 2861 Georgi Kodinov 2009-12-07 Bug #42760: Select doesn't return desired results when we have null values Part 2 : There was a special optimization on the ref access method for ORDER BY ... DESC that was set without actually looking on the type of the selected index for ORDER BY. Fixed the SELECT ... ORDER BY .. DESC (it uses a different code path compared to the ASC that has been fixed with the previous fix).
[10 Dec 2009 15:24]
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/93545 2865 Georgi Kodinov 2009-12-07 Bug #42760: Select doesn't return desired results when we have null values Part 2 : There was a special optimization on the ref access method for ORDER BY ... DESC that was set without actually looking on the type of the selected index for ORDER BY. Fixed the SELECT ... ORDER BY .. DESC (it uses a different code path compared to the ASC that has been fixed with the previous fix).
[16 Dec 2009 8:35]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091216083311-xorsasf5kopjxshf) (version source revid:alik@sun.com-20091214191830-wznm8245ku8xo702) (merge vers: 6.0.14-alpha) (pib:14)
[16 Dec 2009 8:42]
Bugs System
Pushed into 5.5.0-beta (revid:alik@sun.com-20091216082430-s0gtzibcgkv4pqul) (version source revid:alexey.kopytov@sun.com-20091124081906-6pqi7e7sajimog71) (merge vers: 5.5.0-beta) (pib:14)
[16 Dec 2009 8:49]
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 1:39]
Paul DuBois
Noted in 5.5.1, 6.0.14 changelogs. Comparison with NULL values sometimes did not produce a correct result. Setting report to NDI pending push to 5.0.x, 5.1.x.
[19 Dec 2009 8:28]
Bugs System
Pushed into 6.0.14-alpha (revid:alik@sun.com-20091219082307-f3i4fn0tm8trb3c0) (version source revid:alik@sun.com-20091216180721-eoa754i79j4ssd3m) (merge vers: 6.0.14-alpha) (pib:15)
[19 Dec 2009 8:31]
Bugs System
Pushed into 5.5.1-m2 (revid:alik@sun.com-20091219082021-f34nq4jytwamozz0) (version source revid:alexey.kopytov@sun.com-20091211164058-ycpe0f20d1c4h1gl) (merge vers: 5.5.0-beta) (pib:15)
[19 Dec 2009 8:35]
Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20091219082213-nhjjgmphote4ntxj) (version source revid:alik@sun.com-20091216180221-a5ps59gajad3pip9) (pib:15)
[20 Dec 2009 0:33]
Paul DuBois
Setting report to NDI pending push to 5.0.x, 5.1.x.
[14 Jan 2010 8:26]
Bugs System
Pushed into 5.0.90 (revid:joro@sun.com-20100114082402-05fod2h6z9x9wok8) (version source revid:aelkin@mysql.com-20091214144410-630vanwyllvvacad) (merge vers: 5.0.89) (pib:16)
[14 Jan 2010 18:01]
Paul DuBois
Noted in 5.0.90 changelog. Setting report to NDI pending push to 5.1.x, Celosia.
[15 Jan 2010 9:00]
Bugs System
Pushed into 5.1.43 (revid:joro@sun.com-20100115085139-qkh0i0fpohd9u9p5) (version source revid:joro@sun.com-20091210153801-ozpah1jkucqjdufw) (merge vers: 5.1.42) (pib:16)
[15 Jan 2010 18:22]
Paul DuBois
Noted in 5.1.43 changelog. Setting report to NDI pending push to Celosia.
[12 Mar 2010 14:07]
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:23]
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:37]
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)
[12 Mar 2010 17:43]
Paul DuBois
Fixed in earlier 5.1.x, 5.5.x.