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:
@ -4131,6 +4131,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
switch ((*prepare_func)(thd, table, check_opt)) {
|
||||
case 1: // error, message written to net
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
end_trans(thd, ROLLBACK);
|
||||
close_thread_tables(thd);
|
||||
DBUG_PRINT("admin", ("simple error, admin next table"));
|
||||
continue;
|
||||
@ -4189,6 +4190,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
table_name);
|
||||
protocol->store(buff, length, system_charset_info);
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
end_trans(thd, COMMIT);
|
||||
close_thread_tables(thd);
|
||||
lex->reset_query_tables_list(FALSE);
|
||||
table->table=0; // For query cache
|
||||
@ -4461,6 +4463,7 @@ send_result_message:
|
||||
}
|
||||
}
|
||||
ha_autocommit_or_rollback(thd, 0);
|
||||
end_trans(thd, COMMIT);
|
||||
close_thread_tables(thd);
|
||||
table->table=0; // For query cache
|
||||
if (protocol->write())
|
||||
@ -4470,8 +4473,9 @@ send_result_message:
|
||||
send_eof(thd);
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
err:
|
||||
err:
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
end_trans(thd, ROLLBACK);
|
||||
close_thread_tables(thd); // Shouldn't be needed
|
||||
if (table)
|
||||
table->table=0;
|
||||
@ -4994,8 +4998,8 @@ mysql_discard_or_import_tablespace(THD *thd,
|
||||
query_cache_invalidate3(thd, table_list, 0);
|
||||
|
||||
/* The ALTER TABLE is always in its own transaction */
|
||||
error = ha_commit_stmt(thd);
|
||||
if (ha_commit(thd))
|
||||
error = ha_autocommit_or_rollback(thd, 0);
|
||||
if (end_active_trans(thd))
|
||||
error=1;
|
||||
if (error)
|
||||
goto err;
|
||||
@ -5003,7 +5007,6 @@ mysql_discard_or_import_tablespace(THD *thd,
|
||||
|
||||
err:
|
||||
ha_autocommit_or_rollback(thd, error);
|
||||
close_thread_tables(thd);
|
||||
thd->tablespace_op=FALSE;
|
||||
|
||||
if (error == 0)
|
||||
@ -6526,8 +6529,8 @@ view_err:
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
alter_table_manage_keys(table, table->file->indexes_are_disabled(),
|
||||
alter_info->keys_onoff);
|
||||
error= ha_commit_stmt(thd);
|
||||
if (ha_commit(thd))
|
||||
error= ha_autocommit_or_rollback(thd, 0);
|
||||
if (end_active_trans(thd))
|
||||
error= 1;
|
||||
}
|
||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||
@ -6615,7 +6618,7 @@ view_err:
|
||||
|
||||
/* Need to commit before a table is unlocked (NDB requirement). */
|
||||
DBUG_PRINT("info", ("Committing before unlocking table"));
|
||||
if (ha_commit_stmt(thd) || ha_commit(thd))
|
||||
if (ha_autocommit_or_rollback(thd, 0) || end_active_trans(thd))
|
||||
goto err1;
|
||||
committed= 1;
|
||||
}
|
||||
@ -7116,9 +7119,9 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
Ensure that the new table is saved properly to disk so that we
|
||||
can do a rename
|
||||
*/
|
||||
if (ha_commit_stmt(thd))
|
||||
if (ha_autocommit_or_rollback(thd, 0))
|
||||
error=1;
|
||||
if (ha_commit(thd))
|
||||
if (end_active_trans(thd))
|
||||
error=1;
|
||||
|
||||
err:
|
||||
|
Reference in New Issue
Block a user