Skip to content

Commit 4577c7d

Browse files
committed
Bug#18932813: SIMPLE QUERY AND ITS JSON EXPLAIN GIVES 2 ASSERTIONS
Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN PREDICATE INSIDE IN PREDICATE SELECT_LEX::resolve_subquery uses SELECT_LEX::resolve_place to determine if an IN predicate is at the AND-top-level of a WHERE clause or an ON clause, which is one of the requirements for making the IN predicate a candidate for flattening into a semi-join. Although resolve_place can be used to determine if the predicate is in a WHERE clause or an ON clause, it does not reliably tell if the predicate is at the AND-top-level, since many of the fix_field() functions don't remember to reset resolve_place before they descend into their children. Because of this, some IN predicates were incorrectly flagged as candidates for semi-join flattening, and that caused assert failures later when the flattening was attempted. The fix makes the following changes in order to prevent incorrect flagging of candidates: 1) Stop using resolve_place to determine if a predicate is at the AND-top-level. Only use resolve_place to determine if the predicate is in a WHERE clause or an ON clause. 2) Stop switching resolve_place to RESOLVE_NONE for the parts of the query tree where semi-join flattening should be disabled. Instead, introduce a new field in SELECT_LEX specifically for disabling semi-join flattening, called semijoin_disallowed. 3) Switch semijoin_disallowed to true in the cases where resolve_place previously was switched to RESOLVE_NONE. 4) Additionally, switch semijoin_disallowed to true when resolving parts of the query tree where semi-join flattening previously wasn't disabled, but where it should have been disabled because the predicates were not on the top-level (such as the left side of an IN predicate, arguments of aggregate functions, and arguments of LIKE and REGEXP expressions).
1 parent 02b1497 commit 4577c7d

34 files changed

+581
-29
lines changed

mysql-test/include/subquery_sj.inc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6585,6 +6585,21 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
65856585

65866586
DROP TABLE t1;
65876587

6588+
--echo #
6589+
--echo # Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
6590+
--echo # PREDICATE INSIDE IN PREDICATE
6591+
--echo #
6592+
6593+
CREATE TABLE t(X INT) ENGINE=InnoDB;
6594+
INSERT INTO t VALUES (1);
6595+
ANALYZE TABLE t;
6596+
6597+
let $query=SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
6598+
eval EXPLAIN $query;
6599+
eval $query;
6600+
6601+
DROP TABLE t;
6602+
65886603
--echo #
65896604
--echo # Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
65906605
--echo #

