Commit 6a2fbdf9 authored by Sergei Golubchik's avatar Sergei Golubchik

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
parent 1bd1c29e
......@@ -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;
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment