summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2014-11-29 00:29:40 +0100
committerSergei Golubchik <serg@mariadb.org>2014-12-04 10:41:52 +0100
commit6a2fbdf948af3e72be577daaac89e9a3ce69a682 (patch)
tree20ecf808505075ae1cf88cf69a97e71d84a00fa8
parent1bd1c29ea0ec51d2efefcadbc1ca217aff9f7610 (diff)
downloadmariadb-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.result18
-rw-r--r--mysql-test/suite/rpl/t/rpl_row_triggers.test2
-rw-r--r--sql/log_event.cc39
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);