List:Commits« Previous MessageNext Message »
From:Martin Skold Date:February 8 2008 4:11pm
Subject:bk commit into 5.1 tree (mskold:1.2649) BUG#31233
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of mskold.  When mskold 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, 2008-02-08 17:11:33+01:00, mskold@stripped +2 -0
  bug#31233  mysql_alter_table() fails to drop UNIQUE KEY

  sql/mysql_priv.h@stripped, 2008-02-08 17:10:38+01:00, mskold@stripped +1 -0
    bug#31233  mysql_alter_table() fails to drop UNIQUE KEY

  sql/sql_table.cc@stripped, 2008-02-08 17:10:38+01:00, mskold@stripped +57 -12
    bug#31233  mysql_alter_table() fails to drop UNIQUE KEY

diff -Nrup a/sql/mysql_priv.h b/sql/mysql_priv.h
--- a/sql/mysql_priv.h	2007-12-14 14:01:09 +01:00
+++ b/sql/mysql_priv.h	2008-02-08 17:10:38 +01:00
@@ -2146,6 +2146,7 @@ uint build_table_shadow_filename(char *b
 #define FN_TO_IS_TMP    (1 << 1)
 #define FN_IS_TMP       (FN_FROM_IS_TMP | FN_TO_IS_TMP)
 #define NO_FRM_RENAME   (1 << 2)
+#define FN_FRM_ONLY     (1 << 3)
 
 /* from hostname.cc */
 struct in_addr;
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc	2007-12-17 13:39:54 +01:00
+++ b/sql/sql_table.cc	2008-02-08 17:10:38 +01:00
@@ -1831,8 +1831,9 @@ bool quick_rm_table(handlerton *base,con
   if (my_delete(path,MYF(0)))
     error= 1; /* purecov: inspected */
   path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
-  DBUG_RETURN(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
-              error);
+  if (!(flags & FN_FRM_ONLY))
+    error|= ha_delete_table(current_thd, base, path, db, table_name, 0);
+  DBUG_RETURN(error);
 }
 
 /*
@@ -5038,6 +5039,7 @@ err:
       index_drop_count    OUT   The number of elements in the array.
       index_add_buffer    OUT   An array of offsets into key_info_buffer.
       index_add_count     OUT   The number of elements in the array.
+      candidate_key_count  OUT  The number of candidate keys in original table.
 
   DESCRIPTION
     'table' (first argument) contains information of the original
@@ -5068,7 +5070,8 @@ compare_tables(TABLE *table,
                enum_alter_table_change_level *need_copy_table,
                KEY **key_info_buffer,
                uint **index_drop_buffer, uint *index_drop_count,
-               uint **index_add_buffer, uint *index_add_count)
+               uint **index_add_buffer, uint *index_add_count,
+               uint *candidate_key_count)
 {
   Field **f_ptr, *field;
   uint changes= 0, tmp;
@@ -5082,6 +5085,7 @@ compare_tables(TABLE *table,
     create_info->varchar will be reset in mysql_prepare_create_table.
   */
   bool varchar= create_info->varchar;
+  bool not_nullable= true;
   DBUG_ENTER("compare_tables");
 
   {
@@ -5220,6 +5224,7 @@ compare_tables(TABLE *table,
   */
   *index_drop_count= 0;
   *index_add_count= 0;
+  *candidate_key_count= 0;
   for (table_key= table->key_info; table_key < table_key_end; table_key++)
   {
     KEY_PART_INFO *table_part;
@@ -5247,6 +5252,8 @@ compare_tables(TABLE *table,
         (table_key->key_parts != new_key->key_parts))
       goto index_changed;
 
+    
+    not_nullable= true;
     /*
       Check that the key parts remain compatible between the old and
       new tables.
@@ -5255,6 +5262,8 @@ compare_tables(TABLE *table,
          table_part < table_part_end;
          table_part++, new_part++)
     {
+      not_nullable= not_nullable && (! table_part->field->maybe_null());
+
       /*
 	Key definition has changed if we are using a different field or
 	if the used key part length is different. We know that the fields
@@ -5264,6 +5273,15 @@ compare_tables(TABLE *table,
           (table_part->fieldnr - 1 != new_part->fieldnr))
 	goto index_changed;
     }
+
+    /*
+      Count all candidate keys,
+      i.e all non-nullable unique indexes
+     */
+    if ((table_key->flags & HA_NOSAME) && not_nullable)
+      (*candidate_key_count)++;
+
+
     continue;
 
   index_changed:
@@ -5851,13 +5869,16 @@ bool mysql_alter_table(THD *thd,char *ne
   uint *index_drop_buffer;
   uint index_add_count;
   uint *index_add_buffer;
+  uint candidate_key_count;
   bool committed= 0;
+  bool no_pk;
   DBUG_ENTER("mysql_alter_table");
 
   LINT_INIT(index_add_count);
   LINT_INIT(index_drop_count);
   LINT_INIT(index_add_buffer);
   LINT_INIT(index_drop_buffer);
+  LINT_INIT(candidate_key_count);
 
   /*
     Check if we attempt to alter mysql.slow_log or
@@ -6268,7 +6289,8 @@ view_err:
                        &need_copy_table_res,
                        &key_info_buffer,
                        &index_drop_buffer, &index_drop_count,
-                       &index_add_buffer, &index_add_count))
+                       &index_add_buffer, &index_add_count,
+                       &candidate_key_count))
       goto err;
    
     if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
@@ -6302,9 +6324,11 @@ view_err:
       DBUG_PRINT("info", ("index dropped: '%s'", key->name));
       if (key->flags & HA_NOSAME)
       {
-        /* Unique key. Check for "PRIMARY". */
-        if (! my_strcasecmp(system_charset_info,
-                            key->name, primary_key_name))
+        /*
+           Unique key. Check for "PRIMARY"
+           or if dropping last unique key.
+        */
+        if ((uint) (key - table->key_info) !=  table->s->primary_key)
         {
           /* Primary key. */
           needed_online_flags|=  HA_ONLINE_DROP_PK_INDEX;
@@ -6325,7 +6349,8 @@ view_err:
         needed_fast_flags|= HA_ONLINE_DROP_INDEX_NO_WRITES;
       }
     }
-
+    no_pk= ((table->s->primary_key == MAX_KEY) ||
+            (needed_online_flags & HA_ONLINE_DROP_PK_INDEX));
     /* Check added indexes. */
     for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
          idx_p < idx_end_p;
@@ -6335,14 +6360,19 @@ view_err:
       DBUG_PRINT("info", ("index added: '%s'", key->name));
       if (key->flags & HA_NOSAME)
       {
-        /* Unique key. Check for "PRIMARY". */
-        if (! my_strcasecmp(system_charset_info,
-                            key->name, primary_key_name))
+        /*
+           Unique key. Check for "PRIMARY"
+           or if adding first unique key
+        */
+        if ((! my_strcasecmp(system_charset_info,
+                             key->name, primary_key_name)) ||
+            (no_pk && candidate_key_count == 0))
         {
           /* Primary key. */
           needed_online_flags|=  HA_ONLINE_ADD_PK_INDEX;
           needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
           pk_changed++;
+          no_pk= false;
         }
         else
         {
@@ -6359,6 +6389,18 @@ view_err:
       }
     }
 
+    if ((candidate_key_count > 0) && 
+        (needed_online_flags & HA_ONLINE_DROP_PK_INDEX))
+    {
+      /*
+        Dropped primary key when there is some other unique 
+        not null key that should be converted to primary key
+      */
+      needed_online_flags|=  HA_ONLINE_ADD_PK_INDEX;
+      needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
+      pk_changed= 2;
+    }
+
     /*
       Online or fast add/drop index is possible only if
       the primary key is not added and dropped in the same statement.
@@ -6857,7 +6899,10 @@ err1:
     close_temporary_table(thd, new_table, 1, 1);
   }
   else
-    VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
+    VOID(quick_rm_table(new_db_type, new_db, tmp_name,
+                        create_info->frm_only
+                        ? FN_IS_TMP | FN_FRM_ONLY
+                        : FN_IS_TMP));
 
 err:
   /*
Thread
bk commit into 5.1 tree (mskold:1.2649) BUG#31233Martin Skold8 Feb
  • Re: bk commit into 5.1 tree (mskold:1.2649) BUG#31233Ingo Strüwing14 Feb