List:Commits« Previous MessageNext Message »
From:Martin Skold Date:March 12 2008 7:00pm
Subject:bk commit into 5.1 tree (mskold:1.2549) 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-03-12 20:00:49+01:00, mskold@stripped +4 -0
  bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface

  mysql-test/suite/ndb/r/ndb_alter_table_online.result@stripped, 2008-03-12 20:00:42+01:00, mskold@stripped +40 -0
    bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface

  mysql-test/suite/ndb/t/ndb_alter_table_online.test@stripped, 2008-03-12 20:00:42+01:00, mskold@stripped +39 -0
    bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface

  sql/ha_ndbcluster.cc@stripped, 2008-03-12 20:00:42+01:00, mskold@stripped +0 -18
    bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface

  sql/sql_table.cc@stripped, 2008-03-12 20:00:42+01:00, mskold@stripped +88 -10
    bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface

diff -Nrup a/mysql-test/suite/ndb/r/ndb_alter_table_online.result b/mysql-test/suite/ndb/r/ndb_alter_table_online.result
--- a/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2008-01-24 16:45:36 +01:00
+++ b/mysql-test/suite/ndb/r/ndb_alter_table_online.result	2008-03-12 20:00:42 +01:00
@@ -472,6 +472,46 @@ name
 truncate ndb_show_tables_results;
 DROP TABLE t1;
 ****************************************
+* Adding dropping primary key
+****************************************
+CREATE TABLE t1 (a INT UNSIGNED NOT NULL) ENGINE NDB;
+$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+PRIMARY KEY($PK) - UniqueHashIndex
+ALTER ONLINE TABLE t1 ADD PRIMARY KEY (a);
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER ONLINE TABLE t1 ADD PRIMARY KEY (a)'
+ALTER OFFLINE TABLE t1 ADD PRIMARY KEY (a);
+a Unsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+PRIMARY KEY(a) - UniqueHashIndex
+PRIMARY(a) - OrderedIndex
+ALTER ONLINE TABLE t1 DROP PRIMARY KEY;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER ONLINE TABLE t1 DROP PRIMARY KEY'
+ALTER OFFLINE TABLE t1 DROP PRIMARY KEY;
+$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+PRIMARY KEY($PK) - UniqueHashIndex
+CREATE ONLINE UNIQUE INDEX pk ON t1(a);
+ERROR 42000: This version of MySQL doesn't yet support 'CREATE ONLINE UNIQUE INDEX pk ON t1(a)'
+CREATE OFFLINE UNIQUE INDEX pk ON t1(a);
+a Unsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+PRIMARY KEY(a) - UniqueHashIndex
+ALTER ONLINE TABLE t1 DROP INDEX PK;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER ONLINE TABLE t1 DROP INDEX PK'
+ALTER OFFLINE TABLE t1 DROP INDEX PK;
+$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+PRIMARY KEY($PK) - UniqueHashIndex
+DROP TABLE t1;
+CREATE TABLE t1 (a INT UNSIGNED) ENGINE NDB;
+ALTER ONLINE TABLE t1 ADD b INT UNIQUE;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER ONLINE TABLE t1 ADD b INT UNIQUE'
+ALTER OFFLINE TABLE t1 ADD b INT UNIQUE;
+$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR
+PRIMARY KEY($PK) - UniqueHashIndex
+ALTER ONLINE TABLE t1 ADD c INT NOT NULL UNIQUE;
+ERROR 42000: This version of MySQL doesn't yet support 'ALTER ONLINE TABLE t1 ADD c INT NOT NULL UNIQUE'
+ALTER OFFLINE TABLE t1 ADD c INT NOT NULL UNIQUE;
+c Int PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY
+PRIMARY KEY(c) - UniqueHashIndex
+DROP TABLE t1;
+****************************************
 * Add column c as nullable TEXT and BLOB
 ****************************************
 CREATE TABLE t1 (a INT UNSIGNED  AUTO_INCREMENT KEY, b INT DEFAULT 2 COLUMN_FORMAT DYNAMIC) ENGINE NDB;
diff -Nrup a/mysql-test/suite/ndb/t/ndb_alter_table_online.test b/mysql-test/suite/ndb/t/ndb_alter_table_online.test
--- a/mysql-test/suite/ndb/t/ndb_alter_table_online.test	2008-01-24 16:45:36 +01:00
+++ b/mysql-test/suite/ndb/t/ndb_alter_table_online.test	2008-03-12 20:00:42 +01:00
@@ -445,6 +445,45 @@ truncate ndb_show_tables_results;
 
 DROP TABLE t1;
 