mysql-test/r/subquery_sj_all.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11761,6 +11761,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1176111761
ERROR 21000: Subquery returns more than 1 row
1176211762
DROP TABLE t1;
1176311763
#
11764+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11765+
# PREDICATE INSIDE IN PREDICATE
11766+
#
11767+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11768+
INSERT INTO t VALUES (1);
11769+
ANALYZE TABLE t;
11770+
Table Op Msg_type Msg_text
11771+
test.t analyze status OK
11772+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11773+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11774+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11775+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 FirstMatch(t); Using join buffer (Block Nested Loop)
11776+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11777+
Warnings:
11778+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11779+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11780+
1
11781+
1
11782+
DROP TABLE t;
11783+
#
1176411784
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1176511785
#
1176611786
CREATE TABLE t1 (

mysql-test/r/subquery_sj_all_bka.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11767,6 +11767,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1176711767
ERROR 21000: Subquery returns more than 1 row
1176811768
DROP TABLE t1;
1176911769
#
11770+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11771+
# PREDICATE INSIDE IN PREDICATE
11772+
#
11773+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11774+
INSERT INTO t VALUES (1);
11775+
ANALYZE TABLE t;
11776+
Table Op Msg_type Msg_text
11777+
test.t analyze status OK
11778+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11779+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11780+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11781+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 FirstMatch(t); Using join buffer (Block Nested Loop)
11782+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11783+
Warnings:
11784+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11785+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11786+
1
11787+
1
11788+
DROP TABLE t;
11789+
#
1177011790
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1177111791
#
1177211792
CREATE TABLE t1 (

mysql-test/r/subquery_sj_all_bka_nixbnl.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11766,6 +11766,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1176611766
ERROR 21000: Subquery returns more than 1 row
1176711767
DROP TABLE t1;
1176811768
#
11769+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11770+
# PREDICATE INSIDE IN PREDICATE
11771+
#
11772+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11773+
INSERT INTO t VALUES (1);
11774+
ANALYZE TABLE t;
11775+
Table Op Msg_type Msg_text
11776+
test.t analyze status OK
11777+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11778+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11779+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11780+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 FirstMatch(t)
11781+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11782+
Warnings:
11783+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11784+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11785+
1
11786+
1
11787+
DROP TABLE t;
11788+
#
1176911789
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1177011790
#
1177111791
CREATE TABLE t1 (

mysql-test/r/subquery_sj_all_bkaunique.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11703,6 +11703,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1170311703
ERROR 21000: Subquery returns more than 1 row
1170411704
DROP TABLE t1;
1170511705
#
11706+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11707+
# PREDICATE INSIDE IN PREDICATE
11708+
#
11709+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11710+
INSERT INTO t VALUES (1);
11711+
ANALYZE TABLE t;
11712+
Table Op Msg_type Msg_text
11713+
test.t analyze status OK
11714+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11715+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11716+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11717+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 FirstMatch(t); Using join buffer (Block Nested Loop)
11718+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11719+
Warnings:
11720+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11721+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11722+
1
11723+
1
11724+
DROP TABLE t;
11725+
#
1170611726
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1170711727
#
1170811728
CREATE TABLE t1 (

mysql-test/r/subquery_sj_dupsweed.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11720,6 +11720,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1172011720
ERROR 21000: Subquery returns more than 1 row
1172111721
DROP TABLE t1;
1172211722
#
11723+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11724+
# PREDICATE INSIDE IN PREDICATE
11725+
#
11726+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11727+
INSERT INTO t VALUES (1);
11728+
ANALYZE TABLE t;
11729+
Table Op Msg_type Msg_text
11730+
test.t analyze status OK
11731+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11732+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11733+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary
11734+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 End temporary; Using join buffer (Block Nested Loop)
11735+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11736+
Warnings:
11737+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11738+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11739+
1
11740+
1
11741+
DROP TABLE t;
11742+
#
1172311743
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1172411744
#
1172511745
CREATE TABLE t1 (

mysql-test/r/subquery_sj_dupsweed_bka.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11721,6 +11721,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1172111721
ERROR 21000: Subquery returns more than 1 row
1172211722
DROP TABLE t1;
1172311723
#
11724+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11725+
# PREDICATE INSIDE IN PREDICATE
11726+
#
11727+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11728+
INSERT INTO t VALUES (1);
11729+
ANALYZE TABLE t;
11730+
Table Op Msg_type Msg_text
11731+
test.t analyze status OK
11732+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11733+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11734+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary
11735+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 End temporary; Using join buffer (Block Nested Loop)
11736+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11737+
Warnings:
11738+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11739+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11740+
1
11741+
1
11742+
DROP TABLE t;
11743+
#
1172411744
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1172511745
#
1172611746
CREATE TABLE t1 (

mysql-test/r/subquery_sj_dupsweed_bka_nixbnl.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11713,6 +11713,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1171311713
ERROR 21000: Subquery returns more than 1 row
1171411714
DROP TABLE t1;
1171511715
#
11716+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11717+
# PREDICATE INSIDE IN PREDICATE
11718+
#
11719+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11720+
INSERT INTO t VALUES (1);
11721+
ANALYZE TABLE t;
11722+
Table Op Msg_type Msg_text
11723+
test.t analyze status OK
11724+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11725+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11726+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11727+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary; End temporary
11728+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11729+
Warnings:
11730+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11731+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11732+
1
11733+
1
11734+
DROP TABLE t;
11735+
#
1171611736
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1171711737
#
1171811738
CREATE TABLE t1 (

mysql-test/r/subquery_sj_dupsweed_bkaunique.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11722,6 +11722,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1172211722
ERROR 21000: Subquery returns more than 1 row
1172311723
DROP TABLE t1;
1172411724
#
11725+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11726+
# PREDICATE INSIDE IN PREDICATE
11727+
#
11728+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11729+
INSERT INTO t VALUES (1);
11730+
ANALYZE TABLE t;
11731+
Table Op Msg_type Msg_text
11732+
test.t analyze status OK
11733+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11734+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11735+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 Start temporary
11736+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 End temporary; Using join buffer (Block Nested Loop)
11737+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11738+
Warnings:
11739+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11740+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11741+
1
11742+
1
11743+
DROP TABLE t;
11744+
#
1172511745
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1172611746
#
1172711747
CREATE TABLE t1 (

mysql-test/r/subquery_sj_firstmatch.result

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11694,6 +11694,26 @@ WHERE (SELECT b FROM t1) IN (SELECT (d>=1) FROM t1);
1169411694
ERROR 21000: Subquery returns more than 1 row
1169511695
DROP TABLE t1;
1169611696
#
11697+
# Bug#19779600: ASSERT FAILED IN REPLACE_SUBCONDITION WITH IN
11698+
# PREDICATE INSIDE IN PREDICATE
11699+
#
11700+
CREATE TABLE t(X INT) ENGINE=InnoDB;
11701+
INSERT INTO t VALUES (1);
11702+
ANALYZE TABLE t;
11703+
Table Op Msg_type Msg_text
11704+
test.t analyze status OK
11705+
EXPLAIN SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11706+
id select_type table partitions type possible_keys key key_len ref rows filtered Extra
11707+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11708+
1 PRIMARY t NULL ALL NULL NULL NULL NULL 1 100.00 FirstMatch(t); Using join buffer (Block Nested Loop)
11709+
2 SUBQUERY t NULL ALL NULL NULL NULL NULL 1 100.00 NULL
11710+
Warnings:
11711+
Note 1003 /* select#1 */ select 1 AS `1` from `test`.`t` semi join (`test`.`t`) where 1
11712+
SELECT 1 FROM t WHERE (1 IN (SELECT 1 FROM t)) IN (SELECT 1 FROM t);
11713+
1
11714+
1
11715+
DROP TABLE t;
11716+
#
1169711717
# Bug#19465034 ASSERT ON SETUP_SEMIJOIN_DUPS_ELIMINATION IN SQL/SQL_SELECT.CC
1169811718
#
1169911719
CREATE TABLE t1 (

0 commit comments

Comments
 (0)