summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-10-04 10:56:47 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-10-04 10:56:47 +0300
commit627027a6743672ce7b461971f772631d65f759f2 (patch)
treebf88020d3c2615bf8f0dbf4291ae6a6ad6a8d196 /sql/sp_head.cc
parent1950e3246476ae6bee01290f31a3fb98427da73b (diff)
parent5709a7777bd2c5c27b0f535099439f13c251de03 (diff)
downloadmariadb-git-627027a6743672ce7b461971f772631d65f759f2.tar.gz
Merge 10.4 into 10.5
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc106
1 files changed, 63 insertions, 43 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 90fb288cc3c..1968ba83101 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1345,6 +1345,69 @@ sp_head::execute(THD *thd, bool merge_da_on_success)
#endif /* WITH_WSREP */
err_status= i->execute(thd, &ip);
+#ifdef WITH_WSREP
+ if (WSREP(thd))
+ {
+ if (((thd->wsrep_trx().state() == wsrep::transaction::s_executing || thd->in_sub_stmt) &&
+ (thd->is_fatal_error || thd->killed)))
+ {
+ WSREP_DEBUG("SP abort err status %d in sub %d trx state %d",
+ err_status, thd->in_sub_stmt, thd->wsrep_trx().state());
+ err_status= 1;
+ thd->is_fatal_error= 1;
+ /*
+ SP was killed, and it is not due to a wsrep conflict.
+ We skip after_command hook at this point because
+ otherwise it clears the error, and cleans up the
+ whole transaction. For now we just return and finish
+ our handling once we are back to mysql_parse.
+
+ Same applies to a SP execution, which was aborted due
+ to wsrep related conflict, but which is executing as sub statement.
+ SP in sub statement level should not commit not rollback,
+ we have to call for rollback is up-most SP level.
+ */
+ WSREP_DEBUG("Skipping after_command hook for killed SP");
+ }
+ else
+ {
+ const bool must_replay= wsrep_must_replay(thd);
+ if (must_replay)
+ {
+ WSREP_DEBUG("MUST_REPLAY set after SP, err_status %d trx state: %d",
+ err_status, thd->wsrep_trx().state());
+ }
+ (void) wsrep_after_statement(thd);
+
+ /*
+ Reset the return code to zero if the transaction was
+ replayed succesfully.
+ */
+ if (must_replay && !wsrep_current_error(thd))
+ {
+ err_status= 0;
+ thd->get_stmt_da()->reset_diagnostics_area();
+ }
+ /*
+ Final wsrep error status for statement is known only after
+ wsrep_after_statement() call. If the error is set, override
+ error in thd diagnostics area and reset wsrep client_state error
+ so that the error does not get propagated via client-server protocol.
+ */
+ if (wsrep_current_error(thd))
+ {
+ wsrep_override_error(thd, wsrep_current_error(thd),
+ wsrep_current_error_status(thd));
+ thd->wsrep_cs().reset_error();
+ /* Reset also thd->killed if it has been set during BF abort. */
+ if (thd->killed == KILL_QUERY)
+ thd->killed= NOT_KILLED;
+ /* if failed transaction was not replayed, must return with error from here */
+ if (!must_replay) err_status = 1;
+ }
+ }
+ }
+#endif /* WITH_WSREP */
thd->m_digest= parent_digest;
if (i->free_list)
@@ -3604,49 +3667,6 @@ sp_instr_stmt::exec_core(THD *thd, uint *nextp)
(char *)thd->security_ctx->host_or_ip,
3);
int res= mysql_execute_command(thd);
-#ifdef WITH_WSREP
- if (WSREP(thd))
- {
- if ((thd->is_fatal_error || thd->killed_errno()) &&
- (thd->wsrep_trx().state() == wsrep::transaction::s_executing))
- {
- /*
- SP was killed, and it is not due to a wsrep conflict.
- We skip after_statement hook at this point because
- otherwise it clears the error, and cleans up the
- whole transaction. For now we just return and finish
- our handling once we are back to mysql_parse.
- */
- WSREP_DEBUG("Skipping after_command hook for killed SP");
- }
- else
- {
- const bool must_replay= wsrep_must_replay(thd);
- (void) wsrep_after_statement(thd);
- /*
- Reset the return code to zero if the transaction was
- replayed succesfully.
- */
- if (res && must_replay && !wsrep_current_error(thd))
- res= 0;
- /*
- Final wsrep error status for statement is known only after
- wsrep_after_statement() call. If the error is set, override
- error in thd diagnostics area and reset wsrep client_state error
- so that the error does not get propagated via client-server protocol.
- */
- if (wsrep_current_error(thd))
- {
- wsrep_override_error(thd, wsrep_current_error(thd),
- wsrep_current_error_status(thd));
- thd->wsrep_cs().reset_error();
- /* Reset also thd->killed if it has been set during BF abort. */
- if (thd->killed == KILL_QUERY)
- thd->reset_killed();
- }
- }
- }
-#endif /* WITH_WSREP */
MYSQL_QUERY_EXEC_DONE(res);
*nextp= m_ip+1;
return res;