Skip to content

Commit a00b51f

Browse files
dmitryshulgavuvova
authored andcommitted
MDEV-16708: Fixed the failed test main.set_statement
1 parent b33111b commit a00b51f

File tree

6 files changed

+72
-18
lines changed

6 files changed

+72
-18
lines changed

sql/sp_head.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,7 @@ class sp_lex_cursor: public sp_lex_local, public Query_arena
10411041
Query_arena(thd->lex->sphead->get_main_mem_root(), STMT_INITIALIZED_FOR_SP)
10421042
{ }
10431043
~sp_lex_cursor() { free_items(); }
1044-
void cleanup_stmt() { }
1044+
void cleanup_stmt(bool /*restore_set_statement_vars*/) { }
10451045
Query_arena *query_arena() { return this; }
10461046
bool validate()
10471047
{
@@ -1831,7 +1831,8 @@ class sp_instr_cpush : public sp_instr, public sp_cursor
18311831
cursor is closed. For now stored procedures always use materialized
18321832
cursors and the call is not used.
18331833
*/
1834-
virtual void cleanup_stmt() { /* no op */ }
1834+
virtual void cleanup_stmt(bool /*restore_set_statement_vars*/)
1835+
{ /* no op */ }
18351836
private:
18361837

18371838
sp_lex_keeper m_lex_keeper;

sql/sql_class.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3835,7 +3835,7 @@ void Query_arena::set_query_arena(Query_arena *set)
38353835
}
38363836

38373837

3838-
void Query_arena::cleanup_stmt()
3838+
void Query_arena::cleanup_stmt(bool /*restore_set_statement_vars*/)
38393839
{
38403840
DBUG_ASSERT(! "Query_arena::cleanup_stmt() not implemented");
38413841
}

sql/sql_class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1212,7 +1212,7 @@ class Query_arena
12121212

12131213
void free_items();
12141214
/* Close the active state associated with execution of this statement */
1215-
virtual void cleanup_stmt();
1215+
virtual void cleanup_stmt(bool /*restore_set_statement_vars*/);
12161216
};
12171217

12181218

sql/sql_cursor.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ int mysql_open_cursor(THD *thd, select_result *result,
197197
}
198198

199199
*pcursor= materialized_cursor;
200-
thd->stmt_arena->cleanup_stmt();
200+
thd->stmt_arena->cleanup_stmt(true);
201201
}
202202

203203
end:

sql/sql_parse.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2419,7 +2419,18 @@ dispatch_command_return dispatch_command(enum enum_server_command command, THD *
24192419

24202420
thd->update_all_stats();
24212421

2422-
log_slow_statement(thd);
2422+
/*
2423+
Write to slow query log only those statements that received via the text
2424+
protocol except the EXECUTE statement. The reason we do that way is
2425+
that for statements received via binary protocol and for the EXECUTE
2426+
statement, the slow statements have been already written to slow query log
2427+
inside the method Prepared_statement::execute().
2428+
*/
2429+
if(command == COM_QUERY &&
2430+
thd->lex->sql_command != SQLCOM_EXECUTE)
2431+
log_slow_statement(thd);
2432+
else
2433+
delete_explain_query(thd->lex);
24232434

24242435
THD_STAGE_INFO(thd, stage_cleaning_up);
24252436
thd->reset_query();

sql/sql_prepare.cc

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ class Prepared_statement: public Statement
201201
virtual ~Prepared_statement();
202202
void setup_set_params();
203203
virtual Query_arena::Type type() const;
204-
virtual void cleanup_stmt();
204+
virtual void cleanup_stmt(bool restore_set_statement_vars);
205205
bool set_name(const LEX_CSTRING *name);
206206
inline void close_cursor() { delete cursor; cursor= 0; }
207207
inline bool is_in_use() { return flags & (uint) IS_IN_USE; }
@@ -4193,11 +4193,14 @@ Query_arena::Type Prepared_statement::type() const
41934193
}
41944194

41954195

