MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Jorgen Loland Date:March 15 2010 10:25am
Subject:bzr commit into mysql-6.0-codebase-bugfixing branch (jorgen.loland:3822)
Bug#51084
View as plain text  
#At file:///localhome/jl208045/mysql/mysql-6.0-codebase-bugfixing-51084/ based on revid:jorgen.loland@stripped

 3822 Jorgen Loland	2010-03-15
      Bug#51084: "Batched key access crashes for SELECT with derived 
                  table and LEFT JOIN"
      
      JOIN::optimize() may decide to use a join cache to join a table,
      but may have to revise this decision later, e.g. if an 
      incompatible access method is chosen. If it is decided that a
      join cache cannot be employed after all, set_join_cache_denial()
      is called to destroy the cache object. However, if linked join
      buffers are in use, a join cache for another table may link to 
      the cache being removed through the next_cache pointer. The 
      crash happened when the destroyed object was tried accessed 
      through this link.
      
      The fix is to remove the next_cache pointer from the previous 
      cache if the cache being removed has a previous cache.
     @ mysql-test/r/join_cache.result
        Add test for BUG#51084
     @ mysql-test/t/join_cache.test
        Add test for BUG#51084
     @ sql/sql_select.cc
        When removing join cache from a table, the next_cache pointer from the previous cache needs to be reset so that it does not point to a destroyed object.

    modified:
      mysql-test/r/join_cache.result
      mysql-test/t/join_cache.test
      sql/sql_select.cc
=== modified file 'mysql-test/r/join_cache.result'
--- a/mysql-test/r/join_cache.result	2010-01-20 10:11:29 +0000
+++ b/mysql-test/r/join_cache.result	2010-03-15 10:25:16 +0000
@@ -4081,3 +4081,47 @@ c1	c2	c1	c2	LENGTH(t2.c1)	LENGTH(t2.c2)
 2	2	tt	uu	2	2
 set optimizer_join_cache_level=default;
 DROP TABLE t1,t2;
+#
+# Bug#51084: Batched key access crashes for SELECT with
+#            derived table and LEFT JOIN 
+#
+CREATE TABLE t1 (
+carrier int,
+id int PRIMARY KEY
+);
+INSERT INTO t1 VALUES (1,11),(1,12),(2,13);
+CREATE TABLE t2 (
+scan_date int,
+package_id int
+);
+INSERT INTO t2 VALUES (2008,21),(2008,22);
+CREATE TABLE t3 (
+carrier int PRIMARY KEY,
+id int
+);
+INSERT INTO t3 VALUES (1,31);
+CREATE TABLE t4 (
+carrier_id int,
+INDEX carrier_id(carrier_id)
+);
+INSERT INTO t4 VALUES (31),(32);
+SET optimizer_join_cache_level=8;
+
+SELECT COUNT(*)
+FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+ON t3.carrier = t1.carrier;
+COUNT(*)
+6
+
+EXPLAIN
+SELECT COUNT(*)
+FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+ON t3.carrier = t1.carrier;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	ALL	NULL	NULL	NULL	NULL	2	
+1	SIMPLE	t1	ALL	NULL	NULL	NULL	NULL	3	Using join buffer
+1	SIMPLE	t3	eq_ref	PRIMARY	PRIMARY	4	test.t1.carrier	1	
+1	SIMPLE	t4	ref	carrier_id	carrier_id	5	test.t3.id	2	Using index
+
+SET optimizer_join_cache_level=default;
+DROP TABLE t1,t2,t3,t4;

=== modified file 'mysql-test/t/join_cache.test'
--- a/mysql-test/t/join_cache.test	2010-01-20 10:11:29 +0000
+++ b/mysql-test/t/join_cache.test	2010-03-15 10:25:16 +0000
@@ -1751,3 +1751,50 @@ SELECT t1.*, t2.*, LENGTH(t2.c1), LENGTH
 set optimizer_join_cache_level=default;
 
 DROP TABLE t1,t2;
+
+--echo #
+--echo # Bug#51084: Batched key access crashes for SELECT with
+--echo #            derived table and LEFT JOIN 
+--echo #
+
+CREATE TABLE t1 (
+  carrier int,
+  id int PRIMARY KEY
+);
+INSERT INTO t1 VALUES (1,11),(1,12),(2,13);
+
+CREATE TABLE t2 (
+  scan_date int,
+  package_id int
+);
+INSERT INTO t2 VALUES (2008,21),(2008,22);
+
+CREATE TABLE t3 (
+  carrier int PRIMARY KEY,
+  id int
+);
+INSERT INTO t3 VALUES (1,31);
+
+CREATE TABLE t4 (
+  carrier_id int,
+  INDEX carrier_id(carrier_id)
+);
+INSERT INTO t4 VALUES (31),(32);
+
+SET optimizer_join_cache_level=8;
+
+--echo
+SELECT COUNT(*)
+  FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+       ON t3.carrier = t1.carrier;
+
+--echo
+EXPLAIN
+SELECT COUNT(*)
+  FROM (t2 JOIN t1) LEFT JOIN (t3 JOIN t4 ON t3.id = t4.carrier_id)
+       ON t3.carrier = t1.carrier;
+
+--echo
+SET optimizer_join_cache_level=default;
+
+DROP TABLE t1,t2,t3,t4;

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2010-03-11 10:43:36 +0000
+++ b/sql/sql_select.cc	2010-03-15 10:25:16 +0000
@@ -9681,6 +9681,15 @@ void set_join_cache_denial(JOIN_TAB *joi
 {
   if (join_tab->cache)
   {
+    /* 
+      If there is a previous cache linked to this cache through the
+      next_cache pointer: remove the link. No need to do the same for
+      next_cache since cache denial is done backwards starting from
+      the latest cache in the linked list (see revise_cache_usage())
+    */
+    if (join_tab->cache->prev_cache)
+      join_tab->cache->prev_cache->next_cache= 0;
+
     join_tab->cache->free();
     join_tab->cache= 0;
   }


Attachment: [text/bzr-bundle] bzr/jorgen.loland@sun.com-20100315102516-ibimodj65qetfeod.bundle
Thread
bzr commit into mysql-6.0-codebase-bugfixing branch (jorgen.loland:3822)Bug#51084Jorgen Loland15 Mar
  • Re: bzr commit into mysql-6.0-codebase-bugfixing branch(jorgen.loland:3822) Bug#51084Olav Sandstaa16 Mar
    • Re: bzr commit into mysql-6.0-codebase-bugfixing branch(jorgen.loland:3822) Bug#51084Jørgen Løland17 Mar