diff options
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r-- | sql/sp_head.cc | 20 |
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()); } |