diff options
author | aelkin/elkin@koti.dsl.inet.fi <> | 2007-10-13 15:49:42 +0300 |
---|---|---|
committer | aelkin/elkin@koti.dsl.inet.fi <> | 2007-10-13 15:49:42 +0300 |
commit | ed0ab76e28d7a90c94732b689c18dabb1becd920 (patch) | |
tree | 23f909d86ea905c39947805347dd334c866d0114 /sql/sql_update.cc | |
parent | 4c01449b8464468a4be6ad03767e01e35991b038 (diff) | |
download | mariadb-git-ed0ab76e28d7a90c94732b689c18dabb1becd920.tar.gz |
Bug #29136 erred multi-delete on trans table does not rollback the statement
similar to bug_27716, but it was stressed on in the synopsis on that there is another
side of the artifact affecting behaviour in transaction.
Fixed with deploying multi_delete::send_error() - otherwise never called - and refining its logic
to perform binlogging job if needed.
The changeset includes the following side effects:
- added tests to check bug_23333's scenarios on the mixture of tables for multi_update;
- fixes bug@30763 with two-liner patch and a test coinciding to one added for bug_23333.
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r-- | sql/sql_update.cc | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 3f38ad8b33c..f3695976508 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -994,8 +994,8 @@ multi_update::multi_update(TABLE_LIST *table_list, :all_tables(table_list), leaves(leaves_list), update_tables(0), tmp_tables(0), updated(0), found(0), fields(field_list), values(value_list), table_count(0), copy_field(0), - handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(0), - transactional_tables(1), ignore(ignore_arg) + handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1), + transactional_tables(1), ignore(ignore_arg), error_handled(0) {} @@ -1202,7 +1202,6 @@ multi_update::initialize_tables(JOIN *join) if ((thd->options & OPTION_SAFE_UPDATES) && error_if_full_join(join)) DBUG_RETURN(1); main_table=join->join_tab->table; - trans_safe= transactional_tables= main_table->file->has_transactions(); table_to_update= 0; /* Any update has at least one pair (field, value) */ @@ -1484,12 +1483,14 @@ void multi_update::send_error(uint errcode,const char *err) /* First send error what ever it is ... */ my_error(errcode, MYF(0), err); - /* If nothing updated return */ - if (updated == 0) /* the counter might be reset in send_eof */ - return; /* and then the query has been binlogged */ + /* the error was handled or nothing deleted and no side effects return */ + if (error_handled || + !thd->transaction.stmt.modified_non_trans_table && !updated) + return; /* Something already updated so we have to invalidate cache */ - query_cache_invalidate3(thd, update_tables, 1); + if (updated) + query_cache_invalidate3(thd, update_tables, 1); /* If all tables that has been updated are trans safe then just do rollback. If not attempt to do remaining updates. @@ -1525,8 +1526,7 @@ void multi_update::send_error(uint errcode,const char *err) transactional_tables, FALSE); mysql_bin_log.write(&qinfo); } - if (!trans_safe) - thd->transaction.all.modified_non_trans_table= TRUE; + thd->transaction.all.modified_non_trans_table= TRUE; } DBUG_ASSERT(trans_safe || !updated || thd->transaction.stmt.modified_non_trans_table); @@ -1739,8 +1739,6 @@ bool multi_update::send_eof() { if (local_error == 0) thd->clear_error(); - else - updated= 0; /* if there's an error binlog it here not in ::send_error */ Query_log_event qinfo(thd, thd->query, thd->query_length, transactional_tables, FALSE); if (mysql_bin_log.write(&qinfo) && trans_safe) @@ -1749,6 +1747,8 @@ bool multi_update::send_eof() if (thd->transaction.stmt.modified_non_trans_table) thd->transaction.all.modified_non_trans_table= TRUE; } + if (local_error != 0) + error_handled= TRUE; // to force early leave from ::send_error() if (transactional_tables) { |