diff options
Diffstat (limited to 'sql/sql_rename.cc')
-rw-r--r-- | sql/sql_rename.cc | 67 |
1 files changed, 38 insertions, 29 deletions
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 05ebdbf144a..658afd57f9b 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -199,7 +199,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent, else { /* Revert the renames of normal tables with the help of the ddl log */ - ddl_log_revert(thd, &ddl_log_state); + error|= ddl_log_revert(thd, &ddl_log_state); } err: @@ -228,18 +228,6 @@ rename_temporary_table(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table) /** - Parameters for rename_table_and_triggers() -*/ - -struct rename_param -{ - LEX_CSTRING old_alias, new_alias; - LEX_CUSTRING old_version; - handlerton *from_table_hton; -}; - - -/** Check pre-conditions for rename - From table should exists - To table should not exists. @@ -255,7 +243,7 @@ struct rename_param @retval <0 Can't do rename, but no error */ -static int +int rename_check_preconditions(THD *thd, rename_param *param, Table_name *ren_table, const LEX_CSTRING *new_db, @@ -281,7 +269,8 @@ rename_check_preconditions(THD *thd, rename_param *param, if (!ha_table_exists(thd, &ren_table->db, ¶m->old_alias, ¶m->old_version, NULL, - ¶m->from_table_hton, NULL, 0) || + ¶m->from_table_hton, NULL, + (param->rename_flags & FN_FROM_IS_TMP)) || !param->from_table_hton) { my_error(ER_NO_SUCH_TABLE, MYF(if_exists ? ME_NOTE : 0), @@ -301,7 +290,8 @@ rename_check_preconditions(THD *thd, rename_param *param, DBUG_RETURN(-1); } - if (ha_table_exists(thd, new_db, ¶m->new_alias, NULL, NULL, NULL, NULL, 0)) + if (ha_table_exists(thd, new_db, ¶m->new_alias, NULL, NULL, NULL, NULL, + (param->rename_flags & FN_TO_IS_TMP))) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), param->new_alias.str); DBUG_RETURN(1); // This can't be skipped @@ -325,12 +315,17 @@ rename_check_preconditions(THD *thd, rename_param *param, Rename a single table or a view. In case of failure, all changes will be reverted + Even if mysql_rename_tables() cannot be used with LOCK TABLES, + the table can still be locked if we come here from CREATE ... REPLACE. + + If ddl_log_state is NULL then we will not log the rename to the ddl log. + RETURN false Ok true rename failed */ -static bool +bool rename_table_and_triggers(THD *thd, rename_param *param, DDL_LOG_STATE *ddl_log_state, Table_name *ren_table, const LEX_CSTRING *new_db, @@ -340,6 +335,7 @@ rename_table_and_triggers(THD *thd, rename_param *param, handlerton *hton; LEX_CSTRING *old_alias, *new_alias; TRIGGER_RENAME_PARAM rename_param; + rename_param.rename_flags= param->rename_flags; DBUG_ENTER("rename_table_and_triggers"); DBUG_PRINT("enter", ("skip_error: %d", (int) skip_error)); @@ -347,15 +343,19 @@ rename_table_and_triggers(THD *thd, rename_param *param, new_alias= ¶m->new_alias; hton= param->from_table_hton; - DBUG_ASSERT(!thd->locked_tables_mode); - #ifdef WITH_WSREP if (WSREP(thd) && hton && hton != view_pseudo_hton && !wsrep_should_replicate_ddl(thd, hton)) DBUG_RETURN(1); #endif - tdc_remove_table(thd, ren_table->db.str, ren_table->table_name.str); + if (!(param->rename_flags & FN_FROM_IS_TMP)) + tdc_remove_table(thd, ren_table->db.str, ren_table->table_name.str); + + /* + In case of CREATE..REPLACE the temporary table does not have a + MDL lock + */ if (hton != view_pseudo_hton) { @@ -373,19 +373,23 @@ rename_table_and_triggers(THD *thd, rename_param *param, thd->replication_flags= 0; - if (ddl_log_rename_table(ddl_log_state, hton, - &ren_table->db, old_alias, new_db, new_alias)) + if (ddl_log_state && + ddl_log_rename_table(ddl_log_state, hton, + &ren_table->db, old_alias, new_db, new_alias, + DDL_RENAME_PHASE_TABLE, 0)) DBUG_RETURN(1); debug_crash_here("ddl_log_rename_before_rename_table"); if (!(rc= mysql_rename_table(hton, &ren_table->db, old_alias, - new_db, new_alias, ¶m->old_version, 0))) + new_db, new_alias, ¶m->old_version, + param->rename_flags))) { /* Table rename succeded. It's safe to start recovery at rename trigger phase */ debug_crash_here("ddl_log_rename_before_phase_trigger"); - ddl_log_update_phase(ddl_log_state, DDL_RENAME_PHASE_TRIGGER); + if (ddl_log_state) + ddl_log_update_phase(ddl_log_state, DDL_RENAME_PHASE_TRIGGER); debug_crash_here("ddl_log_rename_before_rename_trigger"); @@ -398,10 +402,13 @@ rename_table_and_triggers(THD *thd, rename_param *param, new_alias))) { debug_crash_here("ddl_log_rename_before_stat_tables"); - (void) rename_table_in_stat_tables(thd, &ren_table->db, - &ren_table->table_name, - new_db, new_alias); - debug_crash_here("ddl_log_rename_after_stat_tables"); + if (!(param->rename_flags & FN_IS_TMP)) + { + (void) rename_table_in_stat_tables(thd, &ren_table->db, + &ren_table->table_name, + new_db, new_alias); + debug_crash_here("ddl_log_rename_after_stat_tables"); + } } else { @@ -416,7 +423,8 @@ rename_table_and_triggers(THD *thd, rename_param *param, &ren_table->db, old_alias, ¶m->old_version, NO_FK_CHECKS); debug_crash_here("ddl_log_rename_after_revert_rename_table"); - ddl_log_disable_entry(ddl_log_state); + if (ddl_log_state) + ddl_log_disable_entry(ddl_log_state); debug_crash_here("ddl_log_rename_after_disable_entry"); } } @@ -437,6 +445,7 @@ rename_table_and_triggers(THD *thd, rename_param *param, DBUG_RETURN(1); } + DBUG_ASSERT(ddl_log_state); ddl_log_rename_view(ddl_log_state, &ren_table->db, &ren_table->table_name, new_db, new_alias); debug_crash_here("ddl_log_rename_before_rename_view"); |