From: Martin Skold Date: March 12 2008 2:58pm Subject: bk commit into 5.1 tree (mskold:1.2549) BUG#31233 List-Archive: http://lists.mysql.com/commits/43854 X-Bug: 31233 Message-Id: <200803121458.m2CEwhLJ016661@quadfish.ndb.mysql.com> Below is the list of changes that have just been committed into a local 5.1 repository of mskold. When mskold does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet@stripped, 2008-03-12 15:58:39+01:00, mskold@stripped +3 -0 bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface mysql-test/suite/ndb/r/ndb_alter_table.result@stripped, 2008-03-12 15:55:01+01:00, mskold@stripped +4 -4 bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface sql/ha_ndbcluster.cc@stripped, 2008-03-12 15:55:02+01:00, mskold@stripped +0 -18 bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface sql/sql_table.cc@stripped, 2008-03-12 15:55:02+01:00, mskold@stripped +70 -10 bug#31233 mysql_alter_table() fails to drop UNIQUE KEY: Adpted patch to new online alter interface diff -Nrup a/mysql-test/suite/ndb/r/ndb_alter_table.result b/mysql-test/suite/ndb/r/ndb_alter_table.result --- a/mysql-test/suite/ndb/r/ndb_alter_table.result 2008-03-12 15:30:32 +01:00 +++ b/mysql-test/suite/ndb/r/ndb_alter_table.result 2008-03-12 15:55:01 +01:00 @@ -310,7 +310,7 @@ a b c 12 403 NULL drop table t1; create table t1(a int not null) engine=ndb; -$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY +$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR PRIMARY KEY($PK) - UniqueHashIndex insert into t1 values (1),(2),(3); alter table t1 add primary key (a); @@ -324,7 +324,7 @@ a 3 17 alter table t1 drop primary key; -$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY +$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR PRIMARY KEY($PK) - UniqueHashIndex update t1 set a = 1 where a = 17; select * from t1 order by a; @@ -334,7 +334,7 @@ a 3 drop table t1; create table t1(a int not null) engine=ndb; -$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY +$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR PRIMARY KEY($PK) - UniqueHashIndex insert into t1 values (1),(2),(3); create unique index pk on t1(a); @@ -347,7 +347,7 @@ a 3 17 alter table t1 drop index pk; -$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY +$PK Bigunsigned PRIMARY KEY DISTRIBUTION KEY AT=FIXED ST=MEMORY AUTO_INCR PRIMARY KEY($PK) - UniqueHashIndex update t1 set a = 1 where a = 17; select * from t1 order by a; diff -Nrup a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc --- a/sql/ha_ndbcluster.cc 2008-03-12 15:31:04 +01:00 +++ b/sql/ha_ndbcluster.cc 2008-03-12 15:55:02 +01:00 @@ -10729,24 +10729,6 @@ int ha_ndbcluster::check_if_supported_al ai=1; } - /** - * Changing from/to primary key - * - * This is _not_ correct, but check_if_incompatible_data-interface - * doesnt give more info, so I guess that we can't do any - * online add index if not using primary key - * - * This as mysql will handle a unique not null index as primary - * even wo/ user specifiying it... :-( - * - */ - if ((table_share->primary_key == MAX_KEY && pk) || - (table_share->primary_key != MAX_KEY && !pk) || - (table_share->primary_key == MAX_KEY && !pk && ai)) - { - DBUG_RETURN(HA_ALTER_NOT_SUPPORTED); - } - /* Check that auto_increment value was not changed */ if ((create_info->used_fields & HA_CREATE_USED_AUTO) && create_info->auto_increment_value != 0) diff -Nrup a/sql/sql_table.cc b/sql/sql_table.cc --- a/sql/sql_table.cc 2008-03-12 15:31:57 +01:00 +++ b/sql/sql_table.cc 2008-03-12 15:55:02 +01:00 @@ -5098,6 +5098,8 @@ compare_tables(THD *thd, Create_field *new_field; KEY_PART_INFO *key_part; KEY_PART_INFO *end; + uint candidate_key_count= 0; + bool not_nullable= true; /* Remember if the new definition has new VARCHAR column; create_info->varchar will be reset in mysql_prepare_create_table. @@ -5283,6 +5285,30 @@ compare_tables(THD *thd, DBUG_PRINT("info", ("index count old: %d new: %d", table->s->keys, ha_alter_info->key_count)); + + /* Count all candidate keys. */ + + 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; + + /* + Check if key is a candidate key, i.e. a unique index with no index + fields nullable, then key is either already primary key or could + be promoted to primary key if the original primary key is dropped. + */ + not_nullable= true; + for (table_part= table_key->key_part; + table_part < table_part_end; + table_part++) + { + not_nullable= not_nullable && (! table_part->field->maybe_null()); + } + if ((table_key->flags & HA_NOSAME) && not_nullable) + candidate_key_count++; + } + /* Step through all keys of the old table and search matching new keys. */ @@ -5311,11 +5337,32 @@ compare_tables(THD *thd, if (table_key->flags & HA_NOSAME) { /* Unique key. Check for "PRIMARY". */ - if (! my_strcasecmp(system_charset_info, - table_key->name, primary_key_name)) + if ((uint) (table_key - table->key_info) == table->s->primary_key) + { *alter_flags|= HA_DROP_PK_INDEX; + candidate_key_count--; + } else + { + bool is_not_null; + *alter_flags|= HA_DROP_UNIQUE_INDEX; + key_part= new_key->key_part; + end= key_part + new_key->key_parts; + + /* + Check if all fields in key are declared + NOT NULL and adjust candidate_key_count + */ + for(; key_part != end; key_part++) + { + is_not_null= + (is_not_null && + (!table->field[key_part->fieldnr]->maybe_null())); + } + if (is_not_null) + candidate_key_count--; + } } else *alter_flags|= HA_DROP_INDEX; @@ -5332,9 +5379,8 @@ compare_tables(THD *thd, { if (table_key->flags & HA_NOSAME) { - // Unique key. Check for "PRIMARY". - if (! my_strcasecmp(system_charset_info, - table_key->name, primary_key_name)) + /* Unique key. Check for "PRIMARY". */ + if ((uint) (table_key - table->key_info) == table->s->primary_key) *alter_flags|= HA_ALTER_PK_INDEX; else *alter_flags|= HA_ALTER_UNIQUE_INDEX; @@ -5363,8 +5409,7 @@ compare_tables(THD *thd, if (table_key->flags & HA_NOSAME) { /* Unique key. Check for "PRIMARY" */ - if (! my_strcasecmp(system_charset_info, - table_key->name, primary_key_name)) + if ((uint) (table_key - table->key_info) == table->s->primary_key) *alter_flags|= HA_ALTER_PK_INDEX; else *alter_flags|= HA_ALTER_UNIQUE_INDEX; @@ -5412,6 +5457,10 @@ compare_tables(THD *thd, } if (table_key >= table_key_end) { + bool is_not_null; + bool no_pk= ((table->s->primary_key == MAX_KEY) || + alter_flags->is_set(HA_DROP_PK_INDEX)); + /* Key not found. Add the offset of the key to the add buffer. */ ha_alter_info->index_add_buffer [ha_alter_info->index_add_count++]= @@ -5423,12 +5472,23 @@ compare_tables(THD *thd, /* Mark field to be part of new key */ if ((field= table->field[key_part->fieldnr])) field->flags|= FIELD_IN_ADD_INDEX; + /* + Check if all fields in key are declared + NOT NULL + */ + is_not_null= + (is_not_null && + (!table->field[key_part->fieldnr]->maybe_null())); } if (new_key->flags & HA_NOSAME) { - /* Unique key. Check for "PRIMARY" */ - if (! my_strcasecmp(system_charset_info, - new_key->name, primary_key_name)) + /* Unique key. Check for "PRIMARY" + or if adding first unique key + defined on non-nullable + */ + 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;