List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:June 17 2011 7:08pm
Subject:bzr commit into mysql-trunk branch (Dmitry.Lenev:3218) Bug#12652385
View as plain text  
#At file:///home/dlenev/src/bzr/mysql-trunk-12652385/ based on revid:dmitry.lenev@stripped

 3218 Dmitry Lenev	2011-06-17
      A follow-up for patch that fixed bug #12652385 - "61493:
      REORDERING COLUMNS TO POSITION FIRST CAN CAUSE DATA TO
      BE CORRUPTED".
      
      Moved code which is responsible for detecting that ALTER
      TABLE can't be carried out using in-place algorithm because
      it reorders some columns or replaces some old columns with
      a newly added to one place. Introduced a new auxiliary
      function for performing this check.
      
      Note that we cannot easily make this check part of
      mysql_compare_tables() call as this check is specific to 
      normal ALTER TABLE (i.e. assumes that there are old columns 
      and new columns). While mysql_compare_tables() is also
      used by ALTER TABLE EXCHANGE PARTITION implementation for 
      checking that table and partitioned table has identical
      structure (i.e. in situation when there are no old and
      new columns).

    modified:
      sql/sql_table.cc
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-06-16 23:45:58 +0000
+++ b/sql/sql_table.cc	2011-06-17 19:08:51 +0000
@@ -4978,6 +4978,35 @@ err:
   DBUG_RETURN(-1);
 }
 
+
+/**
+  Check if ALTER TABLE statement changes position of any column
+  in the table or adds new columns.
+
+  @param alter_info  Alter_info object describing structure of new
+                     version of table.
+
+  @retval True  - some column is added or changes its position.
+  @retval False - no columns are added or change their positions.
+*/
+
+static bool has_columns_new_or_reordered(Alter_info *alter_info)
+{
+  List_iterator_fast<Create_field> new_field_it(alter_info->create_list);
+  Create_field *new_field;
+  uint new_field_idx;
+
+  for (new_field_idx= 0, new_field= new_field_it++; new_field;
+       new_field_idx++, new_field= new_field_it++)
+  {
+    if (! new_field->field ||
+        new_field->field->field_index != new_field_idx)
+      return true;
+  }
+  return false;
+}
+
+
 /**
   @brief Check if both DROP and CREATE are present for an index in ALTER TABLE
 
@@ -5577,12 +5606,6 @@ mysql_prepare_alter_table(THD *thd, TABL
     if (drop)
     {
       drop_it.remove();
-      /*
-        ALTER TABLE DROP COLUMN always changes table data even in cases
-        when new version of the table has the same structure as the old
-        one.
-      */
-      alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
       continue;
     }
     /* Check if field is changed */
@@ -5662,11 +5685,6 @@ mysql_prepare_alter_table(THD *thd, TABL
     else if (def->after == first_keyword)
     {
       new_create_list.push_front(def);
-      /*
-        Re-ordering columns in table can't be done using in-place algorithm
-        as it always changes table data.
-      */
-      alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
     }
     else
     {
@@ -5683,11 +5701,6 @@ mysql_prepare_alter_table(THD *thd, TABL
         goto err;
       }
       find_it.after(def);			// Put element after this
-      /*
-        Re-ordering columns in table can't be done using in-place algorithm
-        as it always changes table data.
-      */
-      alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
     }
   }
   if (alter_info->alter_list.elements)
@@ -6368,6 +6381,17 @@ bool mysql_alter_table(THD *thd,char *ne
     if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
       need_copy_table= need_copy_table_res;
 
+    if (need_copy_table != ALTER_TABLE_DATA_CHANGED &&
+        has_columns_new_or_reordered(alter_info))
+    {
+      /*
+        ALTER TABLE which adds new columns (e.g. instead columns being
+        removed) or changes their order can't be executed using in-place
+        algorithm even if table structure stays the same.
+      */
+      need_copy_table= ALTER_TABLE_DATA_CHANGED;
+    }
+
     if (need_copy_table == ALTER_TABLE_INDEX_CHANGED)
     {
       if (is_index_maintenance_unique(table, key_info_buffer,


Attachment: [text/bzr-bundle] bzr/dmitry.lenev@oracle.com-20110617190851-9r4032yo9bchjf4l.bundle
Thread
bzr commit into mysql-trunk branch (Dmitry.Lenev:3218) Bug#12652385Dmitry Lenev19 Jun
  • Re: bzr commit into mysql-trunk branch (Dmitry.Lenev:3218) Bug#12652385Jon Olav Hauglid20 Jun