1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-22993: Crash on EXPLAIN with PUSHED DOWN SELECT and subquery

- select_describe() should not attempt to produce query plans
  for subqueries if the query is handled by a Select Handler.

- JOIN::save_explain_data_intern should not add links to Explain_select
  for children selects if:
  1. The whole query is handled by the Select Handler, or
  2. this select (and so its children) is handled by Derived Handler.
This commit is contained in:
Sergei Petrunia
2020-06-23 23:28:37 +03:00
parent b80b52394d
commit b4abe7c91f
3 changed files with 143 additions and 38 deletions

View File

@ -26840,24 +26840,33 @@ int JOIN::save_explain_data_intern(Explain_query *output,
output->add_node(xpl_sel);
}
for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit();
tmp_unit;
tmp_unit= tmp_unit->next_unit())
/*
Don't try to add query plans for child selects if this select was pushed
down into a Smart Storage Engine:
- the entire statement was pushed down ("PUSHED SELECT"), or
- this derived table was pushed down ("PUSHED DERIVED")
*/
if (!select_lex->pushdown_select && select_lex->type != pushed_derived_text)
{
/*
Display subqueries only if
(1) they are not parts of ON clauses that were eliminated by table
elimination.
(2) they are not merged derived tables
(3) they are not hanging CTEs (they are needed for execution)
*/
if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1)
(!tmp_unit->derived ||
tmp_unit->derived->is_materialized_derived()) && // (2)
!(tmp_unit->with_element &&
(!tmp_unit->derived || !tmp_unit->derived->derived_result))) // (3)
{
explain->add_child(tmp_unit->first_select()->select_number);
for (SELECT_LEX_UNIT *tmp_unit= join->select_lex->first_inner_unit();
tmp_unit;
tmp_unit= tmp_unit->next_unit())
{
/*
Display subqueries only if
(1) they are not parts of ON clauses that were eliminated by table
elimination.
(2) they are not merged derived tables
(3) they are not hanging CTEs (they are needed for execution)
*/
if (!(tmp_unit->item && tmp_unit->item->eliminated) && // (1)
(!tmp_unit->derived ||
tmp_unit->derived->is_materialized_derived()) && // (2)
!(tmp_unit->with_element &&
(!tmp_unit->derived || !tmp_unit->derived->derived_result))) // (3)
{
explain->add_child(tmp_unit->first_select()->select_number);
}
}
}
@ -26890,7 +26899,16 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
THD *thd=join->thd;
select_result *result=join->result;
DBUG_ENTER("select_describe");
if (join->select_lex->pushdown_select)
{
/*
The whole statement was pushed down to a Smart Storage Engine. Do not
attempt to produce a query plan locally.
*/
DBUG_VOID_RETURN;
}
/* Update the QPF with latest values of using_temporary, using_filesort */
for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
unit;