| 9847 | */ |
| 9848 | |
| 9849 | static bool fk_prepare_copy_alter_table(THD *thd, TABLE *table, |
| 9850 | Alter_info *alter_info, |
| 9851 | Alter_table_ctx *alter_ctx) |
| 9852 | { |
| 9853 | List <FOREIGN_KEY_INFO> fk_parent_key_list; |
| 9854 | List <FOREIGN_KEY_INFO> fk_child_key_list; |
| 9855 | FOREIGN_KEY_INFO *f_key; |
| 9856 | |
| 9857 | DBUG_ENTER("fk_prepare_copy_alter_table"); |
| 9858 | |
| 9859 | table->file->get_parent_foreign_key_list(thd, &fk_parent_key_list); |
| 9860 | |
| 9861 | /* OOM when building list. */ |
| 9862 | if (unlikely(thd->is_error())) |
| 9863 | DBUG_RETURN(true); |
| 9864 | |
| 9865 | /* |
| 9866 | Remove from the list all foreign keys in which table participates as |
| 9867 | parent which are to be dropped by this ALTER TABLE. This is possible |
| 9868 | when a foreign key has the same table as child and parent. |
| 9869 | */ |
| 9870 | List_iterator<FOREIGN_KEY_INFO> fk_parent_key_it(fk_parent_key_list); |
| 9871 | List<FOREIGN_KEY_INFO> keys_to_remove; |
| 9872 | |
| 9873 | while ((f_key= fk_parent_key_it++)) |
| 9874 | { |
| 9875 | Alter_drop *drop; |
| 9876 | List_iterator_fast<Alter_drop> drop_it(alter_info->drop_list); |
| 9877 | |
| 9878 | while ((drop= drop_it++)) |
| 9879 | { |
| 9880 | /* |
| 9881 | InnoDB treats foreign key names in case-insensitive fashion. |
| 9882 | So we do it here too. For database and table name type of |
| 9883 | comparison used depends on lower-case-table-names setting. |
| 9884 | For l_c_t_n = 0 we use case-sensitive comparison, for |
| 9885 | l_c_t_n > 0 modes case-insensitive comparison is used. |
| 9886 | */ |
| 9887 | if ((drop->type == Alter_drop::FOREIGN_KEY) && |
| 9888 | drop->name.streq(*f_key->foreign_id) && |
| 9889 | table->s->db.streq(*f_key->foreign_db) && |
| 9890 | table->s->table_name.streq(*f_key->foreign_table)) |
| 9891 | { |
| 9892 | keys_to_remove.push_back(f_key); |
| 9893 | break; |
| 9894 | } |
| 9895 | } |
| 9896 | } |
| 9897 | |
| 9898 | IF_DBUG(uint removed= 0,); |
| 9899 | /* Remove the identified keys */ |
| 9900 | List_iterator<FOREIGN_KEY_INFO> remove_it(keys_to_remove); |
| 9901 | while ((f_key = remove_it++)) |
| 9902 | { |
| 9903 | fk_parent_key_it.rewind(); |
| 9904 | while (FOREIGN_KEY_INFO *fk= fk_parent_key_it++) |
| 9905 | { |
| 9906 | if (fk == f_key) |
no test coverage detected