Skip to content

Commit

Permalink
MDEV-26249: Crash in Explain_node::print_explain_for_children with sl…
Browse files Browse the repository at this point in the history
…ow 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.
  • Loading branch information
spetrunia committed Jan 19, 2022
1 parent dfbfd39 commit 7922fbf
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 0 deletions.
20 changes: 20 additions & 0 deletions mysql-test/main/explain_innodb.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#
# MDEV-26249: Crash in in Explain_node::print_explain_for_children while writing to the slow query log
#
set @sql_tmp=@@slow_query_log;
SET GLOBAL slow_query_log = 1;
SET long_query_time = 0.000000;
SET log_slow_verbosity = 'explain';
CREATE TABLE t1 ( id varchar(50), KEY (id)) engine=innodb;
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
id
select 1;
1
1
explain
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
2 DERIVED t1 index NULL id 53 NULL 1 Using index
SET GLOBAL slow_query_log = @sql_tmp;
drop table t1;
20 changes: 20 additions & 0 deletions mysql-test/main/explain_innodb.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
--echo #
--echo # MDEV-26249: Crash in in Explain_node::print_explain_for_children while writing to the slow query log
--echo #

--source include/have_innodb.inc

set @sql_tmp=@@slow_query_log;
SET GLOBAL slow_query_log = 1;
SET long_query_time = 0.000000;
SET log_slow_verbosity = 'explain';

CREATE TABLE t1 ( id varchar(50), KEY (id)) engine=innodb;
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;
select 1;

explain
SELECT * FROM (SELECT id FROM t1 GROUP BY id) dt WHERE 1=0;

SET GLOBAL slow_query_log = @sql_tmp;
drop table t1;
8 changes: 8 additions & 0 deletions sql/sql_select.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2732,6 +2732,14 @@ int JOIN::optimize_stage2()
}
if (make_aggr_tables_info())
DBUG_RETURN(1);

/*
It could be that we've only done optimization stage 1 for
some of the derived tables, and never did stage 2.
Do it now, otherwise Explain data structure will not be complete.
*/
if (select_lex->handle_derived(thd->lex, DT_OPTIMIZE))
DBUG_RETURN(1);
}
/*
Even with zero matching rows, subqueries in the HAVING clause may
Expand Down

0 comments on commit 7922fbf

Please sign in to comment.