Commit a00b51f6 authored by Dmitry Shulga's avatar Dmitry Shulga Committed by Sergei Golubchik

MDEV-16708: Fixed the failed test main.set_statement

parent b33111ba
......@@ -1041,7 +1041,7 @@ class sp_lex_cursor: public sp_lex_local, public Query_arena
Query_arena(thd->lex->sphead->get_main_mem_root(), STMT_INITIALIZED_FOR_SP)
{ }
~sp_lex_cursor() { free_items(); }
void cleanup_stmt() { }
void cleanup_stmt(bool /*restore_set_statement_vars*/) { }
Query_arena *query_arena() { return this; }
bool validate()
{
......@@ -1831,7 +1831,8 @@ class sp_instr_cpush : public sp_instr, public sp_cursor
cursor is closed. For now stored procedures always use materialized
cursors and the call is not used.
*/
virtual void cleanup_stmt() { /* no op */ }
virtual void cleanup_stmt(bool /*restore_set_statement_vars*/)
{ /* no op */ }
private:
sp_lex_keeper m_lex_keeper;
......
......@@ -3835,7 +3835,7 @@ void Query_arena::set_query_arena(Query_arena *set)
}
void Query_arena::cleanup_stmt()
void Query_arena::cleanup_stmt(bool /*restore_set_statement_vars*/)
{
DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
}
......
......@@ -1212,7 +1212,7 @@ class Query_arena
void free_items();
/* Close the active state associated with execution of this statement */
virtual void cleanup_stmt();
virtual void cleanup_stmt(bool /*restore_set_statement_vars*/);
};
......
......@@ -197,7 +197,7 @@ int mysql_open_cursor(THD *thd, select_result *result,
}
*pcursor= materialized_cursor;
thd->stmt_arena->cleanup_stmt();
thd->stmt_arena->cleanup_stmt(true);
}
end:
......
......@@ -2419,7 +2419,18 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD *
thd->update_all_stats();
log_slow_statement(thd);
/*
Write to slow query log only those statements that received via the text
protocol except the EXECUTE statement. The reason we do that way is
that for statements received via binary protocol and for the EXECUTE
statement, the slow statements have been already written to slow query log
inside the method Prepared_statement::execute().
*/
if(command == COM_QUERY &&
thd->lex->sql_command != SQLCOM_EXECUTE)
log_slow_statement(thd);
else
delete_explain_query(thd->lex);
THD_STAGE_INFO(thd, stage_cleaning_up);
thd->reset_query();
......
......@@ -201,7 +201,7 @@ class Prepared_statement: public Statement
virtual ~Prepared_statement();
void setup_set_params();
virtual Query_arena::Type type() const;
virtual void cleanup_stmt();
virtual void cleanup_stmt(bool restore_set_statement_vars);
bool set_name(const LEX_CSTRING *name);
inline void close_cursor() { delete cursor; cursor= 0; }
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
......@@ -4193,11 +4193,14 @@ Query_arena::Type Prepared_statement::type() const
}
void Prepared_statement::cleanup_stmt()
void Prepared_statement::cleanup_stmt(bool restore_set_statement_vars)
{
DBUG_ENTER("Prepared_statement::cleanup_stmt");
DBUG_PRINT("enter",("stmt: %p", this));
lex->restore_set_statement_var();
if (restore_set_statement_vars)
lex->restore_set_statement_var();
thd->rollback_item_tree_changes();
cleanup_items(free_list);
thd->cleanup_after_query();
......@@ -4406,12 +4409,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
}
/*
Restore original values of variables modified on handling
SET STATEMENT clause.
*/
thd->lex->restore_set_statement_var();
/* The order is important */
lex->unit.cleanup();
......@@ -4440,7 +4437,12 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
if (lex->sql_command != SQLCOM_SET_OPTION)
lex_unlock_plugins(lex);
cleanup_stmt();
/*
Pass the value true to restore original values of variables modified
on handling SET STATEMENT clause.
*/
cleanup_stmt(true);
thd->restore_backup_statement(this, &stmt_backup);
thd->stmt_arena= old_stmt_arena;
thd->cur_stmt= save_cur_stmt;
......@@ -5159,6 +5161,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
(char *) thd->security_ctx->host_or_ip, 1);
error= mysql_execute_command(thd, true);
MYSQL_QUERY_EXEC_DONE(error);
thd->update_server_status();
}
else
{
......@@ -5184,8 +5187,47 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
DBUG_ASSERT(! (error && cursor));
if (! cursor)
cleanup_stmt();
/*
Pass the value false to don't restore set statement variables.
See the next comment block for more details.
*/
cleanup_stmt(false);
/*
Log the statement to slow query log if it passes filtering.
We do it here for prepared statements despite of the fact that the function
log_slow_statement() is also called upper the stack from the function
dispatch_command(). The reason for logging slow queries here is that
the function log_slow_statement() must be called before restoring system
variables that could be set on execution of SET STATEMENT clause. Since
for prepared statement restoring of system variables set on execution of
SET STATEMENT clause is performed on return from the method
Prepared_statement::execute(), by the time the function log_slow_statement()
be invoked from the function dispatch_command() all variables set by
the SET STATEMEN clause would be already reset to their original values
that break semantic of the SET STATEMENT clause.
E.g., lets consider the following statements
SET slow_query_log= 1;
SET @@long_query_time=0.01;
PREPARE stmt FROM 'set statement slow_query_log=0 for select sleep(0.1)';
EXECUTE stmt;
It's expected that the above statements don't write any record
to slow query log since the system variable slow_query_log is set to 0
during execution of the whole statement
'set statement slow_query_log=0 for select sleep(0.1)'
However, if the function log_slow_statement wasn't called here the record
for the statement would be written to slow query log since the variable
slow_query_log is restored to its original value by the time the function
log_slow_statement is called from disptach_command() to write a record
into slow query log.
*/
log_slow_statement(thd);
lex->restore_set_statement_var();
/*
EXECUTE command has its own dummy "explain data". We don't need it,
instead, we want to keep the query plan of the statement that was
......
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