sql_rename.cc
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:4k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /*
  14.   Atomic rename of table;  RENAME TABLE t1 to t2, tmp to t1 [,...]
  15. */
  16. #include "mysql_priv.h"
  17. static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
  18.  bool skip_error);
  19. /*
  20.   Every second entry in the table_list is the original name and every
  21.   second entry is the new name.
  22. */
  23. bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
  24. {
  25.   bool error=1,got_all_locks=1;
  26.   TABLE_LIST *lock_table,*ren_table=0;
  27.   DBUG_ENTER("mysql_rename_tables");
  28.   
  29.   /* Avoid problems with a rename on a table that we have locked or
  30.      if the user is trying to to do this in a transcation context */
  31.   if (thd->locked_tables || thd->active_transaction())
  32.   {
  33.     my_error(ER_LOCK_OR_ACTIVE_TRANSACTION,MYF(0));
  34.     DBUG_RETURN(1);
  35.   }
  36.       
  37.   VOID(pthread_mutex_lock(&LOCK_open));
  38.   for (lock_table=table_list ; lock_table ; lock_table=lock_table->next)
  39.   {
  40.     int got_lock;
  41.     if ((got_lock=lock_table_name(thd,lock_table)) < 0)
  42.       goto end;
  43.     if (got_lock)
  44.       got_all_locks=0;
  45.   }
  46.   
  47.   if (!got_all_locks && wait_for_locked_table_names(thd,table_list))
  48.     goto end;
  49.   if (!(ren_table=rename_tables(thd,table_list,0)))
  50.     error=0;
  51.   
  52. end:
  53.   if (ren_table)
  54.   {
  55.     /* Rename didn't succeed;  rename back the tables in reverse order */
  56.     TABLE_LIST *prev=0,*table;
  57.     /* Reverse the table list */
  58.     while (table_list)
  59.     {
  60.       TABLE_LIST *next=table_list->next;
  61.       table_list->next=prev;
  62.       prev=table_list;
  63.       table_list=next;
  64.     }
  65.     table_list=prev;
  66.     /* Find the last renamed table */
  67.     for (table=table_list ;
  68.  table->next != ren_table ;
  69.  table=table->next->next) ;
  70.     table=table->next->next; // Skipp error table
  71.     /* Revert to old names */
  72.     rename_tables(thd, table, 1);
  73.     /* Note that lock_table == 0 here, so the unlock loop will work */
  74.   }
  75.   if (!error)
  76.   {
  77.     mysql_update_log.write(thd,thd->query,thd->query_length);
  78.     if (mysql_bin_log.is_open())
  79.     {
  80.       Query_log_event qinfo(thd, thd->query);
  81.       mysql_bin_log.write(&qinfo);
  82.     }
  83.     send_ok(&thd->net);
  84.   }
  85.   for (TABLE_LIST *table=table_list ; table != lock_table ; table=table->next)
  86.     unlock_table_name(thd,table);
  87.   pthread_cond_broadcast(&COND_refresh);
  88.   pthread_mutex_unlock(&LOCK_open);
  89.   DBUG_RETURN(error);
  90. }
  91. /*
  92.   Rename all tables in list; Return pointer to wrong entry if something goes
  93.   wrong.  Note that the table_list may be empty!
  94. */
  95. static TABLE_LIST *
  96. rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
  97. {
  98.   TABLE_LIST *ren_table,*new_table;
  99.   DBUG_ENTER("rename_tables");
  100.   for (ren_table=table_list ; ren_table ; ren_table=new_table->next)
  101.   {
  102.     db_type table_type;
  103.     char name[FN_REFLEN];
  104.     new_table=ren_table->next;
  105.     sprintf(name,"%s/%s/%s%s",mysql_data_home,
  106.     new_table->db,new_table->name,
  107.     reg_ext);
  108.     if (!access(name,F_OK))
  109.     {
  110.       my_error(ER_TABLE_EXISTS_ERROR,MYF(0),name);
  111.       return ren_table; // This can't be skipped
  112.     }
  113.     sprintf(name,"%s/%s/%s%s",mysql_data_home,
  114.     ren_table->db,ren_table->name,
  115.     reg_ext);
  116.     if ((table_type=get_table_type(name)) == DB_TYPE_UNKNOWN)
  117.     {
  118.       my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
  119.       if (!skip_error)
  120. return ren_table;
  121.     }
  122.     else if (mysql_rename_table(table_type,
  123. ren_table->db, ren_table->name,
  124. new_table->db, new_table->name))
  125.     {
  126.       if (!skip_error)
  127. return ren_table;
  128.     }
  129.   }
  130.   DBUG_RETURN(0);
  131. }