summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc20
1 files changed, 15 insertions, 5 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f8320e830a5..296135c93e7 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -43,6 +43,7 @@
#include "sql_base.h" // close_thread_tables
#include "transaction.h" // trans_commit_stmt
#include "sql_audit.h"
+#include "debug_sync.h"
/*
Sufficient max length of printed destinations and frame offsets (all uints).
@@ -1123,6 +1124,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
Item_change_list old_change_list;
String old_packet;
uint old_server_status;
+ const uint status_backup_mask= SERVER_STATUS_CURSOR_EXISTS |
+ SERVER_STATUS_LAST_ROW_SENT;
Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
Object_creation_ctx *saved_creation_ctx;
Diagnostics_area *da= thd->get_stmt_da();
@@ -1257,7 +1260,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
It is probably safe to use same thd->convert_buff everywhere.
*/
old_packet.swap(thd->packet);
- old_server_status= thd->server_status;
+ old_server_status= thd->server_status & status_backup_mask;
/*
Switch to per-instruction arena here. We can do it since we cleanup
@@ -1275,6 +1278,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
/* Discard the initial part of executing routines. */
thd->profiling.discard_current_query();
#endif
+ DEBUG_SYNC(thd, "sp_head_execute_before_loop");
do
{
sp_instr *i;
@@ -1379,7 +1383,7 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
/* Restore all saved */
- thd->server_status= old_server_status;
+ thd->server_status= (thd->server_status & ~status_backup_mask) | old_server_status;
old_packet.swap(thd->packet);
DBUG_ASSERT(thd->change_list.is_empty());
old_change_list.move_elements_to(&thd->change_list);
@@ -1852,9 +1856,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
as one select and not resetting THD::user_var_events before
each invocation.
*/
- mysql_mutex_lock(&LOCK_thread_count);
- q= global_query_id;
- mysql_mutex_unlock(&LOCK_thread_count);
+ q= get_query_id();
mysql_bin_log.start_union_events(thd, q + 1);
binlog_save_options= thd->variables.option_bits;
thd->variables.option_bits&= ~OPTION_BIN_LOG;
@@ -2290,6 +2292,11 @@ sp_head::restore_lex(THD *thd)
*/
if (sp_update_sp_used_routines(&m_sroutines, &sublex->sroutines))
DBUG_RETURN(TRUE);
+
+ /* If this substatement is a update query, then mark MODIFIES_DATA */
+ if (is_update_query(sublex->sql_command))
+ m_flags|= MODIFIES_DATA;
+
/*
Merge tables used by this statement (but not by its functions or
procedures) to multiset of tables used by this routine.
@@ -3109,7 +3116,10 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
thd->query_name_consts= 0;
if (!thd->is_error())
+ {
+ res= 0;
thd->get_stmt_da()->reset_diagnostics_area();
+ }
}
DBUG_RETURN(res || thd->is_error());
}