summaryrefslogtreecommitdiff
path: root/sql/sql_rename.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_rename.cc')
-rw-r--r--sql/sql_rename.cc67
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, &param->old_alias,
&param->old_version, NULL,
- &param->from_table_hton, NULL, 0) ||
+ &param->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, &param->new_alias, NULL, NULL, NULL, NULL, 0))
+ if (ha_table_exists(thd, new_db, &param->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= &param->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, &param->old_version, 0)))
+ new_db, new_alias, &param->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, &param->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");