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:
@ -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()))
|
||||
{
|
||||
|
Reference in New Issue
Block a user