mirror of
https://github.com/MariaDB/server.git
synced 2025-04-24 18:27:21 +03:00
MDEV-16708: Fixed the failed test main.set_statement
This commit is contained in:
parent
b33111ba93
commit
a00b51f639
@ -1041,7 +1041,7 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
|
||||
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 @@ resume:
|
||||
|
||||
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 @@ public:
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user