diff options
author | Alexey Botchkov <holyfoot@askmonty.org> | 2014-02-06 16:27:05 +0100 |
---|---|---|
committer | Alexey Botchkov <holyfoot@askmonty.org> | 2014-02-06 16:27:05 +0100 |
commit | bf050b1db219944ff836d5125f262ab0cf1a8a21 (patch) | |
tree | 18269f1f54ca502cdb19130d4c59ee330c1c88cd /sql/sql_table.cc | |
parent | 73aea0a73244e65a6ebb5c215281e254c66301fc (diff) | |
download | mariadb-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.cc | 84 |
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; + } } } |