Skip to content

Commit b471224

Browse files
MDEV-31279 Crash when lateral derived is guaranteed to return no rows
Consider this query SELECT t1.* FROM t1, (SELECT t2.b FROM t2 WHERE NOT EXISTS (SELECT 1 FROM t3) GROUP BY b) sq where sq.b = t1.a; If SELECT 1 FROM t3 is expensive, for example t3 has > thd->variables.expensive_subquery_limit, first evaluation is deferred to mysql_derived_fill(). There it is noted that, in the above case NOT EXISTS (SELECT 1 FROM t3) is constant and false. This causes the join variable zero_result_cause to be set to "Impossible WHERE noticed after reading const tables" and the handler for this join is never "opened" via handler::ha_open. When mysql_derived_fill() is called for the next group of results, this unopened handler is not taken into account. reviewed by Igor Babaev (igor@mariadb.com)
1 parent c17aca2 commit b471224

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

mysql-test/main/derived_split_innodb.result

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -826,4 +826,19 @@ SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
826826
a b
827827
DROP VIEW v;
828828
DROP TABLE t1, t2, t3;
829+
#
830+
# MDEV-31279 Crash when lateral derived is guaranteed to return no rows
831+
#
832+
CREATE TABLE t1 (a CHAR(1)) ENGINE=MyISAM;
833+
INSERT INTO t1 VALUES ('1'),('2');
834+
CREATE TABLE t2 (b INT, KEY(b)) ENGINE=MyISAM;
835+
ALTER TABLE t2 DISABLE KEYS;
836+
INSERT INTO t2 VALUES (1),(2),(3);
837+
ALTER TABLE t2 ENABLE KEYS;
838+
CREATE TABLE t3 (c INT) ENGINE=MyISAM;
839+
INSERT INTO t3 (c) SELECT seq FROM seq_1_to_101;
840+
SELECT * FROM t1 WHERE t1.a IN (SELECT b FROM
841+
(SELECT t2.b FROM t2 WHERE NOT EXISTS (SELECT 1 FROM t3) GROUP BY b) sq);
842+
a
843+
DROP TABLE t1, t2, t3;
829844
# End of 10.4 tests

mysql-test/main/derived_split_innodb.test

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,22 @@ SELECT * FROM t1 JOIN t2 WHERE (t1.a, t2.b) IN (SELECT * FROM v);
483483
DROP VIEW v;
484484
DROP TABLE t1, t2, t3;
485485

486+
--echo #
487+
--echo # MDEV-31279 Crash when lateral derived is guaranteed to return no rows
488+
--echo #
489+
490+
CREATE TABLE t1 (a CHAR(1)) ENGINE=MyISAM;
491+
INSERT INTO t1 VALUES ('1'),('2');
492+
CREATE TABLE t2 (b INT, KEY(b)) ENGINE=MyISAM;
493+
ALTER TABLE t2 DISABLE KEYS;
494+
INSERT INTO t2 VALUES (1),(2),(3);
495+
ALTER TABLE t2 ENABLE KEYS;
496+
CREATE TABLE t3 (c INT) ENGINE=MyISAM;
497+
INSERT INTO t3 (c) SELECT seq FROM seq_1_to_101;
498+
499+
SELECT * FROM t1 WHERE t1.a IN (SELECT b FROM
500+
(SELECT t2.b FROM t2 WHERE NOT EXISTS (SELECT 1 FROM t3) GROUP BY b) sq);
501+
502+
DROP TABLE t1, t2, t3;
503+
486504
--echo # End of 10.4 tests

sql/sql_derived.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,9 @@ bool mysql_derived_fill(THD *thd, LEX *lex, TABLE_LIST *derived)
12271227
goto err;
12281228
JOIN *join= unit->first_select()->join;
12291229
join->first_record= false;
1230+
if (join->zero_result_cause)
1231+
goto err;
1232+
12301233
for (uint i= join->top_join_tab_count;
12311234
i < join->top_join_tab_count + join->aggr_tables;
12321235
i++)

0 commit comments

Comments
 (0)