~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
/* Copyright (C) 2000-2003 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
/* create and drop of databases */
612.2.4 by Monty Taylor
Moved some defines to config.h. Stopped including config.h directly anywhere.
18
#include <drizzled/global.h>
481.1.9 by Monty Taylor
Added autoconf tests for location of cstdint and cinttypes. Use those in C++ programs now, so that we don't have to define _STDC_LIMIT_MACROS, etc by hand. Stop, in fact, defining those by hand.
19
#include CSTDINT_H
20
#include CINTTYPES_H
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
21
#include <string>
22
#include <fstream>
988.1.1 by Jay Pipes
Changes libserialize to libdrizzledmessage per ML discussion. All GPB messages are now in the drizzled::message namespace.
23
#include <drizzled/message/schema.pb.h>
318 by Brian Aker
Modified sql_db to now use Google Proto buffers instead of MySQL type.
24
using namespace std;
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
25
#include <drizzled/server_includes.h>
212.5.13 by Monty Taylor
Moved my_sys/my_pthread/my_nosys and mysys_err to mysys.
26
#include <mysys/mysys_err.h>
212.5.38 by Monty Taylor
Moved my_dir (and removed references to a lot of places)
27
#include <mysys/my_dir.h>
549 by Monty Taylor
Took gettext.h out of header files.
28
#include <drizzled/error.h>
538 by Monty Taylor
Moved gettext.h into drizzled in anticipation of the new client lib.
29
#include <drizzled/gettext.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.
30
#include <mysys/hash.h>
31
#include <drizzled/session.h>
32
#include <drizzled/db.h>
33
#include <drizzled/sql_base.h>
670.2.4 by Monty Taylor
Removed more stuff from the headers.
34
#include <drizzled/lock.h>
722.4.1 by Mark Atwood
integrate errmsg plugin into sql_print_* functions
35
#include <drizzled/errmsg_print.h>
1039.5.31 by Jay Pipes
This patch does a few things:
36
#include <drizzled/replication_services.h>
1089.10.1 by Stewart Smith
fix SHOW CREATE DATABASE for default collation. Move database metadata reading code around to be a bit more sane.
37
#include <drizzled/message/schema.pb.h>
988.1.6 by Jay Pipes
Removed old protobuf_replicator plugin, fixed up db.cc and other files to use new
38
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
39
using namespace drizzled;
40
822 by Brian Aker
Merge from Stewart.
41
#define MY_DB_OPT_FILE "db.opt"
1 by brian
clean slate
42
#define MAX_DROP_TABLE_Q_LEN      1024
43
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
44
const char *del_exts[]= {".dfe", ".BAK", ".TMD",".opt", NULL};
1 by brian
clean slate
45
static TYPELIB deletable_extentions=
46
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
47
520.1.22 by Brian Aker
Second pass of thd cleanup
48
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
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.
49
                                 const char *db, const char *path,
327.2.4 by Brian Aker
Refactoring table.h
50
                                 TableList **dropped_tables);
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.
51
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
52
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name);
53
            
1 by brian
clean slate
54
55
/**
56
  Return default database collation.
57
520.1.22 by Brian Aker
Second pass of thd cleanup
58
  @param session     Thread context.
1 by brian
clean slate
59
  @param db_name Database name.
60
61
  @return CHARSET_INFO object. The operation always return valid character
62
    set, even if the database does not exist.
63
*/
64
1014.3.1 by Brian Aker
Simplify the calling stack for getting schema collation. We need to extend
65
const CHARSET_INFO *get_default_db_collation(const char *db_name)
1 by brian
clean slate
66
{
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
67
  message::Schema db;
1089.10.1 by Stewart Smith
fix SHOW CREATE DATABASE for default collation. Move database metadata reading code around to be a bit more sane.
68
69
  get_database_metadata(db_name, &db);
70
71
  /* If for some reason the db.opt file lacks a collation,
72
     we just return the default */
73
74
  if (db.has_collation())
75
  {
76
    const string buffer= db.collation();
77
    const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
78
79
    if (!cs)
80
    {
81
      errmsg_printf(ERRMSG_LVL_ERROR,
82
                    _("Error while loading database options: '%s':"),db_name);
83
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
84
85
      return default_charset_info;
86
    }
87
88
    return cs;
89
  }
90
91
  return default_charset_info;
1 by brian
clean slate
92
}
93
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
94
/* path is path to database, not schema file */
95
static int write_schema_file(Session *session,
96
			     const char *path, const char *name,
97
			     HA_CREATE_INFO *create)
