maria:10.9-MDEV-5816

Last commit made on 2022-06-15
Get this branch:
git clone -b 10.9-MDEV-5816 https://git.launchpad.net/maria

Branch merges

Branch information

Name:
10.9-MDEV-5816
Repository:
lp:maria

Recent commits

2e3b543... by Dmitry Shulga <email address hidden>

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

Fixed the test main.sp

b96b358... by Dmitry Shulga <email address hidden>

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

- Use expression string provided by sp_expr_lex for crearting
  an instance of the class sp_instr_freturn on parsing the SP operator RETURN ...
- Assign thd->lex->sphead->m_thd before re-parsing a instruction's statement string
  and restore its original value after parsing done. It is require on order to avoid
  assert failure DBUG_ASSERT(sphead->m_thd)
- Added implementation of the method sp_instr_freturn::on_after_expr_parsing
  that is called after statement re-paring is done in order to update the
  data member m_value to point on a item just created on statement parsing
- Added trivial implementation of the method sp_instr_cpush::get_expr_query,
  sp_instr_cursor_copy_struct::get_expr_query. They will be adjusted later in the
  following patches
- Modified the grammar rule to fix issues with handling statements
    SET var:=expression
    RETURN (SELECT ...)

28aae57... by Dmitry Shulga <email address hidden>

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

Added storing of an instance of Table_triggers_list inside
sp_head class in order to be able to setup trigger's field
after trigger's instruction has been recompiled.

6fc5bbf... by Dmitry Shulga <email address hidden>

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

Don't delete sp_head object on parser error. In case the parser reports
internal error the method LEX::cleanup_lex_after_parse_error() is called
to handle the error condition. Formerly, this resulted in deleting
an instance of sp_head class if it was created by the parser.
Ii was correct way to clean up side effects after parser work
terminated until re-parsing of failed statement inside a stored
routine be added. As soon as support for recompilation of failed
statement inside a stored routing has been added it is not allowed
to delete an instance of sp_head on handling a parser error
since sp_head's destructor deletes every SP instruction used by the
stored routine. Instead, just restore the origin lex used before
stored routine has been executed.

2a4a22d... by Dmitry Shulga <email address hidden>

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

- Use a separate free_list for every SP instruction during its parsing
- Reset sp_head::m_tmp_query to the beginning of a SP instruction's
statement before its parsing.

94cfa1a... by Dmitry Shulga <email address hidden>

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

Make a copy of the statement CREATE FUNCTION/PROCEDURE/EVENT/TRIGGER
used for creating a stored routine on its own mem root.

a18d3b2... by Dmitry Shulga <email address hidden>

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

Fixed dangling pointer problem by assigning the null value to
the data member thd->lex inside the method sp_lex_keeper::free_lex
in case it points to a LEX object just deleted.

868f77e... by Dmitry Shulga <email address hidden>

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

Added re-parsing of a failed statement inside a stored routine.
This is initial implementation. Following patches will make
improvements.

General idea of the patch is to install an instance of the class
Reprepare_observer before executing a next SP instruction and
re-parse a statement of this SP instruction in case of
its execution failure.

To implement the described approach the class sp_lex_keeper
has been extended with the method validate_lex_and_exec_core()
that is just a wrapper around the method reset_lex_and_exec_core()
with additional setting/resetting an instance of the class
Reprepare_observer on each iteration of SP instruction
execution.

If reset_lex_and_exec_core() returns error and an instance
of the class Reprepare_observer is installed before running
an SP instruction then a number of attempts to re-run the SP
instruction is checked against a max. limit and in case it doesn't
reach the limit a statement for failed SP instruction is re-parsed.

Re-parsing of a statement for failed SP instruction is implemented
by the new method sp_le_inst::parse_expr() that prepends
an SP instruction's statement with the clause 'SELECT' and parse it.
SP statement parsing is performed on a SP instruction's MEM_ROOT.
On successful re-parsing of SP instruction's statement the virtual
methods adjust_sql_command() and on_after_expr_parsing() of the class
sp_lex_instr is called to update the SP instruction state with a
new data created on parsing the statement.

Few words about reason for prepending a SP instruction's statement
with the clause 'SELECT' - this is required step to produce a valid
SQL statement, since for some SP instructions, such as SET var=func(),
the instructions statement (in the above case it is the text 'var=func()')
is not a valid SQL statement. Wrapping such text inside 'SELECT ( )'
produces a correct operator from SQL syntax point of view.

6d9eaaa... by Dmitry Shulga <email address hidden>

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

Added storing of an original sql expression for an instruction
being parsed inside classes derived from the class sp_lex_instr.

Stored sql expression is returned by the abstract method
  sp_lex_instr::get_expr_query
redefined in derived classes.

The virtual method sp_lex_instr::get_query() has been added to return
a parseable string for a statement that corresponds to the given
instruction.

a7e68ad... by Dmitry Shulga <email address hidden>

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 sp_lex_keeper. Every SP instruction
that does need access to LEX object on its processing should inherit this class
and implement two abstract methods:
  is_invalid(),
  invalidate().

These method will be used in subsequent patches to implement recomplilation 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 the base abstract class (that is, not inhereted from
the class sp_instr).

Every jump SP instruction now must be inhereted 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
does need access to LEX object or not.

Moreover, the class sp_cursor is no more owner of sp_lex_keeper.
Instead, the virtual method get_lex_keeper() has been added to the
class sp_cursor() that returns nullptr and this method is overriden
in the derived class sp_instr_cpush to provide a pointer to a real
instance of the class sp_lex_keeper.