diff options
author | Varun Gupta <varun.gupta@mariadb.com> | 2020-08-04 14:36:01 +0530 |
---|---|---|
committer | Varun Gupta <varun.gupta@mariadb.com> | 2020-08-06 10:55:03 +0530 |
commit | ab578bdf453c3cb0e9ca561cf373f64c96b22fda (patch) | |
tree | 72419bb4e1b55c503d13dbaaa60555eb93122b4e | |
parent | 0e80f5a6934692dd7a47b6d31104fa194bbf18ec (diff) | |
download | mariadb-git-ab578bdf453c3cb0e9ca561cf373f64c96b22fda.tar.gz |
MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index
Removing the ORDER BY clause from the UNION when UNION is inside an IN/ALL/ANY/EXISTS subquery.
The rewrites are done for subqueries but this rewrite is not done for the fake_select of
the UNION.
-rw-r--r-- | mysql-test/r/subselect4.result | 41 | ||||
-rw-r--r-- | mysql-test/t/subselect4.test | 25 | ||||
-rw-r--r-- | sql/item_subselect.h | 4 | ||||
-rw-r--r-- | sql/sql_union.cc | 19 |
4 files changed, 89 insertions, 0 deletions
diff --git a/mysql-test/r/subselect4.result b/mysql-test/r/subselect4.result index 606ab847028..e7655131fcf 100644 --- a/mysql-test/r/subselect4.result +++ b/mysql-test/r/subselect4.result @@ -2608,3 +2608,44 @@ region area population Central America and the Caribbean 442 66422 SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; +# +# MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +EXPLAIN +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 +2 SUBQUERY A ALL NULL NULL NULL NULL 2 +3 UNION B ALL NULL NULL NULL NULL 2 +NULL UNION RESULT <union2,3> ALL NULL NULL NULL NULL NULL +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where +2 DEPENDENT SUBQUERY A ALL NULL NULL NULL NULL 2 Using where +3 DEPENDENT UNION B ALL NULL NULL NULL NULL 2 Using where +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +a +1 +2 +DROP TABLE t1,t2; +# end of 10.1 tests diff --git a/mysql-test/t/subselect4.test b/mysql-test/t/subselect4.test index 21ec28b1c03..8f1ad51ca50 100644 --- a/mysql-test/t/subselect4.test +++ b/mysql-test/t/subselect4.test @@ -2138,3 +2138,28 @@ WHERE population/area = (SELECT MAX(population/area) from t1 B where A.region = SET @@optimizer_switch= @save_optimizer_switch; DROP TABLE t1; + +--echo # +--echo # MDEV-9513: Assertion `join->group_list || !join->is_in_subquery()' failed in create_sort_index +--echo # + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (a INT); +INSERT INTO t2 VALUES (2),(3); +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); + +EXPLAIN +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE EXISTS (SELECT A.a FROM t1 A UNION SELECT B.a FROM t2 B ORDER BY 1); + +EXPLAIN +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); +SELECT t1.a FROM t1 WHERE t1.a IN ( SELECT A.a FROM t1 A UNION ALL SELECT B.a FROM t2 B ORDER BY 1); + +DROP TABLE t1,t2; + +--echo # end of 10.1 tests diff --git a/sql/item_subselect.h b/sql/item_subselect.h index ee8b31f4f17..9771b067ac4 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -131,6 +131,10 @@ public: Item_subselect(THD *thd); virtual subs_type substype() { return UNKNOWN_SUBS; } + bool is_exists_predicate() + { + return substype() == Item_subselect::EXISTS_SUBS; + } bool is_in_predicate() { return (substype() == Item_subselect::IN_SUBS || diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 38de2d592ed..0e623777ef0 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -388,6 +388,25 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; is_union_select= is_union() || fake_select_lex; + /* + If we are reading UNION output and the UNION is in the + IN/ANY/ALL/EXISTS subquery, then ORDER BY is redundant and hence should + be removed. + Example: + select ... col IN (select col2 FROM t1 union select col3 from t2 ORDER BY 1) + + (as for ORDER BY ... LIMIT, it currently not supported inside + IN/ALL/ANY subqueries) + (For non-UNION this removal of ORDER BY clause is done in + check_and_do_in_subquery_rewrites()) + */ + if (is_union() && item && + (item->is_in_predicate() || item->is_exists_predicate())) + { + global_parameters()->order_list.first= NULL; + global_parameters()->order_list.elements= 0; + } + /* Global option */ if (is_union_select) |