summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
authorAlexey Botchkov <holyfoot@askmonty.org>2014-02-06 16:27:05 +0100
committerAlexey Botchkov <holyfoot@askmonty.org>2014-02-06 16:27:05 +0100
commitbf050b1db219944ff836d5125f262ab0cf1a8a21 (patch)
tree18269f1f54ca502cdb19130d4c59ee330c1c88cd /sql/sql_table.cc
parent73aea0a73244e65a6ebb5c215281e254c66301fc (diff)
downloadmariadb-git-bf050b1db219944ff836d5125f262ab0cf1a8a21.tar.gz
MDEV-4439 ALTER TABLE .. [ADD|DROP] FOREIGN KEY IF [NOT] EXISTS does not work if constraint name is not used.
Patches for server and the Innodb engine. Server is fixed so it does nothing if no indexes left to alter. Innodb parser is fixed so it looks for the IF [NOT] EXISTS option in a string. Another change is that it uses the index name for the internal dictionary. Prior to that it only used the CONSTRAINT name for it.
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc84
1 files changed, 65 insertions, 19 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 45d9c5dc091..bd43dfff478 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -5304,7 +5304,8 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
{
alter_info->flags&= ~Alter_info::ALTER_ADD_COLUMN;
if (alter_info->key_list.is_empty())
- alter_info->flags&= ~Alter_info::ALTER_ADD_INDEX;
+ alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
+ Alter_info::ADD_FOREIGN_KEY);
}
break;
}
@@ -5379,13 +5380,32 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
else /* Alter_drop::KEY */
{
uint n_key;
- for (n_key=0; n_key < table->s->keys; n_key++)
+ if (drop->type != Alter_drop::FOREIGN_KEY)
{
- if (my_strcasecmp(system_charset_info,
- drop->name, table->key_info[n_key].name) == 0)
+ for (n_key=0; n_key < table->s->keys; n_key++)
{
- remove_drop= FALSE;
- break;
+ if (my_strcasecmp(system_charset_info,
+ drop->name, table->key_info[n_key].name) == 0)
+ {
+ remove_drop= FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ List <FOREIGN_KEY_INFO> fk_child_key_list;
+ FOREIGN_KEY_INFO *f_key;
+ table->file->get_foreign_key_list(thd, &fk_child_key_list);
+ List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
+ while ((f_key= fk_key_it++))
+ {
+ if (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
+ drop->name) == 0)
+ {
+ remove_drop= FALSE;
+ break;
+ }
}
}
}
@@ -5397,7 +5417,8 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
drop_it.remove();
if (alter_info->drop_list.is_empty())
alter_info->flags&= ~(Alter_info::ALTER_DROP_COLUMN |
- Alter_info::ALTER_DROP_INDEX);
+ Alter_info::ALTER_DROP_INDEX |
+ Alter_info::DROP_FOREIGN_KEY);
}
}
}
@@ -5408,6 +5429,7 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
Key *key;
List_iterator<Key> key_it(alter_info->key_list);
uint n_key;
+ bool remove_key;
const char *keyname;
while ((key=key_it++))
{
@@ -5424,24 +5446,48 @@ handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info)
if (keyname == NULL)
continue;
}
- for (n_key=0; n_key < table->s->keys; n_key++)
+ remove_key= FALSE;
+ if (key->type != Key::FOREIGN_KEY)
{
- if (my_strcasecmp(system_charset_info,
- keyname, table->key_info[n_key].name) == 0)
+ for (n_key=0; n_key < table->s->keys; n_key++)
{
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
- ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), keyname);
- key_it.remove();
- if (key->type == Key::FOREIGN_KEY)
+ if (my_strcasecmp(system_charset_info,
+ keyname, table->key_info[n_key].name) == 0)
{
- /* ADD FOREIGN KEY appends two items. */
- key_it.remove();
+ remove_key= TRUE;
+ break;
}
- if (alter_info->key_list.is_empty())
- alter_info->flags&= ~Alter_info::ALTER_ADD_INDEX;
- break;
}
}
+ else
+ {
+ List <FOREIGN_KEY_INFO> fk_child_key_list;
+ FOREIGN_KEY_INFO *f_key;
+ table->file->get_foreign_key_list(thd, &fk_child_key_list);
+ List_iterator<FOREIGN_KEY_INFO> fk_key_it(fk_child_key_list);
+ while ((f_key= fk_key_it++))
+ {
+ if (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
+ key->name.str) == 0)
+ remove_key= TRUE;
+ break;
+ }
+ }
+ if (remove_key)
+ {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), key->name.str);
+ key_it.remove();
+ if (key->type == Key::FOREIGN_KEY)
+ {
+ /* ADD FOREIGN KEY appends two items. */
+ key_it.remove();
+ }
+ if (alter_info->key_list.is_empty())
+ alter_info->flags&= ~(Alter_info::ALTER_ADD_INDEX |
+ Alter_info::ADD_FOREIGN_KEY);
+ break;
+ }
}
}