#At file:///home/marty/MySQL/mysql-5.5-cluster/ based on revid:jonas.oreland@stripped
3390 Martin Skold 2011-06-29
Reverted add/drop index behavior in the backward compatible layer to minimize difference to mainline
modified:
mysql-test/suite/innodb/r/innodb-index.result
sql/handler.cc
sql/sql_table.cc
=== modified file 'mysql-test/suite/innodb/r/innodb-index.result'
--- a/mysql-test/suite/innodb/r/innodb-index.result 2011-06-27 10:16:18 +0000
+++ b/mysql-test/suite/innodb/r/innodb-index.result 2011-06-29 12:00:46 +0000
@@ -834,7 +834,7 @@ Table Op Msg_type Msg_text
test.t1 check status OK
explain select * from t1 where b like 'adfd%';
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL b NULL NULL NULL 15 Using where
+1 SIMPLE t1 range b b 769 NULL 11 Using where
drop table t1;
set global innodb_file_per_table=on;
set global innodb_file_format='Barracuda';
=== modified file 'sql/handler.cc'
--- a/sql/handler.cc 2011-06-27 10:22:41 +0000
+++ b/sql/handler.cc 2011-06-29 12:00:46 +0000
@@ -3405,6 +3405,49 @@ handler::ha_prepare_for_alter()
}
#ifndef MCP_WL3749
+
+/**
+ @brief Check if both DROP and CREATE are present for an index in ALTER TABLE
+
+ @details Checks if any index is being modified (present as both DROP INDEX
+ and ADD INDEX) in the current ALTER TABLE statement. Needed for disabling
+ in-place ALTER TABLE.
+
+ @param table The table being altered
+ @param alter_info The ALTER TABLE structure
+ @return presence of index being altered
+ @retval FALSE No such index
+ @retval TRUE Have at least 1 index modified
+*/
+
+static bool
+is_index_maintenance_unique (TABLE *table, Alter_info *alter_info)
+{
+ DBUG_ENTER("is_index_maintenance_unique");
+ DBUG_PRINT("info", ("Checking is_index_maintenance_unique"));
+ List_iterator<Key> key_it(alter_info->key_list);
+ List_iterator<Alter_drop> drop_it(alter_info->drop_list);
+ Key *key;
+
+ while ((key= key_it++))
+ {
+ if (key->name.str)
+ {
+ Alter_drop *drop;
+
+ drop_it.rewind();
+ while ((drop= drop_it++))
+ {
+ DBUG_PRINT("info", ("Checking %s vs %s", key->name.str, drop->name));
+ if (drop->type == Alter_drop::KEY &&
+ !my_strcasecmp(system_charset_info, key->name.str, drop->name))
+ DBUG_RETURN(TRUE);
+ }
+ }
+ }
+ DBUG_RETURN(FALSE);
+}
+
/*
Default implementation to support fast alter table
and old online add/drop index interface
@@ -3424,11 +3467,22 @@ handler::check_if_supported_alter(TABLE
supported_alter_operations |
HA_ADD_INDEX |
HA_DROP_INDEX |
+ HA_ALTER_INDEX |
HA_ADD_UNIQUE_INDEX |
HA_DROP_UNIQUE_INDEX |
+ HA_ALTER_UNIQUE_INDEX |
HA_ADD_PK_INDEX |
- HA_DROP_PK_INDEX;
+ HA_DROP_PK_INDEX |
+ HA_ALTER_PK_INDEX;
+ HA_ALTER_FLAGS not_fast_operations;
+ not_fast_operations=
+ not_fast_operations |
+ HA_ADD_FOREIGN_KEY |
+ HA_DROP_FOREIGN_KEY |
+ HA_ALTER_FOREIGN_KEY |
+ HA_ADD_CONSTRAINT;
HA_ALTER_FLAGS not_supported= ~(supported_alter_operations);
+ HA_ALTER_FLAGS fast_operations= not_supported & ~(not_fast_operations);
DBUG_PRINT("info", ("handler_alter_flags: %lu", handler_alter_flags));
#ifndef DBUG_OFF
{
@@ -3437,10 +3491,18 @@ handler::check_if_supported_alter(TABLE
DBUG_PRINT("info", ("alter_flags: %s", dbug_string));
not_supported.print(dbug_string);
DBUG_PRINT("info", ("not_supported: %s", dbug_string));
+ fast_operations.print(dbug_string);
+ DBUG_PRINT("info", ("fast_operations: %s", dbug_string));
}
#endif
+
+ /* Bug #49838 DROP INDEX and ADD UNIQUE INDEX for same index may corrupt definition at engine */
+ if (is_index_maintenance_unique(table, alter_info))
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
+
/* Check the old alter table flags */
- if ((*alter_flags & not_supported).is_set())
+ if ((*alter_flags & fast_operations).is_set() &&
+ table_changes != IS_EQUAL_NO)
{
/* Not adding/dropping index check if supported as fast alter */
DBUG_PRINT("info", ("alter_info->change_level %u", alter_info->change_level));
@@ -3451,10 +3513,13 @@ handler::check_if_supported_alter(TABLE
else
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
}
+ else if ((*alter_flags & not_supported).is_set())
+ DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
else
{
/* Add index */
- if ((*alter_flags & HA_ADD_INDEX).is_set())
+ if ((*alter_flags & HA_ADD_INDEX).is_set() ||
+ (*alter_flags & HA_ALTER_INDEX).is_set())
{
if (handler_alter_flags & HA_INPLACE_ADD_INDEX_NO_READ_WRITE)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
@@ -3466,7 +3531,8 @@ handler::check_if_supported_alter(TABLE
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
}
/* Drop index */
- if ((*alter_flags & HA_DROP_INDEX).is_set())
+ if ((*alter_flags & HA_DROP_INDEX).is_set() ||
+ (*alter_flags & HA_ALTER_INDEX).is_set())
{
if (handler_alter_flags & HA_INPLACE_DROP_INDEX_NO_READ_WRITE)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
@@ -3478,7 +3544,8 @@ handler::check_if_supported_alter(TABLE
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
}
/* Add unique index */
- if ((*alter_flags & HA_ADD_UNIQUE_INDEX).is_set())
+ if ((*alter_flags & HA_ADD_UNIQUE_INDEX).is_set() ||
+ (*alter_flags & HA_ALTER_UNIQUE_INDEX).is_set())
{
if (handler_alter_flags & HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
@@ -3490,7 +3557,8 @@ handler::check_if_supported_alter(TABLE
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
}
/* Drop unique index */
- if ((*alter_flags & HA_DROP_UNIQUE_INDEX).is_set())
+ if ((*alter_flags & HA_DROP_UNIQUE_INDEX).is_set() ||
+ (*alter_flags & HA_ALTER_UNIQUE_INDEX).is_set())
{
if (handler_alter_flags & HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
@@ -3502,7 +3570,8 @@ handler::check_if_supported_alter(TABLE
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
}
/* Add primary key */
- if ((*alter_flags & HA_ADD_PK_INDEX).is_set())
+ if ((*alter_flags & HA_ADD_PK_INDEX).is_set() ||
+ (*alter_flags & HA_ALTER_PK_INDEX).is_set())
{
if (handler_alter_flags & HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
@@ -3514,7 +3583,8 @@ handler::check_if_supported_alter(TABLE
DBUG_RETURN(HA_ALTER_NOT_SUPPORTED);
}
/* Drop primary key */
- if ((*alter_flags & HA_DROP_PK_INDEX).is_set())
+ if ((*alter_flags & HA_DROP_PK_INDEX).is_set() ||
+ (*alter_flags & HA_ALTER_PK_INDEX).is_set())
{
if (handler_alter_flags & HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE)
result= HA_ALTER_SUPPORTED_WAIT_LOCK;
@@ -3544,8 +3614,10 @@ handler::alter_table_phase1(THD *thd,
HA_ALTER_FLAGS adding;
HA_ALTER_FLAGS dropping;
- adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX;
- dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
+ adding= adding | HA_ADD_INDEX | HA_ADD_UNIQUE_INDEX | HA_ADD_PK_INDEX |
+ HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
+ dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX |
+ HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
if ((*alter_flags & adding).is_set())
{
@@ -3623,7 +3695,8 @@ handler::alter_table_phase2(THD *thd,
int error= 0;
HA_ALTER_FLAGS dropping;
- dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX;
+ dropping= dropping | HA_DROP_INDEX | HA_DROP_UNIQUE_INDEX |
+ HA_ALTER_INDEX | HA_ALTER_UNIQUE_INDEX | HA_ALTER_PK_INDEX;
if ((*alter_flags & dropping).is_set())
{
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2011-06-23 10:29:27 +0000
+++ b/sql/sql_table.cc 2011-06-29 12:00:46 +0000
@@ -5233,6 +5233,40 @@ compare_tables(THD *thd,
continue;
}
+ bool is_not_null= true;
+ bool no_pk= ((table->s->primary_key == MAX_KEY) ||
+ alter_flags->is_set(HA_DROP_PK_INDEX));
+ key_part= new_key->key_part;
+ end= key_part + new_key->key_parts;
+ for(; key_part != end; key_part++)
+ {
+ /*
+ Check if all fields in key are declared
+ NOT NULL
+ */
+ if (key_part->fieldnr < table->s->fields)
+ {
+ /* Mark field to be part of new key */
+ field= table->field[key_part->fieldnr];
+ field->flags|= FIELD_IN_ADD_INDEX;
+ is_not_null= (is_not_null && (!field->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));
+ }
+ }
+
/* Check that the key types are compatible between old and new tables. */
if ((table_key->algorithm != new_key->algorithm) ||
((table_key->flags & HA_KEYFLAG_MASK) !=
@@ -5243,12 +5277,42 @@ compare_tables(THD *thd,
{
/* Unique key. Check for "PRIMARY". */
if ((uint) (table_key - table->key_info) == table->s->primary_key)
- *alter_flags|= HA_ALTER_PK_INDEX;
+ {
+ if (new_key->flags & HA_NOSAME)
+ *alter_flags|= HA_ALTER_PK_INDEX;
+ else
+ {
+ *alter_flags|= HA_ALTER_PK_INDEX;
+ *alter_flags|= HA_DROP_PK_INDEX | HA_ADD_INDEX;
+ }
+ }
else
- *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+ {
+ if (new_key->flags & HA_NOSAME)
+ *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+ else
+ {
+ *alter_flags|= HA_ALTER_UNIQUE_INDEX;
+ *alter_flags|= HA_DROP_UNIQUE_INDEX | HA_ADD_INDEX;
+ }
+ }
}
else
- *alter_flags|= HA_ALTER_INDEX;
+ {
+ if (new_key->flags & HA_NOSAME)
+ {
+ *alter_flags|= HA_ALTER_INDEX;
+ *alter_flags|= HA_DROP_INDEX;
+ 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;
+ }
+ else
+ *alter_flags|= HA_ALTER_INDEX;
+ }
goto index_changed;
}
@@ -5369,7 +5433,7 @@ compare_tables(THD *thd,
(no_pk && candidate_key_count == 0 && is_not_null))
*alter_flags|= HA_ADD_PK_INDEX;
else
- *alter_flags|= HA_ADD_UNIQUE_INDEX;
+ *alter_flags|= HA_ADD_UNIQUE_INDEX;
}
else
*alter_flags|= HA_ADD_INDEX;
@@ -6642,6 +6706,17 @@ bool mysql_alter_table(THD *thd,char *ne
uint candidate_key_count= 0;
bool no_pk;
#endif
+#ifndef MCP_WL3749
+ int alter_supported= HA_ALTER_NOT_SUPPORTED;
+ List<Alter_drop> drop_list;
+ List<Create_field> create_list;
+ List<Alter_column> alter_list;
+ List<Key> key_list;
+ List<Alter_drop> drop_list_orig(alter_info->drop_list, thd->mem_root);
+ List<Create_field> create_list_orig(alter_info->create_list, thd->mem_root);
+ List<Alter_column> alter_list_orig(alter_info->alter_list, thd->mem_root);
+ List<Key> key_list_orig(alter_info->key_list, thd->mem_root);
+#endif
DBUG_ENTER("mysql_alter_table");
DBUG_PRINT("info", ("alter_info->build_method %u", alter_info->build_method));
@@ -7360,11 +7435,28 @@ bool mysql_alter_table(THD *thd,char *ne
else
altered_table->part_info= table->part_info;
#endif
- switch (table->file->check_if_supported_alter(altered_table,
- create_info,
- alter_info,
- &ha_alter_flags,
- table_changes)) {
+ DBUG_PRINT("info", ("Reverting alter_info"));
+ drop_list= List<Alter_drop>(alter_info->drop_list, thd->mem_root);
+ create_list= List<Create_field>(alter_info->create_list, thd->mem_root);
+ alter_list= List<Alter_column>(alter_info->alter_list, thd->mem_root);
+ key_list= List<Key>(alter_info->key_list, thd->mem_root);
+ alter_info->drop_list= drop_list_orig;
+ alter_info->create_list= create_list_orig;
+ alter_info->alter_list= alter_list_orig;
+ alter_info->key_list= key_list_orig;
+
+ alter_supported= (table->file->check_if_supported_alter(altered_table,
+ create_info,
+ alter_info,
+ &ha_alter_flags,
+ table_changes));
+
+ DBUG_PRINT("info", ("Restoring alter_info"));
+ alter_info->drop_list= drop_list;
+ alter_info->create_list= create_list;
+ alter_info->alter_list= alter_list;
+ alter_info->key_list= key_list;
+ switch (alter_supported) {
case HA_ALTER_SUPPORTED_WAIT_LOCK:
case HA_ALTER_SUPPORTED_NO_LOCK:
/*
Attachment: [text/bzr-bundle] bzr/martin.skold@oracle.com-20110629120046-i3rhverwf8j836yf.bundle
| Thread |
|---|
| • bzr commit into mysql-5.5-cluster branch (Martin.Skold:3390) | Martin Skold | 29 Jun |