From 1d502a29e56213c23ce8da9cab8296b4f764fef1 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Fri, 1 Sep 2023 19:27:01 +0700 Subject: [PATCH] MDEV-14959: Fixed possible memory leaks that could happen on running PS/SP depending on a trigger Moved call of the function check_and_update_table_version() just before the place where the function extend_table_list() is invoked in order to avoid allocation of memory on a PS/SP memory root marked as read only. It happens by the reason that the function extend_table_list() invokes sp_add_used_routine() to add a trigger created for the table in time frame between execution the statement EXECUTE `stmt_id` . For example, the following test case create table t1 (a int); prepare stmt from "insert into t1 (a) value (1)"; execute stmt; create trigger t1_bi before insert on t1 for each row set @message= new.a; execute stmt; # (*) adds the trigger t1_bi to a list of used routines that involves allocation of a memory on PS memory root that has been already marked as read only on first run of the statement 'execute stmt'. In result, when the statement marked with (*) is executed it results in assert hit. To fix the issue call the function check_and_update_table_version() before invocation of extend_table_list() to force re-compilation of PS/SP that resets read-only flag of its memory root. --- sql/sql_base.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 47b9c4c6db9..9b1043393e7 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3965,6 +3965,12 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags, if (tables->open_strategy && !tables->table) goto end; + /* Check and update metadata version of a base table. */ + error= check_and_update_table_version(thd, tables, tables->table->s); + + if (unlikely(error)) + goto end; + error= extend_table_list(thd, tables, prelocking_strategy, has_prelocking_list); if (unlikely(error)) goto end; @@ -3972,11 +3978,6 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags, /* Copy grant information from TABLE_LIST instance to TABLE one. */ tables->table->grant= tables->grant; - /* Check and update metadata version of a base table. */ - error= check_and_update_table_version(thd, tables, tables->table->s); - - if (unlikely(error)) - goto end; /* After opening a MERGE table add the children to the query list of tables, so that they are opened too.