17
17
Atomic rename of table; RENAME TABLE t1 to t2, tmp to t1 [,...]
19
19
#include <drizzled/server_includes.h>
20
#include <drizzled/drizzled_error_messages.h>
22
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
25
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list);
20
#include <drizzled/error.h>
21
#include <drizzled/table_list.h>
22
#include <drizzled/session.h>
23
#include <drizzled/lock.h>
24
#include "drizzled/rename.h"
26
static TableList *rename_tables(Session *session, TableList *table_list,
29
static TableList *reverse_table_list(TableList *table_list);
28
32
Every second entry in the table_list is the original name and every
29
33
second entry is the new name.
32
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
35
bool drizzle_rename_tables(Session *session, TableList *table_list)
35
TABLE_LIST *ren_table= 0;
38
TableList *ren_table= NULL;
38
41
Avoid problems with a rename on a table that we have locked or
39
42
if the user is trying to to do this in a transcation context
41
if (thd->locked_tables || thd->active_transaction())
44
if (session->inTransaction())
43
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
44
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
46
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
48
mysql_ha_rm_tables(thd, table_list, false);
50
if (wait_if_global_read_lock(thd,0,1))
53
pthread_mutex_lock(&LOCK_open);
54
if (lock_table_names_exclusively(thd, table_list))
50
if (wait_if_global_read_lock(session,0,1))
53
pthread_mutex_lock(&LOCK_open); /* Rename table lock for exclusive access */
54
if (lock_table_names_exclusively(session, table_list))
56
56
pthread_mutex_unlock(&LOCK_open);
61
if ((ren_table=rename_tables(thd,table_list,0)))
61
if ((ren_table=rename_tables(session,table_list,0)))
63
63
/* Rename didn't succeed; rename back the tables in reverse order */
66
66
/* Reverse the table list */
67
67
table_list= reverse_table_list(table_list);
72
72
table= table->next_local->next_local) ;
73
73
table= table->next_local->next_local; // Skip error table
74
74
/* Revert to old names */
75
rename_tables(thd, table, 1);
75
rename_tables(session, table, 1);
77
77
/* Revert the table list (for prepared statements) */
78
78
table_list= reverse_table_list(table_list);
83
83
An exclusive lock on table names is satisfactory to ensure
89
89
pthread_mutex_unlock(&LOCK_open);
91
/* Lets hope this doesn't fail as the result will be messy */
92
if (!silent && !error)
91
/* Lets hope this doesn't fail as the result will be messy */
94
write_bin_log(thd, true, thd->query, thd->query_length);
94
write_bin_log(session, true, session->query, session->query_length);
98
pthread_mutex_lock(&LOCK_open);
99
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
98
pthread_mutex_lock(&LOCK_open); /* unlock all tables held */
99
unlock_table_names(table_list, NULL);
100
100
pthread_mutex_unlock(&LOCK_open);
103
start_waiting_global_read_lock(thd);
103
start_waiting_global_read_lock(session);
150
150
true rename failed
154
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
155
char *new_table_alias, bool skip_error)
154
do_rename(Session *session, TableList *ren_table, const char *new_db, const char *new_table_name, bool skip_error)
158
char name[FN_REFLEN];
159
157
const char *new_alias, *old_alias;
160
/* TODO: What should this really be set to - it doesn't
161
get set anywhere before it's used? */
162
enum legacy_db_type table_type=DB_TYPE_UNKNOWN;
164
if (lower_case_table_names == 2)
166
old_alias= ren_table->alias;
167
new_alias= new_table_alias;
171
160
old_alias= ren_table->table_name;
172
161
new_alias= new_table_name;
174
build_table_filename(name, sizeof(name),
175
new_db, new_alias, reg_ext, 0);
176
if (!access(name,F_OK))
164
StorageEngine *engine= NULL;
166
if (ha_table_exists_in_engine(session, ren_table->db, old_alias, &engine)
167
!= HA_ERR_TABLE_EXIST)
169
my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
173
if (ha_table_exists_in_engine(session, new_db, new_alias)
174
!=HA_ERR_NO_SUCH_TABLE)
178
176
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
179
177
return(1); // This can't be skipped
181
build_table_filename(name, sizeof(name),
182
ren_table->db, old_alias, reg_ext, 0);
184
rc= mysql_rename_table(ha_resolve_by_legacy_type(thd, table_type),
185
ren_table->db, old_alias,
186
new_db, new_alias, 0);
180
rc= mysql_rename_table(engine,
181
ren_table->db, old_alias,
182
new_db, new_alias, 0);
187
183
if (rc && !skip_error)
214
210
true rename failed
218
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
214
rename_tables(Session *session, TableList *table_list, bool skip_error)
220
TABLE_LIST *ren_table, *new_table;
216
TableList *ren_table, *new_table;
222
218
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
224
220
new_table= ren_table->next_local;
225
if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
226
new_table->alias, skip_error))
221
if (do_rename(session, ren_table, new_table->db, new_table->table_name, skip_error))
227
222
return(ren_table);