summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2021-09-20 19:55:57 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2021-09-23 09:48:02 +0200
commit818efba5bec916b2025602370afc2d7908f0693d (patch)
tree03664571e98bebf5bab3a36e6a4d196195f42447
parent1cb218c37cc3fe01a1ff2fe9b1cbfb591e90d5ce (diff)
downloadmariadb-git-818efba5bec916b2025602370afc2d7908f0693d.tar.gz
MDEV-25564 Server crashed on running some EXPLAIN statements
Exclude from explain substituted single value subquery without tables.
-rw-r--r--mysql-test/r/explain.result13
-rw-r--r--mysql-test/t/explain.test10
-rw-r--r--sql/item_subselect.cc22
-rw-r--r--sql/sql_explain.h14
4 files changed, 58 insertions, 1 deletions
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 6d73f1ac4d6..fa8e014ed23 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -407,3 +407,16 @@ id select_type table type possible_keys key key_len ref rows Extra
2 SUBQUERY t1 system NULL NULL NULL NULL 1
drop table t1, t2;
# End of 10.1 tests
+#
+# 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
+#
+# End of 10.2 test
+#
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index d5be354c852..9d8c6245d56 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -333,3 +333,13 @@ explain replace into t2 select 100, (select a from t1);
drop table t1, t2;
--echo # End of 10.1 tests
+
+--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 # End of 10.2 test
+--echo #
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 25621dfe104..884b7bdf0c2 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1205,6 +1205,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
)
{
have_to_be_excluded= 1;
+ // this should work but no
+ this->eliminated= 1;
if (thd->lex->describe)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
@@ -1213,6 +1215,26 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
ER_SELECT_REDUCED, warn_buff);
}
+ if (thd->lex->explain)
+ {
+ /*
+ Exclude explain node of this subselect, because it will be
+ eliminamed
+ */
+ SELECT_LEX *outer= select_lex->outer_select();
+ Explain_node *parent;
+ if (outer->master_unit()->fake_select_lex != outer)
+ parent= thd->lex->explain->get_select(outer->select_number);
+ else
+ /*
+ subqueries of fake_select connected to explain node of the unit
+ (not fake select)
+ */
+ parent=
+ thd->lex->explain->get_union(outer->master_unit()->first_select()->
+ select_number);
+ parent->remove_child((int)select_lex->select_number);
+ }
substitution= select_lex->item_list.head();
/*
as far as we moved content to upper level we have to fix dependences & Co
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 08af84b3562..54ed3c55ee0 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -124,13 +124,25 @@ public:
/*
A node may have children nodes. When a node's explain structure is
created, children nodes may not yet have QPFs. This is why we store ids.
+
+ TODO: shoud be unsigned as SELECT_LEX::select_number
*/
Dynamic_array<int> children;
void add_child(int select_no)
{
children.append(select_no);
}
-
+ void remove_child(int select_no)
+ {
+ for (int i= 0; i < (int) children.elements(); i++)
+ {
+ if ((children.at(i)) == select_no)
+ {
+ children.del(i);
+ return;
+ }
+ }
+ }
virtual int print_explain(Explain_query *query, select_result_sink *output,
uint8 explain_flags, bool is_analyze)=0;
virtual void print_explain_json(Explain_query *query, Json_writer *writer,