| Bug #34945 | ref_or_null queries that are null_rejecting and have a null value crash mysql | ||
|---|---|---|---|
| Submitted: | 28 Feb 2008 22:53 | Modified: | 15 Mar 2008 8:59 |
| Reporter: | Eric Bergen (OCA) | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | MySQL Server: DML | Severity: | S2 (Serious) |
| Version: | 5.0, 5.1, 6.0 BK | OS: | Any (All) |
| Assigned to: | Sergey Petrunya | CPU Architecture: | Any |
| Tags: | Contribution, crash, join_read_always_key, join_read_always_key_or_null, null_rejecting, ref_or_null, regression | ||
[28 Feb 2008 23:54]
Sveta Smirnova
Thank you for the report. Verified as described.
[3 Mar 2008 17:33]
Sergey Petrunya
More details: the crash is caused by failed assertion. In release builds, attempts do do index lookups before initializing the index cause errors like this: ERROR 126: Incorrect key file for table '%s'; try to repair it . The bug was introduced by fix for BUG#12144.
[3 Mar 2008 17:36]
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/43328 ChangeSet@1.2598, 2008-03-03 20:35:44+03:00, sergefp@mysql.com +3 -0 BUG#34945: "ref_or_null queries that are null_rejecting and have a null value crash mysql" - Apply Eric Bergen's patch: in join_read_always_key(), move ha_index_init() call to before the late NULLs filtering code. - Backport function comments from 6.0.
[3 Mar 2008 17:39]
Sergey Petrunya
The suggested fix is correct. Thanks Eric ! :-)
[13 Mar 2008 19:28]
Bugs System
Pushed into 6.0.5-alpha
[13 Mar 2008 19:35]
Bugs System
Pushed into 5.1.24-rc
[13 Mar 2008 19:42]
Bugs System
Pushed into 5.0.60
[15 Mar 2008 8:59]
Jon Stephens
Documented bugfix in the 5.0.60, 5.1.24, and 6.0.5 changelogs as follows:
A query that performed a ref_or_null join where the second table used a
key having one or columns that could be NULL and had a column value that
was NULL caused the server to crash.

Description: A query that does a ref_or_null join where the second table has key part that could be null and a value that is null crashes mysql. join_read_always_key() can return before calling ha_index_init(). After that join_read_always_key_or_null will try to call safe_index_read() to read the index which crashes because the index was never initialized. The patch moves the index initialization before the null check in join_read_always_key() so the index is initialized in both cases. How to repeat: CREATE TABLE `bar` ( `a` int(11) default NULL, `b` int(11) default NULL, KEY `a` (`a`,`b`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO `bar` VALUES (0,10),(0,11),(0,12); CREATE TABLE `foo` ( `a` int(11) default NULL, `b` int(11) default NULL, KEY `a` (`a`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; INSERT INTO `foo` VALUES (3,NULL),(3,11),(3,12); SELECT * FROM foo inner join bar WHERE ( bar.a = 0 OR bar.a IS NULL) AND foo.a = 3 AND foo.b = bar.b ; Suggested fix: diff -urN mysql-5.0.51a-orig/sql/sql_select.cc mysql-5.0.51a/sql/sql_select.cc --- mysql-5.0.51a-orig/sql/sql_select.cc 2008-01-11 06:43:13.000000000 -0800 +++ mysql-5.0.51a/sql/sql_select.cc 2008-02-28 14:33:37.000000000 -0800 @@ -11116,13 +11116,15 @@ int error; TABLE *table= tab->table; + if (!table->file->inited) + table->file->ha_index_init(tab->ref.key); + for (uint i= 0 ; i < tab->ref.key_parts ; i++) { if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null()) return -1; - } - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key); + } + if (cp_buffer_from_ref(tab->join->thd, &tab->ref)) return -1; if ((error=table->file->index_read(table->record[0],