98
{
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
99
  message::Schema db;
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
100
  char schema_file_tmp[FN_REFLEN];
101
  string schema_file(path);
102
103
  assert(path);
104
  assert(name);
105
  assert(create);
106
822 by Brian Aker
Merge from Stewart.
107
  snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
108
109
  schema_file.append(1, FN_LIBCHAR);
822 by Brian Aker
Merge from Stewart.
110
  schema_file.append(MY_DB_OPT_FILE);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
111
112
  int fd= mkstemp(schema_file_tmp);
113
114
  if (fd==-1)
115
    return errno;
116
117
  if (!create->default_table_charset)
118
    create->default_table_charset= session->variables.collation_server;
119
120
  db.set_name(name);
121
  db.set_collation(create->default_table_charset->name);
122
123
  if (!db.SerializeToFileDescriptor(fd))
124
  {
125
    close(fd);
126
    unlink(schema_file_tmp);
127
    return -1;
128
  }
129
130
  if (rename(schema_file_tmp, schema_file.c_str()) == -1)
131
  {
132
    close(fd);
133
    return errno;
134
  }
135
136
  close(fd);
137
  return 0;
138
}
139
1118.2.1 by Stewart Smith
fix drizzled::message::Table usage so that in kernel .cc files we are 'using namespace drizzled'
140
int get_database_metadata(const char *dbname, message::Schema *db)
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
141
{
142
  char db_opt_path[FN_REFLEN];
1039.1.6 by Brian Aker
Refactor for build_table_filename()
143
  size_t length;
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
144
145
  /*
146
    Pass an empty file name, and the database options file name as extension
147
    to avoid table name to file name encoding.
148
  */
1039.1.6 by Brian Aker
Refactor for build_table_filename()
149
  length= build_table_filename(db_opt_path, sizeof(db_opt_path),
1089.10.1 by Stewart Smith
fix SHOW CREATE DATABASE for default collation. Move database metadata reading code around to be a bit more sane.
150
                              dbname, "", false);
1039.1.6 by Brian Aker
Refactor for build_table_filename()
151
  strcpy(db_opt_path + length, MY_DB_OPT_FILE);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
152
1089.10.1 by Stewart Smith
fix SHOW CREATE DATABASE for default collation. Move database metadata reading code around to be a bit more sane.
153
  int fd= open(db_opt_path, O_RDONLY);
154
155
  if (fd == -1)
156
    return errno;
157
158
  if (!db->ParseFromFileDescriptor(fd))
159
  {
160
    close(fd);
161
    return -1;
162
  }
163
  close(fd);
164
165
  return 0;
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
166
}
167
1 by brian
clean slate
168
/*
169
  Create a database
170
171
  SYNOPSIS
172
  mysql_create_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
173
  session		Thread handler
1 by brian
clean slate
174
  db		Name of database to create
175
		Function assumes that this is already validated.
176
  create_info	Database create options (like character set)
177
178
  SIDE-EFFECTS
179
   1. Report back to client that command succeeded (my_ok)
180
   2. Report errors to client
181
   3. Log event to binary log
182
183
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
184
  false ok
185
  true  Error
1 by brian
clean slate
186
187
*/
188
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
189
bool mysql_create_db(Session *session, const char *db, HA_CREATE_INFO *create_info, bool is_if_not_exists)
1 by brian
clean slate
190
{
1130.1.2 by Monty Taylor
Re-org'd the replication stuff into slots.
191
  ReplicationServices &replication_services= ReplicationServices::singleton();
1 by brian
clean slate
192
  char	 path[FN_REFLEN+16];
193
  long result= 1;
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
194
  int error_erno;
195
  bool error= false;
482 by Brian Aker
Remove uint.
196
  uint32_t path_len;
1 by brian
clean slate
197
198
  /* do not create 'information_schema' db */
575.4.7 by Monty Taylor
More header cleanup.
199
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
1 by brian
clean slate
200
  {
201
    my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
202
    return(-1);
1 by brian
clean slate
203
  }
204
205
  /*
206
    Do not create database if another thread is holding read lock.
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
207
    Wait for global read lock before acquiring LOCK_create_db.
1 by brian
clean slate
208
    After wait_if_global_read_lock() we have protection against another
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
209
    global read lock. If we would acquire LOCK_create_db first,
1 by brian
clean slate
210
    another thread could step in and get the global read lock before we
211
    reach wait_if_global_read_lock(). If this thread tries the same as we
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
212
    (admin a db), it would then go and wait on LOCK_create_db...
1 by brian
clean slate
213
    Furthermore wait_if_global_read_lock() checks if the current thread
214
    has the global read lock and refuses the operation with
215
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
216
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
217
  if (wait_if_global_read_lock(session, 0, 1))
1 by brian
clean slate
218
  {
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
219
    error= true;
1 by brian
clean slate
220
    goto exit2;
221
  }
222
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
223
  pthread_mutex_lock(&LOCK_create_db);
1 by brian
clean slate
224
225
  /* Check directory */
1039.1.6 by Brian Aker
Refactor for build_table_filename()
226
  path_len= build_table_filename(path, sizeof(path), db, "", false);
1 by brian
clean slate
227
  path[path_len-1]= 0;                    // Remove last '/' from path
228
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
229
  if (mkdir(path,0777) == -1)
1 by brian
clean slate
230
  {
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
231
    if (errno == EEXIST)
1 by brian
clean slate
232
    {
1222.2.3 by Brian Aker
Remove a few more options, from options in HA_CREATE_INFO.
233
      if (! is_if_not_exists)
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
234
      {
235
	my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
236
	error= true;
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
237
	goto exit;
238
      }
239
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
240
			  ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
241
      session->my_ok();
242
      error= false;
1 by brian
clean slate
243
      goto exit;
244
    }
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
245
246
    my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
247
    error= true;
1 by brian
clean slate
248
    goto exit;
249
  }
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
250
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
251
  error_erno= write_schema_file(session, path, db, create_info);
252
  if (error_erno && error_erno != EEXIST)
1 by brian
clean slate
253
  {
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
254
    if (rmdir(path) >= 0)
255
    {
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
256
      error= true;
1 by brian
clean slate
257
      goto exit;
258
    }
259
  }
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
260
  else if (error_erno)
261
    error= true;
262
1039.5.31 by Jay Pipes
This patch does a few things:
263
  replication_services.rawStatement(session, session->query, session->query_length);
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
264
  session->my_ok(result);
1 by brian
clean slate
265
266
exit:
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
267
  pthread_mutex_unlock(&LOCK_create_db);
520.1.22 by Brian Aker
Second pass of thd cleanup
268
  start_waiting_global_read_lock(session);
1 by brian
clean slate
269
exit2:
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
270
  return error;
1 by brian
clean slate
271
}
272
273
274
/* db-name is already validated when we come here */
275
520.1.22 by Brian Aker
Second pass of thd cleanup
276
bool mysql_alter_db(Session *session, const char *db, HA_CREATE_INFO *create_info)
1 by brian
clean slate
277
{
1130.1.2 by Monty Taylor
Re-org'd the replication stuff into slots.
278
  ReplicationServices &replication_services= ReplicationServices::singleton();
1 by brian
clean slate
279
  long result=1;
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
280
  int error= 0;
281
  char	 path[FN_REFLEN+16];
282
  uint32_t path_len;
1 by brian
clean slate
283
284
  /*
285
    Do not alter database if another thread is holding read lock.
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
286
    Wait for global read lock before acquiring LOCK_create_db.
1 by brian
clean slate
287
    After wait_if_global_read_lock() we have protection against another
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
288
    global read lock. If we would acquire LOCK_create_db first,
1 by brian
clean slate
289
    another thread could step in and get the global read lock before we
290
    reach wait_if_global_read_lock(). If this thread tries the same as we
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
291
    (admin a db), it would then go and wait on LOCK_create_db...
1 by brian
clean slate
292
    Furthermore wait_if_global_read_lock() checks if the current thread
293
    has the global read lock and refuses the operation with
294
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
295
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
296
  if ((error=wait_if_global_read_lock(session,0,1)))
811.1.2 by Stewart Smith
remove existing db.opt implementation.
297
    goto exit;
1 by brian
clean slate
298
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
299
  pthread_mutex_lock(&LOCK_create_db);
1 by brian
clean slate
300
301
  /* Change options if current database is being altered. */
1039.1.6 by Brian Aker
Refactor for build_table_filename()
302
  path_len= build_table_filename(path, sizeof(path), db, "", false);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
303
  path[path_len-1]= 0;                    // Remove last '/' from path
304
305
  error= write_schema_file(session, path, db, create_info);
306
  if (error && error != EEXIST)
307
  {
308
    /* TODO: find some witty way of getting back an error message */
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
309
    pthread_mutex_unlock(&LOCK_create_db);
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
310
    goto exit;
311
  }
1 by brian
clean slate
312
1039.5.31 by Jay Pipes
This patch does a few things:
313
  replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
836 by Brian Aker
Fixed session call from function to method.
314
  session->my_ok(result);
1 by brian
clean slate
315
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
316
  pthread_mutex_unlock(&LOCK_create_db);
520.1.22 by Brian Aker
Second pass of thd cleanup
317
  start_waiting_global_read_lock(session);
811.1.2 by Stewart Smith
remove existing db.opt implementation.
318
exit:
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
319
  return error ? true : false;
1 by brian
clean slate
320
}
321
322
323
/*
324
  Drop all tables in a database and the database itself
325
326
  SYNOPSIS
327
    mysql_rm_db()
520.1.22 by Brian Aker
Second pass of thd cleanup
328
    session			Thread handle
1 by brian
clean slate
329
    db			Database name in the case given by user
330
		        It's already validated and set to lower case
331
                        (if needed) when we come here
332
    if_exists		Don't give error if database doesn't exists
333
    silent		Don't generate errors
334
335
  RETURN
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
336
    false ok (Database dropped)
1 by brian
clean slate
337
    ERROR Error
338
*/
339
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
340
bool mysql_rm_db(Session *session,char *db,bool if_exists)
1 by brian
clean slate
341
{
342
  long deleted=0;
253 by Brian Aker
Removed final my_bool from sql_db.
343
  int error= false;
1 by brian
clean slate
344
  char	path[FN_REFLEN+16];
345
  MY_DIR *dirp;
482 by Brian Aker
Remove uint.
346
  uint32_t length;
1034.1.5 by Brian Aker
Small refactor of db.cc
347
  TableList *dropped_tables= NULL;
1 by brian
clean slate
348
349
  if (db && (strcmp(db, "information_schema") == 0))
350
  {
575.4.7 by Monty Taylor
More header cleanup.
351
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
1014.3.3 by Brian Aker
Formating fix.
352
    return true;
1 by brian
clean slate
353
  }
354
355
  /*
356
    Do not drop database if another thread is holding read lock.
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
357
    Wait for global read lock before acquiring LOCK_create_db.
1 by brian
clean slate
358
    After wait_if_global_read_lock() we have protection against another
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
359
    global read lock. If we would acquire LOCK_create_db first,
1 by brian
clean slate
360
    another thread could step in and get the global read lock before we
361
    reach wait_if_global_read_lock(). If this thread tries the same as we
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
362
    (admin a db), it would then go and wait on LOCK_create_db...
1 by brian
clean slate
363
    Furthermore wait_if_global_read_lock() checks if the current thread
364
    has the global read lock and refuses the operation with
365
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
366
  */
520.1.22 by Brian Aker
Second pass of thd cleanup
367
  if (wait_if_global_read_lock(session, 0, 1))
1 by brian
clean slate
368
  {
369
    error= -1;
370
    goto exit2;
371
  }
372
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
373
  pthread_mutex_lock(&LOCK_create_db);
1 by brian
clean slate
374
1039.1.6 by Brian Aker
Refactor for build_table_filename()
375
  length= build_table_filename(path, sizeof(path), db, "", false);
822 by Brian Aker
Merge from Stewart.
376
  strcpy(path+length, MY_DB_OPT_FILE);         // Append db option file name
820.1.11 by Stewart Smith
re-introduce db.opt, but with parsing it from disk instead of in process cache with mutex.
377
  unlink(path);
1 by brian
clean slate
378
  path[length]= '\0';				// Remove file name
379
380
  /* See if the directory exists */
381
  if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
382
  {
383
    if (!if_exists)
384
    {
385
      error= -1;
386
      my_error(ER_DB_DROP_EXISTS, MYF(0), db);
387
      goto exit;
388
    }
389
    else
520.1.22 by Brian Aker
Second pass of thd cleanup
390
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
391
			  ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
392
  }
393
  else
394
  {
1046.1.2 by Brian Aker
Comments on LOCK_open
395
    pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
1 by brian
clean slate
396
    remove_db_from_cache(db);
397
    pthread_mutex_unlock(&LOCK_open);
398
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
399
1 by brian
clean slate
400
    error= -1;
1034.1.5 by Brian Aker
Small refactor of db.cc
401
    if ((deleted= mysql_rm_known_files(session, dirp, db, path, &dropped_tables)) >= 0)
1 by brian
clean slate
402
    {
1152.1.4 by Brian Aker
Remove wrappers from SE
403
      plugin::StorageEngine::dropDatabase(path);
1 by brian
clean slate
404
      error = 0;
405
    }
406
  }
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
407
  if (deleted >= 0)
1 by brian
clean slate
408
  {
409
    const char *query;
308 by Brian Aker
ulong conversion
410
    uint32_t query_length;
520.1.22 by Brian Aker
Second pass of thd cleanup
411
    if (!session->query)
1 by brian
clean slate
412
    {
413
      /* The client used the old obsolete mysql_drop_db() call */
414
      query= path;
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
415
      query_length= sprintf(path, "drop database `%s`", db);
1 by brian
clean slate
416
    }
417
    else
418
    {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
419
      query= session->query;
520.1.22 by Brian Aker
Second pass of thd cleanup
420
      query_length= session->query_length;
1 by brian
clean slate
421
    }
1130.1.2 by Monty Taylor
Re-org'd the replication stuff into slots.
422
    ReplicationServices &replication_services= ReplicationServices::singleton();
1039.5.31 by Jay Pipes
This patch does a few things:
423
    replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
520.1.22 by Brian Aker
Second pass of thd cleanup
424
    session->clear_error();
425
    session->server_status|= SERVER_STATUS_DB_DROPPED;
836 by Brian Aker
Fixed session call from function to method.
426
    session->my_ok((uint32_t) deleted);
520.1.22 by Brian Aker
Second pass of thd cleanup
427
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
1 by brian
clean slate
428
  }
798.2.19 by Brian Aker
Converted db.cc away from using binlog
429
  else
1 by brian
clean slate
430
  {
431
    char *query, *query_pos, *query_end, *query_data_start;
327.2.4 by Brian Aker
Refactoring table.h
432
    TableList *tbl;
482 by Brian Aker
Remove uint.
433
    uint32_t db_len;
1 by brian
clean slate
434
520.1.22 by Brian Aker
Second pass of thd cleanup
435
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
1 by brian
clean slate
436
      goto exit; /* not much else we can do */
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
437
    query_pos= query_data_start= strcpy(query,"drop table ")+11;
1 by brian
clean slate
438
    query_end= query + MAX_DROP_TABLE_Q_LEN;
439
    db_len= strlen(db);
440
1130.1.2 by Monty Taylor
Re-org'd the replication stuff into slots.
441
    ReplicationServices &replication_services= ReplicationServices::singleton();
1 by brian
clean slate
442
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
443
    {
482 by Brian Aker
Remove uint.
444
      uint32_t tbl_name_len;
1 by brian
clean slate
445
446
      /* 3 for the quotes and the comma*/
447
      tbl_name_len= strlen(tbl->table_name) + 3;
448
      if (query_pos + tbl_name_len + 1 >= query_end)
449
      {
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
450
        /* These DDL methods and logging protected with LOCK_create_db */
1039.5.31 by Jay Pipes
This patch does a few things:
451
        replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
1 by brian
clean slate
452
        query_pos= query_data_start;
453
      }
454
455
      *query_pos++ = '`';
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
456
      query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
1 by brian
clean slate
457
      *query_pos++ = '`';
458
      *query_pos++ = ',';
459
    }
460
461
    if (query_pos != query_data_start)
462
    {
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
463
      /* These DDL methods and logging protected with LOCK_create_db */
1039.5.31 by Jay Pipes
This patch does a few things:
464
      replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
1 by brian
clean slate
465
    }
466
  }
467
468
exit:
469
  /*
470
    If this database was the client's selected database, we silently
471
    change the client's selected database to nothing (to have an empty
520.1.22 by Brian Aker
Second pass of thd cleanup
472
    SELECT DATABASE() in the future). For this we free() session->db and set
1 by brian
clean slate
473
    it to 0.
474
  */
1220.1.9 by Brian Aker
Remove char *db from session, and replaces it with std::string.
475
  if (! session->db.empty() && ! strcmp(session->db.c_str(), db))
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
476
    mysql_change_db_impl(session, NULL);
971.3.2 by Eric Day
Renamed LOCK_drizzleclient_create_db to LOCK_create_db since this has nothing to do with drizzleclient. I think Monty accidently got this during the drizzleclient rename.
477
  pthread_mutex_unlock(&LOCK_create_db);
520.1.22 by Brian Aker
Second pass of thd cleanup
478
  start_waiting_global_read_lock(session);
1 by brian
clean slate
479
exit2:
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
480
  return(error);
1 by brian
clean slate
481
}
482
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
483
484
static int rm_table_part2(Session *session, TableList *tables)
485
{
486
  TableList *table;
487
  String wrong_tables;
488
  int error= 0;
489
  bool foreign_key_error= false;
490
491
  pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
492
493
  /*
494
    If we have the table in the definition cache, we don't have to check the
495
    .frm cursor to find if the table is a normal table (not view) and what
496
    engine to use.
497
  */
498
499
  for (table= tables; table; table= table->next_local)
500
  {
501
    TableShare *share;
502
    table->db_type= NULL;
503
    if ((share= TableShare::getShare(table->db, table->table_name)))
504
      table->db_type= share->db_type();
505
  }
506
507
  if (lock_table_names_exclusively(session, tables))
508
  {
509
    pthread_mutex_unlock(&LOCK_open);
510
    return 1;
511
  }
512
513
  /* Don't give warnings for not found errors, as we already generate notes */
514
  session->no_warnings_for_error= 1;
515
516
  for (table= tables; table; table= table->next_local)
517
  {
518
    char *db=table->db;
519
    plugin::StorageEngine *table_type;
520
521
    error= session->drop_temporary_table(table);
522
523
    switch (error) {
524
    case  0:
525
      // removed temporary table
526
      continue;
527
    case -1:
528
      error= 1;
529
      goto err_with_placeholders;
530
    default:
531
      // temporary table not found
532
      error= 0;
533
    }
534
535
    table_type= table->db_type;
536
537
    {
538
      Table *locked_table;
539
      abort_locked_tables(session, db, table->table_name);
540
      remove_table_from_cache(session, db, table->table_name,
541
                              RTFC_WAIT_OTHER_THREAD_FLAG |
542
                              RTFC_CHECK_KILLED_FLAG);
543
      /*
544
        If the table was used in lock tables, remember it so that
545
        unlock_table_names can free it
546
      */
547
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
548
        table->table= locked_table;
549
550
      if (session->killed)
551
      {
552
        error= -1;
553
        goto err_with_placeholders;
554
      }
555
    }
556
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
557
    TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : NO_TMP_TABLE);
558
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
559
    if ((table_type == NULL
560
          && (plugin::StorageEngine::getTableDefinition(*session,
1223.4.17 by Brian Aker
Added a form of getTableDefinition() that uses TableIdentifiers
561
                                                        identifier) != EEXIST)))
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
562
    {
563
      // Table was not found on disk and table can't be created from engine
564
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
565
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
566
                          table->table_name);
567
    }
