Skip to content

Commit aad70e9

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 de85355 commit aad70e9

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
@@ -7240,6 +7240,22 @@ a
72407240
5
72417241
SET @@optimizer_switch= @optimiser_switch_save;
72427242
DROP TABLE t1, t2, t3;
7243+
#
7244+
# MDEV-16820: impossible where with inexpensive subquery
7245+
#
7246+
create table t1 (a int) engine=myisam;
7247+
insert into t1 values (3), (1), (7);
7248+
create table t2 (b int, index idx(b));
7249+
insert into t2 values (2), (5), (3), (2);
7250+
explain select * from t1 where (select max(b) from t2) = 10;
7251+
id select_type table type possible_keys key key_len ref rows Extra
7252+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7253+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7254+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7255+
id select_type table type possible_keys key key_len ref rows Extra
7256+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7257+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7258+
drop table t1,t2;
72437259
End of 5.5 tests
72447260
# End of 10.0 tests
72457261
#

mysql-test/r/subselect_no_exists_to_in.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7240,6 +7240,22 @@ a
72407240
5
72417241
SET @@optimizer_switch= @optimiser_switch_save;
72427242
DROP TABLE t1, t2, t3;
7243+
#
7244+
# MDEV-16820: impossible where with inexpensive subquery
7245+
#
7246+
create table t1 (a int) engine=myisam;
7247+
insert into t1 values (3), (1), (7);
7248+
create table t2 (b int, index idx(b));
7249+
insert into t2 values (2), (5), (3), (2);
7250+
explain select * from t1 where (select max(b) from t2) = 10;
7251+
id select_type table type possible_keys key key_len ref rows Extra
7252+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7253+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7254+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7255+
id select_type table type possible_keys key key_len ref rows Extra
7256+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7257+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7258+
drop table t1,t2;
72437259
End of 5.5 tests
72447260
# End of 10.0 tests
72457261
#

mysql-test/r/subselect_no_mat.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7233,6 +7233,22 @@ a
72337233
5
72347234
SET @@optimizer_switch= @optimiser_switch_save;
72357235
DROP TABLE t1, t2, t3;
7236+
#
7237+
# MDEV-16820: impossible where with inexpensive subquery
7238+
#
7239+
create table t1 (a int) engine=myisam;
7240+
insert into t1 values (3), (1), (7);
7241+
create table t2 (b int, index idx(b));
7242+
insert into t2 values (2), (5), (3), (2);
7243+
explain select * from t1 where (select max(b) from t2) = 10;
7244+
id select_type table type possible_keys key key_len ref rows Extra
7245+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7246+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7247+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7248+
id select_type table type possible_keys key key_len ref rows Extra
7249+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7250+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7251+
drop table t1,t2;
72367252
End of 5.5 tests
72377253
# End of 10.0 tests
72387254
#

mysql-test/r/subselect_no_opts.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7231,6 +7231,22 @@ a
72317231
5
72327232
SET @@optimizer_switch= @optimiser_switch_save;
72337233
DROP TABLE t1, t2, t3;
7234+
#
7235+
# MDEV-16820: impossible where with inexpensive subquery
7236+
#
7237+
create table t1 (a int) engine=myisam;
7238+
insert into t1 values (3), (1), (7);
7239+
create table t2 (b int, index idx(b));
7240+
insert into t2 values (2), (5), (3), (2);
7241+
explain select * from t1 where (select max(b) from t2) = 10;
7242+
id select_type table type possible_keys key key_len ref rows Extra
7243+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7244+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7245+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7246+
id select_type table type possible_keys key key_len ref rows Extra
7247+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7248+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7249+
drop table t1,t2;
72347250
End of 5.5 tests
72357251
# End of 10.0 tests
72367252
#

