Details
Description
When joining against a derived table where MRR is chosen by the optimizer, in DsMrr_impl::get_disk_sweep_mrr_cost, primary_file->table (accessed as table) is NULL but is dereferenced.
#3 0x0000000001000a9c in DsMrr_impl::get_disk_sweep_mrr_cost (this=this@entry=0x267c7278, keynr=keynr@entry=0, rows=rows@entry=20, flags=<optimized out>, buffer_size=buffer_size@entry=0x7f223bd5cc8c, cost=cost@entry=0x7f223bd5cb70) at sql/multi_range_read.cc:1722
|
|
1711| /* Adjust buffer size if we expect to use only part of the buffer */
|
1712| if (n_full_steps)
|
1713| {
|
1714| get_sort_and_sweep_cost(table, rows_in_full_step, cost);
|
1715| cost->multiply(n_full_steps);
|
1716| }
|
1717| else
|
1718| {
|
1719| cost->reset();
|
1720| *buffer_size= MY_MAX(*buffer_size,
|
1721| (size_t)(1.2*rows_in_last_step) * elem_size +
|
1722+> primary_file->ref_length + table->key_info[keynr].key_length);
|
1723| }
|
|
(gdb) p primary_file
|
$1 = (handler *) 0x267c6e20
|
(gdb) p table
|
$2 = (TABLE *) 0x0
|
Unfortunately I don't have a non-sensitive reproducible test case to provide, but the following patch fixes the problem for us by disabling MRR for joins against derived tables. It's unclear if this is the right solution or if it's a "big hammer" approach – alternate approaches are welcome.
Patch follows:
--- sql/sql_select.cc 2014-07-21 17:18:26.000000000 -0700
|
+++ sql/sql_select.cc 2014-09-18 22:46:52.000000000 -0700
|
@@ -10595,6 +10595,9 @@ uint check_join_cache_usage(JOIN_TAB *ta
|
if (tab->ref.is_access_triggered())
|
goto no_join_cache;
|
|
+ if (tab->table->pos_in_table_list->is_materialized_derived())
|
+ goto no_join_cache;
|
+
|
if (!tab->is_ref_for_hash_join())
|
{
|
flags= HA_MRR_NO_NULL_ENDPOINTS | HA_MRR_SINGLE_POINT;
|
Testcase:
create table ten(a int);
insert into ten values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
create table one_k(a int);
insert into one_k select A.a + B.a* 10 + C.a * 100 from ten A, ten B, ten C;
create table t10 (a int);
insert into t10 select * from ten;
create table t12 (a int, b int, c text);
insert into t12 select a,a,'blob-data' from one_k;
set join_cache_level=6;
set @@optimizer_switch='derived_merge=on,derived_with_keys=on,mrr=on';
explain
select * from
t10 join
(select * from t12 order by a limit 1000) as D1
where
D1.a= t10.a;