568
    else
569
    {
1223.4.16 by Brian Aker
Drop Table now uses identifier.
570
      error= plugin::StorageEngine::dropTable(*session,
571
                                              identifier,
572
                                              false);
1223.4.11 by Brian Aker
Modifications to use mysql_rm_table
573
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
574
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
575
      {
576
	error= 0;
577
        session->clear_error();
578
      }
579
580
      if (error == HA_ERR_ROW_IS_REFERENCED)
581
      {
582
        /* the table is referenced by a foreign key constraint */
583
        foreign_key_error= true;
584
      }
585
    }
586
587
    if (error == 0 || (foreign_key_error == false))
588
        write_bin_log_drop_table(session, true, db, table->table_name);
589
590
    if (error)
591
    {
592
      if (wrong_tables.length())
593
        wrong_tables.append(',');
594
      wrong_tables.append(String(table->table_name,system_charset_info));
595
    }
596
  }
597
  /*
598
    It's safe to unlock LOCK_open: we have an exclusive lock
599
    on the table name.
600
  */
601
  pthread_mutex_unlock(&LOCK_open);
602
  error= 0;
603
  if (wrong_tables.length())
604
  {
605
    if (!foreign_key_error)
606
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
607
                      wrong_tables.c_ptr());
608
    else
609
    {
610
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
611
    }
