diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2020-03-03 13:50:33 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2020-03-03 13:50:33 +0300 |
commit | 193725b81ed813d0318c1fa82de284c337246d9e (patch) | |
tree | 5491a62650565a58d24cfc629b7466f29b617d18 /sql | |
parent | fa8ad7543947f5c74dece982d42bab59b6479449 (diff) | |
download | mariadb-git-193725b81ed813d0318c1fa82de284c337246d9e.tar.gz |
MDEV-7318 RENAME INDEX
This patch adds support of RENAME INDEX operation to the ALTER TABLE
statement. Code which determines if ALTER TABLE can be done in-place
for "simple" storage engines like MyISAM, Heap and etc. was updated to
handle ALTER TABLE ... RENAME INDEX as an in-place operation. Support
for in-place ALTER TABLE ... RENAME INDEX for InnoDB was covered by
MDEV-13301.
Syntax changes
==============
A new type of <alter_specification> is added:
<rename index clause> ::= RENAME ( INDEX | KEY ) <oldname> TO <newname>
Where <oldname> and <newname> are identifiers for old name and new
name of the index.
Semantic changes
================
The result of "ALTER TABLE t1 RENAME INDEX a TO b" is a table which
contents and structure are identical to the old version of 't1' with
the only exception index 'a' being called 'b'.
Neither <oldname> nor <newname> can be "primary". The index being
renamed should exist and its new name should not be occupied
by another index on the same table.
Related to: WL#6555, MDEV-13301
Diffstat (limited to 'sql')
-rw-r--r-- | sql/handler.cc | 3 | ||||
-rw-r--r-- | sql/sql_alter.cc | 2 | ||||
-rw-r--r-- | sql/sql_alter.h | 4 | ||||
-rw-r--r-- | sql/sql_class.h | 15 | ||||
-rw-r--r-- | sql/sql_table.cc | 43 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 |
6 files changed, 75 insertions, 2 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 7d61252eea6..806d91bdbc5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4585,7 +4585,8 @@ handler::check_if_supported_inplace_alter(TABLE *altered_table, ALTER_DROP_CHECK_CONSTRAINT | ALTER_PARTITIONED | ALTER_VIRTUAL_GCOL_EXPR | - ALTER_RENAME; + ALTER_RENAME | + ALTER_RENAME_INDEX; /* Is there at least one operation that requires copy algorithm? */ if (ha_alter_info->handler_flags & ~inplace_offline_operations) diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc index 0828e1b7ba8..23e2e3e097f 100644 --- a/sql/sql_alter.cc +++ b/sql/sql_alter.cc @@ -25,6 +25,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) :drop_list(rhs.drop_list, mem_root), alter_list(rhs.alter_list, mem_root), key_list(rhs.key_list, mem_root), + alter_rename_key_list(rhs.alter_rename_key_list, mem_root), create_list(rhs.create_list, mem_root), check_constraint_list(rhs.check_constraint_list, mem_root), flags(rhs.flags), partition_flags(rhs.partition_flags), @@ -46,6 +47,7 @@ Alter_info::Alter_info(const Alter_info &rhs, MEM_ROOT *mem_root) list_copy_and_replace_each_value(drop_list, mem_root); list_copy_and_replace_each_value(alter_list, mem_root); list_copy_and_replace_each_value(key_list, mem_root); + list_copy_and_replace_each_value(alter_rename_key_list, mem_root); list_copy_and_replace_each_value(create_list, mem_root); /* partition_names are not deeply copied currently */ } diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 41408a91836..a553c31346a 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -19,6 +19,7 @@ class Alter_drop; class Alter_column; +class Alter_rename_key; class Key; /** @@ -87,6 +88,8 @@ public: List<Alter_column> alter_list; // List of keys, used by both CREATE and ALTER TABLE. List<Key> key_list; + // List of keys to be renamed. + List<Alter_rename_key> alter_rename_key_list; // List of columns, used by both CREATE and ALTER TABLE. List<Create_field> create_list; @@ -123,6 +126,7 @@ public: drop_list.empty(); alter_list.empty(); key_list.empty(); + alter_rename_key_list.empty(); create_list.empty(); check_constraint_list.empty(); flags= 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 6a7c0cd4d94..123bf0c0583 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -355,6 +355,21 @@ public: }; +class Alter_rename_key : public Sql_alloc +{ +public: + LEX_CSTRING old_name; + LEX_CSTRING new_name; + + Alter_rename_key(LEX_CSTRING old_name_arg, LEX_CSTRING new_name_arg) + : old_name(old_name_arg), new_name(new_name_arg) {} + + Alter_rename_key *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Alter_rename_key(*this); } + +}; + + class Key :public Sql_alloc, public DDL_options { public: enum Keytype { PRIMARY, UNIQUE, MULTIPLE, FULLTEXT, SPATIAL, FOREIGN_KEY}; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b5cc07b1411..3b56a721801 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6601,7 +6601,7 @@ static int compare_uint(const uint *s, const uint *t) enum class Compare_keys : uint32_t { - Equal, + Equal= 0, EqualButKeyPartLength, EqualButComment, NotEqual @@ -7998,6 +7998,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, List<Create_field> new_create_list; /* New key definitions are added here */ List<Key> new_key_list; + List<Alter_rename_key> rename_key_list(alter_info->alter_rename_key_list); List_iterator<Alter_drop> drop_it(alter_info->drop_list); List_iterator<Create_field> def_it(alter_info->create_list); List_iterator<Alter_column> alter_it(alter_info->alter_list); @@ -8446,6 +8447,39 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, continue; } + /* If this index is to stay in the table check if it has to be renamed. */ + List_iterator<Alter_rename_key> rename_key_it(rename_key_list); + Alter_rename_key *rename_key; + + while ((rename_key= rename_key_it++)) + { + if (!my_strcasecmp(system_charset_info, key_name, rename_key->old_name.str)) + { + if (!my_strcasecmp(system_charset_info, key_name, primary_key_name)) + { + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), rename_key->old_name.str); + goto err; + } + else if (!my_strcasecmp(system_charset_info, rename_key->new_name.str, + primary_key_name)) + { + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), rename_key->new_name.str); + goto err; + } + + key_name= rename_key->new_name.str; + rename_key_it.remove(); + /* + If the user has explicitly renamed the key, we should no longer + treat it as generated. Otherwise this key might be automatically + dropped by mysql_prepare_create_table() and this will confuse + code in fill_alter_inplace_info(). + */ + key_info->flags&= ~HA_GENERATED_KEY; + break; + } + } + if (key_info->algorithm == HA_KEY_ALG_LONG_HASH) { setup_keyinfo_hash(key_info); @@ -8772,6 +8806,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, } } + if (rename_key_list.elements) + { + my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), rename_key_list.head()->old_name.str, + table->s->table_name.str); + goto err; + } + if (!create_info->comment.str) { create_info->comment.str= table->s->comment.str; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1d4a8a7e228..b032ce66cc7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7732,6 +7732,16 @@ alter_list_item: if (unlikely(Lex->add_alter_list($3, $5))) MYSQL_YYABORT; } + | RENAME key_or_index field_ident TO_SYM field_ident + { + LEX *lex=Lex; + Alter_rename_key *ak= new (thd->mem_root) + Alter_rename_key($3, $5); + if (ak == NULL) + MYSQL_YYABORT; + lex->alter_info.alter_rename_key_list.push_back(ak); + lex->alter_info.flags|= ALTER_RENAME_INDEX; + } | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate { if (!$4) |