summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
authorVarun Gupta <varun.gupta@mariadb.com>2020-08-18 17:31:10 +0530
committerVarun Gupta <varun.gupta@mariadb.com>2020-08-19 14:45:19 +0530
commitd08b9d3c1c5be5dc183b1384730973be0e70c44d (patch)
tree4463a9041ea33e822be6b4949f2afb21f8e5f53d /sql/sql_lex.cc
parent8ddc2182fdfd8f8b8dcffccb4605cd9deac35c7a (diff)
downloadmariadb-git-10.1-varun.tar.gz
MDEV-23160: SIGSEGV in Explain_node::print_explain_for_children on UNION SELECT or on EXPLAIN EXTENDED10.1-varun
The issue here was that the ORDER BY clause had a subquery and the ORDER BY clause was defined for a UNION inside an IN subquery. For IN/ALL/ANY subquery the ORDER BY clause makes no sense and should be removed. But the removal of the ORDER BY clause happened before name resolution. So an invalid query could also be parsed and would not return an error. The reason for the crash is that for EXPLAIN of UNION, the fake_select_lex adds the removed subquery as its child. The subquery being removed does not create a node for itself for EXPLAIN. But when the EXPLAIN is printed for the fake_select_lex it tries to print the nodes of its children. The fix would be to mark the subquery to be eliminated so that it is not added as a child to the fake_select_lex node. Then after name resolution is done and the query is valid then remove the subquery so that it does not get executed.
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc38
1 files changed, 36 insertions, 2 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index e863308159e..853b4d8cc1a 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -3170,7 +3170,41 @@ bool st_select_lex_unit::union_needs_tmp_table()
global_parameters()->order_list.elements != 0 ||
thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
thd->lex->sql_command == SQLCOM_REPLACE_SELECT;
-}
+}
+
+
+/*
+ @brief
+ Check if the ORDER BY clause is redundant or empty
+
+ @retval
+ TRUE order by is redundant or empty
+ FALSE OTHERWISE
+*/
+
+bool st_select_lex_unit::is_order_by_clause_redundant()
+{
+ if (global_parameters()->order_list.elements == 0)
+ return true;
+ if (is_union_op_inside_in_predicate())
+ return true;
+ return false;
+}
+
+
+/*
+ @brief
+ Check if UNION is in side an IN/ALL/ANY subquery
+
+ @retval
+ TRUE UNION inside in an IN/ALL/ANY subquery
+ FALSE Otherwise
+*/
+bool st_select_lex_unit::is_union_op_inside_in_predicate()
+{
+ return is_union() && item && item->is_in_predicate();
+}
+
/**
@brief Set the initial purpose of this TABLE_LIST object in the list of used
@@ -4678,7 +4712,7 @@ int st_select_lex_unit::save_union_explain(Explain_query *output)
eu->add_select(sl->select_number);
eu->fake_select_type= "UNION RESULT";
- eu->using_filesort= MY_TEST(global_parameters()->order_list.first);
+ eu->using_filesort= MY_TEST(!is_order_by_clause_redundant());
eu->using_tmp= union_needs_tmp_table();
// Save the UNION node