612
    error= 1;
613
  }
614
615
  pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
616
err_with_placeholders:
617
  unlock_table_names(tables, NULL);
618
  pthread_mutex_unlock(&LOCK_open);
619
  session->no_warnings_for_error= 0;
620
621
  return(error);
622
}
623
1 by brian
clean slate
624
/*
255 by Brian Aker
Removed RAID table delete point.
625
  Removes files with known extensions plus.
520.1.22 by Brian Aker
Second pass of thd cleanup
626
  session MUST be set when calling this function!
1 by brian
clean slate
627
*/
628
520.1.22 by Brian Aker
Second pass of thd cleanup
629
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
1034.1.5 by Brian Aker
Small refactor of db.cc
630
				 const char *org_path,
327.2.4 by Brian Aker
Refactoring table.h
631
                                 TableList **dropped_tables)
1 by brian
clean slate
632
{
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
633
  long deleted= 0;
1 by brian
clean slate
634
  char filePath[FN_REFLEN];
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
635
  TableList *tot_list= NULL, **tot_list_next;
1 by brian
clean slate
636
637
  tot_list_next= &tot_list;
638
1034.1.5 by Brian Aker
Small refactor of db.cc
639
  for (uint32_t idx= 0;
895 by Brian Aker
Completion (?) of uint conversion.
640
       idx < (uint32_t) dirp->number_off_files && !session->killed ;
1 by brian
clean slate
641
       idx++)
642
  {
643
    FILEINFO *file=dirp->dir_entry+idx;
644
    char *extension;
645
646
    /* skiping . and .. */
647
    if (file->name[0] == '.' && (!file->name[1] ||
648
       (file->name[1] == '.' &&  !file->name[2])))
649
      continue;
650
651
    if (!(extension= strrchr(file->name, '.')))
376 by Brian Aker
strend remove
652
      extension= strchr(file->name, '\0');
1 by brian
clean slate
653
    if (find_type(extension, &deletable_extentions,1+2) <= 0)
654
    {
584.2.7 by Stewart Smith
rename and delete tabledefinition protobuf file
655
      /*
656
        ass ass ass.
657
658
        strange checking for magic extensions that are then deleted if
659
        not reg_ext (i.e. .frm).
660
661
        and (previously) we'd err out on drop database if files not matching
662
        engine ha_known_exts() or deletable_extensions were present.
663
664
        presumably this was to avoid deleting other user data... except if that
665
        data happened to be in files ending in .BAK, .opt or .TMD. *fun*
666
       */
1 by brian
clean slate
667
      continue;
668
    }
669
    /* just for safety we use files_charset_info */
670
    if (db && !my_strcasecmp(files_charset_info,
896.4.9 by Stewart Smith
No longer write the FRM. just use proto.
671
                             extension, ".dfe"))
1 by brian
clean slate
672
    {
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
673
      uint32_t db_len= strlen(db);
674
1 by brian
clean slate
675
      /* Drop the table nicely */
1039.1.14 by Brian Aker
Fix for gcc 4.1
676
      *extension= 0;			// Remove extension
327.2.4 by Brian Aker
Refactoring table.h
677
      TableList *table_list=(TableList*)
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
678
                              session->calloc(sizeof(*table_list) +
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
679
                                          db_len + 1 +
1 by brian
clean slate
680
                                          strlen(file->name) + 1);
681
682
      if (!table_list)
683
        goto err;
684
      table_list->db= (char*) (table_list+1);
641.4.1 by Toru Maesaka
First pass of replacing MySQL's my_stpcpy() with appropriate libc calls
685
      table_list->table_name= strcpy(table_list->db, db) + db_len + 1;
398.1.10 by Monty Taylor
Actually removed VOID() this time.
686
      filename_to_tablename(file->name, table_list->table_name,
687
                            strlen(file->name) + 1);
1 by brian
clean slate
688
      table_list->alias= table_list->table_name;	// If lower_case_table_names=2
584.2.1 by Stewart Smith
convert tmp_file_prefix to TMP_FILE_PREFIX to indicate it's a macro
689
      table_list->internal_tmp_table= is_prefix(file->name, TMP_FILE_PREFIX);
1 by brian
clean slate
690
      /* Link into list */
691
      (*tot_list_next)= table_list;
692
      tot_list_next= &table_list->next_local;
693
      deleted++;
694
    }
695
    else
696
    {
673.2.1 by Toru Maesaka
First pass of replacing MySQL's strxmov with libc alternatives
697
      sprintf(filePath, "%s/%s", org_path, file->name);
1 by brian
clean slate
698
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
699
      {
700
	goto err;
701
      }
702
    }
703
  }
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
704
  if (session->killed)
1 by brian
clean slate
705
    goto err;
706
1223.4.10 by Brian Aker
Split remove table into 2 parts. The piece for dropDatabase() needs to be
707
  if (tot_list)
708
  {
709
    if (rm_table_part2(session, tot_list))
710
      goto err;
711
  }
712
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
713
  my_dirend(dirp);
714
1 by brian
clean slate
715
  if (dropped_tables)
716
    *dropped_tables= tot_list;
660.1.3 by Eric Herman
removed trailing whitespace with simple script:
717
1060.1.1 by Eric Lambert
-removed rm_dir_w_symlink method call with rmdir since dir should not be a sym link in the first place.
718
  if (rmdir(org_path))
719
  {
720
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, errno);
1034.1.5 by Brian Aker
Small refactor of db.cc
721
    return -1;
1060.1.1 by Eric Lambert
-removed rm_dir_w_symlink method call with rmdir since dir should not be a sym link in the first place.
722
  }
