diff options
author | unknown <monty@donna.mysql.com> | 2000-08-21 03:07:54 +0300 |
---|---|---|
committer | unknown <monty@donna.mysql.com> | 2000-08-21 03:07:54 +0300 |
commit | 90bc6094eed4bde988bad568ac48bd686a127639 (patch) | |
tree | 379a5a06cf55a36b2e0e00d4285abc1b28e666d7 /sql/sql_rename.cc | |
parent | 2019201ba6e950ef5167869da707112897218745 (diff) | |
download | mariadb-git-90bc6094eed4bde988bad568ac48bd686a127639.tar.gz |
Merge of last changes
sql/ChangeLog:
Update of last changes
sql/mysql_priv.h:
RENAME TABLE
sql/sql_parse.cc:
RENAME TABLE ; MORE Access checks; Faster alloc
Diffstat (limited to 'sql/sql_rename.cc')
-rw-r--r-- | sql/sql_rename.cc | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc new file mode 100644 index 00000000000..ac7b0bbdc41 --- /dev/null +++ b/sql/sql_rename.cc @@ -0,0 +1,132 @@ +/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + 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" + + +static TABLE_LIST *mysql_rename_tables(THD *thd, TABLE_LIST *table_list, + bool skip_error); + +/* + Every second entry in the table_list is the original name and every + second entry is the new name. +*/ + +bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) +{ + bool error=1,got_all_locks=1; + db_type table_type; + TABLE_LIST *lock_table,*ren_table=0,*new_table; + DBUG_ENTER("mysql_rename_tables"); + + /* 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 */ + + if (thd->locked_tables || thd->active_transaction()) + { + my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0)); + DBUG_RETURN(1); + } + + VOID(pthread_mutex_lock(&LOCK_open)); + for (lock_table=table_list ; lock_table ; lock_table=lock_table->next) + { + int got_lock; + if ((got_lock=lock_table_name(thd,lock_table)) < 0) + goto end; + if (got_lock) + got_all_locks=0; + } + + if (!got_all_locks && wait_for_locked_table_names(thd,table_list)) + goto end; + + if (!(ren_table=mysql_rename_tables(thd,table_list,0))) + error=0; + +end: + if (ren_table) + { + /* Rename didn't succeed; rename back the tables in reverse order */ + TABLE_LIST *prev=0,*table; + /* + Reverse the table list ; Note that we need to handle the case that + every second entry must stay in place in respect to the previous + */ + while (table_list) + { + TABLE_LIST *next=table_list->next->next; + table_list->next->next=prev; + prev=table_list; + table_list=next; + } + table_list=prev; + + /* Find the last renamed table */ + for (table=table_list ; table->next != ren_table ; + table=table->next->next) ; + table=table->next->next; // Skipp error table + /* Revert to old names */ + mysql_rename_tables(thd, table, 1); + /* Note that lock_table == 0 here, so the unlock loop will work */ + } + if (!error) + { + mysql_update_log.write(thd->query,thd->query_length); + Query_log_event qinfo(thd, thd->query); + mysql_bin_log.write(&qinfo); + } + for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next) + unlock_table_name(thd,table); + pthread_cond_broadcast(&COND_refresh); + pthread_mutex_unlock(&LOCK_open); + DBUG_RETURN(error); +} + + +/* + Rename all tables in list; Return pointer to wrong entry if something goes + wrong. +*/ + +static TABLE_LIST * +mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error) +{ + TABLE_LIST *ren_table; + for (ren_table=table_list ; ren_table ; ren_table=ren_table->next) + { + db_type table_type; + char name[FN_REFLEN]; + TABLE_LIST *new_table=ren_table->next; + + sprintf(name,"%s/%s/%s%s",mysql_data_home, + ren_table->db,ren_table->name, + reg_ext); + if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN || + mysql_rename_table(table_type, + ren_table->db, ren_table->name, + new_table->db, new_table->name)) + { + if (!skip_error) + return ren_table; + } + } + return 0; +} |