Skip to content

Commit c631060

Browse files
committed
MDEV-16820 Lost 'Impossible where' from query with inexpensive subquery
This patch fixes another problem introduced by the patch for mdev-4817. The latter changed Item_cond::fix_fields() in such a way that it could call the virtual method is_expensive(). With the first its call the method saves the result in Item::is_expensive_cache. For all next calls the method returns the result from this cache. So if the item once was determined as expensive the method always returns true. For subqueries it's not good, because non-optimized subqueries always is considered as expensive. It means that the cache should be invalidated after the call of optimize_constant_subqueries().
1 parent 1bda5e3 commit c631060

File tree

9 files changed

+123
-0
lines changed

9 files changed

+123
-0
lines changed

mysql-test/r/subselect.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7211,4 +7211,20 @@ a
72117211
5
72127212
SET @@optimizer_switch= @optimiser_switch_save;
72137213
DROP TABLE t1, t2, t3;
7214+
#
7215+
# MDEV-16820: impossible where with inexpensive subquery
7216+
#
7217+
create table t1 (a int) engine=myisam;
7218+
insert into t1 values (3), (1), (7);
7219+
create table t2 (b int, index idx(b));
7220+
insert into t2 values (2), (5), (3), (2);
7221+
explain select * from t1 where (select max(b) from t2) = 10;
7222+
id select_type table type possible_keys key key_len ref rows Extra
7223+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7224+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7225+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7226+
id select_type table type possible_keys key key_len ref rows Extra
7227+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7228+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7229+
drop table t1,t2;
72147230
End of 5.5 tests

mysql-test/r/subselect_no_exists_to_in.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7211,6 +7211,22 @@ a
72117211
5
72127212
SET @@optimizer_switch= @optimiser_switch_save;
72137213
DROP TABLE t1, t2, t3;
7214+
#
7215+
# MDEV-16820: impossible where with inexpensive subquery
7216+
#
7217+
create table t1 (a int) engine=myisam;
7218+
insert into t1 values (3), (1), (7);
7219+
create table t2 (b int, index idx(b));
7220+
insert into t2 values (2), (5), (3), (2);
7221+
explain select * from t1 where (select max(b) from t2) = 10;
7222+
id select_type table type possible_keys key key_len ref rows Extra
7223+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7224+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7225+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7226+
id select_type table type possible_keys key key_len ref rows Extra
7227+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7228+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7229+
drop table t1,t2;
72147230
End of 5.5 tests
72157231
set optimizer_switch=default;
72167232
select @@optimizer_switch like '%exists_to_in=off%';

mysql-test/r/subselect_no_mat.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7204,6 +7204,22 @@ a
72047204
5
72057205
SET @@optimizer_switch= @optimiser_switch_save;
72067206
DROP TABLE t1, t2, t3;
7207+
#
7208+
# MDEV-16820: impossible where with inexpensive subquery
7209+
#
7210+
create table t1 (a int) engine=myisam;
7211+
insert into t1 values (3), (1), (7);
7212+
create table t2 (b int, index idx(b));
7213+
insert into t2 values (2), (5), (3), (2);
7214+
explain select * from t1 where (select max(b) from t2) = 10;
7215+
id select_type table type possible_keys key key_len ref rows Extra
7216+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7217+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7218+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7219+
id select_type table type possible_keys key key_len ref rows Extra
7220+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7221+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7222+
drop table t1,t2;
72077223
End of 5.5 tests
72087224
set optimizer_switch=default;
72097225
select @@optimizer_switch like '%materialization=on%';

mysql-test/r/subselect_no_opts.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7202,5 +7202,21 @@ a
72027202
5
72037203
SET @@optimizer_switch= @optimiser_switch_save;
72047204
DROP TABLE t1, t2, t3;
7205+
#
7206+
# MDEV-16820: impossible where with inexpensive subquery
7207+
#
7208+
create table t1 (a int) engine=myisam;
7209+
insert into t1 values (3), (1), (7);
7210+
create table t2 (b int, index idx(b));
7211+
insert into t2 values (2), (5), (3), (2);
7212+
explain select * from t1 where (select max(b) from t2) = 10;
7213+
id select_type table type possible_keys key key_len ref rows Extra
7214+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7215+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7216+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7217+
id select_type table type possible_keys key key_len ref rows Extra
7218+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7219+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7220+
drop table t1,t2;
72057221
End of 5.5 tests
72067222
set @optimizer_switch_for_subselect_test=null;

