Commit 1a0e1f13 authored by unknown's avatar unknown

Bug#23556: TRUNCATE TABLE still maps to DELETE

 This is the 5.0 part of the fix.
 Currently TRUNCATE command will not call
 delete_all_rows() in the handler (that implements
 the "fast" TRUNCATE for InnoDB) when there are
 triggers on the table.
 As decided by the architecture team TRUNCATE must
 use "fast" TRUNCATE even when there are triggers.
 Thus it must ignore the triggers. 
 Made TRUNCATE to ignore the triggers and call
 delete_all_rows() for all storage engines
 to maintain engine consistency.


mysql-test/r/trigger.result:
  Bug#23556: TRUNCATE TABLE still maps to DELETE
   - test case
mysql-test/t/trigger.test:
  Bug#23556: TRUNCATE TABLE still maps to DELETE
   - test case
sql/sql_delete.cc:
  Bug#23556: TRUNCATE TABLE still maps to DELETE
   - We implemenent fast TRUNCATE for InnoDB even
     if triggers are present.  
   - TRUNCATE ignores triggers.
parent e139c57f
...@@ -1241,4 +1241,29 @@ i j ...@@ -1241,4 +1241,29 @@ i j
2 2 2 2
13 13 13 13
drop table t1; drop table t1;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW
INSERT INTO t2 VALUES (OLD.a);
FLUSH STATUS;
TRUNCATE t1;
SHOW STATUS LIKE 'handler_delete';
Variable_name Value
Handler_delete 0
SELECT COUNT(*) FROM t2;
COUNT(*)
0
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
DELETE FROM t2;
FLUSH STATUS;
DELETE FROM t1;
SHOW STATUS LIKE 'handler_delete';
Variable_name Value
Handler_delete 8
SELECT COUNT(*) FROM t2;
COUNT(*)
8
DROP TRIGGER trg_t1;
DROP TABLE t1,t2;
End of 5.0 tests End of 5.0 tests
...@@ -1498,5 +1498,30 @@ update t1 set i= i+ 10 where j > 2; ...@@ -1498,5 +1498,30 @@ update t1 set i= i+ 10 where j > 2;
select * from t1; select * from t1;
drop table t1; drop table t1;
#
# Bug#23556 TRUNCATE TABLE still maps to DELETE
#
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW
INSERT INTO t2 VALUES (OLD.a);
FLUSH STATUS;
TRUNCATE t1;
SHOW STATUS LIKE 'handler_delete';
SELECT COUNT(*) FROM t2;
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
DELETE FROM t2;
FLUSH STATUS;
DELETE FROM t1;
SHOW STATUS LIKE 'handler_delete';
SELECT COUNT(*) FROM t2;
DROP TRIGGER trg_t1;
DROP TABLE t1,t2;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -76,10 +76,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -76,10 +76,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
Test if the user wants to delete all rows and deletion doesn't have 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 any side-effects (because of triggers), so we can use optimized
handler::delete_all_rows() method. handler::delete_all_rows() method.
We implement fast TRUNCATE for InnoDB even if triggers are present.
TRUNCATE ignores triggers.
*/ */
if (!using_limit && const_cond && (!conds || conds->val_int()) && 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)) &&
(thd->lex->sql_command == SQLCOM_TRUNCATE ||
!(table->triggers && table->triggers->has_delete_triggers())) !(table->triggers && table->triggers->has_delete_triggers()))
)
{ {
deleted= table->file->records; deleted= table->file->records;
if (!(error=table->file->delete_all_rows())) if (!(error=table->file->delete_all_rows()))
......
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