diff options
author | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2023-02-06 15:52:00 +0700 |
---|---|---|
committer | Dmitry Shulga <dmitry.shulga@mariadb.com> | 2023-02-06 15:52:00 +0700 |
commit | a957d2f8cb3544fb48b0ddeaa664575ff13162a3 (patch) | |
tree | a7ae037652bf4adff4d2aa1f534b0b3fabc1fd8d | |
parent | 8eb903e1aaef1452e35fc8f3cfb94115db33c986 (diff) | |
download | mariadb-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.cc | 8 | ||||
-rw-r--r-- | sql/sp_head.h | 1 |
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() { |