~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_rename.cc

pandora-build v0.72 - Moved remaining hard-coded tests into pandora-build
macros.
Add PANDORA_DRIZZLE_BUILD to run the extra checks that drizzle needs that 
plugins would also need to run so we can just use that macro in generated
external plugin builds.
Added support to register_plugins for external plugin building.
Renamed register_plugins.py to pandora-plugin.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2000-2006 MySQL AB
2
 
 
3
 
   This program is free software; you can redistribute it and/or modify
4
 
   it under the terms of the GNU General Public License as published by
5
 
   the Free Software Foundation; version 2 of the License.
6
 
 
7
 
   This program is distributed in the hope that it will be useful,
8
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 
   GNU General Public License for more details.
11
 
 
12
 
   You should have received a copy of the GNU General Public License
13
 
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
 
 
16
 
/*
17
 
  Atomic rename of table;  RENAME TABLE t1 to t2, tmp to t1 [,...]
18
 
*/
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);
26
 
 
27
 
/*
28
 
  Every second entry in the table_list is the original name and every
29
 
  second entry is the new name.
30
 
*/
31
 
 
32
 
bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent)
33
 
{
34
 
  bool error= 1;
35
 
  TABLE_LIST *ren_table= 0;
36
 
 
37
 
  /*
38
 
    Avoid problems with a rename on a table that we have locked or
39
 
    if the user is trying to to do this in a transcation context
40
 
  */
41
 
  if (thd->locked_tables || thd->active_transaction())
42
 
  {
43
 
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
44
 
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
45
 
    return(1);
46
 
  }
47
 
 
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))
55
 
  {
56
 
    pthread_mutex_unlock(&LOCK_open);
57
 
    goto err;
58
 
  }
59
 
 
60
 
  error=0;
61
 
  if ((ren_table=rename_tables(thd,table_list,0)))
62
 
  {
63
 
    /* Rename didn't succeed;  rename back the tables in reverse order */
64
 
    TABLE_LIST *table;
65
 
 
66
 
    /* Reverse the table list */
67
 
    table_list= reverse_table_list(table_list);
68
 
 
69
 
    /* Find the last renamed table */
70
 
    for (table= table_list;
71
 
         table->next_local != ren_table ;
72
 
         table= table->next_local->next_local) ;
73
 
    table= table->next_local->next_local;               // Skip error table
74
 
    /* Revert to old names */
75
 
    rename_tables(thd, table, 1);
76
 
 
77
 
    /* Revert the table list (for prepared statements) */
78
 
    table_list= reverse_table_list(table_list);
79
 
 
80
 
    error= 1;
81
 
  }
82
 
  /*
83
 
    An exclusive lock on table names is satisfactory to ensure
84
 
    no other thread accesses this table.
85
 
    We still should unlock LOCK_open as early as possible, to provide
86
 
    higher concurrency - query_cache_invalidate can take minutes to
87
 
    complete.
88
 
  */
89
 
  pthread_mutex_unlock(&LOCK_open);
90
 
 
91
 
  /* Lets hope this doesn't fail as the result will be messy */ 
92
 
  if (!silent && !error)
93
 
  {
94
 
    write_bin_log(thd, true, thd->query, thd->query_length);
95
 
    my_ok(thd);
96
 
  }
97
 
 
98
 
  pthread_mutex_lock(&LOCK_open);
99
 
  unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
100
 
  pthread_mutex_unlock(&LOCK_open);
101
 
 
102
 
err:
103
 
  start_waiting_global_read_lock(thd);
104
 
  return(error);
105
 
}
106
 
 
107
 
 
108
 
/*
109
 
  reverse table list
110
 
 
111
 
  SYNOPSIS
112
 
    reverse_table_list()
113
 
    table_list pointer to table _list
114
 
 
115
 
  RETURN
116
 
    pointer to new (reversed) list
117
 
*/
118
 
static TABLE_LIST *reverse_table_list(TABLE_LIST *table_list)
119
 
{
120
 
  TABLE_LIST *prev= 0;
121
 
 
122
 
  while (table_list)
123
 
  {
124
 
    TABLE_LIST *next= table_list->next_local;
125
 
    table_list->next_local= prev;
126
 
    prev= table_list;
127
 
    table_list= next;
128
 
  }
129
 
  return (prev);
130
 
}
131
 
 
132
 
 
133
 
/*
134
 
  Rename a single table or a view
135
 
 
136
 
  SYNPOSIS
137
 
    do_rename()
138
 
      thd               Thread handle
139
 
      ren_table         A table/view to be renamed
140
 
      new_db            The database to which the table to be moved to
141
 
      new_table_name    The new table/view name
142
 
      new_table_alias   The new table/view alias
143
 
      skip_error        Whether to skip error
144
 
 
145
 
  DESCRIPTION
146
 
    Rename a single table or a view.
147
 
 
148
 
  RETURN
149
 
    false     Ok
150
 
    true      rename failed
151
 
*/
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)
156
 
{
157
 
  int rc= 1;
158
 
  char name[FN_REFLEN];
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;
163
 
 
164
 
  if (lower_case_table_names == 2)
165
 
  {
166
 
    old_alias= ren_table->alias;
167
 
    new_alias= new_table_alias;
168
 
  }
169
 
  else
170
 
  {
171
 
    old_alias= ren_table->table_name;
172
 
    new_alias= new_table_name;
173
 
  }
174
 
  build_table_filename(name, sizeof(name),
175
 
                       new_db, new_alias, reg_ext, 0);
176
 
  if (!access(name,F_OK))
177
 
  {
178
 
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
179
 
    return(1);                  // This can't be skipped
180
 
  }
181
 
  build_table_filename(name, sizeof(name),
182
 
                       ren_table->db, old_alias, reg_ext, 0);
183
 
 
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);
187
 
  if (rc && !skip_error)
188
 
    return(1);
189
 
 
190
 
  return(0);
191
 
 
192
 
}
193
 
/*
194
 
  Rename all tables in list; Return pointer to wrong entry if something goes
195
 
  wrong.  Note that the table_list may be empty!
196
 
*/
197
 
 
198
 
/*
199
 
  Rename tables/views in the list
200
 
 
201
 
  SYNPOSIS
202
 
    rename_tables()
203
 
      thd               Thread handle
204
 
      table_list        List of tables to rename
205
 
      skip_error        Whether to skip errors
206
 
 
207
 
  DESCRIPTION
208
 
    Take a table/view name from and odd list element and rename it to a
209
 
    the name taken from list element+1. Note that the table_list may be
210
 
    empty.
211
 
 
212
 
  RETURN
213
 
    false     Ok
214
 
    true      rename failed
215
 
*/
216
 
 
217
 
static TABLE_LIST *
218
 
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
219
 
{
220
 
  TABLE_LIST *ren_table, *new_table;
221
 
 
222
 
  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
223
 
  {
224
 
    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))
227
 
      return(ren_table);
228
 
  }
229
 
  return(0);
230
 
}