diff --git a/mysql-test/main/merge.result b/mysql-test/main/merge.result index 0e9a2cb9896ab..f98c0f4d28472 100644 --- a/mysql-test/main/merge.result +++ b/mysql-test/main/merge.result @@ -3970,3 +3970,96 @@ DROP TABLE t1; # # End of 10.11 tests # +# +# MDEV-30088 Assertion `cond_selectivity <= 1.0' failed in get_range_limit_read_cost +# +CREATE TABLE t1 (a TIMESTAMP, KEY(a)) ENGINE=MRG_MyISAM; +explain SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +a COUNT(*) +DROP TABLE t1; +# +# MDEV-30525: Assertion `ranges > 0' fails in IO_AND_CPU_COST handler::keyread_time +# +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE tm (a INT, KEY(a)) ENGINE=MRG_MyISAM UNION=(t1,t2); +SELECT DISTINCT a FROM tm WHERE a > 50; +a +DROP TABLE tm, t1, t2; +# Testcase 2: +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE tm (a INT, KEY(a)) ENGINE=MERGE UNION = (t1, t2) INSERT_METHOD=FIRST; +ANALYZE TABLE tm PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.tm analyze status Engine-independent statistics collected +test.tm analyze note The storage engine for the table doesn't support analyze +SELECT DISTINCT a FROM (SELECT * FROM tm WHERE a iS NOT NULL) AS sq; +a +DROP TABLE tm, t1, t2; +# +# MDEV-30568 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +# +CREATE TABLE t1 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE tm (f INT, KEY(f)) ENGINE=MERGE UNION = (t1, t2); +SELECT DISTINCT f FROM tm WHERE f IN (47, 126, 97, 48, 73, 0); +f +DROP TABLE tm, t1, t2; +# +# MDEV-30786 SIGFPE in cost_group_min_max on EXP +# +SET use_stat_tables='preferably'; +CREATE TABLE t1 (a INT,b INT,KEY i1 (a),KEY i2 (b)) ENGINE=MRG_MyISAM; +ANALYZE LOCAL TABLE t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze note The storage engine for the table doesn't support analyze +EXPLAIN SELECT DISTINCT a FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL i1 5 NULL 1 Using index for group-by +drop table t1; +set use_stat_tables=default; +# +# End of 11.0 tests +# +# +# MDEV-29174: UPDATE of view that uses MERGE table +# +CREATE TABLE t1 (a int) ENGINE=MERGE; +CREATE VIEW v1 AS SELECT a FROM t1; +UPDATE v1 SET a=0; +DROP VIEW v1; +DROP TABLE t1; +# End of 11.1 tests +# +# MDEV-38474 Double free or corruption, ASAN heap-use-after-free in st_join_table::cleanup +# +# Test case 1, fails on 10.11+ +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TABLE t3 (c INT); +# Inserts are optional, fails with and without data +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (3),(4); +INSERT INTO t3 VALUES (5),(6); +EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT b FROM t2 WHERE a IN ((SELECT c FROM t3 WHERE FALSE HAVING c < 0))); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +3 MATERIALIZED NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +DROP TABLE t1, t2, t3; +# Test case 2, fails on 11.4 but not on 10.11 +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TABLE t3 (c INT); +CREATE TABLE t4 (d INT PRIMARY KEY); +SET SQL_SAFE_UPDATES=1; +UPDATE t1 STRAIGHT_JOIN t2 SET a = 89 WHERE 9 IN (SELECT c FROM t3 WHERE c IN (SELECT MAX(d) FROM t4)); +ERROR HY000: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column +DROP TABLE t1, t2, t3, t4; +# +# End of 11.4 tests +# diff --git a/mysql-test/main/merge.test b/mysql-test/main/merge.test index e66b3ea1dc44e..16a5a6853a4c7 100644 --- a/mysql-test/main/merge.test +++ b/mysql-test/main/merge.test @@ -2905,3 +2905,98 @@ DROP TABLE t1; --echo # --echo # End of 10.11 tests --echo # + +--echo # +--echo # MDEV-30088 Assertion `cond_selectivity <= 1.0' failed in get_range_limit_read_cost +--echo # + +CREATE TABLE t1 (a TIMESTAMP, KEY(a)) ENGINE=MRG_MyISAM; +explain SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +SELECT a, COUNT(*) FROM t1 WHERE a >= '2000-01-01 00:00:00' GROUP BY a; +DROP TABLE t1; + +--echo # +--echo # MDEV-30525: Assertion `ranges > 0' fails in IO_AND_CPU_COST handler::keyread_time +--echo # +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE tm (a INT, KEY(a)) ENGINE=MRG_MyISAM UNION=(t1,t2); +SELECT DISTINCT a FROM tm WHERE a > 50; +DROP TABLE tm, t1, t2; + +--echo # Testcase 2: +CREATE TABLE t1 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE t2 (a INT, KEY(a)) ENGINE=MyISAM; +CREATE TABLE tm (a INT, KEY(a)) ENGINE=MERGE UNION = (t1, t2) INSERT_METHOD=FIRST; +ANALYZE TABLE tm PERSISTENT FOR ALL; +SELECT DISTINCT a FROM (SELECT * FROM tm WHERE a iS NOT NULL) AS sq; +DROP TABLE tm, t1, t2; + +--echo # +--echo # MDEV-30568 Assertion `cond_selectivity <= 1.000000001' failed in get_range_limit_read_cost +--echo # +CREATE TABLE t1 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE t2 (f INT, KEY(f)) ENGINE=MyISAM; +CREATE TABLE tm (f INT, KEY(f)) ENGINE=MERGE UNION = (t1, t2); +SELECT DISTINCT f FROM tm WHERE f IN (47, 126, 97, 48, 73, 0); +DROP TABLE tm, t1, t2; + +--echo # +--echo # MDEV-30786 SIGFPE in cost_group_min_max on EXP +--echo # +SET use_stat_tables='preferably'; +CREATE TABLE t1 (a INT,b INT,KEY i1 (a),KEY i2 (b)) ENGINE=MRG_MyISAM; +ANALYZE LOCAL TABLE t1; +EXPLAIN SELECT DISTINCT a FROM t1; +drop table t1; +set use_stat_tables=default; + +--echo # +--echo # End of 11.0 tests +--echo # +--echo # +--echo # MDEV-29174: UPDATE of view that uses MERGE table +--echo # + +CREATE TABLE t1 (a int) ENGINE=MERGE; +CREATE VIEW v1 AS SELECT a FROM t1; +UPDATE v1 SET a=0; +DROP VIEW v1; +DROP TABLE t1; + +--echo # End of 11.1 tests + +--echo # +--echo # MDEV-38474 Double free or corruption, ASAN heap-use-after-free in st_join_table::cleanup +--echo # + +--echo # Test case 1, fails on 10.11+ +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TABLE t3 (c INT); + +--echo # Inserts are optional, fails with and without data +INSERT INTO t1 VALUES (1),(2); +INSERT INTO t2 VALUES (3),(4); +INSERT INTO t3 VALUES (5),(6); + +EXPLAIN SELECT * FROM t1 WHERE a IN (SELECT b FROM t2 WHERE a IN ((SELECT c FROM t3 WHERE FALSE HAVING c < 0))); + +DROP TABLE t1, t2, t3; + +--echo # Test case 2, fails on 11.4 but not on 10.11 +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TABLE t3 (c INT); +CREATE TABLE t4 (d INT PRIMARY KEY); + +SET SQL_SAFE_UPDATES=1; +--error ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE +UPDATE t1 STRAIGHT_JOIN t2 SET a = 89 WHERE 9 IN (SELECT c FROM t3 WHERE c IN (SELECT MAX(d) FROM t4)); + +DROP TABLE t1, t2, t3, t4; + +--echo # +--echo # End of 11.4 tests +--echo # + diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 43615249ecb90..670c719555ae0 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2975,7 +2975,7 @@ void st_select_lex_node::init_query_common() into the front of the stranded_clean_list: before: root -> B -> A after: root -> this -> B -> A - During cleanup, the stranded units are cleaned in FIFO order. + During cleanup, the stranded units are cleaned in LIFO order (parent-first). */ void st_select_lex_unit::remember_my_cleanup() { @@ -2994,11 +2994,16 @@ void st_select_lex_unit::remember_my_cleanup() void st_select_lex_unit::cleanup_stranded_units() { - if (!stranded_clean_list) - return; - - stranded_clean_list->cleanup(); + st_select_lex_unit *cur= stranded_clean_list; stranded_clean_list= nullptr; + + while (cur) + { + st_select_lex_unit *next= cur->stranded_clean_list; + cur->stranded_clean_list= nullptr; + cur->cleanup(); + cur= next; + } } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index dda95677332c2..0d87c830adf38 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -2597,8 +2597,6 @@ bool st_select_lex_unit::exec_recursive() bool st_select_lex_unit::cleanup() { - cleanup_stranded_units(); - bool error= 0; DBUG_ENTER("st_select_lex_unit::cleanup"); @@ -2684,6 +2682,12 @@ bool st_select_lex_unit::cleanup() } } + /* + Cleanup stranded units only after this unit has completed its own + cleanup, ensuring a parent-first (LIFO) cleanup order for merged tables. + */ + cleanup_stranded_units(); + DBUG_RETURN(error); }