From 560598c9b2f0f38bb5eec281ef1b00dbe964ed87 Mon Sep 17 00:00:00 2001 From: sachin Date: Sun, 3 Mar 2019 17:56:48 +0530 Subject: [PATCH] MDEV-18799 Long unique does not work after failed alter table Restore table->key_info after calling setup_keyinfo_hash in mysql_prepare_alter_table. --- mysql-test/main/long_unique_bugs.result | 21 +++++++++++++++++++++ mysql-test/main/long_unique_bugs.test | 12 ++++++++++++ sql/sql_table.cc | 12 ++++++++---- sql/table.cc | 2 ++ 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index 716c343f9c4..0dec6572879 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -63,3 +63,24 @@ ALTER TABLE t1 DROP x, ALGORITHM=INPLACE; ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY UPDATE t1 SET x = 'bar'; DROP TABLE t1; +create table t1(a blob unique , b blob); +insert into t1 values(1,1),(2,1); +alter table t1 add unique(b); +ERROR 23000: Duplicate entry '1' for key 'b' +show keys from t1;; +Table t1 +Non_unique 0 +Key_name a +Seq_in_index 1 +Column_name a +Collation A +Cardinality NULL +Sub_part NULL +Packed NULL +Null YES +Index_type HASH +Comment +Index_comment +insert into t1 values(1,1); +ERROR 23000: Duplicate entry '1' for key 'a' +DROP TABLE t1; diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index 05a9bf83aa4..d4dbe26a221 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -82,3 +82,15 @@ INSERT INTO t1 VALUES (1,'foo'); ALTER TABLE t1 DROP x, ALGORITHM=INPLACE; UPDATE t1 SET x = 'bar'; DROP TABLE t1; + +# +# MDEV-18799 Long unique does not work after failed alter table +# +create table t1(a blob unique , b blob); +insert into t1 values(1,1),(2,1); +--error ER_DUP_ENTRY +alter table t1 add unique(b); +--query_vertical show keys from t1; +--error ER_DUP_ENTRY +insert into t1 values(1,1); +DROP TABLE t1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e35deb19c80..80aebd2f9ad 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8299,10 +8299,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, */ for (uint i=0 ; i < table->s->keys ; i++,key_info++) { + bool long_hash_key= false; if (key_info->flags & HA_INVISIBLE_KEY) continue; if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) + { setup_keyinfo_hash(key_info); + long_hash_key= true; + } const char *key_name= key_info->name.str; Alter_drop *drop; drop_it.rewind(); @@ -8427,10 +8431,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, LEX_CSTRING tmp_name; bzero((char*) &key_create_info, sizeof(key_create_info)); if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) - { - key_info->flags|= HA_NOSAME; key_info->algorithm= HA_KEY_ALG_UNDEF; - } key_create_info.algorithm= key_info->algorithm; /* We copy block size directly as some engines, like Area, sets this @@ -8476,8 +8477,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, &key_parts, key_info->option_list, DDL_options()); new_key_list.push_back(key, thd->mem_root); } - if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) + if (long_hash_key) + { + key_info->algorithm= HA_KEY_ALG_LONG_HASH; re_setup_keyinfo_hash(key_info); + } } { Key *key; diff --git a/sql/table.cc b/sql/table.cc index 4da873b2e8f..d0615962f33 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -8983,6 +8983,7 @@ void setup_keyinfo_hash(KEY *key_info) key_info->key_part-= no_of_keyparts; key_info->user_defined_key_parts= key_info->usable_key_parts= key_info->ext_key_parts= no_of_keyparts; + key_info->flags|= HA_NOSAME; } /* re_setup_keyinfo_hash reverts th setup_keyinfo_hash and this type of @@ -8997,6 +8998,7 @@ void re_setup_keyinfo_hash(KEY *key_info) key_info->key_part++; key_info->user_defined_key_parts= key_info->usable_key_parts= key_info->ext_key_parts= 1; + key_info->flags&= ~HA_NOSAME; } /** @brief clone of current handler.