Commit 6840af6e authored by Dmitry Shulga's avatar Dmitry Shulga

MDEV-5816: Stored programs: validation of stored program statements

This is the prerequisite patch introducing the class sp_lex_instr
that encapsulates access to an instance of the class sp_lex_keeper.
Every SP instruction that need to get access to a LEX object on its
processing should inherit this class and implement two abstract methods:
  is_invalid(),
  invalidate().

These methods will be used in subsequent patches to implement recompilation of
SP instructions on failure.

Currently, the following instructions are derived from the class sp_lex_instr:
  sp_instr_stmt,
  sp_instr_set,
  sp_instr_set_trigger_field,
  sp_instr_jump_if_not,
  sp_instr_freturn,
  sp_instr_cpush,
  sp_instr_cursor_copy_struct,
  sp_instr_set_case_expr

Additionally, this patch converts the class sp_instr_opt_meta
to a base abstract class (that is, not inherited from the class
sp_instr). Since this class originally was designed to provide a way
for opimizer to update a destination address for jump SP-instructions,
the only useful method at the interface of this class is set_destination
and therefore inheritance from the class sp_instr is meaningless.

Every jump SP instruction now must be inherited directly from
the class sp_instr_opt_meta and additionally from either the class
sp_lex_instr or sp_instr depending on whether this SP instruction
need to get access to a LEX object or not.

Moreover, the class sp_cursor doesn't own a data member of
the class sp_lex_keeper any more. Instead, the virtual method
get_lex_keeper() has been added to the class sp_cursor() that
returns nullptr and this method is overridden in the derived class
sp_instr_cpush to provide a pointer to a real instance of
the class sp_lex_keeper. Doing this way we exclude duplication
of a data member of the type sp_lex_keeper at the class sp_instr_cpush
since it is derived both from sp_lex_instr and sp_cursor, and sp_lex_instr
already encapsulates a data member of the class sp_lex_keeper.
parent 40d730fb
......@@ -747,15 +747,6 @@ sp_instr_set_trigger_field::print(String *str)
QT_ITEM_ORIGINAL_FUNC_NULLIF));
}
/*
sp_instr_opt_meta
*/
uint sp_instr_opt_meta::get_cont_dest() const
{
return m_cont_dest;
}
/*
sp_instr_jump class functions
......@@ -918,8 +909,15 @@ sp_instr_jump_if_not::opt_move(uint dst, List<sp_instr_opt_meta> *bp)
}
else if (m_cont_optdest)
m_cont_dest= m_cont_optdest->m_ip; // Backward
/* This will take care of m_dest and m_ip */
sp_instr_jump::opt_move(dst, bp);
/*
Take care about m_dest and m_ip
*/
if (m_dest > m_ip)
bp->push_back(this); // Forward
else if (m_optdest)
m_dest= m_optdest->m_ip; // Backward
m_ip= dst;
}
......@@ -1195,7 +1193,7 @@ sp_instr_cpush::execute(THD *thd, uint *nextp)
{
DBUG_ENTER("sp_instr_cpush::execute");
sp_cursor::reset(thd, &m_lex_keeper);
sp_cursor::reset(thd);
m_lex_keeper.disable_query_cache();
thd->spcont->push_cursor(this);
......@@ -1492,14 +1490,14 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp)
/*
Copy structure only once. If the cursor%ROWTYPE variable is declared
inside a LOOP block, it gets its structure on the first loop interation
inside a LOOP block, it gets its structure on the first loop iteration
and remembers the structure for all consequent loop iterations.
It we recreated the structure on every iteration, we would get
potential memory leaks, and it would be less efficient.
*/
if (!row->arguments())
{
sp_cursor tmp(thd, &m_lex_keeper, true);
sp_cursor tmp(thd, true);
// Open the cursor without copying data
if (!(ret= tmp.open(thd)))
{
......
This diff is collapsed.
......@@ -6016,19 +6016,17 @@ class sp_cursor: public sp_cursor_statistics
public:
sp_cursor()
:result(NULL, false),
m_lex_keeper(NULL),
server_side_cursor(NULL)
{ }
sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper, bool view_structure_only)
sp_cursor(THD *thd_arg, bool view_structure_only)
:result(thd_arg, view_structure_only),
m_lex_keeper(lex_keeper),
server_side_cursor(NULL)
{}
virtual ~sp_cursor()
{ destroy(); }
sp_lex_keeper *get_lex_keeper() { return m_lex_keeper; }
virtual sp_lex_keeper *get_lex_keeper() { return nullptr; }
int open(THD *thd);
......@@ -6041,17 +6039,15 @@ class sp_cursor: public sp_cursor_statistics
bool export_structure(THD *thd, Row_definition_list *list);
void reset(THD *thd_arg, sp_lex_keeper *lex_keeper)
void reset(THD *thd_arg)
{
sp_cursor_statistics::reset();
result.reset(thd_arg);
m_lex_keeper= lex_keeper;
server_side_cursor= NULL;
}
private:
Select_fetch_into_spvars result;
sp_lex_keeper *m_lex_keeper;
Server_side_cursor *server_side_cursor;
void destroy();
};
......
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