From 99c0e243dee351f3a458ae66bd4a77790f8ff441 Mon Sep 17 00:00:00 2001 From: Rex Date: Wed, 1 Feb 2023 15:59:39 +1200 Subject: MDEV-23384 Server crashes in subselect_indexsubquery_engine::print with optimizer trace enabled unitialized data structures causing subselect_indexsubquery_engine::print and subselect_uniquesubquery_engine::print to crash when optimizer_trace is enabled --- mysql-test/main/opt_trace.result | 47 +++++++++++++++++++++++++++++ mysql-test/main/opt_trace.test | 64 ++++++++++++++++++++++++++++++++++++++++ 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.bappend(STRING_WITH_LEN("(")); 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("")); } 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("(")); 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); -- cgit v1.2.1