~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>
1 by brian
clean slate
21
520.1.22 by Brian Aker
Second pass of thd cleanup
22
static TableList *rename_tables(Session *session, TableList *table_list,
1 by brian
clean slate
23
				 bool skip_error);
24
327.2.4 by Brian Aker
Refactoring table.h
25
static TableList *reverse_table_list(TableList *table_list);
1 by brian
clean slate
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
520.1.22 by Brian Aker
Second pass of thd cleanup
32
bool mysql_rename_tables(Session *session, TableList *table_list, bool silent)
1 by brian
clean slate
33
{
34
  bool error= 1;
327.2.4 by Brian Aker
Refactoring table.h
35
  TableList *ren_table= 0;
1 by brian
clean slate
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
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
41
  if (session->locked_tables || session->active_transaction())
1 by brian
clean slate
42
  {
43
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
44
               ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
45
    return(1);
1 by brian
clean slate
46
  }
47
520.1.22 by Brian Aker
Second pass of thd cleanup
48
  mysql_ha_rm_tables(session, table_list, false);
1 by brian
clean slate
49
520.1.22 by Brian Aker
Second pass of thd cleanup
50
  if (wait_if_global_read_lock(session,0,1))
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
51
    return(1);
1 by brian
clean slate
52
53
  pthread_mutex_lock(&LOCK_open);
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
60
  error=0;
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
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
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
94
    write_bin_log(session, true, session->query, session->query_length);
95
    my_ok(session);
1 by brian
clean slate
96
  }
97
98
  pthread_mutex_lock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
99
  unlock_table_names(session, table_list, (TableList*) 0);
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);
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
104
  return(error);
1 by brian
clean slate
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
*/
327.2.4 by Brian Aker
Refactoring table.h
118
static TableList *reverse_table_list(TableList *table_list)
1 by brian
clean slate
119
{
327.2.4 by Brian Aker
Refactoring table.h
120
  TableList *prev= 0;
1 by brian
clean slate
121
122
  while (table_list)
123
  {
327.2.4 by Brian Aker
Refactoring table.h
124
    TableList *next= table_list->next_local;
1 by brian
clean slate
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()
520.1.22 by Brian Aker
Second pass of thd cleanup
138
      session               Thread handle
1 by brian
clean slate
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
520.1.22 by Brian Aker
Second pass of thd cleanup
154
do_rename(Session *session, TableList *ren_table, char *new_db, char *new_table_name,
1 by brian
clean slate
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;
77.1.77 by Monty Taylor
A crapton more warning cleanups (I turned on more warnings)
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;
1 by brian
clean slate
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);
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
179
    return(1);			// This can't be skipped
1 by brian
clean slate
180
  }
181
  build_table_filename(name, sizeof(name),
182
                       ren_table->db, old_alias, reg_ext, 0);
183
520.1.22 by Brian Aker
Second pass of thd cleanup
184
  rc= mysql_rename_table(ha_resolve_by_legacy_type(session, table_type),
1 by brian
clean slate
185
                               ren_table->db, old_alias,
186
                               new_db, new_alias, 0);
187
  if (rc && !skip_error)
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
188
    return(1);
1 by brian
clean slate
189
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
190
  return(0);
1 by brian
clean slate
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()
520.1.22 by Brian Aker
Second pass of thd cleanup
203
      session               Thread handle
1 by brian
clean slate
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
327.2.4 by Brian Aker
Refactoring table.h
217
static TableList *
520.1.22 by Brian Aker
Second pass of thd cleanup
218
rename_tables(Session *session, TableList *table_list, bool skip_error)
1 by brian
clean slate
219
{
327.2.4 by Brian Aker
Refactoring table.h
220
  TableList *ren_table, *new_table;
1 by brian
clean slate
221
222
  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
223
  {
224
    new_table= ren_table->next_local;
520.1.22 by Brian Aker
Second pass of thd cleanup
225
    if (do_rename(session, ren_table, new_table->db, new_table->table_name,
1 by brian
clean slate
226
                  new_table->alias, skip_error))
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
227
      return(ren_table);
1 by brian
clean slate
228
  }
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
229
  return(0);
1 by brian
clean slate
230
}