List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:November 15 2010 10:41pm
Subject:bzr commit into mysql-5.5-bugteam branch (mattias.jonsson:3126)
View as plain text  
#At file:///Users/mattiasj/mysql-bzr/topush-5.5-bugteam/ based on revid:mattias.jonsson@stripped

 3126 Mattias Jonsson	2010-11-15 [merge]
      merge

    modified:
      mysql-test/r/partition.result
      mysql-test/t/partition.test
      sql/ha_partition.cc
      sql/handler.h
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2010-10-01 14:06:10 +0000
+++ b/mysql-test/r/partition.result	2010-11-05 11:01:10 +0000
@@ -1,5 +1,38 @@
 drop table if exists t1, t2;
 #
+# Bug#57778: failed primary key add to partitioned innodb table
+#            inconsistent and crashes
+#
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL)
+PARTITION BY KEY (a) PARTITIONS 2;
+INSERT INTO t1 VALUES (0,1), (0,2);
+ALTER TABLE t1 ADD PRIMARY KEY (a);
+ERROR 23000: Duplicate entry '0' for key 'PRIMARY'
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) NOT NULL,
+  `b` int(11) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY KEY (a)
+PARTITIONS 2 */
+SELECT * FROM t1;
+a	b
+0	1
+0	2
+UPDATE t1 SET a = 1, b = 1 WHERE a = 0 AND b = 2;
+ALTER TABLE t1 ADD PRIMARY KEY (a);
+SELECT * FROM t1;
+a	b
+1	1
+0	1
+ALTER TABLE t1 DROP PRIMARY KEY;
+SELECT * FROM t1;
+a	b
+1	1
+0	1
+DROP TABLE t1;
+#
 # Bug#57113: ha_partition::extra(ha_extra_function):
 #            Assertion `m_extra_cache' failed
 CREATE TABLE t1

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2010-10-01 14:06:10 +0000
+++ b/mysql-test/t/partition.test	2010-11-05 11:01:10 +0000
@@ -15,6 +15,24 @@ drop table if exists t1, t2;
 --enable_warnings
 
 --echo #
+--echo # Bug#57778: failed primary key add to partitioned innodb table
+--echo #            inconsistent and crashes
+--echo #
+CREATE TABLE t1 (a INT NOT NULL, b INT NOT NULL)
+PARTITION BY KEY (a) PARTITIONS 2;
+INSERT INTO t1 VALUES (0,1), (0,2);
+--error ER_DUP_ENTRY
+ALTER TABLE t1 ADD PRIMARY KEY (a);
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
+UPDATE t1 SET a = 1, b = 1 WHERE a = 0 AND b = 2;
+ALTER TABLE t1 ADD PRIMARY KEY (a);
+SELECT * FROM t1;
+ALTER TABLE t1 DROP PRIMARY KEY;
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
 --echo # Bug#57113: ha_partition::extra(ha_extra_function):
 --echo #            Assertion `m_extra_cache' failed
 CREATE TABLE t1

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2010-11-15 16:44:27 +0000
+++ b/sql/ha_partition.cc	2010-11-15 22:38:26 +0000
@@ -6408,9 +6408,42 @@ bool ha_partition::get_error_message(int
 */
 uint ha_partition::alter_table_flags(uint flags)
 {
+  uint flags_to_return, flags_to_check;
   DBUG_ENTER("ha_partition::alter_table_flags");
-  DBUG_RETURN(ht->alter_table_flags(flags) |
-              m_file[0]->alter_table_flags(flags)); 
+
+  flags_to_return= ht->alter_table_flags(flags);
+  flags_to_return|= m_file[0]->alter_table_flags(flags); 
+
+  /*
+    If one partition fails we must be able to revert the change for the other,
+    already altered, partitions. So both ADD and DROP can only be supported in
+    pairs.
+  */
+  flags_to_check= HA_ONLINE_ADD_INDEX_NO_WRITES;
+  flags_to_check|= HA_ONLINE_DROP_INDEX_NO_WRITES;
+  if ((flags_to_return & flags_to_check) != flags_to_check)
+    flags_to_return&= ~flags_to_check;
+  flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
+  flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
+  if ((flags_to_return & flags_to_check) != flags_to_check)
+    flags_to_return&= ~flags_to_check;
+  flags_to_check= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
+  flags_to_check|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
+  if ((flags_to_return & flags_to_check) != flags_to_check)
+    flags_to_return&= ~flags_to_check;
+  flags_to_check= HA_ONLINE_ADD_INDEX;
+  flags_to_check|= HA_ONLINE_DROP_INDEX;
+  if ((flags_to_return & flags_to_check) != flags_to_check)
+    flags_to_return&= ~flags_to_check;
+  flags_to_check= HA_ONLINE_ADD_UNIQUE_INDEX;
+  flags_to_check|= HA_ONLINE_DROP_UNIQUE_INDEX;
+  if ((flags_to_return & flags_to_check) != flags_to_check)
+    flags_to_return&= ~flags_to_check;
+  flags_to_check= HA_ONLINE_ADD_PK_INDEX;
+  flags_to_check|= HA_ONLINE_DROP_PK_INDEX;
+  if ((flags_to_return & flags_to_check) != flags_to_check)
+    flags_to_return&= ~flags_to_check;
+  DBUG_RETURN(flags_to_return);
 }
 
 
@@ -6445,6 +6478,7 @@ int ha_partition::add_index(TABLE *table
   handler **file;
   int ret= 0;
 
+  DBUG_ENTER("ha_partition::add_index");
   /*
     There has already been a check in fix_partition_func in mysql_alter_table
     before this call, which checks for unique/primary key violations of the
@@ -6452,8 +6486,28 @@ int ha_partition::add_index(TABLE *table
   */
   for (file= m_file; *file; file++)
     if ((ret=  (*file)->add_index(table_arg, key_info, num_of_keys)))
-      break;
-  return ret;
+      goto err;
+  DBUG_RETURN(ret);
+err:
+  if (file > m_file)
+  {
+    uint *key_numbers= (uint*) ha_thd()->alloc(sizeof(uint) * num_of_keys);
+    uint old_num_of_keys= table_arg->s->keys;
+    uint i;
+    /* The newly created keys have the last id's */
+    for (i= 0; i < num_of_keys; i++)
+      key_numbers[i]= i + old_num_of_keys;
+    if (!table_arg->key_info)
+      table_arg->key_info= key_info;
+    while (--file >= m_file)
+    {
+      (void) (*file)->prepare_drop_index(table_arg, key_numbers, num_of_keys);
+      (void) (*file)->final_drop_index(table_arg);
+    }
+    if (table_arg->key_info == key_info)
+      table_arg->key_info= NULL;
+  }
+  DBUG_RETURN(ret);
 }
 
 

=== modified file 'sql/handler.h'
--- a/sql/handler.h	2010-10-06 14:34:28 +0000
+++ b/sql/handler.h	2010-11-05 11:01:10 +0000
@@ -174,6 +174,8 @@
 /*
   These bits are set if different kinds of indexes can be created
   off-line without re-create of the table (but with a table lock).
+  Partitioning needs both ADD and DROP to be supported by its underlying
+  handlers, due to error handling, see bug#57778.
 */
 #define HA_ONLINE_ADD_INDEX_NO_WRITES           (1L << 0) /*add index w/lock*/
 #define HA_ONLINE_DROP_INDEX_NO_WRITES          (1L << 1) /*drop index w/lock*/

No bundle (reason: revision is a merge).
Thread
bzr commit into mysql-5.5-bugteam branch (mattias.jonsson:3126) Mattias Jonsson15 Nov