~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/rename.cc

  • Committer: Brian Aker
  • Date: 2009-07-11 19:23:04 UTC
  • mfrom: (1089.1.14 merge)
  • Revision ID: brian@gaz-20090711192304-ootijyl5yf9jq9kd
Merge Brian

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
  Atomic rename of table;  RENAME TABLE t1 to t2, tmp to t1 [,...]
18
18
*/
19
19
#include <drizzled/server_includes.h>
20
 
#include <drizzled/drizzled_error_messages.h>
21
 
 
22
 
static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
23
 
                                 bool skip_error);
24
 
 
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"
 
25
 
 
26
static TableList *rename_tables(Session *session, TableList *table_list,
 
27
                                bool skip_error);
 
28
 
 
29
static TableList *reverse_table_list(TableList *table_list);
26
30
 
27
31
/*
28
32
  Every second entry in the table_list is the original name and every
29
33
  second entry is the new name.
30
34
*/
31
 
 
32
 
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
 
35
bool drizzle_rename_tables(Session *session, TableList *table_list)
33
36
{
34
 
  bool error= 1;
35
 
  TABLE_LIST *ren_table= 0;
 
37
  bool error= true;
 
38
  TableList *ren_table= NULL;
36
39
 
37
40
  /*
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
40
43
  */
41
 
  if (thd->locked_tables || thd->active_transaction())
 
44
  if (session->inTransaction())
42
45
  {
43
 
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
44
 
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
45
 
    return(1);
 
46
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 
47
    return true;
46
48
  }
47
49
 
48
 
  mysql_ha_rm_tables(thd, table_list, false);
49
 
 
50
 
  if (wait_if_global_read_lock(thd,0,1))
51
 
    return(1);
52
 
 
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))
 
51
    return true;
 
52
 
 
53
  pthread_mutex_lock(&LOCK_open); /* Rename table lock for exclusive access */
 
54
  if (lock_table_names_exclusively(session, table_list))
55
55
  {
56
56
    pthread_mutex_unlock(&LOCK_open);
57
57
    goto err;
58
58
  }
59
59
 
60
 
  error=0;
61
 
  if ((ren_table=rename_tables(thd,table_list,0)))
 
60
  error= false;
 
61
  if ((ren_table=rename_tables(session,table_list,0)))
62
62
  {
63
63
    /* Rename didn't succeed;  rename back the tables in reverse order */
64
 
    TABLE_LIST *table;
 
64
    TableList *table;
65
65
 
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);
76
76
 
77
77
    /* Revert the table list (for prepared statements) */
78
78
    table_list= reverse_table_list(table_list);
79
79
 
80
 
    error= 1;
 
80
    error= true;
81
81
  }
82
82
  /*
83
83
    An exclusive lock on table names is satisfactory to ensure
88
88
  */
89
89
  pthread_mutex_unlock(&LOCK_open);
90
90
 
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 */
 
92
  if (!error)
93
93
  {
94
 
    write_bin_log(thd, true, thd->query, thd->query_length);
95
 
    my_ok(thd);
 
94
    write_bin_log(session, true, session->query, session->query_length);
 
95
    session->my_ok();
96
96
  }
97
97
 
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);
101
101
 
102
102
err:
103
 
  start_waiting_global_read_lock(thd);
104
 
  return(error);
 
103
  start_waiting_global_read_lock(session);
 
104
 
 
105
  return error;
105
106
}
106
107
 
107
108
 
115
116
  RETURN
116
117
    pointer to new (reversed) list
117
118
*/
118
 
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
 
119
static TableList *reverse_table_list(TableList *table_list)
119
120
{
120
 
  TABLE_LIST *prev= 0;
 
121
  TableList *prev= NULL;
121
122
 
122
123
  while (table_list)
123
124
  {
124
 
    TABLE_LIST *next= table_list->next_local;
 
125
    TableList *next= table_list->next_local;
125
126
    table_list->next_local= prev;
126
127
    prev= table_list;
127
128
    table_list= next;
135
136
 
136
137
  SYNPOSIS
137
138
    do_rename()
138
 
      thd               Thread handle
 
139
      session               Thread handle
139
140
      ren_table         A table/view to be renamed
140
141
      new_db            The database to which the table to be moved to
141
142
      new_table_name    The new table/view name
142
 
      new_table_alias   The new table/view alias
143
143
      skip_error        Whether to skip error
144
144
 
145
145
  DESCRIPTION
150
150
    true      rename failed
151
151
*/
152
152
 
153
 
bool
154
 
do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db, char *new_table_name,
155
 
          char *new_table_alias, bool skip_error)
 
153
static bool
 
154
do_rename(Session *session, TableList *ren_table, const char *new_db, const char *new_table_name, bool skip_error)
156
155
{
157
 
  int rc= 1;
158
 
  char name[FN_REFLEN];
 
156
  bool rc= true;
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;
163
158
 
164
 
  if (lower_case_table_names == 2)
165
 
  {
166
 
    old_alias= ren_table->alias;
167
 
    new_alias= new_table_alias;
168
 
  }
169
 
  else
170
159
  {
171
160
    old_alias= ren_table->table_name;
172
161
    new_alias= new_table_name;
173
162
  }
174
 
  build_table_filename(name, sizeof(name),
175
 
                       new_db, new_alias, reg_ext, 0);
176
 
  if (!access(name,F_OK))
 
163
 
 
164
  StorageEngine *engine= NULL;
 
165
 
 
166
  if (ha_table_exists_in_engine(session, ren_table->db, old_alias, &engine)
 
167
     != HA_ERR_TABLE_EXIST)
 
168
  {
 
169
    my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
 
170
    return true;
 
171
  }
 
172
 
 
173
  if (ha_table_exists_in_engine(session, new_db, new_alias)
 
174
      !=HA_ERR_NO_SUCH_TABLE)
177
175
  {
178
176
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
179
177
    return(1);                  // This can't be skipped
180
178
  }
181
 
  build_table_filename(name, sizeof(name),
182
 
                       ren_table->db, old_alias, reg_ext, 0);
183
179
 
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)
188
 
    return(1);
 
184
    return true;
189
185
 
190
 
  return(0);
 
186
  return false;
191
187
 
192
188
}
193
189
/*
200
196
 
201
197
  SYNPOSIS
202
198
    rename_tables()
203
 
      thd               Thread handle
 
199
      session               Thread handle
204
200
      table_list        List of tables to rename
205
201
      skip_error        Whether to skip errors
206
202
 
214
210
    true      rename failed
215
211
*/
216
212
 
217
 
static TABLE_LIST *
218
 
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
 
213
static TableList *
 
214
rename_tables(Session *session, TableList *table_list, bool skip_error)
219
215
{
220
 
  TABLE_LIST *ren_table, *new_table;
 
216
  TableList *ren_table, *new_table;
221
217
 
222
218
  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
223
219
  {
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);
228
223
  }
229
224
  return(0);