List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:May 15 2007 8:40am
Subject:bk commit into 5.0 tree (aelkin:1.2439) BUG#27417
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of elkin. When elkin does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-05-15 09:40:26+03:00, aelkin@stripped
+4 -0
  Bug #27417  	thd->no_trans_update.stmt lost value inside of SF-exec-stack
  
  Once had been set the flag might later got reset inside of a stored routine execution
stack.
  The reason was in that there was no check if a new statement started at time of
resetting.
  The artifact affects most of binlogable DML queries.
  
  Fixed with checking thd->in_sub_stmt to know precisely about the new statement.
  Couple of minor issues refined along the fix, see per-file comments.
  
  Test is delayed till related bug#13270, bug#23333.
  

  sql/sql_delete.cc@stripped, 2007-05-15 09:40:21+03:00,
aelkin@stripped +27 -14
    correcting delete and multi-delete queries to set and reset
thd->no_trans_update.stmt

  sql/sql_insert.cc@stripped, 2007-05-15 09:40:22+03:00,
aelkin@stripped +6 -3
    correcting insert and insert .. select to set and reset the flag correctly

  sql/sql_load.cc@stripped, 2007-05-15 09:40:22+03:00,
aelkin@stripped +4 -7
    correcting load data to set and reset the flag;
    eliminating a separate issue where the flag was stored and re-stored after
write_record
    which can change it and the change should remain permanent.

  sql/sql_update.cc@stripped, 2007-05-15 09:40:22+03:00,
aelkin@stripped +26 -18
    correcting update and multi-update to set and reset the flag;
    eliminating a separate issue in multi_update::do_updates where
    either one of the class members trans_safe, transactional_tables was
    set after the per-table loop whereas both should be calculated during
    looping.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	aelkin
# Host:	dsl-hkibras-fe31f900-164.dhcp.inet.fi
# Root:	/home/elkin/MySQL/TEAM/FIXES/5.0/bug27417-no_trans_update__stmt

--- 1.197/sql/sql_delete.cc	2007-04-17 16:51:56 +03:00
+++ 1.198/sql/sql_delete.cc	2007-05-15 09:40:21 +03:00
@@ -216,6 +216,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *
   init_ftfuncs(thd, select_lex, 1);
   thd->proc_info="updating";
 
+  if (!thd->in_sub_stmt)
+    thd->no_trans_update.stmt= FALSE;
+
   if (table->triggers)
   {
     table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
@@ -245,10 +248,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *
         error= 1;
         break;
       }
-
+      
       if (!(error=table->file->delete_row(table->record[0])))
       {
-	deleted++;
+        deleted++;
+        if (!transactional_table)
+          thd->no_trans_update.stmt= TRUE;
+        
         if (table->triggers &&
             table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
                                               TRG_ACTION_AFTER, FALSE))
@@ -256,11 +262,11 @@ bool mysql_delete(THD *thd, TABLE_LIST *
           error= 1;
           break;
         }
-	if (!--limit && using_limit)
-	{
-	  error= -1;
-	  break;
-	}
+        if (!--limit && using_limit)
+        {
+          error= -1;
+          break;
+        }
       }
       else
       {
@@ -579,6 +585,9 @@ multi_delete::initialize_tables(JOIN *jo
       delete_while_scanning= 0;
     }
   }
+  if (!thd->in_sub_stmt)
+    thd->no_trans_update.stmt= FALSE;
+
   walk= delete_tables;
   tempfiles_ptr= tempfiles;
   if (delete_while_scanning)
@@ -644,20 +653,22 @@ 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);
+        DBUG_RETURN(1);
       table->status|= STATUS_DELETED;
       if (!(error=table->file->delete_row(table->record[0])))
       {
-	deleted++;
+        deleted++;
+        if (!table->file->has_transactions())
+          thd->no_trans_update.stmt= TRUE;
         if (table->triggers &&
             table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
                                               TRG_ACTION_AFTER, FALSE))
