mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
A fix and a test case for Bug#12713 "Error in a stored function called from
a SELECT doesn't cause ROLLBACK of statem". The idea of the fix is to ensure that we always commit the current statement at the end of dispatch_command(). In order to not issue redundant disc syncs, an optimization of the two-phase commit protocol is implemented to bypass the two phase commit if the transaction is read-only.
This commit is contained in:
@ -1465,21 +1465,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
break;
|
||||
}
|
||||
|
||||
thd_proc_info(thd, "closing tables");
|
||||
/* Free tables */
|
||||
close_thread_tables(thd);
|
||||
/* If commit fails, we should be able to reset the OK status. */
|
||||
thd->main_da.can_overwrite_status= TRUE;
|
||||
ha_autocommit_or_rollback(thd, thd->is_error());
|
||||
thd->main_da.can_overwrite_status= FALSE;
|
||||
|
||||
thd->transaction.stmt.reset();
|
||||
|
||||
/*
|
||||
assume handlers auto-commit (if some doesn't - transaction handling
|
||||
in MySQL should be redesigned to support it; it's a big change,
|
||||
and it's not worth it - better to commit explicitly only writing
|
||||
transactions, read-only ones should better take care of themselves.
|
||||
saves some work in 2pc too)
|
||||
see also sql_base.cc - close_thread_tables()
|
||||
*/
|
||||
bzero(&thd->transaction.stmt, sizeof(thd->transaction.stmt));
|
||||
if (!thd->active_transaction())
|
||||
thd->transaction.xid_state.xid.null();
|
||||
|
||||
/* report error issued during command execution */
|
||||
if (thd->killed_errno())
|
||||
@ -1496,6 +1488,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
net_end_statement(thd);
|
||||
query_cache_end_of_result(thd);
|
||||
|
||||
thd->proc_info= "closing tables";
|
||||
/* Free tables */
|
||||
close_thread_tables(thd);
|
||||
|
||||
log_slow_statement(thd);
|
||||
|
||||
thd_proc_info(thd, "cleaning up");
|
||||
@ -3011,10 +3007,8 @@ end_with_restore_list:
|
||||
/* INSERT ... SELECT should invalidate only the very first table */
|
||||
TABLE_LIST *save_table= first_table->next_local;
|
||||
first_table->next_local= 0;
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
query_cache_invalidate3(thd, first_table, 1);
|
||||
first_table->next_local= save_table;
|
||||
thd->lock=0;
|
||||
}
|
||||
delete sel_result;
|
||||
}
|
||||
@ -3985,7 +3979,6 @@ end_with_restore_list:
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_PROC_AUTO_GRANT_FAIL,
|
||||
ER(ER_PROC_AUTO_GRANT_FAIL));
|
||||
close_thread_tables(thd);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
Reference in New Issue
Block a user