00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*- 00002 * vim:expandtab:shiftwidth=2:tabstop=2:smarttab: 00003 * 00004 * Copyright (C) 2009 Sun Microsystems, Inc. 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <config.h> 00022 #include <drizzled/show.h> 00023 #include <drizzled/session.h> 00024 #include <drizzled/lock.h> 00025 #include <drizzled/statement/drop_table.h> 00026 #include <drizzled/sql_table.h> 00027 #include <drizzled/sql_lex.h> 00028 00029 namespace drizzled 00030 { 00031 00032 00033 /* 00034 delete (drop) tables. 00035 00036 SYNOPSIS 00037 rm_table() 00038 session Thread handle 00039 tables List of tables to delete 00040 if_exists If 1, don't give error if one table doesn't exists 00041 00042 NOTES 00043 Will delete all tables that can be deleted and give a compact error 00044 messages for tables that could not be deleted. 00045 If a table is in use, we will wait for all users to free the table 00046 before dropping it 00047 00048 Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set, but 00049 not if under LOCK TABLES. 00050 00051 RETURN 00052 false OK. In this case ok packet is sent to user 00053 true Error 00054 00055 */ 00056 00057 static bool rm_table(Session *session, TableList *tables, bool if_exists, bool drop_temporary) 00058 { 00059 bool error, need_start_waiting= false; 00060 00061 /* mark for close and remove all cached entries */ 00062 00063 if (not drop_temporary) 00064 { 00065 if (not (need_start_waiting= not session->wait_if_global_read_lock(false, true))) 00066 return true; 00067 } 00068 00069 /* 00070 Acquire table::Cache::singleton().mutex() after wait_if_global_read_lock(). If we would hold 00071 table::Cache::singleton().mutex() during wait_if_global_read_lock(), other threads could not 00072 close their tables. This would make a pretty deadlock. 00073 */ 00074 error= rm_table_part2(session, tables, if_exists, drop_temporary); 00075 00076 if (need_start_waiting) 00077 { 00078 session->startWaitingGlobalReadLock(); 00079 } 00080 00081 if (error) 00082 return true; 00083 00084 session->my_ok(); 00085 00086 return false; 00087 } 00088 00089 bool statement::DropTable::execute() 00090 { 00091 TableList *first_table= (TableList *) lex().select_lex.table_list.first; 00092 TableList *all_tables= lex().query_tables; 00093 assert(first_table == all_tables && first_table != 0); 00094 00095 if (not drop_temporary) 00096 { 00097 if (session().inTransaction()) 00098 { 00099 my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0)); 00100 return true; 00101 } 00102 } 00103 00104 /* DDL and binlog write order protected by table::Cache::singleton().mutex() */ 00105 00106 return rm_table(&session(), first_table, drop_if_exists, drop_temporary); 00107 } 00108 00109 } /* namespace drizzled */