Skip to content

Commit 40b3525

Browse files
spetruniavuvova
authored andcommitted
MDEV-28621: group by optimization incorrectly removing subquery where subject buried in a function
Workaround patch: Do not remove GROUP BY clause when it has subquer(ies) in it. remove_redundant_subquery_clauses() removes redundant GROUP BY clause from queries in form: expr IN (SELECT no_aggregates GROUP BY ...) expr {CMP} {ALL|ANY|SOME} (SELECT no_aggregates GROUP BY ...) This hits problems when the GROUP BY clause itself has subquer(y/ies). This patch is just a workaround: it disables removal of GROUP BY clause if the clause has one or more subqueries in it. Tests: - subselect_elimination.test has all known crashing cases. - subselect4.result, insert_select.result are updated. Note that in some cases results of SELECT are changed too (not just EXPLAINs). These are caused by non-deterministic SQL: when running a query like: x > ANY( SELECT col1 FROM t1 GROUP BY constant_expression) without removing the GROUP BY, the executor is free to pick the value of t1.col1 from any row in the GROUP BY group (denote it $COL1_VAL). Then, it computes x > ANY(SELECT $COL1_VAL). When running the same query and removing the GROUP BY: x > ANY( SELECT col1 FROM t1) the executor will actually check all rows of t1.
1 parent ec6aa9a commit 40b3525

File tree

5 files changed

+585
-51
lines changed

5 files changed

+585
-51
lines changed

mysql-test/main/insert_select.result

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,6 @@ select * from t1;
973973
a
974974
3
975975
1
976-
2
977976
delete from t1;
978977
insert into t1 values (3), (1);
979978
insert into t1
@@ -984,8 +983,6 @@ select * from t1;
984983
a
985984
3
986985
1
987-
3
988-
2
989986
delete from t1;
990987
insert into t1 values (3), (1);
991988
insert into t1
@@ -996,6 +993,7 @@ select * from t1;
996993
a
997994
3
998995
1
996+
3
999997
2
1000998
delete from t1;
1001999
insert into t1 values (3), (1);
@@ -1022,15 +1020,13 @@ select * from t1;
10221020
a
10231021
3
10241022
1
1025-
2
10261023
delete from t1;
10271024
insert into t1 values (3), (1);
10281025
execute stmt;
10291026
select * from t1;
10301027
a
10311028
3
10321029
1
1033-
2
10341030
delete from t1;
10351031
insert into t1 values (3), (1);
10361032
delete from t1
@@ -1040,6 +1036,8 @@ group by (select * from (select a from t1) dt
10401036
where a = 1)));
10411037
select * from t1;
10421038
a
1039+
3
1040+
1
10431041
deallocate prepare stmt;
10441042
drop table t1,t2,t3;
10451043
#

