1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2009 Sun Microsystems, Inc.
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <drizzled/show.h>
23
#include <drizzled/lock.h>
24
#include <drizzled/session.h>
25
#include <drizzled/statement/rename_table.h>
26
#include "drizzled/sql_table.h"
27
#include "drizzled/pthread_globals.h"
28
#include "drizzled/plugin/storage_engine.h"
33
bool statement::RenameTable::execute()
35
TableList *first_table= (TableList *) getSession()->lex->select_lex.table_list.first;
36
TableList *all_tables= getSession()->lex->query_tables;
37
assert(first_table == all_tables && first_table != 0);
40
if (getSession()->inTransaction())
42
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
46
for (table= first_table; table; table= table->next_local->next_local)
48
TableList old_list, new_list;
50
we do not need initialize old_list and new_list because we will
51
come table[0] and table->next[0] there
54
new_list= table->next_local[0];
57
if (renameTables(first_table))
65
bool statement::RenameTable::renameTables(TableList *table_list)
68
TableList *ren_table= NULL;
71
Avoid problems with a rename on a table that we have locked or
72
if the user is trying to to do this in a transcation context
74
if (getSession()->inTransaction())
76
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
80
if (getSession()->wait_if_global_read_lock(false, true))
84
boost::mutex::scoped_lock scopedLock(table::Cache::singleton().mutex()); /* Rename table lock for exclusive access */
86
if (not getSession()->lock_table_names_exclusively(table_list))
89
ren_table= renameTablesInList(table_list, false);
93
/* Rename didn't succeed; rename back the tables in reverse order */
96
/* Reverse the table list */
97
table_list= reverseTableList(table_list);
99
/* Find the last renamed table */
100
for (table= table_list;
101
table->next_local != ren_table;
102
table= table->next_local->next_local)
105
table= table->next_local->next_local; // Skip error table
107
/* Revert to old names */
108
renameTablesInList(table, true);
112
table_list->unlock_table_names();
116
/* Lets hope this doesn't fail as the result will be messy */
119
write_bin_log(getSession(), *getSession()->getQueryString());
120
getSession()->my_ok();
123
getSession()->startWaitingGlobalReadLock();
128
TableList *statement::RenameTable::reverseTableList(TableList *table_list)
130
TableList *prev= NULL;
134
TableList *next= table_list->next_local;
135
table_list->next_local= prev;
142
bool statement::RenameTable::rename(TableList *ren_table,
144
const char *new_table_name,
148
const char *new_alias, *old_alias;
151
old_alias= ren_table->getTableName();
152
new_alias= new_table_name;
155
plugin::StorageEngine *engine= NULL;
156
message::table::shared_ptr table_proto;
158
identifier::Table old_identifier(ren_table->getSchemaName(), old_alias, message::Table::STANDARD);
160
if (plugin::StorageEngine::getTableDefinition(*getSession(), old_identifier, table_proto) != EEXIST)
162
my_error(ER_TABLE_UNKNOWN, old_identifier);
166
engine= plugin::StorageEngine::findByName(*getSession(), table_proto->engine().name());
168
identifier::Table new_identifier(new_db, new_alias, message::Table::STANDARD);
169
if (plugin::StorageEngine::doesTableExist(*getSession(), new_identifier))
171
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
172
return 1; // This can't be skipped
175
rc= rename_table(*getSession(), engine, old_identifier, new_identifier);
176
if (rc && ! skip_error)
182
TableList *statement::RenameTable::renameTablesInList(TableList *table_list,
185
TableList *ren_table, *new_table;
187
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
189
new_table= ren_table->next_local;
190
if (rename(ren_table, new_table->getSchemaName(), new_table->getTableName(), skip_error))
196
} /* namespace drizzled */