Skip to content

Commit 1fde449

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 57cde8c commit 1fde449

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
@@ -7235,6 +7235,22 @@ a
72357235
5
72367236
SET @@optimizer_switch= @optimiser_switch_save;
72377237
DROP TABLE t1, t2, t3;
7238+
#
7239+
# MDEV-16820: impossible where with inexpensive subquery
7240+
#
7241+
create table t1 (a int) engine=myisam;
7242+
insert into t1 values (3), (1), (7);
7243+
create table t2 (b int, index idx(b));
7244+
insert into t2 values (2), (5), (3), (2);
7245+
explain select * from t1 where (select max(b) from t2) = 10;
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+
explain select * from t1 where (select max(b) from t2) = 10 and t1.a > 3;
7250+
id select_type table type possible_keys key key_len ref rows Extra
7251+
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE
7252+
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
7253+
drop table t1,t2;
72387254
End of 5.5 tests
72397255
# End of 10.0 tests
72407256
#

mysql-test/r/subselect_no_exists_to_in.result

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

mysql-test/r/subselect_no_mat.result

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

mysql-test/r/subselect_no_opts.result

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

mysql-test/r/subselect_no_scache.result

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

mysql-test/r/subselect_no_semijoin.result

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

mysql-test/t/subselect.test

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

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

sql/item.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,11 @@ class Item: public Value_source,
14491449
virtual bool exists2in_processor(uchar *opt_arg) { return 0; }
14501450
virtual bool find_selective_predicates_list_processor(uchar *opt_arg)
14511451
{ return 0; }
1452+
bool cleanup_is_expensive_cache_processor(uchar *arg)
1453+
{
1454+
is_expensive_cache= (int8)(-1);
1455+
return 0;
1456+
}
14521457

14531458
/* To call bool function for all arguments */
14541459
struct bool_func_call_args

sql/sql_select.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1212,6 +1212,13 @@ JOIN::optimize_inner()
12121212
if (optimize_constant_subqueries())
12131213
DBUG_RETURN(1);
12141214

1215+
if (conds && conds->has_subquery())
1216+
(void) conds->walk(&Item::cleanup_is_expensive_cache_processor,
1217+
0, (uchar*)0);
1218+
if (having && having->has_subquery())
1219+
(void) having->walk(&Item::cleanup_is_expensive_cache_processor,
1220+
0, (uchar*)0);
1221+
12151222
if (setup_jtbm_semi_joins(this, join_list, &conds))
12161223
DBUG_RETURN(1);
12171224

0 commit comments

Comments
 (0)