mysql-test/main/subselect4.result

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,48 +2979,44 @@ where a >= any (select b from t2 group by (select c from t3 where c = 1));
29792979
id select_type table type possible_keys key key_len ref rows filtered Extra
29802980
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
29812981
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
2982+
3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
29822983
Warnings:
2983-
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`)))
2984+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <nop>(<in_optimizer>(`test`.`t1`.`a`,<min>(/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` group by (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1)) <= <cache>(`test`.`t1`.`a`)))
29842985
select a from t1
29852986
where a >= any (select b from t2 group by (select c from t3 where c = 1));
29862987
a
2987-
3
2988-
2
29892988
prepare stmt from "select a from t1
29902989
where a >= any (select b from t2 group by (select c from t3 where c = 1))";
29912990
execute stmt;
29922991
a
2993-
3
2994-
2
29952992
execute stmt;
29962993
a
2997-
3
2998-
2
29992994
deallocate prepare stmt;
30002995
explain extended select a from t1
30012996
where a <= all (select b from t2 group by (select c from t3 where c = 1));
30022997
id select_type table type possible_keys key key_len ref rows filtered Extra
30032998
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
30042999
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
3000+
3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
30053001
Warnings:
3006-
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`)))
3002+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <not>(<in_optimizer>(`test`.`t1`.`a`,<min>(/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` group by (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1)) < <cache>(`test`.`t1`.`a`)))
30073003
select a from t1
30083004
where a <= all (select b from t2 group by (select c from t3 where c = 1));
30093005
a
3006+
3
30103007
1
30113008
2
30123009
explain extended select a from t1
30133010
where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1));
30143011
id select_type table type possible_keys key key_len ref rows filtered Extra
30153012
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
30163013
2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
3014+
3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where
30173015
Warnings:
3018-
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`)))
3016+
Note 1003 /* select#1 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where <nop>(<in_optimizer>(`test`.`t1`.`a`,<min>(/* select#2 */ select `test`.`t2`.`b` from `test`.`t2` group by 1 + (/* select#3 */ select `test`.`t3`.`c` from `test`.`t3` where `test`.`t3`.`c` = 1)) <= <cache>(`test`.`t1`.`a`)))
30193017
select a from t1
30203018
where a >= any (select b from t2 group by 1 + (select c from t3 where c = 1));
30213019
a
3022-
3
3023-
2
30243020
drop table t1,t2,t3;
30253021
#
30263022
# MDEV-29139: Redundant IN/ALL/ANY predicand in GROUP BY clause of
@@ -3040,8 +3036,10 @@ group by (select a from t1 where a = 1) in (select d from t4));
30403036
id select_type table type possible_keys key key_len ref rows filtered Extra
30413037
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
30423038
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
3039+
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
3040+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
30433041
Warnings:
3044-
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where 1
3042+
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <in_optimizer>(1,exists(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null))) limit 1))
30453043
select b from t2
30463044
where exists (select c from t3
30473045
group by (select a from t1 where a = 1) in (select d from t4));
@@ -3067,8 +3065,10 @@ any (select d from t4));
30673065
id select_type table type possible_keys key key_len ref rows filtered Extra
30683066
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
30693067
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
3068+
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
3069+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
30703070
Warnings:
3071-
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where 1
3071+
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <in_optimizer>(1,exists(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <nop>(<expr_cache><(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)>(<in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) >= `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null))))) limit 1))
30723072
select b from t2
30733073
where exists (select c from t3
30743074
group by (select a from t1 where a = 1) >=
@@ -3083,8 +3083,10 @@ all (select d from t4));
30833083
id select_type table type possible_keys key key_len ref rows filtered Extra
30843084
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
30853085
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
3086+
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
3087+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
30863088
Warnings:
3087-
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where 1
3089+
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <in_optimizer>(1,exists(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <not>(<expr_cache><(/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)>(<in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) >= `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null))))) limit 1))
30883090
select b from t2
30893091
where exists (select c from t3
30903092
group by (select a from t1 where a = 1) <
@@ -3096,46 +3098,50 @@ explain extended select b from t2
30963098
where b in (select c from t3
30973099
group by (select a from t1 where a = 1) in (select d from t4));
30983100
id select_type table type possible_keys key key_len ref rows filtered Extra
3099-
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00
3100-
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1 100.00
3101+
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
3102+
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 test.t2.b 1 100.00
31013103
2 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 100.00
3104+
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
3105+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
31023106
Warnings:
3103-
Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t2` semi join (`test`.`t3`) where 1
3107+
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from <materialize> (/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) join `test`.`t2` where `<subquery2>`.`c` = `test`.`t2`.`b`
31043108
select b from t2
31053109
where b in (select c from t3
31063110
group by (select a from t1 where a = 1) in (select d from t4));
31073111
b
3108-
2
31093112
explain extended select b from t2
31103113
where b >= any (select c from t3
31113114
group by (select a from t1 where a = 1) in
31123115
(select d from t4));
31133116
id select_type table type possible_keys key key_len ref rows filtered Extra
31143117
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
31153118
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
3119+
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
3120+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
31163121
Warnings:
3117-
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <nop>(<in_optimizer>(`test`.`t2`.`b`,(/* select#2 */ select min(`test`.`t3`.`c`) from `test`.`t3`) <= <cache>(`test`.`t2`.`b`)))
3122+
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <nop>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) <= <cache>(`test`.`t2`.`b`)))
31183123
select b from t2
31193124
where b >= any (select c from t3
31203125
group by (select a from t1 where a = 1) in
31213126
(select d from t4));
31223127
b
3123-
3
3124-
2
31253128
explain extended select b from t2
31263129
where b <= all (select c from t3
31273130
group by (select a from t1 where a = 1) in
31283131
(select d from t4));
31293132
id select_type table type possible_keys key key_len ref rows filtered Extra
31303133
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where
31313134
2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
3135+
4 SUBQUERY t4 ALL NULL NULL NULL NULL 2 100.00 Using where
3136+
3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where
31323137
Warnings:
3133-
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <not>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3`) < <cache>(`test`.`t2`.`b`)))
3138+
Note 1003 /* select#1 */ select `test`.`t2`.`b` AS `b` from `test`.`t2` where <not>(<in_optimizer>(`test`.`t2`.`b`,<min>(/* select#2 */ select `test`.`t3`.`c` from `test`.`t3` group by <in_optimizer>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1),<exists>(/* select#4 */ select `test`.`t4`.`d` from `test`.`t4` where trigcond(<cache>((/* select#3 */ select `test`.`t1`.`a` from `test`.`t1` where `test`.`t1`.`a` = 1)) = `test`.`t4`.`d` or `test`.`t4`.`d` is null) having trigcond(`test`.`t4`.`d` is null)))) < <cache>(`test`.`t2`.`b`)))
31343139
select b from t2
31353140
where b <= all (select c from t3
31363141
group by (select a from t1 where a = 1) in
31373142
(select d from t4));
31383143
b
3144+
3
31393145
2
31403146
drop table t1,t2,t3,t4;
31413147
# End of 10.3 tests

0 commit comments

Comments
 (0)