4196-
void Prepared_statement::cleanup_stmt()
4196+
void Prepared_statement::cleanup_stmt(bool restore_set_statement_vars)
41974197
{
41984198
DBUG_ENTER("Prepared_statement::cleanup_stmt");
41994199
DBUG_PRINT("enter",("stmt: %p", this));
4200-
lex->restore_set_statement_var();
4200+
4201+
if (restore_set_statement_vars)
4202+
lex->restore_set_statement_var();
4203+
42014204
thd->rollback_item_tree_changes();
42024205
cleanup_items(free_list);
42034206
thd->cleanup_after_query();
@@ -4406,12 +4409,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
44064409
lex->context_analysis_only&= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
44074410
}
44084411

4409-
/*
4410-
Restore original values of variables modified on handling
4411-
SET STATEMENT clause.
4412-
*/
4413-
thd->lex->restore_set_statement_var();
4414-
44154412
/* The order is important */
44164413
lex->unit.cleanup();
44174414

@@ -4440,7 +4437,12 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
44404437
if (lex->sql_command != SQLCOM_SET_OPTION)
44414438
lex_unlock_plugins(lex);
44424439

4443-
cleanup_stmt();
4440+
/*
4441+
Pass the value true to restore original values of variables modified
4442+
on handling SET STATEMENT clause.
4443+
*/
4444+
cleanup_stmt(true);
4445+
44444446
thd->restore_backup_statement(this, &stmt_backup);
44454447
thd->stmt_arena= old_stmt_arena;
44464448
thd->cur_stmt= save_cur_stmt;
@@ -5159,6 +5161,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
51595161
(char *) thd->security_ctx->host_or_ip, 1);
51605162
error= mysql_execute_command(thd, true);
51615163
MYSQL_QUERY_EXEC_DONE(error);
5164+
thd->update_server_status();
51625165
}
51635166
else
51645167
{
@@ -5184,8 +5187,47 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
51845187
DBUG_ASSERT(! (error && cursor));
51855188

51865189
if (! cursor)
5187-
cleanup_stmt();
5188-
5190+
/*
5191+
Pass the value false to don't restore set statement variables.
5192+
See the next comment block for more details.
5193+
*/
5194+
cleanup_stmt(false);
5195+
5196+
/*
5197+
Log the statement to slow query log if it passes filtering.
5198+
We do it here for prepared statements despite of the fact that the function
5199+
log_slow_statement() is also called upper the stack from the function
5200+
dispatch_command(). The reason for logging slow queries here is that
5201+
the function log_slow_statement() must be called before restoring system
5202+
variables that could be set on execution of SET STATEMENT clause. Since
5203+
for prepared statement restoring of system variables set on execution of
5204+
SET STATEMENT clause is performed on return from the method
5205+
Prepared_statement::execute(), by the time the function log_slow_statement()
5206+
be invoked from the function dispatch_command() all variables set by
5207+
the SET STATEMEN clause would be already reset to their original values
5208+
that break semantic of the SET STATEMENT clause.
5209+
5210+
E.g., lets consider the following statements
5211+
SET slow_query_log= 1;
5212+
SET @@long_query_time=0.01;
5213+
PREPARE stmt FROM 'set statement slow_query_log=0 for select sleep(0.1)';
5214+
EXECUTE stmt;
5215+
5216+
It's expected that the above statements don't write any record
5217+
to slow query log since the system variable slow_query_log is set to 0
5218+
during execution of the whole statement
5219+
'set statement slow_query_log=0 for select sleep(0.1)'
5220+
5221+
However, if the function log_slow_statement wasn't called here the record
5222+
for the statement would be written to slow query log since the variable
5223+
slow_query_log is restored to its original value by the time the function
5224+
log_slow_statement is called from disptach_command() to write a record
5225+
into slow query log.
5226+
*/
5227+
log_slow_statement(thd);
5228+
5229+
lex->restore_set_statement_var();
5230+
51895231
/*
51905232
EXECUTE command has its own dummy "explain data". We don't need it,
51915233
instead, we want to keep the query plan of the statement that was

0 commit comments

Comments
 (0)