-
Marko Mäkelä authored
Revert the work-around and really fix Bug#14105491 ADD FOREIGN KEY ON COLUMNS BEING RENAMED DOES NOT WORK CORRECTLY Refactor ha_innobase::commit_inplace_alter_table() as follows: First, update the data dictionary definitions in the persistent data dictionary within a single data dictionary transaction. If any step fails, roll back the dictionary transaction. Update the foreign key constraints in the same data dictionary transaction with everything else. Only if the definitions were successfully updated, perform the corresponding modifications in the data dictionary cache. In this way, there is no need to implement any logic for rolling back any changes in the data dictionary cache. (Adding an index is the most notable exception to this, as we will allocate a placeholder for the index.) dict_foreign_eval_sql(): Replace dict_table_t and dict_foreign_t with table name and foreign key id. dict_create_add_foreign_field_to_dictionary(): Replace dict_table_t with table_name. dict_create_add_foreign_to_dictionary(): Replace dict_table_t with table name. Remove the parameter id_nr, and assume that foreign->id be assigned by the caller. dict_create_add_foreign_id(): Assign foreign->id if needed. This used to be part of dict_create_add_foreign_to_dictionary(). dict_foreign_find_index(): dict_foreign_add_to_cache(), dict_foreign_qualify_index(), dict_load_foreign(), dict_load_foreigns(): Add the parameter col_names[], to be used instead of table->col_names when the columns are being renamed but the table definition in the data dictionary cache has not been updated yet. dict_foreign_replace_index(): Add the parameter col_names[] and remove the parameter trx. Return a Boolean, indicating whether all replacements were found. fil_mtr_rename_log(): Add the parameter mtr, so that multiple renames can be logged in a single mini-transaction, together with logging a transaction commit. innobase_check_fk_option(): Make the parameter const. innobase_find_fk_index(), innobase_get_foreign_key_info(): Add the parameter col_names[] so that this can work with renamed columns. Add the parameters drop_index[] and n_drop_index to avoid future conflicts with RENAME INDEX or other operations. ha_innobase_inplace_ctx: Add user_trx, col_names[] and tmp_name. innobase_get_col_names(): Initialize a list of all column names in the table if any columns were renamed. This will be used for initializing ctx->col_names. prepare_inplace_alter_table_dict(): Take most parameters via ha_alter_info->handler_ctx. When the table is rebuilt, the new copy of the table (ctx->indexed_table) will contain the renamed columns, so the ctx->col_names will be reset to NULL. innobase_check_foreign_key_index(): Add the parameter col_names[]. innobase_drop_foreign_try(): Renamed from innobase_drop_foreign_dict(). Replace TABLE_SHARE with table_name and dict_foreign_t with foreign_id. Do not touch the data dictionary cache. innobase_rename_column_try(): Renamed from innobase_rename_column(). Replace TABLE_SHARE with table_name and prebuilt with user_table. Do not touch the data dictionary cache. innobase_rename_columns_try(): Renamed from innobase_rename_columns(). Replace TABLE_SHARE with table_name and prebuilt with user_table. innobase_undo_add_fk(): Remove. No FOREIGN KEY operations will not be performed in the data dictionary cache until after the dictionary transaction has been committed. innobase_rename_columns_cache(): New function, for renaming the columns of a table in the data dictionary cache. This is only needed when the table was not rebuilt. commit_get_autoinc(): Refactored function, for getting the auto-increment value of the table on commit. innobase_update_foreign_try(): New function: Add or drop foreign key constraints. innobase_update_foreign_cache(): New function: Add or drop foreign key constraints in the data dictionary cache after the changes were committed. We will rely on dict_load_foreigns(). commit_try_rebuild(): Refactored function: Apply the changes to the data dictionary tables when the table was rebuilt. commit_cache_rebuild(): New function: Apply the changes to the data dictionary cache and the file system after the changes were committed. The table will not be dropped here. commit_try_norebuild(): Refactored function: Apply the changes to the data dictionary tables when the table was not rebuilt. commit_cache_norebuild(): New function: Apply the changes to the data dictionary cache and the file system after the changes were committed. TODO: Do the actual DROP INDEX (row_merge_drop_indexes_dict) later, outside exclusive metadata lock. commit_update_stats(): Refactored function: Update index cardinality statistics after the ALTER TABLE operation was committed. ha_innobase::commit_inplace_alter_table(): Do not modify the data dictionary cache until after the data dictionary transaction has been committed. row_merge_rename_tables_dict(): Renamed from row_merge_rename_tables(). Do not commit the transaction. trx_commit_low(): New function, to commit a transaction together with an already started mini-transaction. This will be called by ha_innobase::commit_inplace_alter_table() when rebuilding the table. rb#1637 approved by Jimmy Yang
Marko Mäkelä authoredRevert the work-around and really fix Bug#14105491 ADD FOREIGN KEY ON COLUMNS BEING RENAMED DOES NOT WORK CORRECTLY Refactor ha_innobase::commit_inplace_alter_table() as follows: First, update the data dictionary definitions in the persistent data dictionary within a single data dictionary transaction. If any step fails, roll back the dictionary transaction. Update the foreign key constraints in the same data dictionary transaction with everything else. Only if the definitions were successfully updated, perform the corresponding modifications in the data dictionary cache. In this way, there is no need to implement any logic for rolling back any changes in the data dictionary cache. (Adding an index is the most notable exception to this, as we will allocate a placeholder for the index.) dict_foreign_eval_sql(): Replace dict_table_t and dict_foreign_t with table name and foreign key id. dict_create_add_foreign_field_to_dictionary(): Replace dict_table_t with table_name. dict_create_add_foreign_to_dictionary(): Replace dict_table_t with table name. Remove the parameter id_nr, and assume that foreign->id be assigned by the caller. dict_create_add_foreign_id(): Assign foreign->id if needed. This used to be part of dict_create_add_foreign_to_dictionary(). dict_foreign_find_index(): dict_foreign_add_to_cache(), dict_foreign_qualify_index(), dict_load_foreign(), dict_load_foreigns(): Add the parameter col_names[], to be used instead of table->col_names when the columns are being renamed but the table definition in the data dictionary cache has not been updated yet. dict_foreign_replace_index(): Add the parameter col_names[] and remove the parameter trx. Return a Boolean, indicating whether all replacements were found. fil_mtr_rename_log(): Add the parameter mtr, so that multiple renames can be logged in a single mini-transaction, together with logging a transaction commit. innobase_check_fk_option(): Make the parameter const. innobase_find_fk_index(), innobase_get_foreign_key_info(): Add the parameter col_names[] so that this can work with renamed columns. Add the parameters drop_index[] and n_drop_index to avoid future conflicts with RENAME INDEX or other operations. ha_innobase_inplace_ctx: Add user_trx, col_names[] and tmp_name. innobase_get_col_names(): Initialize a list of all column names in the table if any columns were renamed. This will be used for initializing ctx->col_names. prepare_inplace_alter_table_dict(): Take most parameters via ha_alter_info->handler_ctx. When the table is rebuilt, the new copy of the table (ctx->indexed_table) will contain the renamed columns, so the ctx->col_names will be reset to NULL. innobase_check_foreign_key_index(): Add the parameter col_names[]. innobase_drop_foreign_try(): Renamed from innobase_drop_foreign_dict(). Replace TABLE_SHARE with table_name and dict_foreign_t with foreign_id. Do not touch the data dictionary cache. innobase_rename_column_try(): Renamed from innobase_rename_column(). Replace TABLE_SHARE with table_name and prebuilt with user_table. Do not touch the data dictionary cache. innobase_rename_columns_try(): Renamed from innobase_rename_columns(). Replace TABLE_SHARE with table_name and prebuilt with user_table. innobase_undo_add_fk(): Remove. No FOREIGN KEY operations will not be performed in the data dictionary cache until after the dictionary transaction has been committed. innobase_rename_columns_cache(): New function, for renaming the columns of a table in the data dictionary cache. This is only needed when the table was not rebuilt. commit_get_autoinc(): Refactored function, for getting the auto-increment value of the table on commit. innobase_update_foreign_try(): New function: Add or drop foreign key constraints. innobase_update_foreign_cache(): New function: Add or drop foreign key constraints in the data dictionary cache after the changes were committed. We will rely on dict_load_foreigns(). commit_try_rebuild(): Refactored function: Apply the changes to the data dictionary tables when the table was rebuilt. commit_cache_rebuild(): New function: Apply the changes to the data dictionary cache and the file system after the changes were committed. The table will not be dropped here. commit_try_norebuild(): Refactored function: Apply the changes to the data dictionary tables when the table was not rebuilt. commit_cache_norebuild(): New function: Apply the changes to the data dictionary cache and the file system after the changes were committed. TODO: Do the actual DROP INDEX (row_merge_drop_indexes_dict) later, outside exclusive metadata lock. commit_update_stats(): Refactored function: Update index cardinality statistics after the ALTER TABLE operation was committed. ha_innobase::commit_inplace_alter_table(): Do not modify the data dictionary cache until after the data dictionary transaction has been committed. row_merge_rename_tables_dict(): Renamed from row_merge_rename_tables(). Do not commit the transaction. trx_commit_low(): New function, to commit a transaction together with an already started mini-transaction. This will be called by ha_innobase::commit_inplace_alter_table() when rebuilding the table. rb#1637 approved by Jimmy Yang
Loading