Index: mysql-5.1-innodb-online-alter/sql/sql_table.cc =================================================================== --- mysql-5.1-innodb-online-alter.orig/sql/sql_table.cc 2008-01-10 15:47:09.000000000 +0100 +++ mysql-5.1-innodb-online-alter/sql/sql_table.cc 2008-01-10 16:05:33.000000000 +0100 @@ -2988,6 +2988,7 @@ mysql_prepare_create_table(THD *thd, HA_ if (!unique_key && !primary_key && (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY)) { + DBUG_ASSERT(false); my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0)); DBUG_RETURN(TRUE); } @@ -5038,6 +5039,7 @@ err: index_drop_count OUT The number of elements in the array. index_add_buffer OUT An array of offsets into key_info_buffer. index_add_count OUT The number of elements in the array. + unique_index_count OUT The number of unique indexes in original table. DESCRIPTION 'table' (first argument) contains information of the original @@ -5068,7 +5070,8 @@ compare_tables(TABLE *table, enum_alter_table_change_level *need_copy_table, KEY **key_info_buffer, uint **index_drop_buffer, uint *index_drop_count, - uint **index_add_buffer, uint *index_add_count) + uint **index_add_buffer, uint *index_add_count, + uint *unique_index_count) { Field **f_ptr, *field; uint changes= 0, tmp; @@ -5220,12 +5223,16 @@ compare_tables(TABLE *table, */ *index_drop_count= 0; *index_add_count= 0; + *unique_index_count= 0; 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; KEY_PART_INFO *new_part; + if (table_key->flags & HA_NOSAME) + (*unique_index_count)++; + /* Search a new key with the same name. */ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++) { @@ -5850,12 +5857,14 @@ bool mysql_alter_table(THD *thd,char *ne uint index_drop_count; uint *index_drop_buffer; uint index_add_count; + uint unique_index_count; uint *index_add_buffer; bool committed= 0; DBUG_ENTER("mysql_alter_table"); LINT_INIT(index_add_count); LINT_INIT(index_drop_count); + LINT_INIT(unique_index_count); LINT_INIT(index_add_buffer); LINT_INIT(index_drop_buffer); @@ -6268,7 +6277,8 @@ view_err: &need_copy_table_res, &key_info_buffer, &index_drop_buffer, &index_drop_count, - &index_add_buffer, &index_add_count)) + &index_add_buffer, &index_add_count, + &unique_index_count)) goto err; if (need_copy_table == ALTER_TABLE_METADATA_ONLY) @@ -6302,9 +6312,13 @@ view_err: DBUG_PRINT("info", ("index dropped: '%s'", key->name)); if (key->flags & HA_NOSAME) { - /* Unique key. Check for "PRIMARY". */ - if (! my_strcasecmp(system_charset_info, - key->name, primary_key_name)) + /* + Unique key. Check for "PRIMARY" + or if dropping last unique key. + */ + if ((! my_strcasecmp(system_charset_info, + key->name, primary_key_name)) || + (unique_index_count == 1)) { /* Primary key. */ needed_online_flags|= HA_ONLINE_DROP_PK_INDEX; @@ -6335,9 +6349,14 @@ view_err: DBUG_PRINT("info", ("index added: '%s'", key->name)); if (key->flags & HA_NOSAME) { - /* Unique key. Check for "PRIMARY". */ - if (! my_strcasecmp(system_charset_info, - key->name, primary_key_name)) + /* + Unique key. Check for "PRIMARY" + or if adding first unique key + */ + if ((! my_strcasecmp(system_charset_info, + key->name, primary_key_name)) || + (unique_index_count == 0) || + (needed_online_flags & HA_ONLINE_DROP_PK_INDEX)) { /* Primary key. */ needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;