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

This is the prerequisite patch to make interface of the class
Reprepare_observer more similar to the one used by MySQL.

This patch adds the method can_retry() to the class Reprepare_observer
that returns true in case max. number of attempts to re-run a failing
statement is not yet reached. To control the number of re-run attempts
already done the data member m_attempt has been introduced. Doing this way,
we encapsulate activity with incrementing a counter on every statement
run and checking whether it reaches a limit or not inside implementation
of the class Reprepare_observer instead duplicating such boiler plate code
in every place where controlling for reaching a limit of max. number attempts
for re-running failed statement is required.
This commit is contained in:
Dmitry Shulga 2023-06-13 18:25:53 +07:00
parent c5405c075f
commit 053475fe4f
2 changed files with 15 additions and 7 deletions

View file

@ -3806,6 +3806,7 @@ Reprepare_observer::report_error(THD *thd)
*/
thd->get_stmt_da()->set_error_status(ER_NEED_REPREPARE);
m_invalidated= TRUE;
m_attempt++;
return TRUE;
}
@ -4377,7 +4378,6 @@ Prepared_statement::set_parameters(String *expanded_query,
@retval FALSE successfully executed the statement, perhaps
after having reprepared it a few times.
*/
const static int MAX_REPREPARE_ATTEMPTS= 3;
bool
Prepared_statement::execute_loop(String *expanded_query,
@ -4386,7 +4386,6 @@ Prepared_statement::execute_loop(String *expanded_query,
uchar *packet_end)
{
Reprepare_observer reprepare_observer;
int reprepare_attempt= 0;
bool error;
iterations= FALSE;
@ -4439,7 +4438,7 @@ reexecute:
(sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
!thd->is_fatal_error && !thd->killed &&
reprepare_observer.is_invalidated() &&
reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
reprepare_observer.can_retry())
{
DBUG_ASSERT(thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE);
thd->clear_error();
@ -4568,8 +4567,6 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
// iterations changed by set_bulk_parameters
while ((iterations || start_param) && !error && !thd->is_error())
{
int reprepare_attempt= 0;
/*
Here we set parameters for not optimized commands,
optimized commands do it inside thier internal loop.
@ -4629,7 +4626,7 @@ reexecute:
(sql_command_flags[lex->sql_command] & CF_REEXECUTION_FRAGILE) &&
!thd->is_fatal_error && !thd->killed &&
reprepare_observer.is_invalidated() &&
reprepare_attempt++ < MAX_REPREPARE_ATTEMPTS)
reprepare_observer.can_retry())
{
DBUG_ASSERT(thd->get_stmt_da()->sql_errno() == ER_NEED_REPREPARE);
thd->clear_error();

View file

@ -65,8 +65,19 @@ public:
bool report_error(THD *thd);
bool is_invalidated() const { return m_invalidated; }
void reset_reprepare_observer() { m_invalidated= FALSE; }
bool can_retry() const
{
// The method must be called only for a statement that is invalidated
assert(is_invalidated());
return m_attempt <= MAX_REPREPARE_ATTEMPTS;
}
private:
bool m_invalidated;
bool m_invalidated{false};
int m_attempt{0};
static const int MAX_REPREPARE_ATTEMPTS= 3;
};