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.
This commit is contained in:
Yuchen Pei 2024-10-25 18:03:40 +11:00
parent decdd4bf49
commit b8c2bd9f69
No known key found for this signature in database
GPG Key ID: 3DD1B35105743563
4 changed files with 38 additions and 1 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;