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.cc145
1 files changed, 82 insertions, 63 deletions
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 1b1d138546c..620b5ef3d75 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -19,6 +19,7 @@
Atomic rename of table; RENAME TABLE t1 to t2, tmp to t1 [,...]
*/
+#include <my_global.h>
#include "sql_priv.h"
#include "unireg.h"
#include "sql_rename.h"
@@ -29,16 +30,19 @@
#include "lock.h" // MYSQL_OPEN_SKIP_TEMPORARY
#include "sql_base.h" // tdc_remove_table, lock_table_names,
#include "sql_handler.h" // mysql_ha_rm_tables
-#include "datadict.h"
+#include "sql_statistics.h"
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
bool skip_error);
+static bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,
+ char *new_table_name, char *new_table_alias,
+ bool skip_error);
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
/*
- Every second entry in the table_list is the original name and every
- second entry is the new name.
+ Every two entries in the table_list form a pair of original name and
+ the new name.
*/
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
@@ -81,12 +85,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
for (to_table= 0, ren_table= table_list; ren_table;
to_table= 1 - to_table, ren_table= ren_table->next_local)
{
- int log_table_rename= 0;
-
- if ((log_table_rename=
- check_if_log_table(ren_table->db_length, ren_table->db,
- ren_table->table_name_length,
- ren_table->table_name, 1)))
+ int log_table_rename;
+ if ((log_table_rename= check_if_log_table(ren_table, TRUE, NullS)))
{
/*
as we use log_table_rename as an array index, we need it to start
@@ -142,13 +142,9 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
}
if (lock_table_names(thd, table_list, 0, thd->variables.lock_wait_timeout,
- MYSQL_OPEN_SKIP_TEMPORARY))
+ 0))
goto err;
- for (ren_table= table_list; ren_table; ren_table= ren_table->next_local)
- tdc_remove_table(thd, TDC_RT_REMOVE_ALL, ren_table->db,
- ren_table->table_name, FALSE);
-
error=0;
/*
An exclusive lock on table names is satisfactory to ensure
@@ -216,6 +212,28 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
}
+static bool
+do_rename_temporary(THD *thd, TABLE_LIST *ren_table, TABLE_LIST *new_table,
+ bool skip_error)
+{
+ const char *new_alias;
+ DBUG_ENTER("do_rename_temporary");
+
+ new_alias= (lower_case_table_names == 2) ? new_table->alias :
+ new_table->table_name;
+
+ if (find_temporary_table(thd, new_table))
+ {
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
+ DBUG_RETURN(1); // This can't be skipped
+ }
+
+
+ DBUG_RETURN(rename_temporary_table(thd, ren_table->table,
+ new_table->db, new_alias));
+}
+
+
/*
Rename a single table or a view
@@ -236,16 +254,13 @@ static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
true rename failed
*/
-bool
+static bool
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
char *new_table_alias, bool skip_error)
{
int rc= 1;
- char new_name[FN_REFLEN + 1], old_name[FN_REFLEN + 1];
+ handlerton *hton;
const char *new_alias, *old_alias;
- frm_type_enum frm_type;
- enum legacy_db_type table_type;
-
DBUG_ENTER("do_rename");
if (lower_case_table_names == 2)
@@ -260,47 +275,49 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
}
DBUG_ASSERT(new_alias);
- build_table_filename(new_name, sizeof(new_name) - 1,
- new_db, new_alias, reg_ext, 0);
- build_table_filename(old_name, sizeof(old_name) - 1,
- ren_table->db, old_alias, reg_ext, 0);
- if (check_table_file_presence(old_name,
- new_name, new_db, new_alias, new_alias, TRUE))
+ if (ha_table_exists(thd, new_db, new_alias))
{
- DBUG_RETURN(1); // This can't be skipped
+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
+ DBUG_RETURN(1); // This can't be skipped
}
- frm_type= dd_frm_type(thd, old_name, &table_type);
- switch (frm_type)
+ if (ha_table_exists(thd, ren_table->db, old_alias, &hton) && hton)
{
- case FRMTYPE_TABLE:
+ DBUG_ASSERT(!thd->locked_tables_mode);
+ tdc_remove_table(thd, TDC_RT_REMOVE_ALL,
+ ren_table->db, ren_table->table_name, false);
+
+ if (hton != view_pseudo_hton)
+ {
+ if (!(rc= mysql_rename_table(hton, ren_table->db, old_alias,
+ new_db, new_alias, 0)))
{
- if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
- table_type),
- ren_table->db, old_alias,
- new_db, new_alias, 0)))
+ LEX_STRING db_name= { ren_table->db, ren_table->db_length };
+ LEX_STRING table_name= { ren_table->table_name,
+ ren_table->table_name_length };
+ LEX_STRING new_table= { (char *) new_alias, strlen(new_alias) };
+ LEX_STRING new_db_name= { (char*)new_db, strlen(new_db)};
+ (void) rename_table_in_stat_tables(thd, &db_name, &table_name,
+ &new_db_name, &new_table);
+ if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
+ old_alias,
+ ren_table->table_name,
+ new_db,
+ new_alias)))
{
- if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
- old_alias,
- ren_table->table_name,
- new_db,
- new_alias)))
- {
- /*
- We've succeeded in renaming table's .frm and in updating
- corresponding handler data, but have failed to update table's
- triggers appropriately. So let us revert operations on .frm
- and handler's data and report about failure to rename table.
- */
- (void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
- table_type),
- new_db, new_alias,
- ren_table->db, old_alias, NO_FK_CHECKS);
- }
+ /*
+ We've succeeded in renaming table's .frm and in updating
+ corresponding handler data, but have failed to update table's
+ triggers appropriately. So let us revert operations on .frm
+ and handler's data and report about failure to rename table.
+ */
+ (void) mysql_rename_table(hton, new_db, new_alias,
+ ren_table->db, old_alias, NO_FK_CHECKS);
}
}
- break;
- case FRMTYPE_VIEW:
+ }
+ else
+ {
/*
change of schema is not allowed
except of ALTER ...UPGRADE DATA DIRECTORY NAME command
@@ -308,23 +325,22 @@ do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
*/
if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE &&
strcmp(ren_table->db, new_db))
- my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
- new_db);
+ my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, new_db);
else
rc= mysql_rename_view(thd, new_db, new_alias, ren_table);
- break;
- default:
- DBUG_ASSERT(0); // should never happen
- case FRMTYPE_ERROR:
- my_error(ER_FILE_NOT_FOUND, MYF(0), old_name, my_errno);
- break;
+ }
+ }
+ else
+ {
+ my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
}
if (rc && !skip_error)
DBUG_RETURN(1);
DBUG_RETURN(0);
-
}
+
+
/*
Rename all tables in list; Return pointer to wrong entry if something goes
wrong. Note that the table_list may be empty!
@@ -359,8 +375,11 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
{
new_table= ren_table->next_local;
- if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
- new_table->alias, skip_error))
+
+ if (is_temporary_table(ren_table) ?
+ do_rename_temporary(thd, ren_table, new_table, skip_error) :
+ do_rename(thd, ren_table, new_table->db, new_table->table_name,
+ new_table->alias, skip_error))
DBUG_RETURN(ren_table);
}
DBUG_RETURN(0);