From a775788e4c612cebe3d8ca6153977aebff725a1e Mon Sep 17 00:00:00 2001 From: Raghunandan Bhat Date: Tue, 27 Jan 2026 22:53:06 +0530 Subject: [PATCH] MDEV-37243: SP memory root protection disappears after a metadata change Problem: When a stored routine involes a cursor and metadata of table on which the cursor is defined changes, the SP instruction has to be reparsed. For ex: CREATE OR REPLACE TABLE t1 (a INT); CREATE OR REPLACE FUNCTION f1() RETURNS INT BEGIN DECLARE vc INT DEFAULT 0; DECLARE cur CURSOR FOR SELECT a FROM t1; OPEN cur; FETCH cur INTO vc; CLOSE cur; RETURN vc; END; SELECT f1(); - first execution, sp-mem_root marked read-only on exec SELECT f1(); - read-only sp-mem_root ALTER TABLE t1 MODIFY a TEXT; - metadta change SELECT f1(); - reparse, rerun instr and mark new mem_root read-only sp_lex_instr is re-parsed after the metadata change, which sets up a new mem_root for reparsing. Once the instruction is re-parsed and re-executed(via reset_lex_and_exec_core), the new memory root assigned to the instruction being reparsed remains writable. This violates the invariant of SP memory root protection. Fix: Mark the new memory root created for reparsing with read-only flag, after the first execution of the SP instruction. --- sql/sp_instr.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sql/sp_instr.cc b/sql/sp_instr.cc index 88afd2415245d..374c9dab5423e 100644 --- a/sql/sp_instr.cc +++ b/sql/sp_instr.cc @@ -534,7 +534,19 @@ int sp_lex_keeper::validate_lex_and_exec_core(THD *thd, uint *nextp, m_first_execution= false; if (!rc) + { + /* + sp_lex_instr is re-parsed after the metadata change, which sets up a new + mem_root for reparsing. Once the sp_lex_instr is reparsed and re-executed + (via reset_lex_and_exec_core) it should be marked as read-only to enforce + sp memory root protection. + */ +#ifdef PROTECT_STATEMENT_MEMROOT + if (rerun_the_same_instr && instr->mem_root) + instr->mem_root->flags |= ROOT_FLAG_READ_ONLY; +#endif break; + } /* Raise the error upper level in case: