Commit d958f298 authored by unknown's avatar unknown

Merge quad.:/mnt/raid/alik/MySQL/devel/5.0-rt

into  quad.:/mnt/raid/alik/MySQL/devel/5.1-rt-merged


sql/sql_delete.cc:
  Manually merged.
parents b0fda34b 326c4e90
...@@ -140,4 +140,23 @@ select * from t3; ...@@ -140,4 +140,23 @@ select * from t3;
c c
1 1
drop table t1, t2, t3; drop table t1, t2, t3;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=innodb;
CREATE TABLE t2(b INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=innodb;
INSERT INTO t1 VALUES (1);
CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW SET @a = 1;
CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1;
SET @a = 0;
SET @b = 0;
TRUNCATE t1;
SELECT @a, @b;
@a @b
0 0
INSERT INTO t1 VALUES (1);
DELETE FROM t1;
SELECT @a, @b;
@a @b
1 1
DROP TABLE t2, t1;
End of 5.0 tests End of 5.0 tests
...@@ -128,5 +128,37 @@ drop table t1, t2, t3; ...@@ -128,5 +128,37 @@ drop table t1, t2, t3;
disconnect connection_update; disconnect connection_update;
disconnect connection_aux; disconnect connection_aux;
#
# Bug#34643: TRUNCATE crash if trigger and foreign key.
#
--disable_warnings
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
--enable_warnings
CREATE TABLE t1(a INT PRIMARY KEY) ENGINE=innodb;
CREATE TABLE t2(b INT, FOREIGN KEY(b) REFERENCES t1(a)) ENGINE=innodb;
INSERT INTO t1 VALUES (1);
CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW SET @a = 1;
CREATE TRIGGER t1_ad AFTER DELETE ON t1 FOR EACH ROW SET @b = 1;
SET @a = 0;
SET @b = 0;
TRUNCATE t1;
SELECT @a, @b;
INSERT INTO t1 VALUES (1);
DELETE FROM t1;
SELECT @a, @b;
DROP TABLE t2, t1;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -45,6 +45,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -45,6 +45,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
bool transactional_table, safe_update, const_cond; bool transactional_table, safe_update, const_cond;
bool const_cond_result; bool const_cond_result;
ha_rows deleted= 0; ha_rows deleted= 0;
bool triggers_applicable;
uint usable_index= MAX_KEY; uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex; SELECT_LEX *select_lex= &thd->lex->select_lex;
THD::killed_state killed_status= THD::NOT_KILLED; THD::killed_state killed_status= THD::NOT_KILLED;
...@@ -102,6 +103,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -102,6 +103,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
/* Error evaluating val_int(). */ /* Error evaluating val_int(). */
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/* NOTE: TRUNCATE must not invoke triggers. */
triggers_applicable= table->triggers &&
thd->lex->sql_command != SQLCOM_TRUNCATE;
/* /*
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
...@@ -123,9 +129,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -123,9 +129,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
*/ */
if (!using_limit && const_cond_result && if (!using_limit && const_cond_result &&
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) && !(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
(thd->lex->sql_command == SQLCOM_TRUNCATE || !triggers_applicable &&
(!thd->current_stmt_binlog_row_based && !thd->current_stmt_binlog_row_based &&
!(table->triggers && table->triggers->has_delete_triggers())))) !table->triggers->has_delete_triggers())
{ {
/* Update the table->file->stats.records number */ /* Update the table->file->stats.records number */
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
...@@ -249,7 +255,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -249,7 +255,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
init_ftfuncs(thd, select_lex, 1); init_ftfuncs(thd, select_lex, 1);
thd_proc_info(thd, "updating"); thd_proc_info(thd, "updating");
if (table->triggers && if (triggers_applicable &&
table->triggers->has_triggers(TRG_EVENT_DELETE, table->triggers->has_triggers(TRG_EVENT_DELETE,
TRG_ACTION_AFTER)) TRG_ACTION_AFTER))
{ {
...@@ -274,7 +280,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -274,7 +280,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!(select && select->skip_record())&& ! thd->is_error() ) if (!(select && select->skip_record())&& ! thd->is_error() )
{ {
if (table->triggers && if (triggers_applicable &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE, table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE)) TRG_ACTION_BEFORE, FALSE))
{ {
...@@ -285,7 +291,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ...@@ -285,7 +291,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!(error= table->file->ha_delete_row(table->record[0]))) if (!(error= table->file->ha_delete_row(table->record[0])))
{ {
deleted++; deleted++;
if (table->triggers && if (triggers_applicable &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE, table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE)) TRG_ACTION_AFTER, FALSE))
{ {
......
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