-	  DBUG_RETURN(1);
+          DBUG_RETURN(1);
       }
       else
       {
-	table->file->print_error(error,MYF(0));
-	DBUG_RETURN(1);
+        table->file->print_error(error,MYF(0));
+        DBUG_RETURN(1);
       }
     }
     else
@@ -759,10 +770,12 @@ int multi_delete::do_deletes()
       }
       if ((local_error=table->file->delete_row(table->record[0])))
       {
-	table->file->print_error(local_error,MYF(0));
-	break;
+        table->file->print_error(local_error,MYF(0));
+        break;
       }
       deleted++;
+      if (!table->file->has_transactions())
+        thd->no_trans_update.stmt= TRUE;
       if (table->triggers &&
           table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
                                             TRG_ACTION_AFTER, FALSE))

--- 1.230/sql/sql_insert.cc	2007-04-12 12:46:07 +03:00
+++ 1.231/sql/sql_insert.cc	2007-05-15 09:40:22 +03:00
@@ -629,7 +629,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *t
   if (lock_type != TL_WRITE_DELAYED && !thd->prelocked_mode)
     table->file->start_bulk_insert(values_list.elements);
 
-  thd->no_trans_update.stmt= FALSE;
+  if (!thd->in_sub_stmt)
+    thd->no_trans_update.stmt= FALSE;
   thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
                                        (MODE_STRICT_TRANS_TABLES |
                                         MODE_STRICT_ALL_TABLES)));
@@ -2564,7 +2565,8 @@ select_insert::prepare(List<Item> &value
       table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
     table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
   }
