18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
#include <drizzled/server_includes.h>
22
22
#include <drizzled/show.h>
23
23
#include <drizzled/lock.h>
24
24
#include <drizzled/session.h>
25
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
30
bool statement::RenameTable::execute()
35
TableList *first_table= (TableList *) getSession()->getLex()->select_lex.table_list.first;
36
TableList *all_tables= getSession()->getLex()->query_tables;
32
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
33
TableList *all_tables= session->lex->query_tables;
37
34
assert(first_table == all_tables && first_table != 0);
40
if (getSession()->inTransaction())
42
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
46
36
for (table= first_table; table; table= table->next_local->next_local)
48
38
TableList old_list, new_list;
71
60
Avoid problems with a rename on a table that we have locked or
72
61
if the user is trying to to do this in a transcation context
74
if (getSession()->inTransaction())
63
if (session->inTransaction())
76
65
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))
69
if (wait_if_global_read_lock(session, 0, 1))
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();
72
pthread_mutex_lock(&LOCK_open); /* Rename table lock for exclusive access */
73
if (lock_table_names_exclusively(session, table_list))
75
pthread_mutex_unlock(&LOCK_open);
80
ren_table= renameTablesInList(table_list, 0);
83
/* Rename didn't succeed; rename back the tables in reverse order */
86
/* Reverse the table list */
87
table_list= reverseTableList(table_list);
89
/* Find the last renamed table */
90
for (table= table_list;
91
table->next_local != ren_table;
92
table= table->next_local->next_local)
94
table= table->next_local->next_local; // Skip error table
95
/* Revert to old names */
96
renameTablesInList(table, 1);
100
An exclusive lock on table names is satisfactory to ensure
101
no other thread accesses this table.
102
We still should unlock LOCK_open as early as possible, to provide
103
higher concurrency - query_cache_invalidate can take minutes to
106
pthread_mutex_unlock(&LOCK_open);
116
108
/* Lets hope this doesn't fail as the result will be messy */
119
write_bin_log(getSession(), *getSession()->getQueryString());
120
getSession()->my_ok();
111
write_bin_log(session, true, session->query, session->query_length);
123
getSession()->startWaitingGlobalReadLock();
115
pthread_mutex_lock(&LOCK_open); /* unlock all tables held */
116
unlock_table_names(table_list, NULL);
117
pthread_mutex_unlock(&LOCK_open);
120
start_waiting_global_read_lock(session);
148
145
const char *new_alias, *old_alias;
151
old_alias= ren_table->getTableName();
148
old_alias= ren_table->table_name;
152
149
new_alias= new_table_name;
155
152
plugin::StorageEngine *engine= NULL;
156
message::table::shared_ptr table_message;
158
identifier::Table old_identifier(ren_table->getSchemaName(), old_alias, message::Table::STANDARD);
160
if (not (table_message= plugin::StorageEngine::getTableMessage(*getSession(), old_identifier)))
153
message::Table table_proto;
154
char path[FN_REFLEN];
157
length= build_table_filename(path, sizeof(path),
158
ren_table->db, old_alias, false);
160
if (plugin::StorageEngine::getTableProto(path, &table_proto) != EEXIST)
162
my_error(ER_TABLE_UNKNOWN, old_identifier);
162
my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
166
engine= plugin::StorageEngine::findByName(*getSession(), table_message->engine().name());
168
identifier::Table new_identifier(new_db, new_alias, message::Table::STANDARD);
169
if (plugin::StorageEngine::doesTableExist(*getSession(), new_identifier))
166
engine= plugin::StorageEngine::findByName(session, table_proto.engine().name());
168
length= build_table_filename(path, sizeof(path),
169
new_db, new_alias, false);
171
if (plugin::StorageEngine::getTableProto(path, NULL) != ENOENT)
171
my_error(ER_TABLE_EXISTS_ERROR, new_identifier);
173
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
172
174
return 1; // This can't be skipped
175
rc= rename_table(*getSession(), engine, old_identifier, new_identifier);
177
rc= mysql_rename_table(engine,
178
ren_table->db, old_alias,
179
new_db, new_alias, 0);
176
180
if (rc && ! skip_error)
187
191
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
189
193
new_table= ren_table->next_local;
190
if (rename(ren_table, new_table->getSchemaName(), new_table->getTableName(), skip_error))
194
if (rename(ren_table, new_table->db, new_table->table_name, skip_error))
191
195
return ren_table;
196
200
} /* namespace drizzled */