From b8c2bd9f69d60057876ad5d44521a6079f5d60fe Mon Sep 17 00:00:00 2001 From: Yuchen Pei Date: Fri, 25 Oct 2024 18:03:40 +1100 Subject: [PATCH] MDEV-35249 Fix regression caused by MDEV-34447 MDEV-34447 Removed setting first_cond_optimization to 0 in update and delete when leaf_tables_saved. This can cause problems when two ps executions of an update go through different paths, where the first ps execution goes through single table update only and the second ps execution also goes through multi table update. When this happens, the first_cond_optimization of the outer query is not set to false during the first ps execution because optimize() is not called for the outer query. But then the second ps execution will call optimize() on the outer query, which with first_cond_optimization==true trips the 2nd ps mem leak detection. This is not a problem in higher version as both executions go through multi table updates, possibly due to MDEV-28883. We fix this problem by restoring the FALSE assignments to first_cond_optimization. --- mysql-test/main/ps_mem_leaks.result | 13 +++++++++++++ mysql-test/main/ps_mem_leaks.test | 17 +++++++++++++++++ sql/sql_delete.cc | 6 +++++- sql/sql_update.cc | 3 +++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/ps_mem_leaks.result b/mysql-test/main/ps_mem_leaks.result index 8acfb779bc5..9bf2b573324 100644 --- a/mysql-test/main/ps_mem_leaks.result +++ b/mysql-test/main/ps_mem_leaks.result @@ -325,4 +325,17 @@ PREPARE stmt FROM "UPDATE t SET a = 0 LIMIT ?"; EXECUTE stmt USING 0; EXECUTE stmt USING 1; DROP TABLE t; +# +# MDEV-35249: Assertion `(mem_root->flags & 4) == 0' failed in convert_subq_to_jtbm +# +CREATE TABLE t (a INT, b INT, c INT); +INSERT INTO t VALUES (1,2,3),(4,5,6); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t; +CREATE VIEW v2 AS SELECT * FROM v1; +PREPARE stmt FROM 'UPDATE t SET a = 0 WHERE b IN (SELECT c FROM v2)'; +EXECUTE stmt; +EXECUTE stmt; +DROP VIEW v2; +DROP VIEW v1; +DROP TABLE t; # End of 10.5 tests diff --git a/mysql-test/main/ps_mem_leaks.test b/mysql-test/main/ps_mem_leaks.test index 907f0eb6bba..3e078deff96 100644 --- a/mysql-test/main/ps_mem_leaks.test +++ b/mysql-test/main/ps_mem_leaks.test @@ -323,4 +323,21 @@ EXECUTE stmt USING 1; # CLeanup DROP TABLE t; +--echo # +--echo # MDEV-35249: Assertion `(mem_root->flags & 4) == 0' failed in convert_subq_to_jtbm +--echo # + +CREATE TABLE t (a INT, b INT, c INT); +INSERT INTO t VALUES (1,2,3),(4,5,6); +CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t; +CREATE VIEW v2 AS SELECT * FROM v1; +PREPARE stmt FROM 'UPDATE t SET a = 0 WHERE b IN (SELECT c FROM v2)'; +EXECUTE stmt; +EXECUTE stmt; + +# Cleanup +DROP VIEW v2; +DROP VIEW v1; +DROP TABLE t; + --echo # End of 10.5 tests diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 67d07c3ff44..4c5c4fb6ef5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -379,9 +379,10 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (returning) (void) result->prepare(returning->item_list, NULL); - if (thd->lex->current_select->first_cond_optimization) + if (!thd->lex->current_select->leaf_tables_saved) { thd->lex->current_select->save_leaf_tables(thd); + thd->lex->current_select->leaf_tables_saved= true; thd->lex->current_select->first_cond_optimization= 0; } /* check ORDER BY even if it can be ignored */ @@ -504,6 +505,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->leaf_tables_saved= true; + thd->lex->current_select->first_cond_optimization= 0; } my_ok(thd, 0); @@ -541,6 +543,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, { thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->leaf_tables_saved= true; + thd->lex->current_select->first_cond_optimization= 0; } my_ok(thd, 0); @@ -919,6 +922,7 @@ cleanup: { thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->leaf_tables_saved= true; + thd->lex->current_select->first_cond_optimization= 0; } delete deltempfile; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e96af1a19bf..7bc7041e161 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -573,6 +573,7 @@ int mysql_update(THD *thd, { thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->leaf_tables_saved= true; + thd->lex->current_select->first_cond_optimization= 0; } my_ok(thd); // No matching records @@ -609,6 +610,7 @@ int mysql_update(THD *thd, { thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->leaf_tables_saved= true; + thd->lex->current_select->first_cond_optimization= 0; } my_ok(thd); // No matching records @@ -1383,6 +1385,7 @@ update_end: { thd->lex->current_select->save_leaf_tables(thd); thd->lex->current_select->leaf_tables_saved= true; + thd->lex->current_select->first_cond_optimization= 0; } *found_return= found; *updated_return= updated;