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:
None 
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 22:53] Eric Bergen
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],
[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.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.059 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.