List:Commits« Previous MessageNext Message »
From:Olav Sandstaa Date:May 4 2011 1:24pm
Subject:bzr commit into mysql-trunk branch (olav.sandstaa:3368) Bug#12321461
View as plain text  
#At file:///export/home/tmp/olav/mrr-init-bug/ based on revid:roy.lyseng@stripped

 3368 Olav Sandstaa	2011-05-04
      Fix for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
      
      This crash is caused by a too strict assert that was added in the
      patch for Bug#58463. The purpose of this assert was to detect
      situations where the optimizer pushes an index condition (ICP) on the
      primary index and then later during execution "changes its mind" and
      uses a different index. This assert failed to take into account that
      the handler might be scanned multiple times during execution of query
      and that if MRR is used only on the first initialization of the MRR
      scan it will be initialized to use an index. On the second
      initialization of the MRR scan it will not have an active index open on
      the handler. 
      
      Detailed explanation of how this situation occurs:
      
      The optimizer has decided to scan the second table as a range scan and
      pushed an index condition to the handler on the primary key. The range
      scan will be done using an DS-MRR scan to read the second table
      multiple times (due to join buffering is disabled). This scan is
      initialized from QUICK_RANGE_SELECT::reset().
      
      The first time QUICK_RANGE_SELECT::reset() is called it will
      initialize the handler to use the primary index. Then it will call
      handler::multi_range_read_init() which will set up DS-MRR for this
      scan. This is done in DsMrr_impl::dsmrr_init(). The problematic assert
      will be evaluated and at this point it passes (since the pushed index
      condition is on the same active index as QUICK_RANGE_SELECT::reset()
      initialized). The main thing the initialization of the DS-MRR scan
      does is to create a "clone" of the handler object that will be used
      for some part of the DS-MRR scan. In this cloning process it will
      "copy" the pushed index condition from the main handler object to the
      clone handler object and set up the clone to do the index scan on the
      same index as the main handler was set up to use. Then it will "close"
      the active index on the main handler object since this will be used
      for reading the records from the base table. 
      
      Then a second scan of the table needs to be done and this causes a
      second call to QUICK_RANGE_SELECT::reset(). QUICK_RANGE_SELECT::reset()
      checks if the handler has been initialized, and since it has it does
      not initialize the index. Then it calls handler::multi_range_read_init()
      which calls DsMrr_impl::dsmrr_init(). In DsMrr_impl::dsmrr_init() the
      problematic assert will be evaluated. And this time it fails due to the 
      handler has no active index (since this was "transferred" to the clone
      handler object during the first initialization). Thus the assert fails
      even though we have a valid state of the handler object.
      
      The fix for this problem is to make the assert less strict by adding
      the case where the handler does not have an active index as a legal
      state.
      
      This patch also adds some asserts that validate that the main handler
      object and the clone handler object are in a consistent state with
      regards to information about pushed index conditions.
     @ mysql-test/include/mrr_tests.inc
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr_all.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr_cost.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr_cost_all.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr_cost_icp.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr_icp.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/innodb_mrr_none.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr_all.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr_cost.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr_cost_all.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr_cost_icp.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr_icp.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ mysql-test/r/myisam_mrr_none.result
        Test case for Bug#12321461 CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
     @ sql/handler.cc
        Extend an assert in DsMrr_impl::dsmrr_init() to also pass when the
        handler object does not have an active index.

    modified:
      mysql-test/include/mrr_tests.inc
      mysql-test/r/innodb_mrr.result
      mysql-test/r/innodb_mrr_all.result
      mysql-test/r/innodb_mrr_cost.result
      mysql-test/r/innodb_mrr_cost_all.result
      mysql-test/r/innodb_mrr_cost_icp.result
      mysql-test/r/innodb_mrr_icp.result
      mysql-test/r/innodb_mrr_none.result
      mysql-test/r/myisam_mrr.result
      mysql-test/r/myisam_mrr_all.result
      mysql-test/r/myisam_mrr_cost.result
      mysql-test/r/myisam_mrr_cost_all.result
      mysql-test/r/myisam_mrr_cost_icp.result
      mysql-test/r/myisam_mrr_icp.result
      mysql-test/r/myisam_mrr_none.result
      sql/handler.cc
