@@ -201,7 +201,7 @@ class Prepared_statement: public Statement
201
201
virtual ~Prepared_statement ();
202
202
void setup_set_params ();
203
203
virtual Query_arena::Type type () const ;
204
- virtual void cleanup_stmt ();
204
+ virtual void cleanup_stmt (bool restore_set_statement_vars );
205
205
bool set_name (const LEX_CSTRING *name);
206
206
inline void close_cursor () { delete cursor; cursor= 0 ; }
207
207
inline bool is_in_use () { return flags & (uint) IS_IN_USE; }
@@ -4193,11 +4193,14 @@ Query_arena::Type Prepared_statement::type() const
4193
4193
}
4194
4194
4195
4195
4196
- void Prepared_statement::cleanup_stmt ()
4196
+ void Prepared_statement::cleanup_stmt (bool restore_set_statement_vars )
4197
4197
{
4198
4198
DBUG_ENTER (" Prepared_statement::cleanup_stmt" );
4199
4199
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
+
4201
4204
thd->rollback_item_tree_changes ();
4202
4205
cleanup_items (free_list);
4203
4206
thd->cleanup_after_query ();
@@ -4406,12 +4409,6 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
4406
4409
lex->context_analysis_only &= ~CONTEXT_ANALYSIS_ONLY_PREPARE;
4407
4410
}
4408
4411
4409
- /*
4410
- Restore original values of variables modified on handling
4411
- SET STATEMENT clause.
4412
- */
4413
- thd->lex ->restore_set_statement_var ();
4414
-
4415
4412
/* The order is important */
4416
4413
lex->unit .cleanup ();
4417
4414
@@ -4440,7 +4437,12 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len)
4440
4437
if (lex->sql_command != SQLCOM_SET_OPTION)
4441
4438
lex_unlock_plugins (lex);
4442
4439
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
+
4444
4446
thd->restore_backup_statement (this , &stmt_backup);
4445
4447
thd->stmt_arena = old_stmt_arena;
4446
4448
thd->cur_stmt = save_cur_stmt;
@@ -5159,6 +5161,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
5159
5161
(char *) thd->security_ctx ->host_or_ip , 1 );
5160
5162
error= mysql_execute_command (thd, true );
5161
5163
MYSQL_QUERY_EXEC_DONE (error);
5164
+ thd->update_server_status ();
5162
5165
}
5163
5166
else
5164
5167
{
@@ -5184,8 +5187,47 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor)
5184
5187
DBUG_ASSERT (! (error && cursor));
5185
5188
5186
5189
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
+
5189
5231
/*
5190
5232
EXECUTE command has its own dummy "explain data". We don't need it,
5191
5233
instead, we want to keep the query plan of the statement that was
0 commit comments