diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index b15b9dd6d7e..497bcafdab3 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -3470,4 +3470,25 @@ drop table t; # # End of 10.9 tests # +# +# MDEV-34775 Wrong reopen of already open routine due to auto-create in SP +# +create table t (a int) with system versioning +partition by system_time +interval 1 minute auto; +create function f() +returns int +begin +replace into t select * from t; +return 0; +end $ +set timestamp= @@timestamp + 61; +select f(); +f() +0 +drop table t; +drop function f; +# +# End of 10.11 tests +# set global innodb_stats_persistent= @save_persistent; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index f6b2dcb49f7..cbb83e1330b 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -2717,5 +2717,32 @@ drop table t; --echo # End of 10.9 tests --echo # +--echo # +--echo # MDEV-34775 Wrong reopen of already open routine due to auto-create in SP +--echo # + +create table t (a int) with system versioning +partition by system_time +interval 1 minute auto; + +--delimiter $ +create function f() +returns int +begin + replace into t select * from t; + return 0; +end $ +--delimiter ; + +set timestamp= @@timestamp + 61; +select f(); + +drop table t; +drop function f; + +--echo # +--echo # End of 10.11 tests +--echo # + set global innodb_stats_persistent= @save_persistent; --source suite/versioning/common_finish.inc diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 2162afb17e5..294c4330135 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4561,6 +4561,7 @@ bool open_tables(THD *thd, const DDL_options_st &options, } thd->current_tablenr= 0; + sroutine_to_open= &thd->lex->sroutines_list.first; restart: /* @@ -4576,7 +4577,6 @@ restart: has_prelocking_list= thd->lex->requires_prelocking(); table_to_open= start; - sroutine_to_open= &thd->lex->sroutines_list.first; *counter= 0; THD_STAGE_INFO(thd, stage_opening_tables); prelocking_strategy->reset(thd); @@ -4673,7 +4673,7 @@ restart: elements from the table list (if MERGE tables are involved), */ close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp(), - ot_ctx.remove_implicitly_used_deps()); + false); /* Here we rely on the fact that 'tables' still points to the valid @@ -4741,10 +4741,9 @@ restart: /* F.ex. deadlock happened */ if (ot_ctx.can_recover_from_failed_open()) { - DBUG_ASSERT(ot_ctx.remove_implicitly_used_deps()); close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp(), - ot_ctx.remove_implicitly_used_deps()); + true); if (ot_ctx.recover_from_failed_open()) goto error; @@ -4753,6 +4752,7 @@ restart: goto error; error= FALSE; + sroutine_to_open= &thd->lex->sroutines_list.first; goto restart; } /* @@ -6034,19 +6034,19 @@ bool restart_trans_for_tables(THD *thd, TABLE_LIST *table) trying to reopen tables. NULL if no metadata locks were held and thus all metadata locks should be released. - @param[in] remove_implicit_deps True in case routines and tables implicitly + @param[in] remove_indirect True in case routines and tables implicitly used by a statement should be removed. */ void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, const MDL_savepoint &start_of_statement_svp, - bool remove_implicit_deps) + bool remove_indirect) { - TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); TABLE_LIST *tmp; - if (remove_implicit_deps) + if (remove_indirect) { + TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table(); /* If table list consists only from tables from prelocking set, table list for new attempt should be empty, so we have to update list's root pointer. diff --git a/sql/sql_base.h b/sql/sql_base.h index efcdd79a3cb..742f268c586 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -157,7 +157,7 @@ thr_lock_type read_lock_type_for_table(THD *thd, my_bool mysql_rm_tmp_tables(void); void close_tables_for_reopen(THD *thd, TABLE_LIST **tables, const MDL_savepoint &start_of_statement_svp, - bool remove_implicit_dependencies); + bool remove_indirect); bool table_already_fk_prelocked(TABLE_LIST *tl, LEX_CSTRING *db, LEX_CSTRING *table, thr_lock_type lock_type); TABLE_LIST *find_table_in_list(TABLE_LIST *table, @@ -568,23 +568,6 @@ public: return m_timeout; } - /** - Return true in case tables and routines the statement implicilty - dependent on should be removed, else return false. - - @note The use case when routines and tables the statement implicitly - dependent on shouldn't be removed is the one when a new partition be - created on handling the INSERT statement against a versioning partitioned - table. For this case re-opening a versioning table would result in adding - implicitly dependent routines (e.g. table's triggers) that lead to - allocation of memory on PS mem_root and so leaking a memory until the PS - statement be deallocated. - */ - bool remove_implicitly_used_deps() const - { - return m_action != OT_ADD_HISTORY_PARTITION; - } - uint get_flags() const { return m_flags; } /**