Commit 393cf51c authored by Sergei Petrunia's avatar Sergei Petrunia

MDEV-24925: Server crashes in Item_subselect::init_expr_cache_tracker

The optimizer removes redundant GROUP BY operations. If GROUP BY element
is a subselect, it is "eliminated".

However one must not eliminate the item if it is used both in the select
list and in the GROUP BY, like so:

  select (select ... ) as SUBQ from ... group by SUBQ

Do not eliminate such items.
parent 2c9bf0ae
...@@ -2786,4 +2786,54 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -2786,4 +2786,54 @@ id select_type table type possible_keys key key_len ref rows Extra
set names default; set names default;
set @@in_predicate_conversion_threshold= @save_in_predicate_conversion_threshold; set @@in_predicate_conversion_threshold= @save_in_predicate_conversion_threshold;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-24925: Server crashes in Item_subselect::init_expr_cache_tracker
#
CREATE TABLE t1 (id INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2);
SELECT
1 IN (
SELECT
(SELECT COUNT(id)
FROM t1
WHERE t1_outer.id <> id
) AS f
FROM
t1 AS t1_outer
GROUP BY f
);
1 IN (
SELECT
(SELECT COUNT(id)
FROM t1
WHERE t1_outer.id <> id
) AS f
FROM
t1 AS t1_outer
GROUP BY f
)
1
SELECT
1 IN (
SELECT
(SELECT COUNT(id)
FROM t1
WHERE t1_outer.id <> id
) AS f
FROM
t1 AS t1_outer
GROUP BY 1
);
1 IN (
SELECT
(SELECT COUNT(id)
FROM t1
WHERE t1_outer.id <> id
) AS f
FROM
t1 AS t1_outer
GROUP BY 1
)
1
DROP TABLE t1;
# End of 10.3 tests # End of 10.3 tests
...@@ -2308,4 +2308,36 @@ set names default; ...@@ -2308,4 +2308,36 @@ set names default;
set @@in_predicate_conversion_threshold= @save_in_predicate_conversion_threshold; set @@in_predicate_conversion_threshold= @save_in_predicate_conversion_threshold;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-24925: Server crashes in Item_subselect::init_expr_cache_tracker
--echo #
CREATE TABLE t1 (id INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2);
SELECT
1 IN (
SELECT
(SELECT COUNT(id)
FROM t1
WHERE t1_outer.id <> id
) AS f
FROM
t1 AS t1_outer
GROUP BY f
);
SELECT
1 IN (
SELECT
(SELECT COUNT(id)
FROM t1
WHERE t1_outer.id <> id
) AS f
FROM
t1 AS t1_outer
GROUP BY 1
);
DROP TABLE t1;
--echo # End of 10.3 tests --echo # End of 10.3 tests
...@@ -596,7 +596,16 @@ void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex) ...@@ -596,7 +596,16 @@ void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex)
{ {
for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next) for (ORDER *ord= subq_select_lex->group_list.first; ord; ord= ord->next)
{ {
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL); /*
Do not remove the item if it is used in select list and then referred
from GROUP BY clause by its name or number. Example:
select (select ... ) as SUBQ ... group by SUBQ
Here SUBQ cannot be removed.
*/
if (!ord->in_field_list)
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
} }
subq_select_lex->join->group_list= NULL; subq_select_lex->join->group_list= NULL;
subq_select_lex->group_list.empty(); subq_select_lex->group_list.empty();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment