[Commits] 8fb140b9f8f: MDEV-26249: Crash in Explain_node::print_explain_for_children with slow query log
revision-id: 8fb140b9f8f8b10c1d952247f499d87265fddac9 (mariadb-10.3.31-70-g8fb140b9f8f) parent(s): 9962cda52722b77c2a7e0314bbaa2e4f963f55c1 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2022-01-19 23:14:00 +0300 message: 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. --- mysql-test/main/explain_innodb.result | 20 ++++++++++++++++++++ mysql-test/main/explain_innodb.test | 20 ++++++++++++++++++++ sql/sql_select.cc | 8 ++++++++ 3 files changed, 48 insertions(+) diff --git a/mysql-test/main/explain_innodb.result b/mysql-test/main/explain_innodb.result new file mode 100644 index 00000000000..fe51e45e35d --- /dev/null +++ b/mysql-test/main/explain_innodb.result @@ -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; diff --git a/mysql-test/main/explain_innodb.test b/mysql-test/main/explain_innodb.test new file mode 100644 index 00000000000..2c29a6e26da --- /dev/null +++ b/mysql-test/main/explain_innodb.test @@ -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; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fe02e7b44e4..8a0c649f523 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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
participants (1)
-
Sergei Petrunia