From 62470fc7874515e2bc8bc00cb38844f19c465d7e Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Fri, 24 Nov 2017 21:26:43 +0300 Subject: [PATCH] SQL: recreate PRIMARY KEY on DROP SYSTEM VERSIONING [#348] --- mysql-test/suite/versioning/t/alter.test | 17 +++++++ sql/handler.cc | 59 ++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 71b40c73a2f..e75974f8324 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -320,6 +320,23 @@ alter table non_empty change column sys_trx_end sys_trx_end bigint(20) unsigned generated always as row end; drop table non_empty; +create or replace table t (a int primary key) with system versioning; +insert into t values (1); +update t set a=2; +alter table t drop primary key, add primary key (a), drop system versioning; +select * from t; +--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM +show create table t; + +create or replace table t (a int primary key) with system versioning; +insert into t values (1); +update t set a=2; +alter table t drop system versioning; +select * from t; +--replace_result InnoDB INNODB_OR_MYISAM MyISAM INNODB_OR_MYISAM +show create table t; + + call verify_vtq; } diff --git a/sql/handler.cc b/sql/handler.cc index c6837fd5bd0..9299102ba58 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -6927,6 +6927,29 @@ static bool add_field_to_drop_list(THD *thd, Alter_info *alter_info, return !ad || alter_info->drop_list.push_back(ad, thd->mem_root); } +static bool is_dropping_primary_key(Alter_info *alter_info) +{ + List_iterator_fast it(alter_info->drop_list); + while (Alter_drop *ad= it++) + { + if (ad->type == Alter_drop::KEY && + !my_strcasecmp(system_charset_info, ad->name, primary_key_name)) + return true; + } + return false; +} + +static bool is_adding_primary_key(Alter_info *alter_info) +{ + List_iterator_fast it(alter_info->key_list); + while (Key *key= it++) + { + if (key->type == Key::PRIMARY) + return true; + } + return false; +} + bool Vers_parse_info::check_and_fix_alter(THD *thd, Alter_info *alter_info, HA_CREATE_INFO *create_info, TABLE *table) @@ -6964,6 +6987,42 @@ bool Vers_parse_info::check_and_fix_alter(THD *thd, Alter_info *alter_info, add_field_to_drop_list(thd, alter_info, share->vers_end_field())) return true; + if (share->primary_key != MAX_KEY && !is_adding_primary_key(alter_info) && + !is_dropping_primary_key(alter_info)) + { + alter_info->flags|= Alter_info::ALTER_DROP_INDEX; + Alter_drop *ad= new (thd->mem_root) + Alter_drop(Alter_drop::KEY, primary_key_name, false); + if (!ad || alter_info->drop_list.push_back(ad, thd->mem_root)) + return true; + + alter_info->flags|= Alter_info::ALTER_ADD_INDEX; + LEX_CSTRING key_name= {NULL, 0}; + DDL_options_st options; + options.init(); + Key *pk= new (thd->mem_root) + Key(Key::PRIMARY, &key_name, HA_KEY_ALG_UNDEF, false, options); + if (!pk) + return true; + + st_key &key= table->key_info[share->primary_key]; + for (st_key_part_info *it= key.key_part, + *end= it + key.user_defined_key_parts; + it != end; ++it) + { + if (it->field->vers_sys_field()) + continue; + + Key_part_spec *key_part_spec= new (thd->mem_root) + Key_part_spec(&it->field->field_name, it->length); + if (!key_part_spec || + pk->columns.push_back(key_part_spec, thd->mem_root)) + return true; + } + + alter_info->key_list.push_back(pk); + } + return false; }