+#####################################
+# Adding dropping primary key
+######################################
+# Bug:31233
+######################################
+--echo ****************************************
+--echo * Adding dropping primary key
+--echo ****************************************
+CREATE TABLE t1 (a INT UNSIGNED NOT NULL) ENGINE NDB;
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+--error ER_NOT_SUPPORTED_YET
+ALTER ONLINE TABLE t1 ADD PRIMARY KEY (a);
+ALTER OFFLINE TABLE t1 ADD PRIMARY KEY (a);
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+--error ER_NOT_SUPPORTED_YET
+ALTER ONLINE TABLE t1 DROP PRIMARY KEY;
+ALTER OFFLINE TABLE t1 DROP PRIMARY KEY;
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+--error ER_NOT_SUPPORTED_YET
+CREATE ONLINE UNIQUE INDEX pk ON t1(a);
+CREATE OFFLINE UNIQUE INDEX pk ON t1(a);
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+--error ER_NOT_SUPPORTED_YET
+ALTER ONLINE TABLE t1 DROP INDEX PK;
+ALTER OFFLINE TABLE t1 DROP INDEX PK;
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT UNSIGNED) ENGINE NDB;
+--error ER_NOT_SUPPORTED_YET
+ALTER ONLINE TABLE t1 ADD b INT UNIQUE;
+ALTER OFFLINE TABLE t1 ADD b INT UNIQUE;
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+--error ER_NOT_SUPPORTED_YET
+ALTER ONLINE TABLE t1 ADD c INT NOT NULL UNIQUE;
+ALTER OFFLINE TABLE t1 ADD c INT NOT NULL UNIQUE;
+--exec $NDB_TOOLS_DIR/ndb_desc --no-defaults -d test t1 | grep PRIMARY
+DROP TABLE t1;
+
 ######################################
 # Alter dynmaic table, add TEXT column
 ######################################
diff -Nrup a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
--- a/sql/ha_ndbcluster.cc	2008-03-12 15:31:04 +01:00
+++ b/sql/ha_ndbcluster.cc	2008-03-12 20:00:42 +01:00
@@ -10729,24 +10729,6 @@ int ha_ndbcluster::check_if_supported_al
       ai=1;
   }
 
-  /**
-   * Changing from/to primary key
-   *
-   * This is _not_ correct, but check_if_incompatible_data-interface
-   *   doesnt give more info, so I guess that we can't do any
-   *   online add index if not using primary key
-   *
-   *   This as mysql will handle a unique not null index as primary
-   *     even wo/ user specifiying it... :-(
-   *
-   */
-  if ((table_share->primary_key == MAX_KEY && pk) ||
-      (table_share->primary_key != MAX_KEY && !pk) ||
-      (table_share->primary_key == MAX_KEY && !pk && ai))
-  {
-    DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
-  }
-
   /* Check that auto_increment value was not changed */
   if ((create_info->used_fields & HA_CREATE_USED_AUTO) &&
       create_info->auto_increment_value != 0)
diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc
--- a/sql/sql_table.cc	2008-03-12 15:31:57 +01:00
+++ b/sql/sql_table.cc	2008-03-12 20:00:42 +01:00
@@ -5098,6 +5098,8 @@ compare_tables(THD *thd,
   Create_field *new_field;
   KEY_PART_INFO *key_part;
   KEY_PART_INFO *end;
+  uint candidate_key_count= 0;
+  bool not_nullable= true;
   /*
     Remember if the new definition has new VARCHAR column;
     create_info->varchar will be reset in mysql_prepare_create_table.
@@ -5283,6 +5285,30 @@ compare_tables(THD *thd,
 
   DBUG_PRINT("info", ("index count old: %d  new: %d",
                       table->s->keys, ha_alter_info->key_count));
+
+  /* Count all candidate keys. */
+
+  for (table_key= table->key_info; table_key < table_key_end; table_key++)
+  {
+    KEY_PART_INFO *table_part;
+    KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
+
+    /*
+      Check if key is a candidate key, i.e. a unique index with no index
+      fields nullable, then key is either already primary key or could
+      be promoted to primary key if the original primary key is dropped.
+    */
+    not_nullable= true;
+    for (table_part= table_key->key_part;
+         table_part < table_part_end;
+         table_part++)
+    {
+      not_nullable= not_nullable && (! table_part->field->maybe_null());
+    }
+    if ((table_key->flags & HA_NOSAME) && not_nullable)
+      candidate_key_count++;
+  }
+
   /*
     Step through all keys of the old table and search matching new keys.
   */
@@ -5311,11 +5337,32 @@ compare_tables(THD *thd,
       if (table_key->flags & HA_NOSAME)
       {
         /* Unique key. Check for "PRIMARY". */
-        if (! my_strcasecmp(system_charset_info,
-                            table_key->name, primary_key_name))
+        if ((uint) (table_key - table->key_info) == table->s->primary_key)
+        {
           *alter_flags|= HA_DROP_PK_INDEX;
+          candidate_key_count--;
+        }
         else
+        {
+          bool is_not_null;
+
           *alter_flags|= HA_DROP_UNIQUE_INDEX;
+          key_part= new_key->key_part;
+          end= key_part + new_key->key_parts;
+
+         /*
+            Check if all fields in key are declared
+            NOT NULL and adjust candidate_key_count
+          */
+          for(; key_part != end; key_part++)
+          {
+            is_not_null=
+              (is_not_null && 
+               (!table->field[key_part->fieldnr]->maybe_null()));
+          }
+          if (is_not_null)
+            candidate_key_count--;
+        }
       }
       else
         *alter_flags|= HA_DROP_INDEX;
@@ -5332,9 +5379,8 @@ compare_tables(THD *thd,
     {
       if (table_key->flags & HA_NOSAME)
       {
-        // Unique key. Check for "PRIMARY".
-        if (! my_strcasecmp(system_charset_info,
-                            table_key->name, primary_key_name))
+        /* Unique key. Check for "PRIMARY". */
+        if ((uint) (table_key - table->key_info) == table->s->primary_key)
           *alter_flags|= HA_ALTER_PK_INDEX;
         else
           *alter_flags|= HA_ALTER_UNIQUE_INDEX;
@@ -5363,8 +5409,7 @@ compare_tables(THD *thd,
         if (table_key->flags & HA_NOSAME)
         {
           /* Unique key. Check for "PRIMARY" */
-          if (! my_strcasecmp(system_charset_info,
-                              table_key->name, primary_key_name))
+          if ((uint) (table_key - table->key_info) ==  table->s->primary_key)
             *alter_flags|= HA_ALTER_PK_INDEX;
           else
             *alter_flags|= HA_ALTER_UNIQUE_INDEX;
@@ -5412,6 +5457,10 @@ compare_tables(THD *thd,
     }
     if (table_key >= table_key_end)
     {
+      bool is_not_null= true;
+      bool no_pk= ((table->s->primary_key == MAX_KEY) ||
+                   alter_flags->is_set(HA_DROP_PK_INDEX));
+
       /* Key not found. Add the offset of the key to the add buffer. */
       ha_alter_info->index_add_buffer
            [ha_alter_info->index_add_count++]=
@@ -5423,12 +5472,41 @@ compare_tables(THD *thd,
         /* Mark field to be part of new key */
         if ((field= table->field[key_part->fieldnr]))
           field->flags|= FIELD_IN_ADD_INDEX;
+        /*
+          Check if all fields in key are declared
+          NOT NULL
+         */
+        if (key_part->fieldnr < table->s->fields)
+        {
+          is_not_null=
+            (is_not_null && 
+             (!table->field[key_part->fieldnr]->maybe_null()));
+        }
+        else
+        {
+          /* Index is defined over a newly added column */
+          List_iterator_fast<Create_field>
+            new_field_it(alter_info->create_list);
+          Create_field *new_field;
+          uint fieldnr;
+
+          for (fieldnr= 0, new_field= new_field_it++;
+               fieldnr != key_part->fieldnr;
+               fieldnr++, new_field= new_field_it++);
+          is_not_null=
+            (is_not_null && (new_field->flags & NOT_NULL_FLAG));
+        }
       }
       if (new_key->flags & HA_NOSAME)
       {
-        /* Unique key. Check for "PRIMARY" */
-        if (! my_strcasecmp(system_charset_info,
-                            new_key->name, primary_key_name))
+        /* Unique key. Check for "PRIMARY" 
+           or if adding first unique key
+           defined on non-nullable 
+        */
+        DBUG_PRINT("info",("no_pk %s, candidate_key_count %u, is_not_null %s", (no_pk)?"yes":"no", candidate_key_count, (is_not_null)?"yes":"no"));
+        if ((!my_strcasecmp(system_charset_info,
+                            new_key->name, primary_key_name)) ||
+            (no_pk && candidate_key_count == 0 && is_not_null))
           *alter_flags|= HA_ADD_PK_INDEX;
         else
         *alter_flags|= HA_ADD_UNIQUE_INDEX;
Thread
bk commit into 5.1 tree (mskold:1.2549) BUG#31233Martin Skold12 Mar