diff options
author | Rex <rex.johnston@mariadb.com> | 2023-02-01 15:59:39 +1200 |
---|---|---|
committer | Rex <rex.johnston@mariadb.com> | 2023-03-06 08:29:09 +1200 |
commit | 99c0e243dee351f3a458ae66bd4a77790f8ff441 (patch) | |
tree | 7c6efc5c02986ed326c269d7e9ed6d80a15c3729 | |
parent | b05218e08f45a17f46d1b73cbb9dcb2969dc04cd (diff) | |
download | mariadb-git-bb-10.4-MDEV-23384.tar.gz |
MDEV-23384 Server crashes in subselect_indexsubquery_engine::print with optimizer trace enabledbb-10.4-MDEV-23384
unitialized data structures
causing subselect_indexsubquery_engine::print
and subselect_uniquesubquery_engine::print to crash
when optimizer_trace is enabled
-rw-r--r-- | mysql-test/main/opt_trace.result | 47 | ||||
-rw-r--r-- | mysql-test/main/opt_trace.test | 64 | ||||
-rw-r--r-- | sql/item_subselect.cc | 19 |
3 files changed, 123 insertions, 7 deletions
diff --git a/mysql-test/main/opt_trace.result b/mysql-test/main/opt_trace.result index 2eef0da62bb..3ab3ab16a43 100644 --- a/mysql-test/main/opt_trace.result +++ b/mysql-test/main/opt_trace.result @@ -8522,5 +8522,52 @@ SELECT a FROM t1 WHERE (a,b) in (SELECT @c,@d); a DROP TABLE t1; # +# MDEV-23384: Server crashes in subselect_indexsubquery_engine::print with optimizer trace enabled +# +# test subselect_indexsubquery_engine::print +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c INT); +CREATE TABLE t4 (d INT); +INSERT INTO t4 VALUES (5),(6); +SET SESSION optimizer_trace= 'enabled=on'; +UPDATE t1, t2 SET t2.b = 1 WHERE +( +WITH cte1 AS +( +SELECT MAX(c) FROM t3 WHERE c = 0 OR c IN +( +WITH cte2 AS +( +SELECT d FROM t4 +) +SELECT * FROM cte2 +) +) +SELECT * FROM cte1 +) IS NULL; +# test subselect_uniquesubquery_engine::print +CREATE TABLE t10 (a int, b int) ENGINE=myisam; +CREATE TABLE t11 (a int, b int, unique(a)); +INSERT INTO t11 SELECT seq, seq FROM seq_1_to_10; +CREATE TABLE t12 (a int, key(a)); +INSERT INTO t12 SELECT seq FROM seq_1_to_1000; +SET SESSION optimizer_trace= 'enabled=on'; +SELECT * FROM t12 WHERE t12.a < +( +SELECT b FROM +( +SELECT b FROM t10 WHERE a <3 or a in +( +SELECT a FROM t11 WHERE t11.b<t10.b +) +LIMIT 2 +) T +); +a +DROP TABLE t1, t2, t3, t4, t10, t11, t12; +# # End of 10.4 tests # diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 0785d828a07..727af02c35d 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -678,5 +678,69 @@ SELECT a FROM t1 WHERE (a,b) in (SELECT @c,@d); DROP TABLE t1; --echo # +--echo # MDEV-23384: Server crashes in subselect_indexsubquery_engine::print with optimizer trace enabled +--echo # +--echo # test subselect_indexsubquery_engine::print + +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (3),(4); + +CREATE TABLE t3 (c INT); + +CREATE TABLE t4 (d INT); +INSERT INTO t4 VALUES (5),(6); + +SET SESSION optimizer_trace= 'enabled=on'; + +UPDATE t1, t2 SET t2.b = 1 WHERE +( + WITH cte1 AS + ( + SELECT MAX(c) FROM t3 WHERE c = 0 OR c IN + ( + WITH cte2 AS + ( + SELECT d FROM t4 + ) + SELECT * FROM cte2 + ) + ) + SELECT * FROM cte1 +) IS NULL; + +# we don't actually need the trace, we are testing for a crash +--echo # test subselect_uniquesubquery_engine::print + +CREATE TABLE t10 (a int, b int) ENGINE=myisam; + +CREATE TABLE t11 (a int, b int, unique(a)); + +INSERT INTO t11 SELECT seq, seq FROM seq_1_to_10; + +CREATE TABLE t12 (a int, key(a)); + +INSERT INTO t12 SELECT seq FROM seq_1_to_1000; + +SET SESSION optimizer_trace= 'enabled=on'; + +SELECT * FROM t12 WHERE t12.a < +( + SELECT b FROM + ( + SELECT b FROM t10 WHERE a <3 or a in + ( + SELECT a FROM t11 WHERE t11.b<t10.b + ) + LIMIT 2 + ) T +); + +# Cleanup +DROP TABLE t1, t2, t3, t4, t10, t11, t12; + +--echo # --echo # End of 10.4 tests --echo # diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 461bd9fb144..a8a518451ec 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -4537,7 +4537,7 @@ void subselect_uniquesubquery_engine::print(String *str, str->append(STRING_WITH_LEN("<primary_index_lookup>(")); tab->ref.items[0]->print(str, query_type); str->append(STRING_WITH_LEN(" in ")); - if (tab->table->s->table_category == TABLE_CATEGORY_TEMPORARY) + if (tab->tab_list->table->s->table_category == TABLE_CATEGORY_TEMPORARY) { /* Temporary tables' names change across runs, so they can't be used for @@ -4546,8 +4546,8 @@ void subselect_uniquesubquery_engine::print(String *str, str->append(STRING_WITH_LEN("<temporary table>")); } else - str->append(&tab->table->s->table_name); - KEY *key_info= tab->table->key_info+ tab->ref.key; + str->append(&tab->tab_list->table->s->table_name); + KEY *key_info= tab->tab_list->table->key_info+ tab->ref.key; str->append(STRING_WITH_LEN(" on ")); str->append(&key_info->name); if (cond) @@ -4588,8 +4588,9 @@ void subselect_indexsubquery_engine::print(String *str, str->append(STRING_WITH_LEN("<index_lookup>(")); tab->ref.items[0]->print(str, query_type); str->append(STRING_WITH_LEN(" in ")); - str->append(tab->table->s->table_name.str, tab->table->s->table_name.length); - KEY *key_info= tab->table->key_info+ tab->ref.key; + str->append(tab->tab_list->table->s->table_name.str, + tab->tab_list->table->s->table_name.length); + KEY *key_info= tab->tab_list->table->key_info+ tab->ref.key; str->append(STRING_WITH_LEN(" on ")); str->append(&key_info->name); if (check_null) @@ -5264,11 +5265,15 @@ subselect_hash_sj_engine::make_unique_engine() - this JOIN_TAB has no corresponding JOIN (and doesn't need one), and - here we initialize only those members that are used by subselect_uniquesubquery_engine, so these objects are incomplete. + tab->tab_list is used in ::print, it needs initialization too. */ - if (!(tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) + if (!(tab= (JOIN_TAB*) thd->calloc(sizeof(JOIN_TAB)))) DBUG_RETURN(NULL); - tab->table= tmp_table; + if (!(tab->tab_list= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST)))) + DBUG_RETURN(NULL); + + tab->table= tab->tab_list->table= tmp_table; tab->preread_init_done= FALSE; tab->ref.tmp_table_index_lookup_init(thd, tmp_key, it, FALSE); |