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>
25
static TableList *rename_tables(Session *session, TableList *table_list,
28
static TableList *reverse_table_list(TableList *table_list);
28
31
Every second entry in the table_list is the original name and every
29
32
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, bool silent)
35
TABLE_LIST *ren_table= 0;
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);
51
mysql_ha_rm_tables(session, table_list, false);
50
if (wait_if_global_read_lock(thd,0,1))
53
if (wait_if_global_read_lock(session,0,1))
53
56
pthread_mutex_lock(&LOCK_open);
54
if (lock_table_names_exclusively(thd, table_list))
57
if (lock_table_names_exclusively(session, table_list))
56
59
pthread_mutex_unlock(&LOCK_open);
61
if ((ren_table=rename_tables(thd,table_list,0)))
64
if ((ren_table=rename_tables(session,table_list,0)))
63
66
/* Rename didn't succeed; rename back the tables in reverse order */
66
69
/* Reverse the table list */
67
70
table_list= reverse_table_list(table_list);
72
75
table= table->next_local->next_local) ;
73
76
table= table->next_local->next_local; // Skip error table
74
77
/* Revert to old names */
75
rename_tables(thd, table, 1);
78
rename_tables(session, table, 1);
77
80
/* Revert the table list (for prepared statements) */
78
81
table_list= reverse_table_list(table_list);
89
92
pthread_mutex_unlock(&LOCK_open);
91
/* Lets hope this doesn't fail as the result will be messy */
94
/* Lets hope this doesn't fail as the result will be messy */
92
95
if (!silent && !error)
94
write_bin_log(thd, true, thd->query, thd->query_length);
97
write_bin_log(session, true, session->query, session->query_length);
98
101
pthread_mutex_lock(&LOCK_open);
99
unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
102
unlock_table_names(session, table_list, (TableList*) 0);
100
103
pthread_mutex_unlock(&LOCK_open);
103
start_waiting_global_read_lock(thd);
106
start_waiting_global_read_lock(session);
116
119
pointer to new (reversed) list
118
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
121
static TableList *reverse_table_list(TableList *table_list)
122
125
while (table_list)
124
TABLE_LIST *next= table_list->next_local;
127
TableList *next= table_list->next_local;
125
128
table_list->next_local= prev;
126
129
prev= table_list;
127
130
table_list= next;
154
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
157
do_rename(Session *session, TableList *ren_table, char *new_db, char *new_table_name,
155
158
char *new_table_alias, bool skip_error)
158
char name[FN_REFLEN];
159
161
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
163
if (lower_case_table_names == 2)
171
170
old_alias= ren_table->table_name;
172
171
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))
174
handlerton *hton= NULL;
176
if(ha_table_exists_in_engine(session, ren_table->db, old_alias, &hton)
177
!= HA_ERR_TABLE_EXIST)
179
my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
183
if (ha_table_exists_in_engine(session, new_db, new_alias)
184
!=HA_ERR_NO_SUCH_TABLE)
178
186
my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
179
187
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);
190
rc= mysql_rename_table(hton,
191
ren_table->db, old_alias,
192
new_db, new_alias, 0);
187
193
if (rc && !skip_error)
214
220
true rename failed
218
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
224
rename_tables(Session *session, TableList *table_list, bool skip_error)
220
TABLE_LIST *ren_table, *new_table;
226
TableList *ren_table, *new_table;
222
228
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
224
230
new_table= ren_table->next_local;
225
if (do_rename(thd, ren_table, new_table->db, new_table->table_name,
231
if (do_rename(session, ren_table, new_table->db, new_table->table_name,
226
232
new_table->alias, skip_error))
227
233
return(ren_table);