summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2014-10-20 23:35:34 +0400
committerSergey Petrunya <psergey@askmonty.org>2014-10-20 23:35:34 +0400
commit1a996bde1e3721b8d2d05c9477ee2dd7921d3fdc (patch)
treeed67259d2ccd80fd6f6c623635282ac4441b656a
parent8925b4a935115aef51cfff22564ee2b0d5fb5fce (diff)
downloadmariadb-git-1a996bde1e3721b8d2d05c9477ee2dd7921d3fdc.tar.gz
MDEV-6879: Dereference of NULL primary_file->table in DsMrr_impl::get_disk_sweep_mrr_cost()
(Attempt #2) - Don't attempt to use BKA for materialized derived tables. The table is neither filled nor fully opened yet, so attempt to call handler->multi_range_read_info() causes crash.
-rw-r--r--mysql-test/r/derived_opt.result29
-rw-r--r--mysql-test/t/derived_opt.test29
-rw-r--r--sql/sql_select.cc15
3 files changed, 72 insertions, 1 deletions
diff --git a/mysql-test/r/derived_opt.result b/mysql-test/r/derived_opt.result
index f5e7393591c..acce984b01c 100644
--- a/mysql-test/r/derived_opt.result
+++ b/mysql-test/r/derived_opt.result
@@ -352,4 +352,33 @@ pk pk
72 72
80 80
drop table t1, t2, t3, t4;
+#
+# MDEV-6879: Dereference of NULL primary_file->table in DsMrr_impl::get_disk_sweep_mrr_cost()
+#
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t2 (a int, b int, c text);
+insert into t2
+select
+A.a + B.a* 10,
+A.a + B.a* 10,
+'blob-data'
+from t1 A, t1 B;
+set @tmp_jcl= @@join_cache_level;
+set @tmp_os= @@optimizer_switch;
+set join_cache_level=6;
+set @@optimizer_switch='derived_merge=on,derived_with_keys=on,mrr=on';
+explain
+select * from
+t1 join
+(select * from t2 order by a limit 1000) as D1
+where
+D1.a= t1.a;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY <derived2> hash_ALL key0 #hash#key0 5 test.t1.a 100 Using join buffer (flat, BNLH join)
+2 DERIVED t2 ALL NULL NULL NULL NULL 100 Using filesort
+set join_cache_level=@tmp_jcl;
+set optimizer_switch=@tmp_os;
+drop table t1, t2;
set optimizer_switch=@exit_optimizer_switch;
diff --git a/mysql-test/t/derived_opt.test b/mysql-test/t/derived_opt.test
index b01c479111b..737beb6cb35 100644
--- a/mysql-test/t/derived_opt.test
+++ b/mysql-test/t/derived_opt.test
@@ -272,5 +272,34 @@ limit 10;
drop table t1, t2, t3, t4;
+--echo #
+--echo # MDEV-6879: Dereference of NULL primary_file->table in DsMrr_impl::get_disk_sweep_mrr_cost()
+--echo #
+create table t1(a int);
+insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t2 (a int, b int, c text);
+insert into t2
+select
+ A.a + B.a* 10,
+ A.a + B.a* 10,
+ 'blob-data'
+from t1 A, t1 B;
+
+set @tmp_jcl= @@join_cache_level;
+set @tmp_os= @@optimizer_switch;
+set join_cache_level=6;
+set @@optimizer_switch='derived_merge=on,derived_with_keys=on,mrr=on';
+explain
+select * from
+ t1 join
+ (select * from t2 order by a limit 1000) as D1
+where
+ D1.a= t1.a;
+
+set join_cache_level=@tmp_jcl;
+set optimizer_switch=@tmp_os;
+drop table t1, t2;
+
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 149c6d1126c..3a4aa41378d 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -10550,6 +10550,19 @@ uint check_join_cache_usage(JOIN_TAB *tab,
}
/*
+ Don't use BKA for materialized tables. We could actually have a
+ meaningful use of BKA when linked join buffers are used.
+
+ The problem is, the temp.table is not filled (actually not even opened
+ properly) yet, and this doesn't let us call
+ handler->multi_range_read_info(). It is possible to come up with
+ estimates, etc. without acessing the table, but it seems not to worth the
+ effort now.
+ */
+ if (tab->table->pos_in_table_list->is_materialized_derived())
+ no_bka_cache= true;
+
+ /*
Don't use join buffering if we're dictated not to by no_jbuf_after
(This is not meaningfully used currently)
*/
@@ -10615,7 +10628,7 @@ uint check_join_cache_usage(JOIN_TAB *tab,
if (tab->ref.is_access_triggered())
goto no_join_cache;
- if (!tab->is_ref_for_hash_join())
+ if (!tab->is_ref_for_hash_join() && !no_bka_cache)
{
flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
if (tab->table->covering_keys.is_set(tab->ref.key))