1 by brian
clean slate
723
1039.1.3 by Brian Aker
Remove dead bits from db create/rm
724
  return deleted;
1 by brian
clean slate
725
726
err:
727
  my_dirend(dirp);
1034.1.5 by Brian Aker
Small refactor of db.cc
728
  return -1;
1 by brian
clean slate
729
}
730
731
/**
732
  @brief Internal implementation: switch current database to a valid one.
733
520.1.22 by Brian Aker
Second pass of thd cleanup
734
  @param session            Thread context.
1 by brian
clean slate
735
  @param new_db_name    Name of the database to switch to. The function will
736
                        take ownership of the name (the caller must not free
737
                        the allocated memory). If the name is NULL, we're
738
                        going to switch to NULL db.
739
  @param new_db_charset Character set of the new database.
740
*/
741
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
742
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name)
1 by brian
clean slate
743
{
520.1.21 by Brian Aker
THD -> Session rename
744
  /* 1. Change current database in Session. */
1 by brian
clean slate
745
746
  if (new_db_name == NULL)
747
  {
748
    /*
520.1.21 by Brian Aker
THD -> Session rename
749
      Session::set_db() does all the job -- it frees previous database name and
1 by brian
clean slate
750
      sets the new one.
751
    */
752
520.1.22 by Brian Aker
Second pass of thd cleanup
753
    session->set_db(NULL, 0);
1 by brian
clean slate
754
  }
755
  else
756
  {
757
    /*
520.1.21 by Brian Aker
THD -> Session rename
758
      Here we already have a copy of database name to be used in Session. So,
759
      we just call Session::reset_db(). Since Session::reset_db() does not releases
1 by brian
clean slate
760
      the previous database name, we should do it explicitly.
761
    */
762
1220.1.9 by Brian Aker
Remove char *db from session, and replaces it with std::string.
763
    session->set_db(new_db_name->str, new_db_name->length);
1 by brian
clean slate
764
  }
765
}
766
767
/**
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
768
  Return true if db1_name is equal to db2_name, false otherwise.
1 by brian
clean slate
769
770
  The function allows to compare database names according to the MySQL
771
  rules. The database names db1 and db2 are equal if:
772
     - db1 is NULL and db2 is NULL;
773
     or
774
     - db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
775
       db2 in system character set (UTF8).
776
*/
777
778
static inline bool
779
cmp_db_names(const char *db1_name,
780
             const char *db2_name)
