diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2021-09-20 19:55:57 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2021-09-23 09:48:02 +0200 |
commit | 818efba5bec916b2025602370afc2d7908f0693d (patch) | |
tree | 03664571e98bebf5bab3a36e6a4d196195f42447 | |
parent | 1cb218c37cc3fe01a1ff2fe9b1cbfb591e90d5ce (diff) | |
download | mariadb-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.result | 13 | ||||
-rw-r--r-- | mysql-test/t/explain.test | 10 | ||||
-rw-r--r-- | sql/item_subselect.cc | 22 | ||||
-rw-r--r-- | sql/sql_explain.h | 14 |
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, |