#At file:///home/thek/Development/cpp/mysqlbzr/51-bug40127/ based on
revid:gni@stripped
2842 Kristofer Pettersson 2009-03-20
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 existance of an IGNORE
option before setting an error state during row-by-row delete iteration.
@ sql/sql_delete.cc
* IGNORE option wasn't implemented in multi_delete::send_data
and multi_delete::do_deletes
modified:
sql/sql_delete.cc
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2009-02-09 22:51:59 +0000
+++ b/sql/sql_delete.cc 2009-03-19 23:00:17 +0000
@@ -709,6 +709,8 @@ bool multi_delete::send_data(List<Item>
TABLE_LIST *del_table;
DBUG_ENTER("multi_delete::send_data");
+ bool no_error= thd->lex->current_select->no_error;
+
for (del_table= delete_tables;
del_table;
del_table= del_table->next_local, secure_counter++)
@@ -729,9 +731,28 @@ bool multi_delete::send_data(List<Item>
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
- DBUG_RETURN(1);
+ {
+ /*
+ If the IGNORE option is used the errors will be translated into
+ warnings and we should not interrupt the loop.
+ */
+ if (!no_error)
+ DBUG_RETURN(1);
+ }
table->status|= STATUS_DELETED;
- if (!(error=table->file->ha_delete_row(table->record[0])))
+ error=table->file->ha_delete_row(table->record[0]);
+
+ /*
+ If an error occurred and there is no IGNORE flag;
+ Signal an error and exit.
+ */
+ if (!no_error && error)
+ {
+ table->file->print_error(error,MYF(0));
+ DBUG_RETURN(1);
+ }
+
+ if (!error)
{
deleted++;
if (!table->file->has_transactions())
@@ -739,12 +760,14 @@ bool multi_delete::send_data(List<Item>
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
- DBUG_RETURN(1);
- }
- else
- {
- table->file->print_error(error,MYF(0));
- DBUG_RETURN(1);
+ {
+ /*
+ If the IGNORE option is used the errors will be translated into
+ warning messages and we should not stop.
+ */
+ if (!no_error)
+ DBUG_RETURN(1);
+ }
}
}
else
@@ -834,6 +857,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 no_errors= thd->lex->current_select->no_error;
DBUG_ENTER("do_deletes");
DBUG_ASSERT(do_delete);
@@ -869,21 +897,30 @@ int multi_delete::do_deletes()
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
{
- local_error= 1;
- break;
+ if (!no_errors)
+ {
+ local_error= 1;
+ break;
+ }
}
if ((local_error=table->file->ha_delete_row(table->record[0])))
{
- table->file->print_error(local_error,MYF(0));
- break;
+ if (!no_errors)
+ {
+ 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;
- break;
+ if (!no_errors)
+ {
+ local_error= 1;
+ break;
+ }
}
}
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
Attachment: [text/bzr-bundle] bzr/kristofer.pettersson@sun.com-20090319230017-3vhzkefc3nsy7eq2.bundle
| Thread |
|---|
| • bzr commit into mysql-5.1-bugteam branch (kristofer.pettersson:2842)Bug#40127 | Kristofer Pettersson | 19 Mar 2009 |