mysql-test/r/subselect_no_scache.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7246,6 +7246,22 @@ a
72467246
5
72477247
SET @@optimizer_switch= @optimiser_switch_save;
72487248
DROP TABLE t1, t2, t3;
7249+
#
7250+
# MDEV-16820: impossible where with inexpensive subquery
7251+
#
7252+
create table t1 (a int) engine=myisam;
7253+
insert into t1 values (3), (1), (7);
7254+
create table t2 (b int, index idx(b));
7255+
insert into t2 values (2), (5), (3), (2);
7256+
explain select * from t1 where (select max(b) from t2) = 10;
7257+
id select_type table type possible_keys key key_len ref rows Extra
7258+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7259+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7260+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7261+
id select_type table type possible_keys key key_len ref rows Extra
7262+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7263+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7264+
drop table t1,t2;
72497265
End of 5.5 tests
72507266
# End of 10.0 tests
72517267
#

mysql-test/r/subselect_no_semijoin.result

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7231,6 +7231,22 @@ a
72317231
5
72327232
SET @@optimizer_switch= @optimiser_switch_save;
72337233
DROP TABLE t1, t2, t3;
7234+
#
7235+
# MDEV-16820: impossible where with inexpensive subquery
7236+
#
7237+
create table t1 (a int) engine=myisam;
7238+
insert into t1 values (3), (1), (7);
7239+
create table t2 (b int, index idx(b));
7240+
insert into t2 values (2), (5), (3), (2);
7241+
explain select * from t1 where (select max(b) from t2) = 10;
7242+
id select_type table type possible_keys key key_len ref rows Extra
7243+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7244+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7245+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7246+
id select_type table type possible_keys key key_len ref rows Extra
7247+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7248+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7249+
drop table t1,t2;
72347250
End of 5.5 tests
72357251
# End of 10.0 tests
72367252
#

mysql-test/t/subselect.test

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6102,6 +6102,21 @@ and t1.a in (select `test`.`t3`.`c` from `test`.`t3`);
61026102
SET @@optimizer_switch= @optimiser_switch_save;
61036103
DROP TABLE t1, t2, t3;
61046104

6105+
--echo #
6106+
--echo # MDEV-16820: impossible where with inexpensive subquery
6107+
--echo #
6108+
6109+
create table t1 (a int) engine=myisam;
6110+
insert into t1 values (3), (1), (7);
6111+
6112+
create table t2 (b int, index idx(b));
6113+
insert into t2 values (2), (5), (3), (2);
6114+
6115+
explain select * from t1 where (select max(b) from t2) = 10;
6116+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
6117+
6118+
drop table t1,t2;
6119+
61056120
--echo End of 5.5 tests
61066121
--echo # End of 10.0 tests
61076122

sql/item.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,11 @@ class Item: public Value_source,
16141614
virtual bool limit_index_condition_pushdown_processor(void *arg) { return 0; }
16151615
virtual bool exists2in_processor(void *arg) { return 0; }
16161616
virtual bool find_selective_predicates_list_processor(void *arg) { return 0; }
1617+
bool cleanup_is_expensive_cache_processor(void *arg)
1618+
{
1619+
is_expensive_cache= (int8)(-1);
1620+
return 0;
1621+
}
16171622

16181623
/*
16191624
TRUE if the expression depends only on the table indicated by tab_map

sql/sql_select.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,6 +1335,13 @@ JOIN::optimize_inner()
13351335
if (optimize_constant_subqueries())
13361336
DBUG_RETURN(1);
13371337

1338+
if (conds && conds->has_subquery())
1339+
(void) conds->walk(&Item::cleanup_is_expensive_cache_processor,
1340+
0, (void *) 0);
1341+
if (having && having->has_subquery())
1342+
(void) having->walk(&Item::cleanup_is_expensive_cache_processor,
1343+
0, (void *) 0);
1344+
13381345
if (setup_jtbm_semi_joins(this, join_list, &conds))
13391346
DBUG_RETURN(1);
13401347

0 commit comments

Comments
 (0)