Commit 9e599235 authored by Dmitry Shulga's avatar Dmitry Shulga

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 re-compilation of a 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 a statement re-compilation
after the method restore_thd_mem_root() is called the method
sp_head::add_instr() invoked to add a new instruction for just re-compiled
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 dereferencing null pointer.
parent 6ac1d882
...@@ -532,6 +532,7 @@ void sp_head::destroy(sp_head *sp) ...@@ -532,6 +532,7 @@ void sp_head::destroy(sp_head *sp)
MEM_ROOT own_root= sp->main_mem_root; MEM_ROOT own_root= sp->main_mem_root;
DBUG_PRINT("info", ("mem_root %p moved to %p", DBUG_PRINT("info", ("mem_root %p moved to %p",
&sp->mem_root, &own_root)); &sp->mem_root, &own_root));
sp->m_thd= nullptr;
delete sp; delete sp;
free_root(&own_root, MYF(0)); free_root(&own_root, MYF(0));
...@@ -567,6 +568,7 @@ sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent, ...@@ -567,6 +568,7 @@ sp_head::sp_head(MEM_ROOT *mem_root_arg, sp_package *parent,
m_sp_cache_version(0), m_sp_cache_version(0),
m_creation_ctx(0), m_creation_ctx(0),
unsafe_flags(0), unsafe_flags(0),
new_query_arena_is_set(false),
m_created(0), m_created(0),
m_modified(0), m_modified(0),
m_recursion_level(0), m_recursion_level(0),
...@@ -2790,6 +2792,7 @@ sp_head::reset_thd_mem_root(THD *thd) ...@@ -2790,6 +2792,7 @@ sp_head::reset_thd_mem_root(THD *thd)
free_list= thd->free_list; // Keep the old list free_list= thd->free_list; // Keep the old list
thd->free_list= NULL; // Start a new one thd->free_list= NULL; // Start a new one
m_thd= thd; m_thd= thd;
new_query_arena_is_set= true;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -2809,7 +2812,7 @@ sp_head::restore_thd_mem_root(THD *thd) ...@@ -2809,7 +2812,7 @@ sp_head::restore_thd_mem_root(THD *thd)
skip restoration of old arena/mem_root if this method has been skip restoration of old arena/mem_root if this method has been
already called for this routine. already called for this routine.
*/ */
if (!m_thd) if (!new_query_arena_is_set)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
Item *flist= free_list; // The old list Item *flist= free_list; // The old list
...@@ -2820,7 +2823,8 @@ sp_head::restore_thd_mem_root(THD *thd) ...@@ -2820,7 +2823,8 @@ sp_head::restore_thd_mem_root(THD *thd)
&mem_root, &thd->mem_root)); &mem_root, &thd->mem_root));
thd->free_list= flist; // Restore the old one thd->free_list= flist; // Restore the old one
thd->mem_root= m_thd_root; thd->mem_root= m_thd_root;
m_thd= NULL; new_query_arena_is_set= false;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
......
...@@ -262,6 +262,7 @@ class sp_head :private Query_arena, ...@@ -262,6 +262,7 @@ class sp_head :private Query_arena,
*/ */
uint32 unsafe_flags; uint32 unsafe_flags;
bool new_query_arena_is_set;
public: public:
inline Stored_program_creation_ctx *get_creation_ctx() inline Stored_program_creation_ctx *get_creation_ctx()
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment