summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Shulga <dmitry.shulga@mariadb.com>2023-02-06 15:52:00 +0700
committerDmitry Shulga <dmitry.shulga@mariadb.com>2023-02-06 15:52:00 +0700
commita957d2f8cb3544fb48b0ddeaa664575ff13162a3 (patch)
treea7ae037652bf4adff4d2aa1f534b0b3fabc1fd8d
parent8eb903e1aaef1452e35fc8f3cfb94115db33c986 (diff)
downloadmariadb-git-a957d2f8cb3544fb48b0ddeaa664575ff13162a3.tar.gz
MDEV-5816: Stored programs: validation of stored program statements
Introduced the new data member new_query_arena_is_set of the class sp_head. This data member is used as a protection against double invocation of the method restore_thd_mem_root that is called for restoration of the current query arena. Previously, the data member sp_head::m_thd is used for this goal but after support for recompilation of failed stored routine statement has been added the data member sp_head::m_thd can't be used for this goal. The reason is that on statement recompilation after the method restore_thd_mem_root() is called the method sp_head::add_instr() invoked to add a new instruction for just recompiled statement. The method sp_head::add_instr() de-references m_thd to access the free_list data member. If m_thd was used as a guard against double invocation it would result in a crash on dereferncing null pointer.
-rw-r--r--sql/sp_head.cc8
-rw-r--r--sql/sp_head.h1
2 files changed, 7 insertions, 2 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index cdbb761a925..043f50c424d 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -532,6 +532,7 @@ void sp_head::destroy(sp_head *sp)
MEM_ROOT own_root= sp->main_mem_root;
DBUG_PRINT("info", ("mem_root %p moved to %p",
&sp->mem_root, &own_root));
+ sp->m_thd= nullptr;
delete sp;
free_root(&own_root, MYF(0));
@@ -567,6 +568,7 @@ sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent,
m_sp_cache_version(0),
m_creation_ctx(0),
unsafe_flags(0),
+ new_query_arena_is_set(false),
m_created(0),
m_modified(0),
m_recursion_level(0),
@@ -2790,6 +2792,7 @@ sp_head::reset_thd_mem_root(THD *thd)
free_list= thd->free_list; // Keep the old list
thd->free_list= NULL; // Start a new one
m_thd= thd;
+ new_query_arena_is_set= true;
DBUG_VOID_RETURN;
}
@@ -2809,7 +2812,7 @@ sp_head::restore_thd_mem_root(THD *thd)
skip restoration of old arena/mem_root if this method has been
already called for this routine.
*/
- if (!m_thd)
+ if (!new_query_arena_is_set)
DBUG_VOID_RETURN;
Item *flist= free_list; // The old list
@@ -2820,7 +2823,8 @@ sp_head::restore_thd_mem_root(THD *thd)
&mem_root, &thd->mem_root));
thd->free_list= flist; // Restore the old one
thd->mem_root= m_thd_root;
- m_thd= NULL;
+ new_query_arena_is_set= false;
+
DBUG_VOID_RETURN;
}
diff --git a/sql/sp_head.h b/sql/sp_head.h
index cac403a421f..a19762a6253 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -263,6 +263,7 @@ private:
*/
uint32 unsafe_flags;
+ bool new_query_arena_is_set;
public:
inline Stored_program_creation_ctx *get_creation_ctx()
{