mysql-test/r/subselect_no_scache.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7217,6 +7217,22 @@ a
72177217
5
72187218
SET @@optimizer_switch= @optimiser_switch_save;
72197219
DROP TABLE t1, t2, t3;
7220+
#
7221+
# MDEV-16820: impossible where with inexpensive subquery
7222+
#
7223+
create table t1 (a int) engine=myisam;
7224+
insert into t1 values (3), (1), (7);
7225+
create table t2 (b int, index idx(b));
7226+
insert into t2 values (2), (5), (3), (2);
7227+
explain select * from t1 where (select max(b) from t2) = 10;
7228+
id select_type table type possible_keys key key_len ref rows Extra
7229+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7230+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7231+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7232+
id select_type table type possible_keys key key_len ref rows Extra
7233+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7234+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7235+
drop table t1,t2;
72207236
End of 5.5 tests
72217237
set optimizer_switch=default;
72227238
select @@optimizer_switch like '%subquery_cache=on%';

mysql-test/r/subselect_no_semijoin.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7202,6 +7202,22 @@ a
72027202
5
72037203
SET @@optimizer_switch= @optimiser_switch_save;
72047204
DROP TABLE t1, t2, t3;
7205+
#
7206+
# MDEV-16820: impossible where with inexpensive subquery
7207+
#
7208+
create table t1 (a int) engine=myisam;
7209+
insert into t1 values (3), (1), (7);
7210+
create table t2 (b int, index idx(b));
7211+
insert into t2 values (2), (5), (3), (2);
7212+
explain select * from t1 where (select max(b) from t2) = 10;
7213+
id select_type table type possible_keys key key_len ref rows Extra
7214+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7215+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7216+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7217+
id select_type table type possible_keys key key_len ref rows Extra
7218+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7219+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7220+
drop table t1,t2;
72057221
End of 5.5 tests
72067222
set @optimizer_switch_for_subselect_test=null;
72077223
set @join_cache_level_for_subselect_test=NULL;

mysql-test/t/subselect.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6096,4 +6096,19 @@ and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
60966096
SET @@optimizer_switch= @optimiser_switch_save;
60976097
DROP TABLE t1, t2, t3;
60986098

6099+
--echo #
6100+
--echo # MDEV-16820: impossible where with inexpensive subquery
6101+
--echo #
6102+
6103+
create table t1 (a int) engine=myisam;
6104+
insert into t1 values (3), (1), (7);
6105+
6106+
create table t2 (b int, index idx(b));
6107+
insert into t2 values (2), (5), (3), (2);
6108+
6109+
explain select * from t1 where (select max(b) from t2) = 10;
6110+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
6111+
6112+
drop table t1,t2;
6113+
60996114
--echo End of 5.5 tests

sql/item.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,11 @@ class Item {
12751275
virtual bool exists2in_processor(uchar *opt_arg) { return 0; }
12761276
virtual bool find_selective_predicates_list_processor(uchar *opt_arg)
12771277
{ return 0; }
1278+
bool cleanup_is_expensive_cache_processor(uchar *arg)
1279+
{
1280+
is_expensive_cache= (int8)(-1);
1281+
return 0;
1282+
}
12781283

12791284
/* To call bool function for all arguments */
12801285
struct bool_func_call_args

sql/sql_select.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,13 @@ TODO: make view to decide if it is possible to write to WHERE directly or make S
12071207
if (optimize_constant_subqueries())
12081208
DBUG_RETURN(1);
12091209

1210+
if (conds && conds->has_subquery())
1211+
(void) conds->walk(&Item::cleanup_is_expensive_cache_processor,
1212+
0, (uchar*)0);
1213+
if (having && having->has_subquery())
1214+
(void) having->walk(&Item::cleanup_is_expensive_cache_processor,
1215+
0, (uchar*)0);
1216+
12101217
if (setup_jtbm_semi_joins(this, join_list, &conds))
12111218
DBUG_RETURN(1);
12121219

0 commit comments

Comments
 (0)