2006-12-31 01:02:27 +01:00
|
|
|
/* Copyright (C) 2000-2006 MySQL AB
|
2000-08-21 02:07:54 +02:00
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
2006-12-23 20:17:15 +01:00
|
|
|
the Free Software Foundation; version 2 of the License.
|
2000-08-21 02:07:54 +02:00
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
|
|
|
|
/*
|
|
|
|
Atomic rename of table; RENAME TABLE t1 to t2, tmp to t1 [,...]
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "mysql_priv.h"
|
2006-02-24 21:50:36 +01:00
|
|
|
#include "sql_trigger.h"
|
2000-08-21 02:07:54 +02:00
|
|
|
|
|
|
|
|
2000-08-21 23:18:32 +02:00
|
|
|
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
|
|
|
|
bool skip_error);
|
2000-08-21 02:07:54 +02:00
|
|
|
|
2004-04-05 23:10:43 +02:00
|
|
|
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
|
|
|
|
|
2000-08-21 02:07:54 +02:00
|
|
|
/*
|
|
|
|
Every second entry in the table_list is the original name and every
|
|
|
|
second entry is the new name.
|
|
|
|
*/
|
|
|
|
|
2006-02-13 08:49:28 +01:00
|
|
|
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
|
2000-08-21 02:07:54 +02:00
|
|
|
{
|
2003-03-04 12:36:59 +01:00
|
|
|
bool error= 1;
|
2010-01-24 08:03:23 +01:00
|
|
|
bool binlog_error= 0;
|
2006-11-30 02:40:42 +01:00
|
|
|
TABLE_LIST *ren_table= 0;
|
Fix for Bug #17544 "Cannot do atomic log rotate",
Bug #21785 "Server crashes after rename of the log table" and
Bug #21966 "Strange warnings on create like/repair of the log
tables"
According to the patch, from now on, one should use RENAME to
perform a log table rotation (this should also be reflected in
the manual).
Here is a sample:
use mysql;
CREATE TABLE IF NOT EXISTS general_log2 LIKE general_log;
RENAME TABLE general_log TO general_log_backup, general_log2 TO general_log;
The rules for Rename of the log tables are following:
IF 1. Log tables are enabled
AND 2. Rename operates on the log table and nothing is being
renamed to the log table.
DO 3. Throw an error message.
ELSE 4. Perform rename.
The very RENAME query will go the the old (backup) table. This is
consistent with the behavoiur we have with binlog ROTATE LOGS
statement.
Other problems, which are solved by the patch are:
1) Now REPAIR of the log table is exclusive operation (as it should be), this
also eliminates lock-related warnings. and
2) CREATE LIKE TABLE now usese usual read lock on the source table rather
then name lock, which is too restrictive. This way we get rid of another
log table-related warning, which occured because of the above fact
(as a side-effect, name lock resulted in a warning).
mysql-test/r/log_tables.result:
update result file
mysql-test/t/log_tables.test:
Add tests for the bugs
sql/handler.cc:
update comment
sql/handler.h:
update function to reflect changes in log tables
locking logic.
sql/lock.cc:
Now we allow locking of the log tables for "privileged" threads
Privileged thread must explicitly close and lock log tables. This
is required for admin operations such as REPAIR.
sql/log.cc:
Changes to the file:
1) Add checks for table schema. It's more important now,
as we allow rename of the log tables. Since we should
check for schema when writing to a log table.
E.g. if one created a table with one-only comlumn and
renamed it to general_log, the server should cope with
it.
2) refactor LOGGER::flush(), so that we can now use the same
machinery as we use in FLUSH LOGS in other statements:
whenever we have to perform a serious operation on the log
tables, we have to
(a) lock logger, which blocks other concurrent statements (such
as selects) (b) close logs. Then perform an
exclusive operation, c) reenable logs and d) unlock logger.
3) Add a function to check if a given table is a log table.
4) Add support for "privileged" thread
5) merge is_[general/slow]_log_table_enabled() into one function.
6) Add new function: reopen _log_tables, which reopens the tables,
which were enabled (after temporary close, required for admin
operation)
sql/log.h:
1) add a new call close_n_lock_tables(). Now we use it instead of
LOGGER::flush() in FLUSH LOGS implementation.
2) add a prototype for the function to check if a given
table is a log table;
3) add privileged table flag to table logger
4) merge is_[general/slow]_log_table_enabled()
into one function.
sql/mysql_priv.h:
move log table defines to log.h
sql/sql_delete.cc:
use new function check_if_log_table() instead of direct strcmp
sql/sql_rename.cc:
Traverse the list of tables in mysql_rename_tables
to make sure that log tables are processed correctly
(that is, according to the rules specified in the
main CS comment)
sql/sql_table.cc:
1) mysql_admin_table() should disable logs if it performs
exclusive admin operation on a log table. This way we
also eliminate warning on REPAIR of the log table.
2) mysql_create_like_table should read-lock the source table
instead getting name lock on it. Name lock is too restrictive
in this case.
sql/share/errmsg.txt:
Add a new error message for rename of the log tables
sql/table.cc:
use new function instead of direct strcmp.
change my_strcasecmp() -> strcmp(), when
comparing system db and table names
storage/csv/ha_tina.cc:
update function to reflect changes in log tables
locking logic.
storage/myisam/ha_myisam.cc:
update function to reflect changes in log tables
locking logic.
2006-10-13 15:26:46 +02:00
|
|
|
int to_table;
|
|
|
|
char *rename_log_table[2]= {NULL, NULL};
|
2000-08-21 02:07:54 +02:00
|
|
|
DBUG_ENTER("mysql_rename_tables");
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2002-01-30 14:32:48 +01:00
|
|
|
/*
|
|
|
|
Avoid problems with a rename on a table that we have locked or
|
|
|
|
if the user is trying to to do this in a transcation context
|
|
|
|
*/
|
2000-08-21 02:07:54 +02:00
|
|
|
|
|
|
|
if (thd->locked_tables || thd->active_transaction())
|
|
|
|
{
|
2004-11-12 13:34:00 +01:00
|
|
|
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
|
|
|
|
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
|
2000-08-21 02:07:54 +02:00
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
2001-12-06 13:10:51 +01:00
|
|
|
|
2007-11-29 12:42:26 +01:00
|
|
|
mysql_ha_rm_tables(thd, table_list, FALSE);
|
2007-11-20 18:17:53 +01:00
|
|
|
|
2004-08-20 22:54:42 +02:00
|
|
|
if (wait_if_global_read_lock(thd,0,1))
|
2004-04-01 19:47:09 +02:00
|
|
|
DBUG_RETURN(1);
|
Fix for Bug #17544 "Cannot do atomic log rotate",
Bug #21785 "Server crashes after rename of the log table" and
Bug #21966 "Strange warnings on create like/repair of the log
tables"
According to the patch, from now on, one should use RENAME to
perform a log table rotation (this should also be reflected in
the manual).
Here is a sample:
use mysql;
CREATE TABLE IF NOT EXISTS general_log2 LIKE general_log;
RENAME TABLE general_log TO general_log_backup, general_log2 TO general_log;
The rules for Rename of the log tables are following:
IF 1. Log tables are enabled
AND 2. Rename operates on the log table and nothing is being
renamed to the log table.
DO 3. Throw an error message.
ELSE 4. Perform rename.
The very RENAME query will go the the old (backup) table. This is
consistent with the behavoiur we have with binlog ROTATE LOGS
statement.
Other problems, which are solved by the patch are:
1) Now REPAIR of the log table is exclusive operation (as it should be), this
also eliminates lock-related warnings. and
2) CREATE LIKE TABLE now usese usual read lock on the source table rather
then name lock, which is too restrictive. This way we get rid of another
log table-related warning, which occured because of the above fact
(as a side-effect, name lock resulted in a warning).
mysql-test/r/log_tables.result:
update result file
mysql-test/t/log_tables.test:
Add tests for the bugs
sql/handler.cc:
update comment
sql/handler.h:
update function to reflect changes in log tables
locking logic.
sql/lock.cc:
Now we allow locking of the log tables for "privileged" threads
Privileged thread must explicitly close and lock log tables. This
is required for admin operations such as REPAIR.
sql/log.cc:
Changes to the file:
1) Add checks for table schema. It's more important now,
as we allow rename of the log tables. Since we should
check for schema when writing to a log table.
E.g. if one created a table with one-only comlumn and
renamed it to general_log, the server should cope with
it.
2) refactor LOGGER::flush(), so that we can now use the same
machinery as we use in FLUSH LOGS in other statements:
whenever we have to perform a serious operation on the log
tables, we have to
(a) lock logger, which blocks other concurrent statements (such
as selects) (b) close logs. Then perform an
exclusive operation, c) reenable logs and d) unlock logger.
3) Add a function to check if a given table is a log table.
4) Add support for "privileged" thread
5) merge is_[general/slow]_log_table_enabled() into one function.
6) Add new function: reopen _log_tables, which reopens the tables,
which were enabled (after temporary close, required for admin
operation)
sql/log.h:
1) add a new call close_n_lock_tables(). Now we use it instead of
LOGGER::flush() in FLUSH LOGS implementation.
2) add a prototype for the function to check if a given
table is a log table;
3) add privileged table flag to table logger
4) merge is_[general/slow]_log_table_enabled()
into one function.
sql/mysql_priv.h:
move log table defines to log.h
sql/sql_delete.cc:
use new function check_if_log_table() instead of direct strcmp
sql/sql_rename.cc:
Traverse the list of tables in mysql_rename_tables
to make sure that log tables are processed correctly
(that is, according to the rules specified in the
main CS comment)
sql/sql_table.cc:
1) mysql_admin_table() should disable logs if it performs
exclusive admin operation on a log table. This way we
also eliminate warning on REPAIR of the log table.
2) mysql_create_like_table should read-lock the source table
instead getting name lock on it. Name lock is too restrictive
in this case.
sql/share/errmsg.txt:
Add a new error message for rename of the log tables
sql/table.cc:
use new function instead of direct strcmp.
change my_strcasecmp() -> strcmp(), when
comparing system db and table names
storage/csv/ha_tina.cc:
update function to reflect changes in log tables
locking logic.
storage/myisam/ha_myisam.cc:
update function to reflect changes in log tables
locking logic.
2006-10-13 15:26:46 +02:00
|
|
|
|
|
|
|
if (logger.is_log_table_enabled(QUERY_LOG_GENERAL) ||
|
|
|
|
logger.is_log_table_enabled(QUERY_LOG_SLOW))
|
|
|
|
{
|
|
|
|
|
|
|
|
/*
|
|
|
|
Rules for rename of a log table:
|
|
|
|
|
|
|
|
IF 1. Log tables are enabled
|
|
|
|
AND 2. Rename operates on the log table and nothing is being
|
|
|
|
renamed to the log table.
|
|
|
|
DO 3. Throw an error message.
|
|
|
|
ELSE 4. Perform rename.
|
|
|
|
*/
|
|
|
|
|
|
|
|
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)))
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
as we use log_table_rename as an array index, we need it to start
|
|
|
|
with 0, while QUERY_LOG_SLOW == 1 and QUERY_LOG_GENERAL == 2.
|
|
|
|
So, we shift the value to start with 0;
|
|
|
|
*/
|
|
|
|
log_table_rename--;
|
|
|
|
if (rename_log_table[log_table_rename])
|
|
|
|
{
|
|
|
|
if (to_table)
|
|
|
|
rename_log_table[log_table_rename]= NULL;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Two renames of "log_table TO" w/o rename "TO log_table" in
|
|
|
|
between.
|
|
|
|
*/
|
|
|
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
|
|
|
|
ren_table->table_name);
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (to_table)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Attempt to rename a table TO log_table w/o renaming
|
|
|
|
log_table TO some table.
|
|
|
|
*/
|
|
|
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), ren_table->table_name,
|
|
|
|
ren_table->table_name);
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* save the name of the log table to report an error */
|
|
|
|
rename_log_table[log_table_rename]= ren_table->table_name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (rename_log_table[0] || rename_log_table[1])
|
|
|
|
{
|
|
|
|
if (rename_log_table[0])
|
|
|
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[0],
|
|
|
|
rename_log_table[0]);
|
|
|
|
else
|
|
|
|
my_error(ER_CANT_RENAME_LOG_TABLE, MYF(0), rename_log_table[1],
|
|
|
|
rename_log_table[1]);
|
|
|
|
DBUG_RETURN(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-02 19:14:48 +02:00
|
|
|
pthread_mutex_lock(&LOCK_open);
|
|
|
|
if (lock_table_names_exclusively(thd, table_list))
|
|
|
|
{
|
|
|
|
pthread_mutex_unlock(&LOCK_open);
|
2003-03-03 19:42:49 +01:00
|
|
|
goto err;
|
2007-07-02 19:14:48 +02:00
|
|
|
}
|
|
|
|
|
2003-03-04 12:36:59 +01:00
|
|
|
error=0;
|
2003-03-03 19:42:49 +01:00
|
|
|
if ((ren_table=rename_tables(thd,table_list,0)))
|
2000-08-21 02:07:54 +02:00
|
|
|
{
|
|
|
|
/* Rename didn't succeed; rename back the tables in reverse order */
|
2004-04-05 23:10:43 +02:00
|
|
|
TABLE_LIST *table;
|
2000-08-21 23:18:32 +02:00
|
|
|
|
2004-04-05 23:10:43 +02:00
|
|
|
/* Reverse the table list */
|
|
|
|
table_list= reverse_table_list(table_list);
|
2000-08-21 02:07:54 +02:00
|
|
|
|
|
|
|
/* Find the last renamed table */
|
2004-07-16 00:15:55 +02:00
|
|
|
for (table= table_list;
|
|
|
|
table->next_local != ren_table ;
|
|
|
|
table= table->next_local->next_local) ;
|
|
|
|
table= table->next_local->next_local; // Skip error table
|
2000-08-21 02:07:54 +02:00
|
|
|
/* Revert to old names */
|
2000-08-21 23:18:32 +02:00
|
|
|
rename_tables(thd, table, 1);
|
2004-04-05 23:10:43 +02:00
|
|
|
|
|
|
|
/* Revert the table list (for prepared statements) */
|
|
|
|
table_list= reverse_table_list(table_list);
|
|
|
|
|
2003-03-03 19:42:49 +01:00
|
|
|
error= 1;
|
2000-08-21 02:07:54 +02:00
|
|
|
}
|
2007-07-16 13:57:20 +02:00
|
|
|
/*
|
|
|
|
An exclusive lock on table names is satisfactory to ensure
|
|
|
|
no other thread accesses this table.
|
|
|
|
However, NDB assumes that handler::rename_tables is called under
|
|
|
|
LOCK_open. And it indeed is, from ALTER TABLE.
|
|
|
|
TODO: remove this limitation.
|
|
|
|
We still should unlock LOCK_open as early as possible, to provide
|
|
|
|
higher concurrency - query_cache_invalidate can take minutes to
|
|
|
|
complete.
|
|
|
|
*/
|
|
|
|
pthread_mutex_unlock(&LOCK_open);
|
2001-03-21 21:34:16 +01:00
|
|
|
|
2006-02-13 08:49:28 +01:00
|
|
|
if (!silent && !error)
|
2000-08-21 02:07:54 +02:00
|
|
|
{
|
2010-01-24 08:03:23 +01:00
|
|
|
binlog_error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
|
|
|
|
if (!binlog_error)
|
|
|
|
my_ok(thd);
|
2000-08-21 02:07:54 +02:00
|
|
|
}
|
2001-03-21 21:34:16 +01:00
|
|
|
|
2007-07-02 19:14:48 +02:00
|
|
|
if (!error)
|
|
|
|
query_cache_invalidate3(thd, table_list, 0);
|
|
|
|
|
|
|
|
pthread_mutex_lock(&LOCK_open);
|
2005-03-16 15:11:01 +01:00
|
|
|
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
|
2007-07-02 19:14:48 +02:00
|
|
|
pthread_mutex_unlock(&LOCK_open);
|
2003-03-03 19:42:49 +01:00
|
|
|
|
|
|
|
err:
|
2004-04-01 19:47:09 +02:00
|
|
|
start_waiting_global_read_lock(thd);
|
2010-01-24 08:03:23 +01:00
|
|
|
DBUG_RETURN(error || binlog_error);
|
2000-08-21 02:07:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-04-05 23:10:43 +02:00
|
|
|
/*
|
|
|
|
reverse table list
|
|
|
|
|
|
|
|
SYNOPSIS
|
|
|
|
reverse_table_list()
|
|
|
|
table_list pointer to table _list
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
pointer to new (reversed) list
|
|
|
|
*/
|
|
|
|
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
|
|
|
|
{
|
|
|
|
TABLE_LIST *prev= 0;
|
|
|
|
|
|
|
|
while (table_list)
|
|
|
|
{
|
2004-07-16 00:15:55 +02:00
|
|
|
TABLE_LIST *next= table_list->next_local;
|
|
|
|
table_list->next_local= prev;
|
2004-04-05 23:10:43 +02:00
|
|
|
prev= table_list;
|
|
|
|
table_list= next;
|
|
|
|
}
|
|
|
|
return (prev);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-08-21 02:07:54 +02:00
|
|
|
/*
|
2006-10-13 19:59:52 +02:00
|
|
|
Rename a single table or a view
|
|
|
|
|
|
|
|
SYNPOSIS
|
|
|
|
do_rename()
|
|
|
|
thd Thread handle
|
|
|
|
ren_table A table/view to be renamed
|
|
|
|
new_db The database to which the table to be moved to
|
|
|
|
new_table_name The new table/view name
|
|
|
|
new_table_alias The new table/view alias
|
|
|
|
skip_error Whether to skip error
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Rename a single table or a view.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
false Ok
|
|
|
|
true rename failed
|
2000-08-21 02:07:54 +02:00
|
|
|
*/
|
|
|
|
|
2006-10-13 19:59:52 +02:00
|
|
|
bool
|
|
|
|
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
|
|
|
|
char *new_table_alias, bool skip_error)
|
2000-08-21 02:07:54 +02:00
|
|
|
{
|
2006-10-13 19:59:52 +02:00
|
|
|
int rc= 1;
|
2009-06-19 10:24:43 +02:00
|
|
|
char name[FN_REFLEN + 1];
|
2006-10-13 19:59:52 +02:00
|
|
|
const char *new_alias, *old_alias;
|
2005-09-16 17:13:21 +02:00
|
|
|
frm_type_enum frm_type;
|
2005-12-21 19:18:40 +01:00
|
|
|
enum legacy_db_type table_type;
|
2005-11-03 15:10:11 +01:00
|
|
|
|
2006-10-13 19:59:52 +02:00
|
|
|
DBUG_ENTER("do_rename");
|
2000-08-21 23:18:32 +02:00
|
|
|
|
2006-10-13 19:59:52 +02:00
|
|
|
if (lower_case_table_names == 2)
|
2000-08-21 02:07:54 +02:00
|
|
|
{
|
2006-10-13 19:59:52 +02:00
|
|
|
old_alias= ren_table->alias;
|
|
|
|
new_alias= new_table_alias;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
old_alias= ren_table->table_name;
|
2006-10-20 10:12:38 +02:00
|
|
|
new_alias= new_table_name;
|
2006-10-13 19:59:52 +02:00
|
|
|
}
|
2009-05-19 06:25:36 +02:00
|
|
|
DBUG_ASSERT(new_alias);
|
|
|
|
|
2009-06-19 10:24:43 +02:00
|
|
|
build_table_filename(name, sizeof(name) - 1,
|
2006-10-19 16:43:46 +02:00
|
|
|
new_db, new_alias, reg_ext, 0);
|
2006-10-13 19:59:52 +02:00
|
|
|
if (!access(name,F_OK))
|
|
|
|
{
|
|
|
|
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
|
2006-10-17 22:14:14 +02:00
|
|
|
DBUG_RETURN(1); // This can't be skipped
|
2006-10-13 19:59:52 +02:00
|
|
|
}
|
2009-06-19 10:24:43 +02:00
|
|
|
build_table_filename(name, sizeof(name) - 1,
|
2006-10-19 16:43:46 +02:00
|
|
|
ren_table->db, old_alias, reg_ext, 0);
|
2005-09-18 21:43:28 +02:00
|
|
|
|
2006-10-13 19:59:52 +02:00
|
|
|
frm_type= mysql_frm_type(thd, name, &table_type);
|
|
|
|
switch (frm_type)
|
|
|
|
{
|
|
|
|
case FRMTYPE_TABLE:
|
2005-09-16 17:13:21 +02:00
|
|
|
{
|
2006-10-20 10:12:38 +02:00
|
|
|
if (!(rc= mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
|
|
|
table_type),
|
|
|
|
ren_table->db, old_alias,
|
|
|
|
new_db, new_alias, 0)))
|
2006-02-24 21:50:36 +01:00
|
|
|
{
|
2006-10-13 19:59:52 +02:00
|
|
|
if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
|
|
|
|
old_alias,
|
|
|
|
new_db,
|
|
|
|
new_alias)))
|
2006-02-24 21:50:36 +01:00
|
|
|
{
|
2006-10-13 19:59:52 +02:00
|
|
|
/*
|
|
|
|
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.
|
|
|
|
*/
|
2006-10-19 16:43:46 +02:00
|
|
|
(void) mysql_rename_table(ha_resolve_by_legacy_type(thd,
|
|
|
|
table_type),
|
|
|
|
new_db, new_alias,
|
|
|
|
ren_table->db, old_alias, 0);
|
2006-02-24 21:50:36 +01:00
|
|
|
}
|
|
|
|
}
|
2005-09-16 17:13:21 +02:00
|
|
|
}
|
2006-10-13 19:59:52 +02:00
|
|
|
break;
|
|
|
|
case FRMTYPE_VIEW:
|
2009-04-10 11:25:48 +02:00
|
|
|
/*
|
|
|
|
change of schema is not allowed
|
|
|
|
except of ALTER ...UPGRADE DATA DIRECTORY NAME command
|
|
|
|
because a view has valid internal db&table names in this case.
|
|
|
|
*/
|
|
|
|
if (thd->lex->sql_command != SQLCOM_ALTER_DB_UPGRADE &&
|
|
|
|
strcmp(ren_table->db, new_db))
|
2006-10-13 19:59:52 +02:00
|
|
|
my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db,
|
|
|
|
new_db);
|
|
|
|
else
|
2009-04-13 15:09:10 +02:00
|
|
|
rc= mysql_rename_view(thd, new_db, new_alias, ren_table);
|
2006-10-13 19:59:52 +02:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
DBUG_ASSERT(0); // should never happen
|
|
|
|
case FRMTYPE_ERROR:
|
|
|
|
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
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!
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Rename tables/views in the list
|
|
|
|
|
|
|
|
SYNPOSIS
|
|
|
|
rename_tables()
|
|
|
|
thd Thread handle
|
|
|
|
table_list List of tables to rename
|
|
|
|
skip_error Whether to skip errors
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
Take a table/view name from and odd list element and rename it to a
|
|
|
|
the name taken from list element+1. Note that the table_list may be
|
|
|
|
empty.
|
|
|
|
|
|
|
|
RETURN
|
|
|
|
false Ok
|
|
|
|
true rename failed
|
|
|
|
*/
|
|
|
|
|
|
|
|
static TABLE_LIST *
|
|
|
|
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
|
|
|
{
|
2006-11-30 17:25:05 +01:00
|
|
|
TABLE_LIST *ren_table, *new_table;
|
2006-10-13 19:59:52 +02:00
|
|
|
|
|
|
|
DBUG_ENTER("rename_tables");
|
|
|
|
|
|
|
|
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))
|
2005-09-18 21:43:28 +02:00
|
|
|
DBUG_RETURN(ren_table);
|
2000-08-21 02:07:54 +02:00
|
|
|
}
|
2000-08-21 23:18:32 +02:00
|
|
|
DBUG_RETURN(0);
|
2000-08-21 02:07:54 +02:00
|
|
|
}
|