~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
*/
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
19
#include <drizzled/server_includes.h>
549 by Monty Taylor
Took gettext.h out of header files.
20
#include <drizzled/error.h>
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
21
#include <drizzled/table_list.h>
22
#include <drizzled/session.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
23
#include <drizzled/lock.h>
1085.1.2 by Monty Taylor
Fixed -Wmissing-declarations
24
#include "drizzled/rename.h"
1 by brian
clean slate
25
520.1.22 by Brian Aker
Second pass of thd cleanup
26
static TableList *rename_tables(Session *session, TableList *table_list,
584.1.15 by Monty Taylor
The mega-patch from hell. Renamed sql_class to session (since that's what it is) and removed it and field and table from common_includes.
27
                                bool skip_error);
1 by brian
clean slate
28
327.2.4 by Brian Aker
Refactoring table.h
29
static TableList *reverse_table_list(TableList *table_list);
1 by brian
clean slate
30
31
/*
32
  Every second entry in the table_list is the original name and every
33
  second entry is the new name.
34
*/
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
35
bool drizzle_rename_tables(Session *session, TableList *table_list)
1 by brian
clean slate
36
{
1034.1.4 by Brian Aker
Fixed TableList to correctly construct (and removed memset() calls in
37
  bool error= true;
38
  TableList *ren_table= NULL;
1 by brian
clean slate
39
40
  /*
41
    Avoid problems with a rename on a table that we have locked or
42
    if the user is trying to to do this in a transcation context
43
  */
1054.1.8 by Brian Aker
Remove lock_tables list from session.
44
  if (session->inTransaction())
1 by brian
clean slate
45
  {
934.2.28 by Jay Pipes
Renamed some things to our standards and made private methods private...
46
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
1054.1.8 by Brian Aker
Remove lock_tables list from session.
47
    return true;
1 by brian
clean slate
48
  }
49
520.1.22 by Brian Aker
Second pass of thd cleanup
50
  if (wait_if_global_read_lock(session,0,1))
1054.1.8 by Brian Aker
Remove lock_tables list from session.
51
    return true;
1 by brian
clean slate
52
1046.1.2 by Brian Aker
Comments on LOCK_open
53
  pthread_mutex_lock(&LOCK_open); /* Rename table lock for exclusive access */
520.1.22 by Brian Aker
Second pass of thd cleanup
54
  if (lock_table_names_exclusively(session, table_list))
1 by brian
clean slate
55
  {
56
    pthread_mutex_unlock(&LOCK_open);
57
    goto err;
58
  }
59
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
60
  error= false;
520.1.22 by Brian Aker
Second pass of thd cleanup
61
  if ((ren_table=rename_tables(session,table_list,0)))
1 by brian
clean slate
62
  {
63
    /* Rename didn't succeed;  rename back the tables in reverse order */
327.2.4 by Brian Aker
Refactoring table.h
64
    TableList *table;
1 by brian
clean slate
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 */
520.1.22 by Brian Aker
Second pass of thd cleanup
75
    rename_tables(session, table, 1);
1 by brian
clean slate
76
77
    /* Revert the table list (for prepared statements) */
78
    table_list= reverse_table_list(table_list);
79
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
80
    error= true;
1 by brian
clean slate
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
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
91
  /* Lets hope this doesn't fail as the result will be messy */
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
92
  if (!error)
1 by brian
clean slate
93
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
94
    write_bin_log(session, true, session->query, session->query_length);
836 by Brian Aker
Fixed session call from function to method.
95
    session->my_ok();
1 by brian
clean slate
96
  }
97
1046.1.2 by Brian Aker
Comments on LOCK_open
98
  pthread_mutex_lock(&LOCK_open); /* unlock all tables held */
1034.1.7 by Brian Aker
Remove dead bits to the end of functions.
99
  unlock_table_names(table_list, NULL);
1 by brian
clean slate
100
  pthread_mutex_unlock(&LOCK_open);
101
102
err:
520.1.22 by Brian Aker
Second pass of thd cleanup
103
  start_waiting_global_read_lock(session);
1054.1.8 by Brian Aker
Remove lock_tables list from session.
104
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
105
  return error;
1 by brian
clean slate
106
}
107
108
109
/*
110
  reverse table list
111
112
  SYNOPSIS
113
    reverse_table_list()
114
    table_list pointer to table _list
115
116
  RETURN
117
    pointer to new (reversed) list
118
*/
327.2.4 by Brian Aker
Refactoring table.h
119
static TableList *reverse_table_list(TableList *table_list)
1 by brian
clean slate
120
{
1034.1.4 by Brian Aker
Fixed TableList to correctly construct (and removed memset() calls in
121
  TableList *prev= NULL;
1 by brian
clean slate
122
123
  while (table_list)
124
  {
327.2.4 by Brian Aker
Refactoring table.h
125
    TableList *next= table_list->next_local;
1 by brian
clean slate
126
    table_list->next_local= prev;
127
    prev= table_list;
128
    table_list= next;
129
  }
130
  return (prev);
131
}
132
133
134
/*
135
  Rename a single table or a view
136
137
  SYNPOSIS
138
    do_rename()
520.1.22 by Brian Aker
Second pass of thd cleanup
139
      session               Thread handle
1 by brian
clean slate
140
      ren_table         A table/view to be renamed
141
      new_db            The database to which the table to be moved to
142
      new_table_name    The new table/view name
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
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
153
static bool
154
do_rename(Session *session, TableList *ren_table, const char *new_db, const char *new_table_name, bool skip_error)
1 by brian
clean slate
155
{
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
156
  bool rc= true;
1 by brian
clean slate
157
  const char *new_alias, *old_alias;
158
159
  {
160
    old_alias= ren_table->table_name;
161
    new_alias= new_table_name;
162
  }
673.3.2 by Stewart Smith
start replacing calles to access(2) on frm file name with calls to ha_table_exists_in_engine
163
960.2.26 by Monty Taylor
Rename hton to engine.
164
  StorageEngine *engine= NULL;
1095.3.6 by Stewart Smith
remove ha_table_exists_in_engine and use StorageEngine::getTableProto() instead.
165
  drizzled::message::Table table_proto;
166
  char path[FN_REFLEN];
167
  size_t length;
168
169
  length= build_table_filename(path, sizeof(path),
170
                               ren_table->db, old_alias, false);
171
172
  if (StorageEngine::getTableProto(path, &table_proto)!= EEXIST)
673.3.12 by Stewart Smith
fix RENAME TABLE
173
  {
174
    my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
175
    return true;
673.3.12 by Stewart Smith
fix RENAME TABLE
176
  }
177
1095.3.9 by Stewart Smith
refactor ha_resolve_by_name to accept std::string instead of LEX_STRING
178
  engine= ha_resolve_by_name(session, table_proto.engine().name());
1095.3.6 by Stewart Smith
remove ha_table_exists_in_engine and use StorageEngine::getTableProto() instead.
179
180
  length= build_table_filename(path, sizeof(path),
181
                               new_db, new_alias, false);
182
183
  if (StorageEngine::getTableProto(path, NULL)!=ENOENT)
1 by brian
clean slate
184
  {
185
    my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
186
    return(1);			// This can't be skipped
1 by brian
clean slate
187
  }
188
960.2.26 by Monty Taylor
Rename hton to engine.
189
  rc= mysql_rename_table(engine,
673.3.12 by Stewart Smith
fix RENAME TABLE
190
                         ren_table->db, old_alias,
191
                         new_db, new_alias, 0);
1 by brian
clean slate
192
  if (rc && !skip_error)
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
193
    return true;
1 by brian
clean slate
194
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
195
  return false;
1 by brian
clean slate
196
197
}
198
/*
199
  Rename all tables in list; Return pointer to wrong entry if something goes
200
  wrong.  Note that the table_list may be empty!
201
*/
202
203
/*
204
  Rename tables/views in the list
205
206
  SYNPOSIS
207
    rename_tables()
520.1.22 by Brian Aker
Second pass of thd cleanup
208
      session               Thread handle
1 by brian
clean slate
209
      table_list        List of tables to rename
210
      skip_error        Whether to skip errors
211
212
  DESCRIPTION
213
    Take a table/view name from and odd list element and rename it to a
214
    the name taken from list element+1. Note that the table_list may be
215
    empty.
216
217
  RETURN
218
    false     Ok
219
    true      rename failed
220
*/
221
327.2.4 by Brian Aker
Refactoring table.h
222
static TableList *
520.1.22 by Brian Aker
Second pass of thd cleanup
223
rename_tables(Session *session, TableList *table_list, bool skip_error)
1 by brian
clean slate
224
{
327.2.4 by Brian Aker
Refactoring table.h
225
  TableList *ren_table, *new_table;
1 by brian
clean slate
226
227
  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
228
  {
229
    new_table= ren_table->next_local;
1039.1.5 by Brian Aker
Remove lower case filename bits (aka we just lock into the most compatible
230
    if (do_rename(session, ren_table, new_table->db, new_table->table_name, skip_error))
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
231
      return(ren_table);
1 by brian
clean slate
232
  }
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
233
  return(0);
1 by brian
clean slate
234
}