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>
20
#include <drizzled/error.h>
21
#include <drizzled/table_list.h>
22
#include <drizzled/session.h>
23
#include <drizzled/lock.h>
22
static TableList *rename_tables(THD *thd, TableList *table_list,
25
static TableList *rename_tables(Session *session, TableList *table_list,
25
28
static TableList *reverse_table_list(TableList *table_list);
29
32
second entry is the new name.
32
bool mysql_rename_tables(THD *thd, TableList *table_list, bool silent)
35
bool drizzle_rename_tables(Session *session, TableList *table_list, bool silent)
35
38
TableList *ren_table= 0;
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->locked_tables || session->active_transaction())
43
46
my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
44
47
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))
51
if (wait_if_global_read_lock(session,0,1))
53
54
pthread_mutex_lock(&LOCK_open);
54
if (lock_table_names_exclusively(thd, table_list))
55
if (lock_table_names_exclusively(session, table_list))
56
57
pthread_mutex_unlock(&LOCK_open);
61
if ((ren_table=rename_tables(thd,table_list,0)))
62
if ((ren_table=rename_tables(session,table_list,0)))
63
64
/* Rename didn't succeed; rename back the tables in reverse order */
72
73
table= table->next_local->next_local) ;
73
74
table= table->next_local->next_local; // Skip error table
74
75
/* Revert to old names */
75
rename_tables(thd, table, 1);
76
rename_tables(session, table, 1);
77
78
/* Revert the table list (for prepared statements) */
78
79
table_list= reverse_table_list(table_list);
89
90
pthread_mutex_unlock(&LOCK_open);
91
/* Lets hope this doesn't fail as the result will be messy */
92
/* Lets hope this doesn't fail as the result will be messy */
92
93
if (!silent && !error)
94
write_bin_log(thd, true, thd->query, thd->query_length);
95
write_bin_log(session, true, session->query, session->query_length);
98
99
pthread_mutex_lock(&LOCK_open);
99
unlock_table_names(thd, table_list, (TableList*) 0);
100
unlock_table_names(session, table_list, (TableList*) 0);
100
101
pthread_mutex_unlock(&LOCK_open);
103
start_waiting_global_read_lock(thd);
104
start_waiting_global_read_lock(session);
154
do_rename(THD *thd, TableList *ren_table, char *new_db, char *new_table_name,
155
do_rename(Session *session, TableList *ren_table, char *new_db, char *new_table_name,
155
156
char *new_table_alias, bool skip_error)
158
char name[FN_REFLEN];
159
159
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
161
if (lower_case_table_names == 2)
171
168
old_alias= ren_table->table_name;
172
169
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))
172
handlerton *hton= NULL;
174
if(ha_table_exists_in_engine(session, ren_table->db, old_alias, &hton)
175
!= HA_ERR_TABLE_EXIST)
177
my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
181
if (ha_table_exists_in_engine(session, new_db, new_alias)
182
!=HA_ERR_NO_SUCH_TABLE)
178
184
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
179
185
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);
188
rc= mysql_rename_table(hton,
189
ren_table->db, old_alias,
190
new_db, new_alias, 0);
187
191
if (rc && !skip_error)
217
221
static TableList *
218
rename_tables(THD *thd, TableList *table_list, bool skip_error)
222
rename_tables(Session *session, TableList *table_list, bool skip_error)
220
224
TableList *ren_table, *new_table;
222
226
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
224
228
new_table= ren_table->next_local;
225
if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
229
if (do_rename(session, ren_table, new_table->db, new_table->table_name,
226
230
new_table->alias, skip_error))
227
231
return(ren_table);