List:Commits« Previous MessageNext Message »
From:Kristofer Pettersson Date:March 20 2009 12:00am
Subject:bzr commit into mysql-5.1-bugteam branch (kristofer.pettersson:2842)
Bug#40127
View as plain text  
#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#40127Kristofer Pettersson19 Mar 2009