=== modified file 'mysql-test/include/mrr_tests.inc'
--- a/mysql-test/include/mrr_tests.inc	2011-01-07 08:38:31 +0000
+++ b/mysql-test/include/mrr_tests.inc	2011-05-04 13:24:39 +0000
@@ -377,3 +377,36 @@ eval EXPLAIN $query;
 eval $query;
 
 DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+--echo #
+
+# This test should run with join cache level 0
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+
+CREATE TABLE t1 (
+  pk INTEGER,
+  c1 VARCHAR(1) NOT NULL,
+  PRIMARY KEY (pk)
+);
+
+CREATE TABLE t2 (
+  c1 VARCHAR(1) NOT NULL
+);
+
+INSERT INTO t2 VALUES ('v'), ('c');
+
+let query=
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+
+eval EXPLAIN $query;
+eval $query;
+
+DROP TABLE t1,t2;
+
+# Restore join cache level to its original value
+set optimizer_join_cache_level= @save_join_cache_level;

=== modified file 'mysql-test/r/innodb_mrr.result'
--- a/mysql-test/r/innodb_mrr.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr.result	2011-05-04 13:24:39 +0000
@@ -543,6 +543,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/innodb_mrr_all.result'
--- a/mysql-test/r/innodb_mrr_all.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr_all.result	2011-05-04 13:24:39 +0000
@@ -543,6 +543,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/innodb_mrr_cost.result'
--- a/mysql-test/r/innodb_mrr_cost.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr_cost.result	2011-05-04 13:24:39 +0000
@@ -543,6 +543,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/innodb_mrr_cost_all.result'
--- a/mysql-test/r/innodb_mrr_cost_all.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr_cost_all.result	2011-05-04 13:24:39 +0000
@@ -543,6 +543,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/innodb_mrr_cost_icp.result'
--- a/mysql-test/r/innodb_mrr_cost_icp.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr_cost_icp.result	2011-05-04 13:24:39 +0000
@@ -543,6 +543,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/innodb_mrr_icp.result'
--- a/mysql-test/r/innodb_mrr_icp.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr_icp.result	2011-05-04 13:24:39 +0000
@@ -543,6 +543,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/innodb_mrr_none.result'
--- a/mysql-test/r/innodb_mrr_none.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/innodb_mrr_none.result	2011-05-04 13:24:39 +0000
@@ -542,6 +542,32 @@ ORDER BY i1;
 i1
 DROP TABLE t1, t2;
 #
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
+#
 # Bug#41029 "MRR: SELECT FOR UPDATE fails to lock gaps (InnoDB table)"
 #
 SET AUTOCOMMIT=0;

=== modified file 'mysql-test/r/myisam_mrr.result'
--- a/mysql-test/r/myisam_mrr.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr.result	2011-05-04 13:24:39 +0000
@@ -544,5 +544,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using where; Using MRR
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_mrr_all.result'
--- a/mysql-test/r/myisam_mrr_all.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr_all.result	2011-05-04 13:24:39 +0000
@@ -544,5 +544,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where; Using MRR
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_mrr_cost.result'
--- a/mysql-test/r/myisam_mrr_cost.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr_cost.result	2011-05-04 13:24:39 +0000
@@ -544,5 +544,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_mrr_cost_all.result'
--- a/mysql-test/r/myisam_mrr_cost_all.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr_cost_all.result	2011-05-04 13:24:39 +0000
@@ -544,5 +544,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_mrr_cost_icp.result'
--- a/mysql-test/r/myisam_mrr_cost_icp.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr_cost_icp.result	2011-05-04 13:24:39 +0000
@@ -544,5 +544,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_mrr_icp.result'
--- a/mysql-test/r/myisam_mrr_icp.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr_icp.result	2011-05-04 13:24:39 +0000
@@ -544,5 +544,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using index condition; Using where; Using MRR
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'mysql-test/r/myisam_mrr_none.result'
--- a/mysql-test/r/myisam_mrr_none.result	2011-01-07 08:38:31 +0000
+++ b/mysql-test/r/myisam_mrr_none.result	2011-05-04 13:24:39 +0000
@@ -543,5 +543,31 @@ AND t2.pk IS  NULL
 ORDER BY i1;
 i1
 DROP TABLE t1, t2;
