~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>
1 by brian
clean slate
24
520.1.22 by Brian Aker
Second pass of thd cleanup
25
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.
26
                                bool skip_error);
1 by brian
clean slate
27
327.2.4 by Brian Aker
Refactoring table.h
28
static TableList *reverse_table_list(TableList *table_list);
1 by brian
clean slate
29
30
/*
31
  Every second entry in the table_list is the original name and every
32
  second entry is the new name.
33
*/
34
575.2.2 by Monty Taylor
Moved vio stuff into libdrizzle.
35
bool drizzle_rename_tables(Session *session, TableList *table_list, bool silent)
1 by brian
clean slate
36
{
37
  bool error= 1;
327.2.4 by Brian Aker
Refactoring table.h
38
  TableList *ren_table= 0;
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
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
44
  if (session->locked_tables || session->active_transaction())
1 by brian
clean slate
45
  {
46
    my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
47
               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
48
    return(1);
1 by brian
clean slate
49
  }
50
520.1.22 by Brian Aker
Second pass of thd cleanup
51
  mysql_ha_rm_tables(session, table_list, false);
1 by brian
clean slate
52
520.1.22 by Brian Aker
Second pass of thd cleanup
53
  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
54
    return(1);
1 by brian
clean slate
55
56
  pthread_mutex_lock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
57
  if (lock_table_names_exclusively(session, table_list))
1 by brian
clean slate
58
  {
59
    pthread_mutex_unlock(&LOCK_open);
60
    goto err;
61
  }
62
63
  error=0;
520.1.22 by Brian Aker
Second pass of thd cleanup
64
  if ((ren_table=rename_tables(session,table_list,0)))
1 by brian
clean slate
65
  {
66
    /* Rename didn't succeed;  rename back the tables in reverse order */
327.2.4 by Brian Aker
Refactoring table.h
67
    TableList *table;
1 by brian
clean slate
68
69
    /* Reverse the table list */
70
    table_list= reverse_table_list(table_list);
71
72
    /* Find the last renamed table */
73
    for (table= table_list;
74
	 table->next_local != ren_table ;
75
	 table= table->next_local->next_local) ;
76
    table= table->next_local->next_local;		// Skip error table
77
    /* Revert to old names */
520.1.22 by Brian Aker
Second pass of thd cleanup
78
    rename_tables(session, table, 1);
1 by brian
clean slate
79
80
    /* Revert the table list (for prepared statements) */
81
    table_list= reverse_table_list(table_list);
82
83
    error= 1;
84
  }
85
  /*
86
    An exclusive lock on table names is satisfactory to ensure
87
    no other thread accesses this table.
88
    We still should unlock LOCK_open as early as possible, to provide
89
    higher concurrency - query_cache_invalidate can take minutes to
90
    complete.
91
  */
92
  pthread_mutex_unlock(&LOCK_open);
93
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
94
  /* Lets hope this doesn't fail as the result will be messy */
1 by brian
clean slate
95
  if (!silent && !error)
96
  {
520.1.22 by Brian Aker
Second pass of thd cleanup
97
    write_bin_log(session, true, session->query, session->query_length);
98
    my_ok(session);
1 by brian
clean slate
99
  }
100
101
  pthread_mutex_lock(&LOCK_open);
520.1.22 by Brian Aker
Second pass of thd cleanup
102
  unlock_table_names(session, table_list, (TableList*) 0);
1 by brian
clean slate
103
  pthread_mutex_unlock(&LOCK_open);
104
105
err:
520.1.22 by Brian Aker
Second pass of thd cleanup
106
  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
107
  return(error);
1 by brian
clean slate
108
}
109
110
111
/*
112
  reverse table list
113
114
  SYNOPSIS
115
    reverse_table_list()
116
    table_list pointer to table _list
117
118
  RETURN
119
    pointer to new (reversed) list
120
*/
327.2.4 by Brian Aker
Refactoring table.h
121
static TableList *reverse_table_list(TableList *table_list)
1 by brian
clean slate
122
{
327.2.4 by Brian Aker
Refactoring table.h
123
  TableList *prev= 0;
1 by brian
clean slate
124
125
  while (table_list)
126
  {
327.2.4 by Brian Aker
Refactoring table.h
127
    TableList *next= table_list->next_local;
1 by brian
clean slate
128
    table_list->next_local= prev;
129
    prev= table_list;
130
    table_list= next;
131
  }
132
  return (prev);
133
}
134
135
136
/*
137
  Rename a single table or a view
138
139
  SYNPOSIS
140
    do_rename()
520.1.22 by Brian Aker
Second pass of thd cleanup
141
      session               Thread handle
1 by brian
clean slate
142
      ren_table         A table/view to be renamed
143
      new_db            The database to which the table to be moved to
144
      new_table_name    The new table/view name
145
      new_table_alias   The new table/view alias
146
      skip_error        Whether to skip error
147
148
  DESCRIPTION
149
    Rename a single table or a view.
150
151
  RETURN
152
    false     Ok
153
    true      rename failed
154
*/
155
156
bool
520.1.22 by Brian Aker
Second pass of thd cleanup
157
do_rename(Session *session, TableList *ren_table, char *new_db, char *new_table_name,
1 by brian
clean slate
158
          char *new_table_alias, bool skip_error)
