mirror of
https://github.com/MariaDB/server.git
synced 2025-07-04 01:23:45 +03:00
MDEV-16708: Fixed the failed test main.set_statement
This commit is contained in:
committed by
Sergei Golubchik
parent
b33111ba93
commit
a00b51f639
@ -1041,7 +1041,7 @@ public:
|
|||||||
Query_arena(thd->lex->sphead->get_main_mem_root(), STMT_INITIALIZED_FOR_SP)
|
Query_arena(thd->lex->sphead->get_main_mem_root(), STMT_INITIALIZED_FOR_SP)
|
||||||
{ }
|
{ }
|
||||||
~sp_lex_cursor() { free_items(); }
|
~sp_lex_cursor() { free_items(); }
|
||||||
void cleanup_stmt() { }
|
void cleanup_stmt(bool /*restore_set_statement_vars*/) { }
|
||||||
Query_arena *query_arena() { return this; }
|
Query_arena *query_arena() { return this; }
|
||||||
bool validate()
|
bool validate()
|
||||||
{
|
{
|
||||||
@ -1831,7 +1831,8 @@ public:
|
|||||||
cursor is closed. For now stored procedures always use materialized
|
cursor is closed. For now stored procedures always use materialized
|
||||||
cursors and the call is not used.
|
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:
|
private:
|
||||||
|
|
||||||
sp_lex_keeper m_lex_keeper;
|
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");
|
DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
|
||||||
}
|
}
|
||||||
|
@ -1212,7 +1212,7 @@ public:
|
|||||||
|
|
||||||
void free_items();
|
void free_items();
|
||||||
/* Close the active state associated with execution of this statement */
|
/* 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;
|
*pcursor= materialized_cursor;
|
||||||
thd->stmt_arena->cleanup_stmt();
|
thd->stmt_arena->cleanup_stmt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -2419,7 +2419,18 @@ resume:
|
|||||||
|
|
||||||
thd->update_all_stats();
|
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_STAGE_INFO(thd, stage_cleaning_up);
|
||||||
thd->reset_query();
|
thd->reset_query();
|
||||||
|
@ -201,7 +201,7 @@ public:
|
|||||||
virtual ~Prepared_statement();
|
virtual ~Prepared_statement();
|
||||||
void setup_set_params();
|
void setup_set_params();
|
||||||
virtual Query_arena::Type type() const;
|
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);
|
bool set_name(const LEX_CSTRING *name);
|
||||||
inline void close_cursor() { delete cursor; cursor= 0; }
|
inline void close_cursor() { delete cursor; cursor= 0; }
|
||||||
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
|
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_ENTER("Prepared_statement::cleanup_stmt");
|
||||||
DBUG_PRINT("enter",("stmt: %p", this));
|
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();
|
thd->rollback_item_tree_changes();
|
||||||
cleanup_items(free_list);
|
cleanup_items(free_list);
|
||||||
thd->cleanup_after_query();
|
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;
|
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 */
|
/* The order is important */
|
||||||
lex->unit.cleanup();
|
lex->unit.cleanup();
|
||||||
|
|
||||||
@ -4440,7 +4437,12 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
|
|||||||
if (lex->sql_command != SQLCOM_SET_OPTION)
|
if (lex->sql_command != SQLCOM_SET_OPTION)
|
||||||
lex_unlock_plugins(lex);
|
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->restore_backup_statement(this, &stmt_backup);
|
||||||
thd->stmt_arena= old_stmt_arena;
|
thd->stmt_arena= old_stmt_arena;
|
||||||
thd->cur_stmt= save_cur_stmt;
|
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);
|
(char *) thd->security_ctx->host_or_ip, 1);
|
||||||
error= mysql_execute_command(thd, true);
|
error= mysql_execute_command(thd, true);
|
||||||
MYSQL_QUERY_EXEC_DONE(error);
|
MYSQL_QUERY_EXEC_DONE(error);
|
||||||
|
thd->update_server_status();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5184,7 +5187,46 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
|
|||||||
DBUG_ASSERT(! (error && cursor));
|
DBUG_ASSERT(! (error && cursor));
|
||||||
|
|
||||||
if (! 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,
|
EXECUTE command has its own dummy "explain data". We don't need it,
|
||||||
|
Reference in New Issue
Block a user