MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Georgi Kodinov Date:October 30 2009 7:30am
Subject:bzr commit into mysql-5.0 branch (joro:2829) Bug#42116
View as plain text  
#At file:///home/kgeorge/mysql/work/B42116-5.0-bugteam/ based on revid:sergey.glukhov@stripped

 2829 Georgi Kodinov	2009-10-29
      Bug #42116 : Mysql crash on specific query
      
      Queries with nested outer joins may lead to crashes or 
      bad results because an internal data structure is not handled
      correctly.
      The optimizer uses bitmaps of nested JOINs to determine
      if certain table can be placed at a certain place in the
      JOIN order.
      It does maintain a bitmap describing in which JOINs 
      last placed table is nested.
      When it puts a table it makes sure the bit of every JOIN that
      contains the table in question is set (because JOINs can be nested).
      It does that by recursively setting the bit for the next enclosing
      JOIN when this is the first table in the JOIN and recursively 
      resetting the bit if it's the last table in the JOIN.
      When it removes a table from the join order it should do the
      opposite : recursively unset the bit if it's the only remaining 
      table in this join and and recursively set the bit if it's removing
      the last table of a JOIN.
      There was an error in how the bits was set for the upper levels :
      when removing a table it was setting the bit for all the enclosing 
      nested JOINs even if there were more tables left in the current JOIN
      (which practically means that the upper nested JOINs were not affected).
      Fixed by stopping the recursion at the relevant level.
     @ mysql-test/r/join.result
        Bug #42116: test case
     @ mysql-test/t/join.test
        Bug #42116: test case
     @ sql/sql_select.cc
        Bug #41116: don't go up and set the bits if more tables in
        at the current JOIN level

    modified:
      mysql-test/r/join.result
      mysql-test/t/join.test
      sql/sql_select.cc
=== modified file 'mysql-test/r/join.result'
--- a/mysql-test/r/join.result	2008-10-06 12:18:13 +0000
+++ b/mysql-test/r/join.result	2009-10-29 15:24:29 +0000
@@ -859,4 +859,58 @@ Handler_read_prev	0
 Handler_read_rnd	0
 Handler_read_rnd_next	5
 drop table t1, t2, t3;
+#
+# Bug #42116: Mysql crash on specific query
+#
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, INDEX (a));
+CREATE TABLE t4 (a INT);
+CREATE TABLE t5 (a INT);
+CREATE TABLE t6 (a INT);
+INSERT INTO t1 VALUES (1), (1), (1);
+INSERT INTO t2 VALUES
+(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
+INSERT INTO t3 VALUES
+(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
+EXPLAIN
+SELECT * 
+FROM 
+t1 JOIN t2 ON t1.a = t2.a 
+LEFT JOIN 
+(
+(
+t3 LEFT JOIN t4 ON t3.a = t4.a
+) 
+LEFT JOIN 
+(
+t5 LEFT JOIN t6 ON t5.a = t6.a
+) 
+ON t4.a = t5.a
+) 
+ON t1.a = t3.a;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	
+1	SIMPLE	t3	ref	a	a	5	test.t1.a	2	Using index
+1	SIMPLE	t4	ALL	NULL	NULL	NULL	NULL	0	
+1	SIMPLE	t5	ALL	NULL	NULL	NULL	NULL	0	
+1	SIMPLE	t6	ALL	NULL	NULL	NULL	NULL	0	
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	10	Using where
+SELECT * 
+FROM 
+t1 JOIN t2 ON t1.a = t2.a 
+LEFT JOIN 
+(
+(
+t3 LEFT JOIN t4 ON t3.a = t4.a
+) 
+LEFT JOIN 
+(
+t5 LEFT JOIN t6 ON t5.a = t6.a
+) 
+ON t4.a = t5.a
+) 
+ON t1.a = t3.a;
+a	a	a	a	a	a
+DROP TABLE t1,t2,t3,t4,t5,t6;
 End of 5.0 tests.

=== modified file 'mysql-test/t/join.test'
--- a/mysql-test/t/join.test	2008-10-06 12:18:13 +0000
+++ b/mysql-test/t/join.test	2009-10-29 15:24:29 +0000
@@ -660,5 +660,57 @@ explain select * from t1, t2, t3 where t
 show status like 'Handler_read%'; 
 drop table t1, t2, t3;
 
+--echo #
+--echo # Bug #42116: Mysql crash on specific query
+--echo #
+CREATE TABLE t1 (a INT);
+CREATE TABLE t2 (a INT);
+CREATE TABLE t3 (a INT, INDEX (a));
+CREATE TABLE t4 (a INT);
+CREATE TABLE t5 (a INT);
+CREATE TABLE t6 (a INT);
+
+INSERT INTO t1 VALUES (1), (1), (1);
+
+INSERT INTO t2 VALUES
+(2), (2), (2), (2), (2), (2), (2), (2), (2), (2);
+
+INSERT INTO t3 VALUES
+(3), (3), (3), (3), (3), (3), (3), (3), (3), (3);
+
+EXPLAIN
+SELECT * 
+FROM 
+  t1 JOIN t2 ON t1.a = t2.a 
+  LEFT JOIN 
+  (
+   (
+    t3 LEFT JOIN t4 ON t3.a = t4.a
+   ) 
+   LEFT JOIN 
+   (
+     t5 LEFT JOIN t6 ON t5.a = t6.a
+   ) 
+   ON t4.a = t5.a
+  ) 
+  ON t1.a = t3.a;
+
+SELECT * 
+FROM 
+  t1 JOIN t2 ON t1.a = t2.a 
+  LEFT JOIN 
+  (
+   (
+    t3 LEFT JOIN t4 ON t3.a = t4.a
+   ) 
+   LEFT JOIN 
+   (
+     t5 LEFT JOIN t6 ON t5.a = t6.a
+   ) 
+   ON t4.a = t5.a
+  ) 
+  ON t1.a = t3.a;
+
+DROP TABLE t1,t2,t3,t4,t5,t6;
 
 --echo End of 5.0 tests.

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2009-10-21 09:04:08 +0000
+++ b/sql/sql_select.cc	2009-10-29 15:24:29 +0000
@@ -8640,7 +8640,10 @@ static void restore_prev_nj_state(JOIN_T
       join->cur_embedding_map&= ~last_emb->nested_join->nj_map;
     else if (last_emb->nested_join->join_list.elements-1 ==
              last_emb->nested_join->counter) 
+    {
       join->cur_embedding_map|= last_emb->nested_join->nj_map;
+      break;
+    }
     else
       break;
     last_emb= last_emb->embedding;


Attachment: [text/bzr-bundle] bzr/joro@sun.com-20091029152429-ks55fhrp4lhknyij.bundle
Thread
bzr commit into mysql-5.0 branch (joro:2829) Bug#42116Georgi Kodinov30 Oct