159
{
160
  int rc= 1;
161
  const char *new_alias, *old_alias;
162
163
  if (lower_case_table_names == 2)
164
  {
165
    old_alias= ren_table->alias;
166
    new_alias= new_table_alias;
167
  }
168
  else
169
  {
170
    old_alias= ren_table->table_name;
171
    new_alias= new_table_name;
172
  }
673.3.2 by Stewart Smith
start replacing calles to access(2) on frm file name with calls to ha_table_exists_in_engine
173
673.3.12 by Stewart Smith
fix RENAME TABLE
174
  handlerton *hton= NULL;
175
176
  if(ha_table_exists_in_engine(session, ren_table->db, old_alias, &hton)
177
     != HA_ERR_TABLE_EXIST)
178
  {
179
    my_error(ER_NO_SUCH_TABLE, MYF(0), ren_table->db, old_alias);
180
    return(1);
181
  }
182
673.3.2 by Stewart Smith
start replacing calles to access(2) on frm file name with calls to ha_table_exists_in_engine
183
  if (ha_table_exists_in_engine(session, new_db, new_alias)
184
      !=HA_ERR_NO_SUCH_TABLE)
1 by brian
clean slate
185
  {
186
    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
187
    return(1);			// This can't be skipped
1 by brian
clean slate
188
  }
189
673.3.12 by Stewart Smith
fix RENAME TABLE
190
  rc= mysql_rename_table(hton,
191
                         ren_table->db, old_alias,
192
                         new_db, new_alias, 0);
1 by brian
clean slate
193
  if (rc && !skip_error)
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
194
    return(1);
1 by brian
clean slate
195
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
196
  return(0);
1 by brian
clean slate
197
198
}
199
/*
200
  Rename all tables in list; Return pointer to wrong entry if something goes
201
  wrong.  Note that the table_list may be empty!
202
*/
203
204
/*
205
  Rename tables/views in the list
206
207
  SYNPOSIS
208
    rename_tables()
520.1.22 by Brian Aker
Second pass of thd cleanup
209
      session               Thread handle
1 by brian
clean slate
210
      table_list        List of tables to rename
211
      skip_error        Whether to skip errors
212
213
  DESCRIPTION
214
    Take a table/view name from and odd list element and rename it to a
215
    the name taken from list element+1. Note that the table_list may be
216
    empty.
217
218
  RETURN
219
    false     Ok
220
    true      rename failed
221
*/
222
327.2.4 by Brian Aker
Refactoring table.h
223
static TableList *
520.1.22 by Brian Aker
Second pass of thd cleanup
224
rename_tables(Session *session, TableList *table_list, bool skip_error)
1 by brian
clean slate
225
{
327.2.4 by Brian Aker
Refactoring table.h
226
  TableList *ren_table, *new_table;
1 by brian
clean slate
227
228
  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
229
  {
230
    new_table= ren_table->next_local;
520.1.22 by Brian Aker
Second pass of thd cleanup
231
    if (do_rename(session, ren_table, new_table->db, new_table->table_name,
1 by brian
clean slate
232
                  new_table->alias, skip_error))
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
233
      return(ren_table);
1 by brian
clean slate
234
  }
51.1.63 by Jay Pipes
Removed/replaced BUG symbols and standardized TRUE/FALSE. Removed dbug-only server option
235
  return(0);
1 by brian
clean slate
236
}