summaryrefslogtreecommitdiff
path: root/sql/sql_delete.cc
diff options
context:
space:
mode:
authoranozdrin/alik@quad. <>2008-03-12 16:13:33 +0300
committeranozdrin/alik@quad. <>2008-03-12 16:13:33 +0300
commit2b09a99340a066f1710045df42da1f43ff1d711b (patch)
tree949c8a892915fb127195051b1d08b313100f7a6b /sql/sql_delete.cc
parent93a0992854bc9c1bfe8537972baa75653be2f65d (diff)
downloadmariadb-git-2b09a99340a066f1710045df42da1f43ff1d711b.tar.gz
A fix for Bug#34643: TRUNCATE crash if trigger and foreign key.
In cases when TRUNCATE was executed by invoking mysql_delete() rather than by table recreation (for example, when TRUNCATE was issued on InnoDB table with is referenced by foreign key) triggers were invoked. In debug builds this also led to crash because of an assertion, which assumes that some preliminary actions take place before trigger invocation, which doesn't happen in case of TRUNCATE. The fix is not to execute triggers in mysql_delete() when this function is used by TRUNCATE.
Diffstat (limited to 'sql/sql_delete.cc')
-rw-r--r--sql/sql_delete.cc15
1 files changed, 10 insertions, 5 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index a28a39a769d..3019b68d6f1 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -35,6 +35,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
READ_RECORD info;
bool using_limit=limit != HA_POS_ERROR;
bool transactional_table, safe_update, const_cond;
+ bool triggers_applicable;
ha_rows deleted;
uint usable_index= MAX_KEY;
SELECT_LEX *select_lex= &thd->lex->select_lex;
@@ -93,6 +94,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
select_lex->no_error= thd->lex->ignore;
+ /* 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
any side-effects (because of triggers), so we can use optimized
@@ -102,8 +108,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
*/
if (!using_limit && const_cond && (!conds || conds->val_int()) &&
!(specialflag & (SPECIAL_NO_NEW_FUNC | SPECIAL_SAFE_MODE)) &&
- (thd->lex->sql_command == SQLCOM_TRUNCATE ||
- !(table->triggers && table->triggers->has_delete_triggers()))
+ !(triggers_applicable && table->triggers->has_delete_triggers())
)
{
deleted= table->file->records;
@@ -217,7 +222,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
init_ftfuncs(thd, select_lex, 1);
thd->proc_info="updating";
- if (table->triggers)
+ if (triggers_applicable)
{
table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
if (table->triggers->has_triggers(TRG_EVENT_DELETE,
@@ -239,7 +244,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!(select && select->skip_record())&& !thd->net.report_error )
{
- if (table->triggers &&
+ if (triggers_applicable &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
{
@@ -250,7 +255,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (!(error=table->file->delete_row(table->record[0])))
{
deleted++;
- if (table->triggers &&
+ if (triggers_applicable &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
{