18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
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/pthread_globals.h>
27
#include <drizzled/plugin/storage_engine.h>
28
#include <drizzled/transaction_services.h>
29
#include <drizzled/sql_lex.h>
30
#include <drizzled/table/cache.h>
26
#include "drizzled/sql_table.h"
27
#include "drizzled/pthread_globals.h"
34
32
bool statement::RenameTable::execute()
36
TableList *first_table= (TableList *) lex().select_lex.table_list.first;
37
TableList *all_tables= lex().query_tables;
34
TableList *first_table= (TableList *) session->lex->select_lex.table_list.first;
35
TableList *all_tables= session->lex->query_tables;
38
36
assert(first_table == all_tables && first_table != 0);
41
if (session().inTransaction())
43
my_error(ER_TRANSACTIONAL_DDL_NOT_SUPPORTED, MYF(0));
47
38
for (table= first_table; table; table= table->next_local->next_local)
49
40
TableList old_list, new_list;
72
62
Avoid problems with a rename on a table that we have locked or
73
63
if the user is trying to to do this in a transcation context
75
if (session().inTransaction())
65
if (session->inTransaction())
77
67
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
81
if (session().wait_if_global_read_lock(false, true))
71
if (wait_if_global_read_lock(session, 0, 1))
85
boost::mutex::scoped_lock scopedLock(table::Cache::mutex()); /* Rename table lock for exclusive access */
87
if (not session().lock_table_names_exclusively(table_list))
90
ren_table= renameTablesInList(table_list, false);
94
/* Rename didn't succeed; rename back the tables in reverse order */
97
/* Reverse the table list */
98
table_list= reverseTableList(table_list);
100
/* Find the last renamed table */
101
for (table= table_list;
102
table->next_local != ren_table;
103
table= table->next_local->next_local)
106
table= table->next_local->next_local; // Skip error table
108
/* Revert to old names */
109
renameTablesInList(table, true);
113
table_list->unlock_table_names();
74
pthread_mutex_lock(&LOCK_open); /* Rename table lock for exclusive access */
75
if (lock_table_names_exclusively(session, table_list))
77
pthread_mutex_unlock(&LOCK_open);
82
ren_table= renameTablesInList(table_list, 0);
85
/* Rename didn't succeed; rename back the tables in reverse order */
88
/* Reverse the table list */
89
table_list= reverseTableList(table_list);
91
/* Find the last renamed table */
92
for (table= table_list;
93
table->next_local != ren_table;
94
table= table->next_local->next_local)
96
table= table->next_local->next_local; // Skip error table
97
/* Revert to old names */
98
renameTablesInList(table, 1);
102
An exclusive lock on table names is satisfactory to ensure
103
no other thread accesses this table.
104
We still should unlock LOCK_open as early as possible, to provide
105
higher concurrency - query_cache_invalidate can take minutes to
108
pthread_mutex_unlock(&LOCK_open);
117
110
/* Lets hope this doesn't fail as the result will be messy */
120
TransactionServices &transaction_services= TransactionServices::singleton();
121
transaction_services.rawStatement(session(),
122
*session().getQueryString(),
123
*session().schema());
113
write_bin_log(session, session->query, session->query_length);
127
session().startWaitingGlobalReadLock();
117
pthread_mutex_lock(&LOCK_open); /* unlock all tables held */
118
unlock_table_names(table_list, NULL);
119
pthread_mutex_unlock(&LOCK_open);
122
start_waiting_global_read_lock(session);
152
147
const char *new_alias, *old_alias;
155
old_alias= ren_table->getTableName();
150
old_alias= ren_table->table_name;
156
151
new_alias= new_table_name;
159
154
plugin::StorageEngine *engine= NULL;
160
message::table::shared_ptr table_message;
162
identifier::Table old_identifier(ren_table->getSchemaName(), old_alias, message::Table::STANDARD);
164
if (not (table_message= plugin::StorageEngine::getTableMessage(session(), old_identifier)))
155
message::Table table_proto;
157
TableIdentifier old_identifier(ren_table->db, old_alias, NO_TMP_TABLE);
159
if (plugin::StorageEngine::getTableDefinition(*session, old_identifier, &table_proto) != EEXIST)
166
my_error(ER_TABLE_UNKNOWN, old_identifier);
161
my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
170
engine= plugin::StorageEngine::findByName(session(), table_message->engine().name());
165
engine= plugin::StorageEngine::findByName(*session, table_proto.engine().name());
172
identifier::Table new_identifier(new_db, new_alias, message::Table::STANDARD);
173
if (plugin::StorageEngine::doesTableExist(session(), new_identifier))
167
TableIdentifier new_identifier(new_db, new_alias, NO_TMP_TABLE);
168
if (plugin::StorageEngine::getTableDefinition(*session, new_identifier) != ENOENT)
175
my_error(ER_TABLE_EXISTS_ERROR, new_identifier);
170
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
176
171
return 1; // This can't be skipped
179
rc= rename_table(session(), engine, old_identifier, new_identifier);
174
rc= mysql_rename_table(engine,
175
ren_table->db, old_alias,
176
new_db, new_alias, 0);
180
177
if (rc && ! skip_error)