Skip to content

Commit bd935a4

Browse files
committed
MDEV-29139 Crash when using ANY predicand with redundant subquery in GROUP BY clause
This bug could cause a crash of the server when executing queries containing ANY/ALL predicands with redundant subqueries in GROUP BY clauses. These subqueries are eliminated by remove_redundant_subquery_clause() together with elimination of GROUP BY list containing these subqueries. However the references to the elements of the GROUP BY remained in the JOIN::all_fields list of the right operand of of the ALL/ANY predicand. Later these references confused make_aggr_tables_info() when forming proper execution structures after ALL/ANY predicands had been replaced with expressions containing MIN/MAX set functions. The patch just removes these references from JOIN::all_fields list used by the subquery of the ALL/ANY predicand when its GROUP BY clause is eliminated. Approved by Oleksandr Byelkin <sanja@mariadb.com>
1 parent e8eb6d9 commit bd935a4

File tree

3 files changed

+111
-0
lines changed

3 files changed

+111
-0
lines changed

mysql-test/main/subselect4.result

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2981,4 +2981,61 @@ ANALYZE
29812981
}
29822982
DROP TABLE t1;
29832983
# End of 10.2 tests
2984+
#
2985+
# MDEV-29139: Redundannt subquery in GROUP BY clause of ANY/ALL subquery
2986+
#
2987+
create table t1 (a int);
2988+
insert into t1 values (3), (1), (2);
2989+
create table t2 (b int not null);
2990+
insert into t2 values (4), (2);
2991+
create table t3 (c int);
2992+
insert into t3 values (7), (1);
2993+
explain extended select a from t1
2994+
where a >= any (select b from t2 group by (select c from t3 where c = 1));
2995+
id select_type table type possible_keys key key_len ref rows filtered Extra
2996+
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
2997+
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
2998+
Warnings:
2999+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <nop>(<in_optimizer>(`test`.`t1`.`a`,(/* select#2 */ select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t1`.`a`)))
3000+
select a from t1
3001+
where a >= any (select b from t2 group by (select c from t3 where c = 1));
3002+
a
3003+
3
3004+
2
3005+
prepare stmt from "select a from t1
3006+
where a >= any (select b from t2 group by (select c from t3 where c = 1))";
3007+
execute stmt;
3008+
a
3009+
3
3010+
2
3011+
execute stmt;
3012+
a
3013+
3
3014+
2
3015+
deallocate prepare stmt;
3016+
explain extended select a from t1
3017+
where a <= all (select b from t2 group by (select c from t3 where c = 1));
3018+
id select_type table type possible_keys key key_len ref rows filtered Extra
3019+
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
3020+
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
3021+
Warnings:
3022+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <not>(<in_optimizer>(`test`.`t1`.`a`,(/* select#2 */ select min(`test`.`t2`.`b`) from `test`.`t2`) < <cache>(`test`.`t1`.`a`)))
3023+
select a from t1
3024+
where a <= all (select b from t2 group by (select c from t3 where c = 1));
3025+
a
3026+
1
3027+
2
3028+
explain extended select a from t1
3029+
where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1));
3030+
id select_type table type possible_keys key key_len ref rows filtered Extra
3031+
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
3032+
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
3033+
Warnings:
3034+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <nop>(<in_optimizer>(`test`.`t1`.`a`,(/* select#2 */ select min(`test`.`t2`.`b`) from `test`.`t2`) <= <cache>(`test`.`t1`.`a`)))
3035+
select a from t1
3036+
where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1));
3037+
a
3038+
3
3039+
2
3040+
drop table t1,t2,t3;
29843041
# End of 10.3 tests

mysql-test/main/subselect4.test

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2438,4 +2438,43 @@ DROP TABLE t1;
24382438

24392439
--echo # End of 10.2 tests
24402440

2441+
2442+
--echo #
2443+
--echo # MDEV-29139: Redundannt subquery in GROUP BY clause of ANY/ALL subquery
2444+
--echo #
2445+
2446+
create table t1 (a int);
2447+
insert into t1 values (3), (1), (2);
2448+
create table t2 (b int not null);
2449+
insert into t2 values (4), (2);
2450+
create table t3 (c int);
2451+
insert into t3 values (7), (1);
2452+
2453+
let $q1=
2454+
select a from t1
2455+
where a >= any (select b from t2 group by (select c from t3 where c = 1));
2456+
2457+
eval explain extended $q1;
2458+
eval $q1;
2459+
2460+
eval prepare stmt from "$q1";
2461+
execute stmt;
2462+
execute stmt;
2463+
deallocate prepare stmt;
2464+
2465+
let $q2=
2466+
select a from t1
2467+
where a <= all (select b from t2 group by (select c from t3 where c = 1));
2468+
2469+
eval explain extended $q2;
2470+
eval $q2;
2471+
2472+
let $q3=
2473+
select a from t1
2474+
where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1));
2475+
eval explain extended $q3;
2476+
eval $q3;
2477+
2478+
drop table t1,t2,t3;
2479+
24412480
--echo # End of 10.3 tests

sql/sql_select.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,22 @@ void remove_redundant_subquery_clauses(st_select_lex *subq_select_lex)
605605
Here SUBQ cannot be removed.
606606
*/
607607
if (!ord->in_field_list)
608+
{
608609
(*ord->item)->walk(&Item::eliminate_subselect_processor, FALSE, NULL);
610+
/*
611+
Remove from the JOIN::all_fields list any reference to the elements
612+
of the eliminated GROUP BY list unless it is 'in_field_list'.
613+
This is needed in order not to confuse JOIN::make_aggr_tables_info()
614+
when it constructs different structure for execution phase.
615+
*/
616+
List_iterator<Item> li(subq_select_lex->join->all_fields);
617+
Item *item;
618+
while ((item= li++))
619+
{
620+
if (item == *ord->item)
621+
li.remove();
622+
}
623+
}
609624
}
610625
subq_select_lex->join->group_list= NULL;
611626
subq_select_lex->group_list.empty();

0 commit comments

Comments
 (0)