summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc106
1 files changed, 104 insertions, 2 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1434e0d61d4..471783c280b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4291,7 +4291,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
create_info->period_info.unique_keys++;
}
-
+ key_info->is_ignored= key->key_create_info.is_ignored;
key_info++;
}
@@ -6829,6 +6829,32 @@ Compare_keys compare_keys_but_name(const KEY *table_key, const KEY *new_key,
return result;
}
+
+/**
+ Look-up KEY object by index name using case-insensitive comparison.
+
+ @param key_name Index name.
+ @param key_start Start of array of KEYs for table.
+ @param key_end End of array of KEYs for table.
+
+ @note Case-insensitive comparison is necessary to correctly
+ handle renaming of keys.
+
+ @retval non-NULL - pointer to KEY object for index found.
+ @retval NULL - no index with such name found (or it is marked
+ as renamed).
+*/
+
+static KEY *find_key_ci(const char *key_name, KEY *key_start, KEY *key_end) {
+ for (KEY *key = key_start; key < key_end; key++)
+ {
+ if (!my_strcasecmp(system_charset_info, key_name, key->name.str))
+ return key;
+ }
+ return NULL;
+}
+
+
/**
Compare original and new versions of a table and fill Alter_inplace_info
describing differences between those versions.
@@ -6888,7 +6914,10 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
! (ha_alter_info->index_add_buffer=
(uint*) thd->alloc(sizeof(uint) *
alter_info->key_list.elements)) ||
- ha_alter_info->rename_keys.reserve(ha_alter_info->index_add_count))
+ ha_alter_info->rename_keys.reserve(ha_alter_info->index_add_count) ||
+ ! (ha_alter_info->index_altered_ignorability_buffer=
+ (KEY_PAIR*)thd->alloc(sizeof(KEY_PAIR) *
+ alter_info->alter_index_ignorability_list.elements)))
DBUG_RETURN(true);
/*
@@ -7294,6 +7323,29 @@ static bool fill_alter_inplace_info(THD *thd, TABLE *table, bool varchar,
}
}
+ List_iterator<Alter_index_ignorability>
+ ignorability_index_it(alter_info->alter_index_ignorability_list);
+ Alter_index_ignorability *alter_index_ignorability;
+ while((alter_index_ignorability= ignorability_index_it++))
+ {
+ const char *name= alter_index_ignorability->name();
+
+ KEY *old_key, *new_key;
+ old_key= find_key_ci(name, table->key_info, table_key_end);
+ new_key= find_key_ci(name, ha_alter_info->key_info_buffer, new_key_end);
+
+ DBUG_ASSERT(old_key != NULL);
+
+ if (new_key == NULL)
+ {
+ my_error(ER_KEY_DOES_NOT_EXISTS, MYF(0), name, table->s->table_name.str);
+ DBUG_RETURN(true);
+ }
+ new_key->is_ignored= alter_index_ignorability->is_ignored();
+ ha_alter_info->handler_flags|= ALTER_RENAME_INDEX;
+ ha_alter_info->add_altered_index_ignorability(old_key, new_key);
+ }
+
/*
Sort index_add_buffer according to how key_info_buffer is sorted.
I.e. with primary keys first - see sort_keys().
@@ -8128,6 +8180,17 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
/* New key definitions are added here */
List<Key> new_key_list;
List<Alter_rename_key> rename_key_list(alter_info->alter_rename_key_list);
+
+ /*
+ Create a deep copy of the list of visibility for indexes, as it will be
+ altered here.
+ */
+ List<Alter_index_ignorability>
+ alter_index_ignorability_list(alter_info->alter_index_ignorability_list,
+ thd->mem_root);
+
+ list_copy_and_replace_each_value(alter_index_ignorability_list, thd->mem_root);
+
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);
@@ -8594,6 +8657,18 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
continue;
}
+ List_iterator<Alter_index_ignorability>
+ ignorability_index_it(alter_index_ignorability_list);
+
+ Alter_index_ignorability *index_ignorability;
+ while((index_ignorability= ignorability_index_it++))
+ {
+ const char* name= index_ignorability->name();
+ if (!my_strcasecmp(system_charset_info, key_name, name))
+ ignorability_index_it.remove();
+ }
+
+
/* 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;
@@ -8742,6 +8817,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
key_create_info.parser_name= *plugin_name(key_info->parser);
if (key_info->flags & HA_USES_COMMENT)
key_create_info.comment= key_info->comment;
+ key_create_info.is_ignored= key_info->is_ignored;
/*
We're refreshing an already existing index. Since the index is not
@@ -8773,6 +8849,24 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
else
key_type= Key::MULTIPLE;
+ List_iterator<Alter_index_ignorability>
+ ignorability_index_it(alter_info->alter_index_ignorability_list);
+ Alter_index_ignorability *index_ignorability;
+ while((index_ignorability= ignorability_index_it++))
+ {
+ const char *name= index_ignorability->name();
+ if (!my_strcasecmp(system_charset_info, key_name, name))
+ {
+ if (table->s->primary_key <= MAX_KEY &&
+ table->key_info + table->s->primary_key == key_info)
+ {
+ my_error(ER_PK_INDEX_CANT_BE_IGNORED, MYF(0));
+ goto err;
+ }
+ key_create_info.is_ignored= index_ignorability->is_ignored();
+ }
+ }
+
tmp_name.str= key_name;
tmp_name.length= strlen(key_name);
/* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */
@@ -8975,6 +9069,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
goto err;
}
+ if (alter_index_ignorability_list.elements)
+ {
+ my_error(ER_KEY_DOES_NOT_EXISTS, MYF(0),
+ alter_index_ignorability_list.head()->name(),
+ table->s->table_name.str);
+ goto err;
+ }
+
if (!create_info->comment.str)
{
create_info->comment.str= table->s->comment.str;