From: Martin Skold Date: June 29 2011 12:01pm Subject: bzr push into mysql-5.5-cluster branch (Martin.Skold:3389 to 3390) List-Archive: http://lists.mysql.com/commits/140017 Message-Id: <20110629120133.89D779F8D75@quadfish> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 3389 Jonas Oreland 2011-06-29 [merge] ndb - merge 71 to 55 modified: VERSION storage/ndb/VERSION storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp storage/ndb/src/kernel/blocks/suma/Suma.cpp === 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_it(alter_info->key_list); + List_iterator 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 + 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 drop_list; + List create_list; + List alter_list; + List key_list; + List drop_list_orig(alter_info->drop_list, thd->mem_root); + List create_list_orig(alter_info->create_list, thd->mem_root); + List alter_list_orig(alter_info->alter_list, thd->mem_root); + List 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_info->drop_list, thd->mem_root); + create_list= List(alter_info->create_list, thd->mem_root); + alter_list= List(alter_info->alter_list, thd->mem_root); + key_list= List(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: /* No bundle (reason: useless for push emails).