1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug#40127 Multiple table DELETE IGNORE hangs on foreign key constraint violation

on 5.0            
The server crashes on an assert in net_end_statement indicating that the
Diagnostics area wasn't set properly during execution.
This happened on a multi table DELETE operation using the IGNORE keyword.
The keyword is suppose to allow for execution to continue on a best effort
despite some non-fatal errors. Instead execution stopped and no client
response was sent which would have led to a protocol error if it hadn't been
for the assert.
This patch corrects this issue by checking for the existence of an IGNORE
option before setting an error state during row-by-row delete iteration.
This commit is contained in:
Kristofer Pettersson
2009-03-27 17:08:14 +01:00
parent 1a20ddfef5
commit 137f1e1ed6
3 changed files with 325 additions and 11 deletions

View File

@ -709,6 +709,8 @@ bool multi_delete::send_data(List<Item> &values)
TABLE_LIST *del_table;
DBUG_ENTER("multi_delete::send_data");
bool ignore= thd->lex->current_select->no_error;
for (del_table= delete_tables;
del_table;
del_table= del_table->next_local, secure_counter++)
@ -741,8 +743,12 @@ bool multi_delete::send_data(List<Item> &values)
TRG_ACTION_AFTER, FALSE))
DBUG_RETURN(1);
}
else
else if (!ignore)
{
/*
If the IGNORE option is used errors caused by ha_delete_row don't
have to stop the iteration.
*/
table->file->print_error(error,MYF(0));
DBUG_RETURN(1);
}
@ -834,6 +840,11 @@ int multi_delete::do_deletes()
{
int local_error= 0, counter= 0, tmp_error;
bool will_batch;
/*
If the IGNORE option is used all non fatal errors will be translated
to warnings and we should not break the row-by-row iteration
*/
bool ignore= thd->lex->current_select->no_error;
DBUG_ENTER("do_deletes");
DBUG_ASSERT(do_delete);
@ -872,19 +883,30 @@ int multi_delete::do_deletes()
local_error= 1;
break;
}
if ((local_error=table->file->ha_delete_row(table->record[0])))
local_error= table->file->ha_delete_row(table->record[0]);
if (local_error && !ignore)
{
table->file->print_error(local_error,MYF(0));
break;
}
deleted++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
{
local_error= 1;
table->file->print_error(local_error,MYF(0));
break;
}
/*
Increase the reported number of deleted rows only if no error occurred
during ha_delete_row.
Also, don't execute the AFTER trigger if the row operation failed.
*/
if (!local_error)
{
deleted++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
{
local_error= 1;
break;
}
}
}
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
{