Skip to content

Commit

Permalink
fix(stonedb): fix problem caused by concatenated calls of multiple tr…
Browse files Browse the repository at this point in the history
…iggers.(stoneatom#580)
  • Loading branch information
duanfuxiang0 committed Oct 8, 2022
1 parent 008cc77 commit 6575c7d
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 70 deletions.
75 changes: 71 additions & 4 deletions mysql-test/suite/tianmu/r/trigger.result
Original file line number Diff line number Diff line change
Expand Up @@ -935,21 +935,88 @@ DROP TABLE t1, t2;
#
#bug569:After update trigger
#
create table t1 (i int)engine=tianmu;
insert into t1 values (1),(2),(3),(4);
create trigger trg after update on t1 for each row
set @total_change:=@total_change + new.i - old.i;
set @total_change:=0;
update t1 set i=3;
select @total_change;
@total_change
2
drop trigger trg;
drop table t1;
#
#bug 570:Before delete trigger
#
create table t1 (i int)engine=innodb;
insert into t1 values (1),(2),(3),(4);
create trigger trg before delete on t1 for each row
set @del_sum:= @del_sum + old.i;
set @del_sum:= 0;
delete from t1 where i <= 3;
select @del_sum;
@del_sum
6
drop trigger trg;
drop table t1;
#
#bug 571:After delete trigger
#
create table t1 (i int)engine=innodb;
insert into t1 values (1),(2),(3),(4);
create trigger trg after delete on t1 for each row set @del:= 1;
set @del:= 0;
delete from t1 where i <> 0;
select @del;
@del
1
drop trigger trg;
drop table t1;
#
# bug 580:Trigger.....delete
#
create table t1 (id int primary key, fk_t2 int)engine=tianmu;
create table t2 (id int primary key, fk_t3 int)engine=tianmu;
create table t3 (id int primary key)engine=tianmu;
insert into t1 values (1,1), (2,1), (3,2);
insert into t2 values (1,1), (2,2);
insert into t3 values (1), (2);
create trigger t3_ad after delete on t3 for each row
delete from t2 where fk_t3=old.id;
create trigger t2_ad after delete on t2 for each row
delete from t1 where fk_t2=old.id;
delete from t3 where id = 1;
select * from t1 left join (t2 left join t3 on t2.fk_t3 = t3.id) on t1.fk_t2 = t2.id;
id fk_t2 id fk_t3 id
3 2 2 2 2
drop table t1;
drop table t2;
drop table t3;
#
# bug 581: Trigger....inserted/updated
#
# bug 581:Trigger....inserted/updated
#
# bug 586: trigger contains a SELECT with trigger fields in the select list under DISTINCT
#
#bug 586:trigger contains a SELECT with
# trigger fields in the select list under DISTINCT
#
#create temporary table inside trigger
# bug 589: create temporary table inside trigger
#
CREATE TABLE t1 (a INT, b INT DEFAULT 150)engine=tianmu;
CREATE TRIGGER t1_bi BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
CREATE TEMPORARY TABLE t2 AS SELECT NEW.a, NEW.b;
INSERT INTO t2(a) VALUES (10);
INSERT INTO t2 VALUES (100, 500);
INSERT INTO t2(a) VALUES (1000);
END|
INSERT INTO t1 VALUES (1, 2);
SELECT * FROM t2;
a b
1 2
10 150
100 500
1000 150
DROP TABLE t1;
DROP TEMPORARY TABLE t2;
125 changes: 62 additions & 63 deletions mysql-test/suite/tianmu/t/trigger.test
Original file line number Diff line number Diff line change
Expand Up @@ -991,41 +991,42 @@ DROP TABLE t1, t2;
--echo #bug569:After update trigger
--echo #

#create table t1 (i int)engine=tianmu;
#insert into t1 values (1),(2),(3),(4);
#create trigger trg after update on t1 for each row
# set @total_change:=@total_change + new.i - old.i;
#set @total_change:=0;
#update t1 set i=3;
#select @total_change;
#drop trigger trg;
#drop table t1;
create table t1 (i int)engine=tianmu;
insert into t1 values (1),(2),(3),(4);
create trigger trg after update on t1 for each row
set @total_change:=@total_change + new.i - old.i;
set @total_change:=0;
update t1 set i=3;
select @total_change;
drop trigger trg;
drop table t1;

--echo #
--echo #bug 570:Before delete trigger
--echo #

#create table t1 (i int)engine=innodb;
#insert into t1 values (1),(2),(3),(4);
#create trigger trg before delete on t1 for each row
# set @del_sum:= @del_sum + old.i;
#set @del_sum:= 0;
#delete from t1 where i <= 3;
#select @del_sum;
#drop trigger trg;
create table t1 (i int)engine=innodb;
insert into t1 values (1),(2),(3),(4);
create trigger trg before delete on t1 for each row
set @del_sum:= @del_sum + old.i;
set @del_sum:= 0;
delete from t1 where i <= 3;
select @del_sum;
drop trigger trg;
drop table t1;

--echo #
--echo #bug 571:After delete trigger
--echo #

#create table t1 (i int)engine=innodb;
#insert into t1 values (1),(2),(3),(4);
#create trigger trg after delete on t1 for each row set @del:= 1;
#set @del:= 0;
#delete from t1 where i <> 0;
#select @del;
#drop trigger trg;
#drop table t1;
create table t1 (i int)engine=innodb;
insert into t1 values (1),(2),(3),(4);
create trigger trg after delete on t1 for each row set @del:= 1;
set @del:= 0;
delete from t1 where i <> 0;
select @del;
drop trigger trg;
drop table t1;

--echo #
--echo # bug 580:Trigger.....delete
Expand All @@ -1034,22 +1035,24 @@ DROP TABLE t1, t2;
# Trigger which forces invocation of another trigger
# (emulation of FK on delete cascade policy)

#create table t1 (id int primary key, fk_t2 int)engine=tianmu;
#create table t2 (id int primary key, fk_t3 int)engine=tianmu;
#create table t3 (id int primary key)engine=tianmu;
#insert into t1 values (1,1), (2,1), (3,2);
#insert into t2 values (1,1), (2,2);
#insert into t3 values (1), (2);
#create trigger t3_ad after delete on t3 for each row
# delete from t2 where fk_t3=old.id;
#create trigger t2_ad after delete on t2 for each row
# delete from t1 where fk_t2=old.id;
#delete from t3 where id = 1;
#select * from t1 left join (t2 left join t3 on t2.fk_t3 = t3.id) on t1.fk_t2 = t2.id;
#drop table t1, t2, t3;
create table t1 (id int primary key, fk_t2 int)engine=tianmu;
create table t2 (id int primary key, fk_t3 int)engine=tianmu;
create table t3 (id int primary key)engine=tianmu;
insert into t1 values (1,1), (2,1), (3,2);
insert into t2 values (1,1), (2,2);
insert into t3 values (1), (2);
create trigger t3_ad after delete on t3 for each row
delete from t2 where fk_t3=old.id;
create trigger t2_ad after delete on t2 for each row
delete from t1 where fk_t2=old.id;
delete from t3 where id = 1;
select * from t1 left join (t2 left join t3 on t2.fk_t3 = t3.id) on t1.fk_t2 = t2.id;
drop table t1;
drop table t2;
drop table t3;

--echo #
--echo # bug 581:Trigger....inserted/updated
--echo # bug 581: Trigger....inserted/updated
--echo #

# Trigger which assigns value selected from table to field of row
Expand All @@ -1068,8 +1071,8 @@ DROP TABLE t1, t2;
#drop table t1, t2;

--echo #
--echo #bug 586:trigger contains a SELECT with
--echo # trigger fields in the select list under DISTINCT
--echo # bug 586: trigger contains a SELECT with trigger fields in the select list under DISTINCT
--echo #
#SET sql_mode = 'NO_ENGINE_SUBSTITUTION';
#CREATE TABLE t1 (
# id int NOT NULL DEFAULT '0',
Expand All @@ -1086,7 +1089,7 @@ DROP TABLE t1, t2;
# PRIMARY KEY (fubar_id)
#)engine=tianmu;
#
#DELIMITER |
#DELIMITER |;
#CREATE TRIGGER fubar_change
# AFTER UPDATE ON t1
# FOR EACH ROW
Expand All @@ -1099,7 +1102,7 @@ DROP TABLE t1, t2;
# IF((fubar_id = NEW.id)AND(OLD.c != NEW.c),NOW(),last_change_time);
# END|
#
#DELIMITER ;
#DELIMITER ;|
#INSERT INTO t1 (id,a, b,c,d) VALUES
# (1,'a','b','c',now()),(2,'a','b','c',now());
#
Expand All @@ -1110,26 +1113,22 @@ DROP TABLE t1, t2;
#SET sql_mode = default;

--echo #
--echo #create temporary table inside trigger
--echo # bug 589: create temporary table inside trigger
--echo #
CREATE TABLE t1 (a INT, b INT DEFAULT 150)engine=tianmu;

#CREATE TABLE t1 (a INT, b INT DEFAULT 150)engine=tianmu;
#
#delimiter |;
#CREATE TRIGGER t1_bi BEFORE INSERT ON t1
#FOR EACH ROW
#BEGIN
# CREATE TEMPORARY TABLE t2 AS SELECT NEW.a, NEW.b;
# INSERT INTO t2(a) VALUES (10);
# INSERT INTO t2 VALUES (100, 500);
# INSERT INTO t2(a) VALUES (1000);
#END|
#delimiter ;|
#
#INSERT INTO t1 VALUES (1, 2);
#SELECT * FROM t2;
#
#DROP TABLE t1;
#DROP TEMPORARY TABLE t2;

delimiter |;
CREATE TRIGGER t1_bi BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
CREATE TEMPORARY TABLE t2 AS SELECT NEW.a, NEW.b;
INSERT INTO t2(a) VALUES (10);
INSERT INTO t2 VALUES (100, 500);
INSERT INTO t2(a) VALUES (1000);
END|
delimiter ;|

INSERT INTO t1 VALUES (1, 2);
SELECT * FROM t2;
DROP TABLE t1;
DROP TEMPORARY TABLE t2;
3 changes: 2 additions & 1 deletion sql/handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2924,7 +2924,8 @@ int handler::ha_rnd_init(bool scan)
DBUG_ENTER("ha_rnd_init");
assert(table_share->tmp_table != NO_TMP_TABLE ||
m_lock_type != F_UNLCK);
assert(inited == NONE || (inited == RND && scan));
assert(inited == NONE || (inited == RND && scan) ||
(inited == INDEX && ht->db_type == DB_TYPE_TIANMU));
inited= (result= rnd_init(scan)) ? NONE : RND;
end_range= NULL;
DBUG_RETURN(result);
Expand Down
13 changes: 12 additions & 1 deletion sql/sql_delete.cc
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,18 @@ bool Sql_cmd_delete::mysql_delete(THD *thd, ha_rows limit)
err= true;
goto exit_without_my_ok;
}

#ifdef TIANMU
if (table->s->db_type()->db_type == DB_TYPE_TIANMU
&& table->triggers
&& table->triggers->has_triggers(TRG_EVENT_DELETE, TRG_ACTION_AFTER)) {
/*
The table has AFTER DELETE triggers, trigger might need OLD records,
but RCTable of tianmu engine is only load required columns. So here
we set to all columns to be used.
*/
bitmap_set_all(table->read_set);
}
#endif
if (usable_index==MAX_KEY || qep_tab.quick())
error= init_read_record(&info, thd, NULL, &qep_tab, 1, 1, FALSE);
else
Expand Down
4 changes: 3 additions & 1 deletion storage/tianmu/core/rc_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -468,7 +468,9 @@ void RCTable::Iterator::MoveToRow(int64_t row_id) {
void RCTable::Iterator::FetchValues() {
if (!current_record_fetched) {
LockPacks();
for (auto &func : values_fetchers) func(position);
for (auto &func : values_fetchers) {
func(position);
}
current_record_fetched = true;
}
}
Expand Down

0 comments on commit 6575c7d

Please sign in to comment.