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)
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;
}
......
......@@ -262,6 +262,7 @@ class sp_head :private Query_arena,
*/
uint32 unsafe_flags;
bool new_query_arena_is_set;
public:
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