781
{
782
  return
783
         /* db1 is NULL and db2 is NULL */
784
         (!db1_name && !db2_name) ||
785
786
         /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
787
         (db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
788
}
789
790
791
/**
792
  @brief Change the current database and its attributes unconditionally.
793
520.1.22 by Brian Aker
Second pass of thd cleanup
794
  @param session          thread handle
1 by brian
clean slate
795
  @param new_db_name  database name
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
796
  @param force_switch if force_switch is false, then the operation will fail if
1 by brian
clean slate
797
798
                        - new_db_name is NULL or empty;
799
800
                        - OR new database name is invalid
801
                          (check_db_name() failed);
802
803
                        - OR user has no privilege on the new database;
804
805
                        - OR new database does not exist;
806
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
807
                      if force_switch is true, then
1 by brian
clean slate
808
809
                        - if new_db_name is NULL or empty, the current
810
                          database will be NULL, @@collation_database will
811
                          be set to @@collation_server, the operation will
812
                          succeed.
813
814
                        - if new database name is invalid
815
                          (check_db_name() failed), the current database
816
                          will be NULL, @@collation_database will be set to
817
                          @@collation_server, but the operation will fail;
818
819
                        - user privileges will not be checked
520.1.21 by Brian Aker
THD -> Session rename
820
                          (Session::db_access however is updated);
1 by brian
clean slate
821
822
                          TODO: is this really the intention?
823
                                (see sp-security.test).
824
825
                        - if new database does not exist,the current database
826
                          will be NULL, @@collation_database will be set to
827
                          @@collation_server, a warning will be thrown, the
828
                          operation will succeed.
829
830
  @details The function checks that the database name corresponds to a
831
  valid and existent database, checks access rights and changes the current
832
  database with database attributes (@@collation_database session variable,
520.1.21 by Brian Aker
THD -> Session rename
833
  Session::db_access).
1 by brian
clean slate
834
835
  This function is not the only way to switch the database that is
836
  currently employed. When the replication slave thread switches the
520.1.22 by Brian Aker
Second pass of thd cleanup
837
  database before executing a query, it calls session->set_db directly.
1 by brian
clean slate
838
  However, if the query, in turn, uses a stored routine, the stored routine
839
  will use this function, even if it's run on the slave.
840
841
  This function allocates the name of the database on the system heap: this
842
  is necessary to be able to uniformly change the database from any module
843
  of the server. Up to 5.0 different modules were using different memory to
844
  store the name of the database, and this led to memory corruption:
845
  a stack pointer set by Stored Procedures was used by replication after
846
  the stack address was long gone.
847
848
  @return Operation status
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
849
    @retval false Success
850
    @retval true  Error
1 by brian
clean slate
851
*/
852
520.1.22 by Brian Aker
Second pass of thd cleanup
853
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
1 by brian
clean slate
854
{
855
  LEX_STRING new_db_file_name;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
856
  const CHARSET_INFO *db_default_cl;
1 by brian
clean slate
857
1039.3.14 by Stewart Smith
remove old code for changing databases only called from stored procedures
858
  assert(new_db_name);
859
  assert(new_db_name->length);
1 by brian
clean slate
860
861
  if (my_strcasecmp(system_charset_info, new_db_name->str,
575.4.7 by Monty Taylor
More header cleanup.
862
                    INFORMATION_SCHEMA_NAME.c_str()) == 0)
1 by brian
clean slate
863
  {
864
    /* Switch the current database to INFORMATION_SCHEMA. */
575.4.7 by Monty Taylor
More header cleanup.
865
    /* const_cast<> is safe here: mysql_change_db_impl does a copy */
866
    LEX_STRING is_name= { const_cast<char *>(INFORMATION_SCHEMA_NAME.c_str()),
867
                          INFORMATION_SCHEMA_NAME.length() };
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
868
    mysql_change_db_impl(session, &is_name);
1 by brian
clean slate
869
1014.3.3 by Brian Aker
Formating fix.
870
    return false;
1 by brian
clean slate
871
  }
872
873
  /*
874
    Now we need to make a copy because check_db_name requires a
875
    non-constant argument. Actually, it takes database file name.
876
877
    TODO: fix check_db_name().
878
  */
879
656.1.34 by Monty Taylor
Got closer...
880
  new_db_file_name.length= new_db_name->length;
881
  new_db_file_name.str= (char *)malloc(new_db_name->length + 1);
656.1.44 by Monty Taylor
Added some return checking.
882
  if (new_db_file_name.str == NULL)
1014.3.3 by Brian Aker
Formating fix.
883
    return true;                             /* the error is set */
656.1.34 by Monty Taylor
Got closer...
884
  memcpy(new_db_file_name.str, new_db_name->str, new_db_name->length);
885
  new_db_file_name.str[new_db_name->length]= 0;
886
1 by brian
clean slate
887
888
  /*
889
    NOTE: if check_db_name() fails, we should throw an error in any case,
890
    even if we are called from sp_head::execute().
891
892
    It's next to impossible however to get this error when we are called
893
    from sp_head::execute(). But let's switch the current database to NULL
894
    in this case to be sure.
895
  */
896
897
  if (check_db_name(&new_db_file_name))
898
  {
899
    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
900
    free(new_db_file_name.str);
1 by brian
clean slate
901
902
    if (force_switch)
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
903
      mysql_change_db_impl(session, NULL);
1 by brian
clean slate
904
1014.3.3 by Brian Aker
Formating fix.
905
    return true;
1 by brian
clean slate
906
  }
907
908
  if (check_db_dir_existence(new_db_file_name.str))
909
  {
910
    if (force_switch)
911
    {
912
      /* Throw a warning and free new_db_file_name. */
913
520.1.22 by Brian Aker
Second pass of thd cleanup
914
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1 by brian
clean slate
915
                          ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
916
                          new_db_file_name.str);
917
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
918
      free(new_db_file_name.str);
1 by brian
clean slate
919
920
      /* Change db to NULL. */
921
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
922
      mysql_change_db_impl(session, NULL);
1 by brian
clean slate
923
924
      /* The operation succeed. */
925
1014.3.3 by Brian Aker
Formating fix.
926
      return false;
1 by brian
clean slate
927
    }
928
    else
929
    {
930
      /* Report an error and free new_db_file_name. */
931
932
      my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
477 by Monty Taylor
Removed my_free(). It turns out that it had been def'd to ignore the flags passed to it in the second arg anyway. Gotta love that.
933
      free(new_db_file_name.str);
1 by brian
clean slate
934
935
      /* The operation failed. */
936
1014.3.3 by Brian Aker
Formating fix.
937
      return true;
1 by brian
clean slate
938
    }
939
  }
940
1014.3.1 by Brian Aker
Simplify the calling stack for getting schema collation. We need to extend
941
  db_default_cl= get_default_db_collation(new_db_file_name.str);
1 by brian
clean slate
942
1014.3.2 by Brian Aker
Factor out need for session in many "schema" calls. Removed variable about
943
  mysql_change_db_impl(session, &new_db_file_name);
1220.1.9 by Brian Aker
Remove char *db from session, and replaces it with std::string.
944
  free(new_db_file_name.str);
1 by brian
clean slate
945
1014.3.3 by Brian Aker
Formating fix.
946
  return false;
1 by brian
clean slate
947
}
948
949
/*
950
  Check if there is directory for the database name.
951
952
  SYNOPSIS
953
    check_db_dir_existence()
954
    db_name   database name
955
956
  RETURN VALUES
51.1.51 by Jay Pipes
Removed/replaced DBUG symbols and standardized TRUE/FALSE
957
    false   There is directory for the specified database name.
958
    true    The directory does not exist.
1 by brian
clean slate
959
*/
960
961
bool check_db_dir_existence(const char *db_name)
962
{
963
  char db_dir_path[FN_REFLEN];
482 by Brian Aker
Remove uint.
964
  uint32_t db_dir_path_len;
1 by brian
clean slate
965
966
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1039.1.6 by Brian Aker
Refactor for build_table_filename()
967
                                        db_name, "", false);
1 by brian
clean slate
968
969
  if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
970
    db_dir_path[db_dir_path_len - 1]= 0;
971
972
  /* Check access. */
973
974
  return my_access(db_dir_path, F_OK);
975
}