+#
+# Bug#12321461: CRASH IN DSMRR_IMPL::DSMRR_INIT ON SELECT STRAIGHT_JOIN
+#
+set @save_join_cache_level= @@optimizer_join_cache_level;
+set optimizer_join_cache_level=0;
+CREATE TABLE t1 (
+pk INTEGER,
+c1 VARCHAR(1) NOT NULL,
+PRIMARY KEY (pk)
+);
+CREATE TABLE t2 (
+c1 VARCHAR(1) NOT NULL
+);
+INSERT INTO t2 VALUES ('v'), ('c');
+EXPLAIN SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+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	range	PRIMARY	PRIMARY	4	NULL	1	Using where
+SELECT STRAIGHT_JOIN t1.c1
+FROM t1 RIGHT OUTER JOIN t2 ON t1.c1 = t2.c1
+WHERE t1.pk > 176;
+c1
+DROP TABLE t1,t2;
+set optimizer_join_cache_level= @save_join_cache_level;
 set @@read_rnd_buffer_size= @read_rnd_buffer_size_save;
 set optimizer_switch=default;

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2011-05-02 13:22:25 +0000
+++ b/sql/handler.cc	2011-05-04 13:24:39 +0000
@@ -4784,19 +4784,19 @@ int DsMrr_impl::dsmrr_init(handler *h_ar
   /* 
     This assert will hit if we have pushed an index condition to the
     primary key index and then "change our mind" and use a different
-    index for retrieving data with MRR.
-
-    This assert is too strict for the existing code. If an index
-    condition has been pushed on the primary index the existing code
-    does not clean up information about the pushed index condition when
-    the index scan is completed. Disables the assert until we have
-    a fix for better cleaning up after a pushed index condition. 
+    index for retrieving data with MRR. One of the following criteria
+    must be true:
+      1. We have not pushed an index conditon on this handler.
+      2. We have pushed an index condition and this is on the currently used
+         index.
+      3. We have pushed an index condition but this is not for the primary key.
+      4. We have pushed an index condition and this has been transferred to 
+         the clone (h2) of the handler object.
   */
-  /*
   DBUG_ASSERT(!h->pushed_idx_cond ||
               h->pushed_idx_cond_keyno == h->active_index ||
-              h->pushed_idx_cond_keyno != table->s->primary_key);
-  */
+              h->pushed_idx_cond_keyno != table->s->primary_key ||
+              (h2 && h->pushed_idx_cond_keyno == h2->active_index));
 
   rowids_buf= buf->buffer;
 
@@ -4869,7 +4869,26 @@ int DsMrr_impl::dsmrr_init(handler *h_ar
     /*
       We get here when the access alternates betwen MRR scan(s) and non-MRR
       scans.
+    */
 
+    /* 
+      Verify consistency between the two handler objects:
+      1. The main handler should either use the primary key or not have an
+         active index at this point since the clone handler (h2) is used for
+         reading the index.
+      2. The index used for ICP should be the same for the two handlers or
+         it should not be set on the clone handler (h2).
+      3. The ICP function should be the same for the two handlers or it should
+         not be set for the clone handler (h2).
+    */
+    DBUG_ASSERT(h->active_index == table->s->primary_key ||
+                h->active_index == MAX_KEY);
+    DBUG_ASSERT(h->pushed_idx_cond_keyno == h2->pushed_idx_cond_keyno || 
+                h2->pushed_idx_cond_keyno == MAX_KEY);
+    DBUG_ASSERT(h->pushed_idx_cond == h2->pushed_idx_cond || 
+                h2->pushed_idx_cond == NULL);
+
+    /*
       Calling h->index_end() will invoke dsmrr_close() for this object,
       which will delete h2. We need to keep it, so save put it away and dont
       let it be deleted:


Attachment: [text/bzr-bundle] bzr/olav.sandstaa@oracle.com-20110504132439-h74ya3vrc4ux24i5.bundle
Thread
bzr commit into mysql-trunk branch (olav.sandstaa:3368) Bug#12321461Olav Sandstaa4 May
  • Re: bzr commit into mysql-trunk branch (olav.sandstaa:3368) Bug#12321461Jorgen Loland5 May
    • Re: bzr commit into mysql-trunk branch (olav.sandstaa:3368) Bug#12321461Olav Sandstaa5 May
      • Re: bzr commit into mysql-trunk branch (olav.sandstaa:3368) Bug#12321461Jorgen Loland5 May