-  thd->no_trans_update.stmt= FALSE;
+  if (!thd->in_sub_stmt)
+    thd->no_trans_update.stmt= FALSE;
   thd->abort_on_warning= (!info.ignore &&
                           (thd->variables.sql_mode &
                            (MODE_STRICT_TRANS_TABLES |
@@ -2978,7 +2980,8 @@ select_create::prepare(List<Item> &value
   }
   if (!thd->prelocked_mode)
     table->file->start_bulk_insert((ha_rows) 0);
-  thd->no_trans_update.stmt= FALSE;
+  if (!thd->in_sub_stmt)
+    thd->no_trans_update.stmt= FALSE;
   thd->abort_on_warning= (!info.ignore &&
                           (thd->variables.sql_mode &
                            (MODE_STRICT_TRANS_TABLES |

--- 1.113/sql/sql_load.cc	2007-05-08 03:43:16 +03:00
+++ 1.114/sql/sql_load.cc	2007-05-15 09:40:22 +03:00
@@ -377,7 +377,8 @@ bool mysql_load(THD *thd,sql_exchange *e
       table->file->start_bulk_insert((ha_rows) 0);
     table->copy_blobs=1;
 
-    thd->no_trans_update.stmt= FALSE;
+    if (!thd->in_sub_stmt)
+      thd->no_trans_update.stmt= FALSE;
     thd->abort_on_warning= (!ignore &&
                             (thd->variables.sql_mode &
                              (MODE_STRICT_TRANS_TABLES |
@@ -532,7 +533,7 @@ read_fixed_length(THD *thd, COPY_INFO &i
   Item_field *sql_field;
   TABLE *table= table_list->table;
   ulonglong id;
-  bool no_trans_update_stmt, err;
+  bool err;
   DBUG_ENTER("read_fixed_length");
 
   id= 0;
@@ -560,7 +561,6 @@ read_fixed_length(THD *thd, COPY_INFO &i
 #ifdef HAVE_purify
     read_info.row_end[0]=0;
 #endif
-    no_trans_update_stmt= !table->file->has_transactions();
 
     restore_record(table, s->default_values);
     /*
@@ -628,7 +628,6 @@ read_fixed_length(THD *thd, COPY_INFO &i
     table->auto_increment_field_not_null= FALSE;
     if (err)
       DBUG_RETURN(1);
-    thd->no_trans_update.stmt= no_trans_update_stmt;
    
     /*
       If auto_increment values are used, save the first one for
@@ -671,12 +670,11 @@ read_sep_field(THD *thd, COPY_INFO &info
   TABLE *table= table_list->table;
   uint enclosed_length;
   ulonglong id;
-  bool no_trans_update_stmt, err;
+  bool err;
   DBUG_ENTER("read_sep_field");
 
   enclosed_length=enclosed.length();
   id= 0;
-  no_trans_update_stmt= !table->file->has_transactions();
 
   for (;;it.rewind())
   {
@@ -817,7 +815,6 @@ read_sep_field(THD *thd, COPY_INFO &info
       We don't need to reset auto-increment field since we are restoring
       its default value at the beginning of each loop iteration.
     */
-    thd->no_trans_update.stmt= no_trans_update_stmt;
     if (read_info.next_line())			// Skip to next line
       break;
     if (read_info.line_cuted)

--- 1.215/sql/sql_update.cc	2007-04-12 12:46:07 +03:00
+++ 1.216/sql/sql_update.cc	2007-05-15 09:40:22 +03:00
@@ -429,7 +429,8 @@ int mysql_update(THD *thd,
   query_id=thd->query_id;
 
   transactional_table= table->file->has_transactions();
-  thd->no_trans_update.stmt= FALSE;
+  if (!thd->in_sub_stmt)
+    thd->no_trans_update.stmt= FALSE;
   thd->abort_on_warning= test(!ignore &&
                               (thd->variables.sql_mode &
                                (MODE_STRICT_TRANS_TABLES |
@@ -486,7 +487,8 @@ int mysql_update(THD *thd,
                                             (byte*) table->record[0])))
         {
           updated++;
-          thd->no_trans_update.stmt= !transactional_table;
+          if (!transactional_table)
+            thd->no_trans_update.stmt= TRUE;
           
           if (table->triggers &&
               table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
@@ -1484,28 +1486,28 @@ int multi_update::do_updates(bool from_s
           else if (error == VIEW_CHECK_ERROR)
             goto err;
         }
-	if ((local_error=table->file->update_row(table->record[1],
-						 table->record[0])))
-	{
-	  if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
-	    goto err;
-	}
-	updated++;
-
+        if ((local_error=table->file->update_row(table->record[1],
+                                                 table->record[0])))
+        {
+          if (!ignore || local_error != HA_ERR_FOUND_DUPP_KEY)
+            goto err;
+        }
+        updated++;
+        if (table->file->has_transactions())
+          transactional_tables= 1;
+        else
+        {
+          trans_safe= 0;				// Can't do safe rollback
+          thd->no_trans_update.stmt= TRUE;
+        }
+        
         if (table->triggers &&
             table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
                                               TRG_ACTION_AFTER, TRUE))
           goto err2;
       }
     }
-
-    if (updated != org_updated)
-    {
-      if (table->file->has_transactions())
-	transactional_tables= 1;
-      else
-	trans_safe= 0;				// Can't do safe rollback
-    }
+    DBUG_ASSERT(updated == org_updated || transactional_tables || trans_safe == 0);
     (void) table->file->ha_rnd_end();
     (void) tmp_table->file->ha_rnd_end();
   }
@@ -1527,7 +1529,10 @@ err2:
     if (table->file->has_transactions())
       transactional_tables= 1;
     else
+    {
       trans_safe= 0;
+      thd->no_trans_update.stmt= TRUE;
+    }
   }
   DBUG_RETURN(1);
 }
@@ -1570,7 +1575,10 @@ bool multi_update::send_eof()
         local_error= 1;				// Rollback update
     }
     if (!transactional_tables)
+    {
+      DBUG_ASSERT(thd->no_trans_update.stmt);
       thd->no_trans_update.all= TRUE;
+    }
   }
 
   if (transactional_tables)
Thread
bk commit into 5.0 tree (aelkin:1.2439) BUG#27417Andrei Elkin15 May