mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT
and also MDEV-25564, MDEV-18157. Attempt to produce EXPLAIN output caused a crash in Explain_node::print_explain_for_children. The cause of this was that an Explain_node (actually a derived) had a link to child select#N, but there was no query plan present for select#N. The query plan wasn't present because the subquery was eliminated. - Either it was a degenerate subquery like "(SELECT 1)" in MDEV-25564. - Or it was a subquery in a UNION subquery's ORDER BY clause: col IN (SELECT ... UNION SELECT ... ORDER BY (SELECT FROM t1)) In such cases, legacy code structure in subquery/union processing code(*) makes it hard to detect that the subquery was eliminated, so we end up with EXPLAIN data structures (Explain_node::children) having dangling links to child subqueries. Do make the checks and don't follow the dangling links. (In ideal world, we should not have these dangling links. But fixing the code (*) would have high risk for the stable versions).
This commit is contained in:
@ -407,3 +407,49 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||||||
2 SUBQUERY t1 system NULL NULL NULL NULL 1
|
2 SUBQUERY t1 system NULL NULL NULL NULL 1
|
||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
|
#
|
||||||
|
# End of 10.2 test
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# MDEV-25564: Server crashed on running some EXPLAIN statements
|
||||||
|
#
|
||||||
|
EXPLAIN (SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL Using filesort
|
||||||
|
Warnings:
|
||||||
|
Note 1249 Select 3 was reduced during optimization
|
||||||
|
#
|
||||||
|
# MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT
|
||||||
|
#
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
EXPLAIN
|
||||||
|
SELECT *
|
||||||
|
FROM t1
|
||||||
|
WHERE
|
||||||
|
a IN (SELECT a FROM t1
|
||||||
|
UNION
|
||||||
|
SELECT a FROM t1 ORDER BY (SELECT a))
|
||||||
|
UNION
|
||||||
|
SELECT * FROM t1 ORDER BY (SELECT a);
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||||
|
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||||
|
3 DEPENDENT UNION t1 ALL NULL NULL NULL NULL 3 Using where
|
||||||
|
NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL
|
||||||
|
5 UNION t1 ALL NULL NULL NULL NULL 3
|
||||||
|
NULL UNION RESULT <union1,5> ALL NULL NULL NULL NULL NULL Using filesort
|
||||||
|
6 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
drop table t1;
|
||||||
|
explain
|
||||||
|
VALUES ( (VALUES (2))) UNION VALUES ( (SELECT 3));
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
5 SUBQUERY <derived2> ALL NULL NULL NULL NULL 2
|
||||||
|
2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used
|
||||||
|
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL
|
||||||
|
Warnings:
|
||||||
|
Note 1249 Select 4 was reduced during optimization
|
||||||
|
@ -333,3 +333,34 @@ explain replace into t2 select 100, (select a from t1);
|
|||||||
drop table t1, t2;
|
drop table t1, t2;
|
||||||
|
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # End of 10.2 test
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-25564: Server crashed on running some EXPLAIN statements
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
EXPLAIN (SELECT 1,3) UNION (SELECT 2,1) ORDER BY (SELECT 2);
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
INSERT INTO t1 VALUES (1),(2),(3);
|
||||||
|
|
||||||
|
EXPLAIN
|
||||||
|
SELECT *
|
||||||
|
FROM t1
|
||||||
|
WHERE
|
||||||
|
a IN (SELECT a FROM t1
|
||||||
|
UNION
|
||||||
|
SELECT a FROM t1 ORDER BY (SELECT a))
|
||||||
|
UNION
|
||||||
|
SELECT * FROM t1 ORDER BY (SELECT a);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
explain
|
||||||
|
VALUES ( (VALUES (2))) UNION VALUES ( (SELECT 3));
|
||||||
|
@ -639,7 +639,11 @@ int Explain_node::print_explain_for_children(Explain_query *query,
|
|||||||
for (int i= 0; i < (int) children.elements(); i++)
|
for (int i= 0; i < (int) children.elements(); i++)
|
||||||
{
|
{
|
||||||
Explain_node *node= query->get_node(children.at(i));
|
Explain_node *node= query->get_node(children.at(i));
|
||||||
if (node->print_explain(query, output, explain_flags, is_analyze))
|
/*
|
||||||
|
Note: node may not be present because for certain kinds of subqueries,
|
||||||
|
the optimizer is not able to see that they were eliminated.
|
||||||
|
*/
|
||||||
|
if (node && node->print_explain(query, output, explain_flags, is_analyze))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -683,8 +687,15 @@ void Explain_node::print_explain_json_for_children(Explain_query *query,
|
|||||||
for (int i= 0; i < (int) children.elements(); i++)
|
for (int i= 0; i < (int) children.elements(); i++)
|
||||||
{
|
{
|
||||||
Explain_node *node= query->get_node(children.at(i));
|
Explain_node *node= query->get_node(children.at(i));
|
||||||
/* Derived tables are printed inside Explain_table_access objects */
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Note: node may not be present because for certain kinds of subqueries,
|
||||||
|
the optimizer is not able to see that they were eliminated.
|
||||||
|
*/
|
||||||
|
if (!node)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* Derived tables are printed inside Explain_table_access objects */
|
||||||
if (!is_connection_printable_in_json(node->connection_type))
|
if (!is_connection_printable_in_json(node->connection_type))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user