Skip to content

Commit 7922fbf

Browse files
committed
MDEV-26249: Crash in Explain_node::print_explain_for_children with slow query log
The problem affected queries in form: SELECT FROM (SELECT where Split Materialized is applicable) WHERE 1=0 The problem was caused by this: - The select in derived table uses two-phase optimization (due to a possible Split Materialized). - The primary select has "Impossible where" and so it short-cuts its optimization. - The optimization for the SELECT in the derived table is never finished, and EXPLAIN data structure has a dangling pointer to select #2. Fixed with this: make JOIN::optimize_stage2() invoke optimization of derived tables when it is handing a degenerate JOIN with zero tables. We will not execute the derived tables but we need their query plans for [SHOW]EXPLAIN.
1 parent dfbfd39 commit 7922fbf

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#
2+
# MDEV-26249: Crash in in Explain_node::print_explain_for_children while writing to the slow query log
3+
#
4+
set @sql_tmp=@@slow_query_log;
5+
SET GLOBAL slow_query_log = 1;
6+
SET long_query_time = 0.000000;
7+
SET log_slow_verbosity = 'explain';
8+
CREATE TABLE t1 ( id varchar(50), KEY (id)) engine=innodb;
9+
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
10+
id
11+
select 1;
12+
1
13+
1
14+
explain
15+
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
16+
id select_type table type possible_keys key key_len ref rows Extra
17+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
18+
2 DERIVED t1 index NULL id 53 NULL 1 Using index
19+
SET GLOBAL slow_query_log = @sql_tmp;
20+
drop table t1;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--echo #
2+
--echo # MDEV-26249: Crash in in Explain_node::print_explain_for_children while writing to the slow query log
3+
--echo #
4+
5+
--source include/have_innodb.inc
6+
7+
set @sql_tmp=@@slow_query_log;
8+
SET GLOBAL slow_query_log = 1;
9+
SET long_query_time = 0.000000;
10+
SET log_slow_verbosity = 'explain';
11+
12+
CREATE TABLE t1 ( id varchar(50), KEY (id)) engine=innodb;
13+
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
14+
select 1;
15+
16+
explain
17+
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
18+
19+
SET GLOBAL slow_query_log = @sql_tmp;
20+
drop table t1;

sql/sql_select.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2732,6 +2732,14 @@ int JOIN::optimize_stage2()
27322732
}
27332733
if (make_aggr_tables_info())
27342734
DBUG_RETURN(1);
2735+
2736+
/*
2737+
It could be that we've only done optimization stage 1 for
2738+
some of the derived tables, and never did stage 2.
2739+
Do it now, otherwise Explain data structure will not be complete.
2740+
*/
2741+
if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
2742+
DBUG_RETURN(1);
27352743
}
27362744
/*
27372745
Even with zero matching rows, subqueries in the HAVING clause may

0 commit comments

Comments
 (0)