diff options
Diffstat (limited to 'storage/xtradb/handler/handler0alter.cc')
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 59 |
1 files changed, 42 insertions, 17 deletions
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 85c77f4d8a2..abea5c45058 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -22,6 +22,7 @@ this program; if not, write to the Free Software Foundation, Inc., Smart ALTER TABLE *******************************************************/ +#include <my_global.h> #include <unireg.h> #include <mysqld_error.h> #include <log.h> @@ -2260,7 +2261,7 @@ innobase_check_foreigns_low( /* Check if any FOREIGN KEY constraints are defined on this column. */ - for (dict_foreign_set::iterator it = user_table->foreign_set.begin(); + for (dict_foreign_set::const_iterator it = user_table->foreign_set.begin(); it != user_table->foreign_set.end(); ++it) { @@ -2297,7 +2298,7 @@ innobase_check_foreigns_low( /* Check if any FOREIGN KEY constraints in other tables are referring to the column that is being dropped. */ - for (dict_foreign_set::iterator it + for (dict_foreign_set::const_iterator it = user_table->referenced_set.begin(); it != user_table->referenced_set.end(); ++it) { @@ -2483,7 +2484,7 @@ innobase_build_col_map( innobase_build_col_map_add( heap, dtuple_get_nth_field(add_cols, i), - altered_table->s->field[sql_idx], + altered_table->field[sql_idx], dict_table_is_comp(new_table)); found_col: i++; @@ -2689,7 +2690,7 @@ prepare_inplace_alter_table_dict( if (UNIV_UNLIKELY(ctx->trx->fake_changes)) { trx_rollback_to_savepoint(ctx->trx, NULL); trx_free_for_mysql(ctx->trx); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + DBUG_RETURN(true); } trx_start_for_ddl(ctx->trx, TRX_DICT_OP_INDEX); @@ -3278,9 +3279,6 @@ err_exit: delete ctx; ha_alter_info->handler_ctx = NULL; - /* There might be work for utility threads.*/ - srv_active_wake_master_thread(); - DBUG_RETURN(true); } @@ -3409,7 +3407,7 @@ ha_innobase::prepare_inplace_alter_table( DBUG_ASSERT(!srv_read_only_mode); if (UNIV_UNLIKELY(prebuilt->trx->fake_changes)) { - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + DBUG_RETURN(true); } /* Init online ddl status variables */ @@ -4331,7 +4329,6 @@ func_exit: } trx_commit_for_mysql(prebuilt->trx); - srv_active_wake_master_thread(); MONITOR_ATOMIC_DEC(MONITOR_PENDING_ALTER_TABLE); DBUG_RETURN(fail); } @@ -4505,7 +4502,7 @@ err_exit: rename_foreign: trx->op_info = "renaming column in SYS_FOREIGN_COLS"; - for (dict_foreign_set::iterator it = user_table->foreign_set.begin(); + for (dict_foreign_set::const_iterator it = user_table->foreign_set.begin(); it != user_table->foreign_set.end(); ++it) { @@ -4540,7 +4537,7 @@ rename_foreign: } } - for (dict_foreign_set::iterator it + for (dict_foreign_set::const_iterator it = user_table->referenced_set.begin(); it != user_table->referenced_set.end(); ++it) { @@ -4844,14 +4841,17 @@ innobase_update_foreign_try( /** Update the foreign key constraint definitions in the data dictionary cache after the changes to data dictionary tables were committed. @param ctx In-place ALTER TABLE context +@param user_thd MySQL connection @return InnoDB error code (should always be DB_SUCCESS) */ static __attribute__((nonnull, warn_unused_result)) dberr_t innobase_update_foreign_cache( /*==========================*/ - ha_innobase_inplace_ctx* ctx) + ha_innobase_inplace_ctx* ctx, + THD* user_thd) { dict_table_t* user_table; + dberr_t err = DB_SUCCESS; DBUG_ENTER("innobase_update_foreign_cache"); @@ -4886,9 +4886,34 @@ innobase_update_foreign_cache( /* Load the old or added foreign keys from the data dictionary and prevent the table from being evicted from the data dictionary cache (work around the lack of WL#6049). */ - DBUG_RETURN(dict_load_foreigns(user_table->name, - ctx->col_names, false, true, - DICT_ERR_IGNORE_NONE)); + err = dict_load_foreigns(user_table->name, + ctx->col_names, false, true, + DICT_ERR_IGNORE_NONE); + + if (err == DB_CANNOT_ADD_CONSTRAINT) { + /* It is possible there are existing foreign key are + loaded with "foreign_key checks" off, + so let's retry the loading with charset_check is off */ + err = dict_load_foreigns(user_table->name, + ctx->col_names, false, false, + DICT_ERR_IGNORE_NONE); + + /* The load with "charset_check" off is successful, warn + the user that the foreign key has loaded with mis-matched + charset */ + if (err == DB_SUCCESS) { + push_warning_printf( + user_thd, + Sql_condition::WARN_LEVEL_WARN, + ER_ALTER_INFO, + "Foreign key constraints for table '%s'" + " are loaded with charset check off", + user_table->name); + + } + } + + DBUG_RETURN(err); } /** Commit the changes made during prepare_inplace_alter_table() @@ -5766,12 +5791,12 @@ ha_innobase::commit_inplace_alter_table( /* Rename the tablespace files. */ commit_cache_rebuild(ctx); - error = innobase_update_foreign_cache(ctx); + error = innobase_update_foreign_cache(ctx, user_thd); if (error != DB_SUCCESS) { goto foreign_fail; } } else { - error = innobase_update_foreign_cache(ctx); + error = innobase_update_foreign_cache(ctx, user_thd); if (error != DB_SUCCESS) { foreign_fail: |