mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
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
This commit is contained in:
@@ -65,7 +65,7 @@ i0 1 a
|
|||||||
i1 1 a
|
i1 1 a
|
||||||
u0 1 a d
|
u0 1 a d
|
||||||
u1 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');
|
insert into t1 values ('0','1');
|
||||||
SELECT * FROM t2 order by id;
|
SELECT * FROM t2 order by id;
|
||||||
id cnt o n
|
id cnt o n
|
||||||
@@ -78,12 +78,12 @@ u1 1 a d
|
|||||||
insert into t1 values ('0','1');
|
insert into t1 values ('0','1');
|
||||||
SELECT * FROM t2 order by id;
|
SELECT * FROM t2 order by id;
|
||||||
id cnt o n
|
id cnt o n
|
||||||
d0 1 d
|
d0 2 0
|
||||||
d1 1 d
|
d1 2 0
|
||||||
i0 3 0
|
i0 3 0
|
||||||
i1 3 0
|
i1 3 0
|
||||||
u0 2 0 0
|
u0 1 a d
|
||||||
u1 2 0 0
|
u1 1 a d
|
||||||
# INSERT triggers which cause also DELETE test
|
# INSERT triggers which cause also DELETE test
|
||||||
# (insert duplicate row in table referenced by foreign key)
|
# (insert duplicate row in table referenced by foreign key)
|
||||||
insert into t1 values ('1','1');
|
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');
|
insert into t1 values ('1','1');
|
||||||
SELECT * FROM t2 order by id;
|
SELECT * FROM t2 order by id;
|
||||||
id cnt o n
|
id cnt o n
|
||||||
d0 2 1
|
d0 3 1
|
||||||
d1 2 1
|
d1 3 1
|
||||||
i0 5 1
|
i0 5 1
|
||||||
i1 5 1
|
i1 5 1
|
||||||
u0 2 0 0
|
u0 1 a d
|
||||||
u1 2 0 0
|
u1 1 a d
|
||||||
drop table t3,t1;
|
drop table t3,t1;
|
||||||
SET @@global.slave_exec_mode= @old_slave_exec_mode;
|
SET @@global.slave_exec_mode= @old_slave_exec_mode;
|
||||||
SET @@global.slave_run_triggers_for_rbr= @old_slave_run_triggers_for_rbr;
|
SET @@global.slave_run_triggers_for_rbr= @old_slave_run_triggers_for_rbr;
|
||||||
|
@@ -64,7 +64,7 @@ sync_slave_with_master;
|
|||||||
connection slave;
|
connection slave;
|
||||||
SELECT * FROM t2 order by id;
|
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');
|
insert into t1 values ('0','1');
|
||||||
|
|
||||||
SELECT * FROM t2 order by id;
|
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
|
then there might be another key for which the unique check will
|
||||||
fail, so we're better off just deleting the row and inserting
|
fail, so we're better off just deleting the row and inserting
|
||||||
the correct row.
|
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())
|
!table->file->referenced_by_foreign_key())
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("Updating row using ha_update_row()"));
|
DBUG_PRINT("info",("Updating row using ha_update_row()"));
|
||||||
if (invoke_triggers &&
|
error= table->file->ha_update_row(table->record[1],
|
||||||
process_triggers(TRG_EVENT_UPDATE, TRG_ACTION_BEFORE, FALSE))
|
table->record[0]);
|
||||||
error= HA_ERR_GENERIC; // in case if error is not set yet
|
switch (error) {
|
||||||
else
|
|
||||||
{
|
|
||||||
error= table->file->ha_update_row(table->record[1],
|
|
||||||
table->record[0]);
|
|
||||||
switch (error) {
|
|
||||||
|
|
||||||
case HA_ERR_RECORD_IS_THE_SAME:
|
case HA_ERR_RECORD_IS_THE_SAME:
|
||||||
DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
|
DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
|
||||||
" ha_update_row()"));
|
" ha_update_row()"));
|
||||||
error= 0;
|
error= 0;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DBUG_PRINT("info",("ha_update_row() returns error %d",error));
|
DBUG_PRINT("info",("ha_update_row() returns error %d",error));
|
||||||
table->file->print_error(error, MYF(0));
|
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
|
Reference in New Issue
Block a user