Commit a94819be authored by Mattias Jonsson's avatar Mattias Jonsson

merge

parents 80257cd4 c04318ed
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
......
......@@ -14,6 +14,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
......
......@@ -6408,9 +6408,42 @@ bool ha_partition::get_error_message(int error, String *buf)
*/
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_arg, KEY *key_info, uint num_of_keys)
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_arg, KEY *key_info, uint num_of_keys)
*/
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);
}
......
......@@ -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*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment