diff options
author | Sergei Golubchik <serg@mariadb.org> | 2014-11-29 00:29:40 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2014-12-04 10:41:52 +0100 |
commit | 6a2fbdf948af3e72be577daaac89e9a3ce69a682 (patch) | |
tree | 20ecf808505075ae1cf88cf69a97e71d84a00fa8 | |
parent | 1bd1c29ea0ec51d2efefcadbc1ca217aff9f7610 (diff) | |
download | mariadb-git-6a2fbdf948af3e72be577daaac89e9a3ce69a682.tar.gz |
MDEV-6979 simplify trigger rules for RBR triggers
Rows_log_event::write_row - don't optimize DELETE+INSERT
into UPDATE if RBR triggers are used
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_row_triggers.result | 18 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_row_triggers.test | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 39 |
3 files changed, 26 insertions, 33 deletions
diff --git a/mysql-test/suite/rpl/r/rpl_row_triggers.result b/mysql-test/suite/rpl/r/rpl_row_triggers.result index 82dbc727993..7f37805b635 100644 --- a/mysql-test/suite/rpl/r/rpl_row_triggers.result +++ b/mysql-test/suite/rpl/r/rpl_row_triggers.result @@ -65,7 +65,7 @@ i0 1 a i1 1 a u0 1 a d u1 1 a d -# INSERT triggers which cause also UPDATE test (insert duplicate row) +# INSERT triggers causing DELETE + INSERT (on unique key conflict) insert into t1 values ('0','1'); SELECT * FROM t2 order by id; id cnt o n @@ -78,12 +78,12 @@ u1 1 a d insert into t1 values ('0','1'); SELECT * FROM t2 order by id; id cnt o n -d0 1 d -d1 1 d +d0 2 0 +d1 2 0 i0 3 0 i1 3 0 -u0 2 0 0 -u1 2 0 0 +u0 1 a d +u1 1 a d # INSERT triggers which cause also DELETE test # (insert duplicate row in table referenced by foreign key) insert into t1 values ('1','1'); @@ -91,12 +91,12 @@ CREATE TABLE t3 (C1 CHAR(1) primary key, FOREIGN KEY (C1) REFERENCES t1(C1) ) en insert into t1 values ('1','1'); SELECT * FROM t2 order by id; id cnt o n -d0 2 1 -d1 2 1 +d0 3 1 +d1 3 1 i0 5 1 i1 5 1 -u0 2 0 0 -u1 2 0 0 +u0 1 a d +u1 1 a d drop table t3,t1; SET @@global.slave_exec_mode= @old_slave_exec_mode; SET @@global.slave_run_triggers_for_rbr= @old_slave_run_triggers_for_rbr; diff --git a/mysql-test/suite/rpl/t/rpl_row_triggers.test b/mysql-test/suite/rpl/t/rpl_row_triggers.test index 3a884727325..e3c90d874f0 100644 --- a/mysql-test/suite/rpl/t/rpl_row_triggers.test +++ b/mysql-test/suite/rpl/t/rpl_row_triggers.test @@ -64,7 +64,7 @@ sync_slave_with_master; connection slave; SELECT * FROM t2 order by id; ---echo # INSERT triggers which cause also UPDATE test (insert duplicate row) +--echo # INSERT triggers causing DELETE + INSERT (on unique key conflict) insert into t1 values ('0','1'); SELECT * FROM t2 order by id; diff --git a/sql/log_event.cc b/sql/log_event.cc index 98b34543cb3..66b577ff0bb 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11471,36 +11471,29 @@ Rows_log_event::write_row(rpl_group_info *rgi, then there might be another key for which the unique check will fail, so we're better off just deleting the row and inserting the correct row. + + Additionally we don't use UPDATE if rbr triggers should be invoked - + when triggers are used we want a simple and predictable execution path. */ - if (last_uniq_key(table, keynum) && + if (last_uniq_key(table, keynum) && !invoke_triggers && !table->file->referenced_by_foreign_key()) { DBUG_PRINT("info",("Updating row using ha_update_row()")); - if (invoke_triggers && - process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, FALSE)) - error= HA_ERR_GENERIC; // in case if error is not set yet - else - { - error= table->file->ha_update_row(table->record[1], - table->record[0]); - switch (error) { + error= table->file->ha_update_row(table->record[1], + table->record[0]); + switch (error) { - case HA_ERR_RECORD_IS_THE_SAME: - DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from" - " ha_update_row()")); - error= 0; + case HA_ERR_RECORD_IS_THE_SAME: + DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from" + " ha_update_row()")); + error= 0; - case 0: - break; + case 0: + break; - default: - DBUG_PRINT("info",("ha_update_row() returns error %d",error)); - table->file->print_error(error, MYF(0)); - } - if (invoke_triggers && !error && - (process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_AFTER, TRUE) || - process_triggers(TRG_EVENT_INSERT, TRG_ACTION_AFTER, TRUE))) - error= HA_ERR_GENERIC; // in case if error is not set yet + default: + DBUG_PRINT("info",("ha_update_row() returns error %d",error)); + table->file->print_error(error, MYF(0)); } DBUG_RETURN(error); |