diff options
author | unknown <dlenev@brandersnatch.localdomain> | 2004-11-12 17:04:07 +0300 |
---|---|---|
committer | unknown <dlenev@brandersnatch.localdomain> | 2004-11-12 17:04:07 +0300 |
commit | bb43e8317fc3d78fd5f3d22a0ca0acf090540cd5 (patch) | |
tree | 3d3e39fea75ed94d80cbd130282b1549532aa7e0 | |
parent | e5fd013fdf6c8664daa0bbdcaf0d22bf44e90d62 (diff) | |
download | mariadb-git-bb43e8317fc3d78fd5f3d22a0ca0acf090540cd5.tar.gz |
Fix for bug #5890 "Triggers fail for DELETE without WHERE".
If we have DELETE with always true WHERE clause we should not use
optimized delete_all_rows() method for tables with DELETE triggers,
because in this case we will lose side-effect of deletion.
mysql-test/r/trigger.result:
Added test for bug #5890 "Triggers fail for DELETE without WHERE".
mysql-test/t/trigger.test:
Added test for bug #5890 "Triggers fail for DELETE without WHERE".
sql/sql_delete.cc:
mysql_delete():
We should not use optimized delete_all_rows() method for tables
with DELETE triggers, because in this case we will lose side-effect
of deletion.
sql/sql_trigger.h:
Added new Table_triggers_list::has_delete_triggers() method which
allows to understand quickly if we have some DELETE triggers in
our list.
-rw-r--r-- | mysql-test/r/trigger.result | 12 | ||||
-rw-r--r-- | mysql-test/t/trigger.test | 17 | ||||
-rw-r--r-- | sql/sql_delete.cc | 9 | ||||
-rw-r--r-- | sql/sql_trigger.h | 6 |
4 files changed, 42 insertions, 2 deletions
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result index 2a2e10dbbd5..b45aaea0cbe 100644 --- a/mysql-test/r/trigger.result +++ b/mysql-test/r/trigger.result @@ -174,3 +174,15 @@ create trigger tx1 before insert on t1 for each row set new.x1col = 'x'; insert into t1 values ('y'); drop trigger t1.tx1; drop table t1; +create table t1 (i int) engine=myisam; +insert into t1 values (1), (2); +create trigger trg1 before delete on t1 for each row set @del_before:= @del_before + old.i; +create trigger trg2 after delete on t1 for each row set @del_after:= @del_after + old.i; +set @del_before:=0, @del_after:= 0; +delete from t1; +select @del_before, @del_after; +@del_before @del_after +3 3 +drop trigger t1.trg1; +drop trigger t1.trg2; +drop table t1; diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test index f842d561dc1..7dc976cf716 100644 --- a/mysql-test/t/trigger.test +++ b/mysql-test/t/trigger.test @@ -207,3 +207,20 @@ create trigger tx1 before insert on t1 for each row set new.x1col = 'x'; insert into t1 values ('y'); drop trigger t1.tx1; drop table t1; + +# +# Test for bug #5890 "Triggers fail for DELETE without WHERE". +# If we are going to delete all rows in table but DELETE triggers exist +# we should perform row-by-row deletion instead of using optimized +# delete_all_rows() method. +# +create table t1 (i int) engine=myisam; +insert into t1 values (1), (2); +create trigger trg1 before delete on t1 for each row set @del_before:= @del_before + old.i; +create trigger trg2 after delete on t1 for each row set @del_after:= @del_after + old.i; +set @del_before:=0, @del_after:= 0; +delete from t1; +select @del_before, @del_after; +drop trigger t1.trg1; +drop trigger t1.trg2; +drop table t1; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8bdf19195f3..1cd0d0177f6 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -62,9 +62,14 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, SQL_LIST *order, if (thd->lex->duplicates == DUP_IGNORE) thd->lex->select_lex.no_error= 1; - /* Test if the user wants to delete all rows */ + /* + Test if the user wants to delete all rows and deletion doesn't have + any side-effects (because of triggers), so we can use optimized + handler::delete_all_rows() method. + */ if (!using_limit && const_cond && (!conds || conds->val_int()) && - !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE))) + !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && + !(table->triggers && table->triggers->has_delete_triggers())) { deleted= table->file->records; if (!(error=table->file->delete_all_rows())) diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 8ab2ab003f8..d0376f056d9 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -58,5 +58,11 @@ public: static bool check_n_load(THD *thd, const char *db, const char *table_name, TABLE *table); + bool has_delete_triggers() + { + return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || + bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]); + } + friend class Item_trigger_field; }; |