~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/db.cc

  • Committer: Brian Aker
  • Date: 2010-02-11 22:43:58 UTC
  • Revision ID: brian@gaz-20100211224358-y0gdvnat2ahg4c1e
Disabling support for memcached plugins until we can test for version of
memcached.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
 
16
16
 
17
17
/* create and drop of databases */
 
18
#include "config.h"
 
19
 
 
20
#include <fcntl.h>
 
21
#include <sys/stat.h>
 
22
#include <sys/types.h>
 
23
 
 
24
#include <set>
18
25
#include <string>
19
26
#include <fstream>
20
 
#include <drizzled/serialize/serialize.h>
 
27
 
 
28
#include <drizzled/message/schema.pb.h>
 
29
#include "drizzled/error.h"
 
30
#include <drizzled/gettext.h>
 
31
#include <drizzled/my_hash.h>
 
32
#include "drizzled/internal/m_string.h"
 
33
#include <drizzled/session.h>
 
34
#include <drizzled/db.h>
 
35
#include <drizzled/sql_base.h>
 
36
#include <drizzled/lock.h>
 
37
#include <drizzled/errmsg_print.h>
 
38
#include <drizzled/replication_services.h>
 
39
#include <drizzled/message/schema.pb.h>
 
40
#include "drizzled/sql_table.h"
 
41
#include "drizzled/plugin/info_schema_table.h"
 
42
#include "drizzled/global_charset_info.h"
 
43
#include "drizzled/pthread_globals.h"
 
44
#include "drizzled/charset.h"
 
45
 
 
46
#include "drizzled/internal/my_sys.h"
 
47
 
 
48
#define MY_DB_OPT_FILE "db.opt"
 
49
#define MAX_DROP_TABLE_Q_LEN      1024
 
50
 
21
51
using namespace std;
22
 
#include <drizzled/server_includes.h>
23
 
#include <mysys/mysys_err.h>
24
 
#include <mysys/my_dir.h>
25
 
#include "log.h"
26
 
#include <drizzled/drizzled_error_messages.h>
27
 
 
28
 
 
29
 
#define MAX_DROP_TABLE_Q_LEN      1024
30
 
 
31
 
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
32
 
static TYPELIB deletable_extentions=
33
 
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
34
 
 
35
 
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
36
 
                                 const char *db, const char *path, uint level, 
37
 
                                 TABLE_LIST **dropped_tables);
38
 
         
39
 
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
40
 
static void mysql_change_db_impl(THD *thd,
41
 
                                 LEX_STRING *new_db_name,
42
 
                                 const CHARSET_INFO * const new_db_charset);
43
 
 
44
 
 
45
 
/* Database lock hash */
46
 
HASH lock_db_cache;
47
 
pthread_mutex_t LOCK_lock_db;
48
 
int creating_database= 0;  // how many database locks are made
49
 
 
50
 
 
51
 
/* Structure for database lock */
52
 
typedef struct my_dblock_st
53
 
{
54
 
  char *name;        /* Database name        */
55
 
  uint name_length;  /* Database length name */
56
 
} my_dblock_t;
57
 
 
58
 
 
59
 
/*
60
 
  lock_db key.
61
 
*/
62
 
 
63
 
extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
64
 
 
65
 
uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
66
 
                       bool not_used __attribute__((unused)))
67
 
{
68
 
  *length= ptr->name_length;
69
 
  return (uchar*) ptr->name;
70
 
}
71
 
 
72
 
 
73
 
/*
74
 
  Free lock_db hash element.
75
 
*/
76
 
 
77
 
extern "C" void lock_db_free_element(void *ptr);
78
 
 
79
 
void lock_db_free_element(void *ptr)
80
 
{
81
 
  my_free(ptr, MYF(0));
82
 
}
83
 
 
84
 
 
85
 
/*
86
 
  Delete a database lock entry from hash.
87
 
*/
88
 
 
89
 
void lock_db_delete(const char *name, uint length)
90
 
{
91
 
  my_dblock_t *opt;
92
 
  safe_mutex_assert_owner(&LOCK_lock_db);
93
 
  if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
94
 
                                       (const uchar*) name, length)))
95
 
    hash_delete(&lock_db_cache, (uchar*) opt);
96
 
}
97
 
 
98
 
 
99
 
/* Database options hash */
100
 
static HASH dboptions;
101
 
static bool dboptions_init= 0;
102
 
static rw_lock_t LOCK_dboptions;
103
 
 
104
 
/* Structure for database options */
105
 
typedef struct my_dbopt_st
106
 
{
107
 
  char *name;                   /* Database name                  */
108
 
  uint name_length;             /* Database length name           */
109
 
  const CHARSET_INFO *charset;  /* Database default character set */
110
 
} my_dbopt_t;
111
 
 
112
 
 
113
 
/*
114
 
  Function we use in the creation of our hash to get key.
115
 
*/
116
 
 
117
 
extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
118
 
                                    bool not_used);
119
 
 
120
 
uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
121
 
                         bool not_used __attribute__((unused)))
122
 
{
123
 
  *length= opt->name_length;
124
 
  return (uchar*) opt->name;
125
 
}
126
 
 
127
 
 
128
 
/*
129
 
  Helper function to write a query to binlog used by mysql_rm_db()
130
 
*/
131
 
 
132
 
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
133
 
                                   char *db, uint db_len)
134
 
{
135
 
  Query_log_event qinfo(thd, query, q_len, 0, 0);
136
 
  qinfo.error_code= 0;
137
 
  qinfo.db= db;
138
 
  qinfo.db_len= db_len;
139
 
  mysql_bin_log.write(&qinfo);
140
 
}  
141
 
 
142
 
 
143
 
/*
144
 
  Function to free dboptions hash element
145
 
*/
146
 
 
147
 
extern "C" void free_dbopt(void *dbopt);
148
 
 
149
 
void free_dbopt(void *dbopt)
150
 
{
151
 
  my_free((uchar*) dbopt, MYF(0));
152
 
}
153
 
 
154
 
 
155
 
/* 
156
 
  Initialize database option hash and locked database hash.
157
 
 
158
 
  SYNOPSIS
159
 
    my_database_names()
160
 
 
161
 
  NOTES
162
 
    Must be called before any other database function is called.
163
 
 
164
 
  RETURN
165
 
    0   ok
166
 
    1   Fatal error
167
 
*/
168
 
 
169
 
bool my_database_names_init(void)
170
 
{
171
 
  bool error= false;
172
 
  (void) my_rwlock_init(&LOCK_dboptions, NULL);
173
 
  if (!dboptions_init)
174
 
  {
175
 
    dboptions_init= 1;
176
 
    error= hash_init(&dboptions, lower_case_table_names ? 
177
 
                     &my_charset_bin : system_charset_info,
178
 
                     32, 0, 0, (hash_get_key) dboptions_get_key,
179
 
                     free_dbopt,0) ||
180
 
           hash_init(&lock_db_cache, lower_case_table_names ? 
181
 
                     &my_charset_bin : system_charset_info,
182
 
                     32, 0, 0, (hash_get_key) lock_db_get_key,
183
 
                     lock_db_free_element,0);
184
 
 
185
 
  }
186
 
  return error;
187
 
}
188
 
 
189
 
 
190
 
 
191
 
/* 
192
 
  Free database option hash and locked databases hash.
193
 
*/
194
 
 
195
 
void my_database_names_free(void)
196
 
{
197
 
  if (dboptions_init)
198
 
  {
199
 
    dboptions_init= 0;
200
 
    hash_free(&dboptions);
201
 
    (void) rwlock_destroy(&LOCK_dboptions);
202
 
    hash_free(&lock_db_cache);
203
 
  }
204
 
}
205
 
 
206
 
 
207
 
/*
208
 
  Cleanup cached options
209
 
*/
210
 
 
211
 
void my_dbopt_cleanup(void)
212
 
{
213
 
  rw_wrlock(&LOCK_dboptions);
214
 
  hash_free(&dboptions);
215
 
  hash_init(&dboptions, lower_case_table_names ? 
216
 
            &my_charset_bin : system_charset_info,
217
 
            32, 0, 0, (hash_get_key) dboptions_get_key,
218
 
            free_dbopt,0);
219
 
  rw_unlock(&LOCK_dboptions);
220
 
}
221
 
 
222
 
 
223
 
/*
224
 
  Find database options in the hash.
225
 
  
226
 
  DESCRIPTION
227
 
    Search a database options in the hash, usings its path.
228
 
    Fills "create" on success.
229
 
  
230
 
  RETURN VALUES
231
 
    0 on success.
232
 
    1 on error.
233
 
*/
234
 
 
235
 
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
236
 
{
237
 
  my_dbopt_t *opt;
238
 
  uint length;
239
 
  bool error= true;
240
 
  
241
 
  length= (uint) strlen(dbname);
242
 
  
243
 
  rw_rdlock(&LOCK_dboptions);
244
 
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
245
 
  {
246
 
    create->default_table_charset= opt->charset;
247
 
    error= true;
248
 
  }
249
 
  rw_unlock(&LOCK_dboptions);
250
 
  return error;
251
 
}
252
 
 
253
 
 
254
 
/*
255
 
  Writes database options into the hash.
256
 
  
257
 
  DESCRIPTION
258
 
    Inserts database options into the hash, or updates
259
 
    options if they are already in the hash.
260
 
  
261
 
  RETURN VALUES
262
 
    0 on success.
263
 
    1 on error.
264
 
*/
265
 
 
266
 
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
267
 
{
268
 
  my_dbopt_t *opt;
269
 
  uint length;
270
 
  bool error= false;
271
 
 
272
 
  length= (uint) strlen(dbname);
273
 
  
274
 
  rw_wrlock(&LOCK_dboptions);
275
 
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
276
 
  { 
277
 
    /* Options are not in the hash, insert them */
278
 
    char *tmp_name;
279
 
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
280
 
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
281
 
                         NullS))
282
 
    {
283
 
      error= true;
284
 
      goto end;
285
 
    }
286
 
    
287
 
    opt->name= tmp_name;
288
 
    stpcpy(opt->name, dbname);
289
 
    opt->name_length= length;
290
 
    
291
 
    if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
292
 
    {
293
 
      my_free(opt, MYF(0));
294
 
      goto end;
295
 
    }
296
 
  }
297
 
 
298
 
  /* Update / write options in hash */
299
 
  opt->charset= create->default_table_charset;
300
 
 
301
 
end:
302
 
  rw_unlock(&LOCK_dboptions);  
303
 
  return(error);
304
 
}
305
 
 
306
 
 
307
 
/*
308
 
  Deletes database options from the hash.
309
 
*/
310
 
 
311
 
void del_dbopt(const char *path)
312
 
{
313
 
  my_dbopt_t *opt;
314
 
  rw_wrlock(&LOCK_dboptions);
315
 
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
316
 
                                      strlen(path))))
317
 
    hash_delete(&dboptions, (uchar*) opt);
318
 
  rw_unlock(&LOCK_dboptions);
319
 
}
320
 
 
321
 
 
322
 
/*
323
 
  Create database options file:
324
 
 
325
 
  DESCRIPTION
326
 
    Currently database default charset is only stored there.
327
 
 
328
 
  RETURN VALUES
329
 
  0     ok
330
 
  1     Could not create file or write to it.  Error sent through my_error()
331
 
*/
332
 
 
333
 
static bool write_db_opt(THD *thd, const char *path, const char *name, HA_CREATE_INFO *create)
334
 
{
335
 
  bool error= true;
336
 
  drizzle::Schema db;
337
 
 
338
 
  assert(name);
339
 
 
340
 
  if (!create->default_table_charset)
341
 
    create->default_table_charset= thd->variables.collation_server;
342
 
 
343
 
  if (put_dbopt(path, create))
344
 
    return 1;
345
 
 
346
 
  db.set_name(name);
347
 
  db.set_characterset(create->default_table_charset->csname);
348
 
  db.set_collation(create->default_table_charset->name);
349
 
 
350
 
  fstream output(path, ios::out | ios::trunc | ios::binary);
351
 
  if (!db.SerializeToOstream(&output)) 
352
 
    error= false;
353
 
 
354
 
  return error;
355
 
}
356
 
 
357
 
 
358
 
/*
359
 
  Load database options file
360
 
 
361
 
  load_db_opt()
362
 
  path          Path for option file
363
 
  create        Where to store the read options
364
 
 
365
 
  DESCRIPTION
366
 
 
367
 
  RETURN VALUES
368
 
  0     File found
369
 
  1     No database file or could not open it
370
 
 
371
 
*/
372
 
 
373
 
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
374
 
{
375
 
  bool error=1;
376
 
  drizzle::Schema db;
377
 
  string buffer;
378
 
 
379
 
  memset(create, 0, sizeof(*create));
380
 
  create->default_table_charset= thd->variables.collation_server;
381
 
 
382
 
  /* Check if options for this database are already in the hash */
383
 
  if (!get_dbopt(path, create))
384
 
    return(0);
385
 
 
386
 
  fstream input(path, ios::in | ios::binary);
387
 
  if (!input)
388
 
    goto err1;
389
 
  else if (!db.ParseFromIstream(&input))
390
 
    goto err1;
391
 
 
392
 
  buffer= db.characterset();
393
 
  if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
394
 
  {
395
 
    sql_print_error("Error while loading database options: '%s':",path);
396
 
    sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
397
 
    create->default_table_charset= default_charset_info;
398
 
  }
399
 
 
400
 
  buffer= db.collation();
401
 
  if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
402
 
  {
403
 
    sql_print_error("Error while loading database options: '%s':",path);
404
 
    sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
405
 
    create->default_table_charset= default_charset_info;
406
 
  }
407
 
 
408
 
  /*
409
 
    Put the loaded value into the hash.
410
 
    Note that another thread could've added the same
411
 
    entry to the hash after we called get_dbopt(),
412
 
    but it's not an error, as put_dbopt() takes this
413
 
    possibility into account.
414
 
  */
415
 
  error= put_dbopt(path, create);
416
 
 
417
 
err1:
418
 
  return(error);
419
 
}
420
 
 
421
 
 
422
 
/*
423
 
  Retrieve database options by name. Load database options file or fetch from
424
 
  cache.
425
 
 
426
 
  SYNOPSIS
427
 
    load_db_opt_by_name()
428
 
    db_name         Database name
429
 
    db_create_info  Where to store the database options
430
 
 
431
 
  DESCRIPTION
432
 
    load_db_opt_by_name() is a shortcut for load_db_opt().
433
 
 
434
 
  NOTE
435
 
    Although load_db_opt_by_name() (and load_db_opt()) returns status of
436
 
    the operation, it is useless usually and should be ignored. The problem
437
 
    is that there are 1) system databases ("mysql") and 2) virtual
438
 
    databases ("information_schema"), which do not contain options file.
439
 
    So, load_db_opt[_by_name]() returns false for these databases, but this
440
 
    is not an error.
441
 
 
442
 
    load_db_opt[_by_name]() clears db_create_info structure in any case, so
443
 
    even on failure it contains valid data. So, common use case is just
444
 
    call load_db_opt[_by_name]() without checking return value and use
445
 
    db_create_info right after that.
446
 
 
447
 
  RETURN VALUES (read NOTE!)
448
 
    false   Success
449
 
    true    Failed to retrieve options
450
 
*/
451
 
 
452
 
bool load_db_opt_by_name(THD *thd, const char *db_name,
453
 
                         HA_CREATE_INFO *db_create_info)
454
 
{
455
 
  char db_opt_path[FN_REFLEN];
456
 
 
457
 
  /*
458
 
    Pass an empty file name, and the database options file name as extension
459
 
    to avoid table name to file name encoding.
460
 
  */
461
 
  (void) build_table_filename(db_opt_path, sizeof(db_opt_path),
462
 
                              db_name, "", MY_DB_OPT_FILE, 0);
463
 
 
464
 
  return load_db_opt(thd, db_opt_path, db_create_info);
465
 
}
466
 
 
 
52
 
 
53
namespace drizzled
 
54
{
 
55
 
 
56
const string del_exts[]= {".dfe", ".blk", ".arz", ".BAK", ".TMD", ".opt"};
 
57
static set<string> deletable_extentions(del_exts, &del_exts[sizeof(del_exts)/sizeof(del_exts[0])]);
 
58
 
 
59
 
 
60
static long mysql_rm_known_files(Session *session, CachedDirectory &dirp,
 
61
                                 const string &db, const char *path,
 
62
                                 TableList **dropped_tables);
 
63
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name);
467
64
 
468
65
/**
469
66
  Return default database collation.
470
67
 
471
 
  @param thd     Thread context.
 
68
  @param session     Thread context.
472
69
  @param db_name Database name.
473
70
 
474
71
  @return CHARSET_INFO object. The operation always return valid character
475
72
    set, even if the database does not exist.
476
73
*/
477
74
 
478
 
const CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
479
 
{
480
 
  HA_CREATE_INFO db_info;
481
 
 
482
 
  if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
483
 
    return thd->db_charset;
484
 
 
485
 
  load_db_opt_by_name(thd, db_name, &db_info);
 
75
const CHARSET_INFO *get_default_db_collation(const char *db_name)
 
76
{
 
77
  message::Schema db;
 
78
 
 
79
  get_database_metadata(db_name, &db);
 
80
 
 
81
  /* If for some reason the db.opt file lacks a collation,
 
82
     we just return the default */
 
83
 
 
84
  if (db.has_collation())
 
85
  {
 
86
    const string buffer= db.collation();
 
87
    const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
 
88
 
 
89
    if (!cs)
 
90
    {
 
91
      errmsg_printf(ERRMSG_LVL_ERROR,
 
92
                    _("Error while loading database options: '%s':"),db_name);
 
93
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
 
94
 
 
95
      return default_charset_info;
 
96
    }
 
97
 
 
98
    return cs;
 
99
  }
 
100
 
 
101
  return default_charset_info;
 
102
}
 
103
 
 
104
/* path is path to database, not schema file */
 
105
static int write_schema_file(const char *path, const message::Schema &db)
 
106
{
 
107
  char schema_file_tmp[FN_REFLEN];
 
108
  string schema_file(path);
 
109
 
 
110
  snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path, FN_LIBCHAR, MY_DB_OPT_FILE);
 
111
 
 
112
  schema_file.append(1, FN_LIBCHAR);
 
113
  schema_file.append(MY_DB_OPT_FILE);
 
114
 
 
115
  int fd= mkstemp(schema_file_tmp);
 
116
 
 
117
  if (fd==-1)
 
118
    return errno;
 
119
 
 
120
 
 
121
  if (!db.SerializeToFileDescriptor(fd))
 
122
  {
 
123
    close(fd);
 
124
    unlink(schema_file_tmp);
 
125
    return -1;
 
126
  }
 
127
 
 
128
  if (rename(schema_file_tmp, schema_file.c_str()) == -1)
 
129
  {
 
130
    close(fd);
 
131
    return errno;
 
132
  }
 
133
 
 
134
  close(fd);
 
135
  return 0;
 
136
}
 
137
 
 
138
int get_database_metadata(const char *dbname, message::Schema *db)
 
139
{
 
140
  char db_opt_path[FN_REFLEN];
 
141
  size_t length;
486
142
 
487
143
  /*
488
 
    NOTE: even if load_db_opt_by_name() fails,
489
 
    db_info.default_table_charset contains valid character set
490
 
    (collation_server). We should not fail if load_db_opt_by_name() fails,
491
 
    because it is valid case. If a database has been created just by
492
 
    "mkdir", it does not contain db.opt file, but it is valid database.
 
144
    Pass an empty file name, and the database options file name as extension
 
145
    to avoid table name to file name encoding.
493
146
  */
494
 
 
495
 
  return db_info.default_table_charset;
 
147
  length= build_table_filename(db_opt_path, sizeof(db_opt_path),
 
148
                              dbname, "", false);
 
149
  strcpy(db_opt_path + length, MY_DB_OPT_FILE);
 
150
 
 
151
  int fd= open(db_opt_path, O_RDONLY);
 
152
 
 
153
  if (fd == -1)
 
154
    return errno;
 
155
 
 
156
  if (!db->ParseFromFileDescriptor(fd))
 
157
  {
 
158
    close(fd);
 
159
    return -1;
 
160
  }
 
161
  close(fd);
 
162
 
 
163
  return 0;
496
164
}
497
165
 
498
 
 
499
166
/*
500
167
  Create a database
501
168
 
502
169
  SYNOPSIS
503
170
  mysql_create_db()
504
 
  thd           Thread handler
 
171
  session               Thread handler
505
172
  db            Name of database to create
506
173
                Function assumes that this is already validated.
507
174
  create_info   Database create options (like character set)
508
 
  silent        Used by replication when internally creating a database.
509
 
                In this case the entry should not be logged.
510
175
 
511
176
  SIDE-EFFECTS
512
177
   1. Report back to client that command succeeded (my_ok)
513
178
   2. Report errors to client
514
179
   3. Log event to binary log
515
 
   (The 'silent' flags turns off 1 and 3.)
516
180
 
517
181
  RETURN VALUES
518
182
  false ok
520
184
 
521
185
*/
522
186
 
523
 
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
 
187
bool mysql_create_db(Session *session, const char *db, message::Schema *schema_message, bool is_if_not_exists)
524
188
{
525
 
  char   path[FN_REFLEN+16];
526
 
  char   tmp_query[FN_REFLEN+16];
 
189
  ReplicationServices &replication_services= ReplicationServices::singleton();
527
190
  long result= 1;
528
 
  int error= 0;
529
 
  struct stat stat_info;
530
 
  uint create_options= create_info ? create_info->options : 0;
531
 
  uint path_len;
 
191
  int error_erno;
 
192
  bool error= false;
532
193
 
533
194
  /* do not create 'information_schema' db */
534
 
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
 
195
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.c_str()))
535
196
  {
536
197
    my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
537
198
    return(-1);
538
199
  }
539
200
 
 
201
  schema_message->set_name(db);
 
202
 
540
203
  /*
541
204
    Do not create database if another thread is holding read lock.
542
 
    Wait for global read lock before acquiring LOCK_mysql_create_db.
 
205
    Wait for global read lock before acquiring LOCK_create_db.
543
206
    After wait_if_global_read_lock() we have protection against another
544
 
    global read lock. If we would acquire LOCK_mysql_create_db first,
 
207
    global read lock. If we would acquire LOCK_create_db first,
545
208
    another thread could step in and get the global read lock before we
546
209
    reach wait_if_global_read_lock(). If this thread tries the same as we
547
 
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
 
210
    (admin a db), it would then go and wait on LOCK_create_db...
548
211
    Furthermore wait_if_global_read_lock() checks if the current thread
549
212
    has the global read lock and refuses the operation with
550
213
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
551
214
  */
552
 
  if (wait_if_global_read_lock(thd, 0, 1))
 
215
  if (wait_if_global_read_lock(session, 0, 1))
553
216
  {
554
 
    error= -1;
 
217
    error= true;
555
218
    goto exit2;
556
219
  }
557
220
 
558
 
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
559
 
 
560
 
  /* Check directory */
561
 
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
562
 
  path[path_len-1]= 0;                    // Remove last '/' from path
563
 
 
564
 
  if (!stat(path,&stat_info))
 
221
  pthread_mutex_lock(&LOCK_create_db);
 
222
 
 
223
  /* check directory */
 
224
  char   path[FN_REFLEN+16];
 
225
  uint32_t path_len;
 
226
  path_len= build_table_filename(path, sizeof(path), db, "", false);
 
227
  path[path_len-1]= 0;                    // remove last '/' from path
 
228
 
 
229
  if (mkdir(path, 0777) == -1)
565
230
  {
566
 
    if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
 
231
    if (errno == EEXIST)
567
232
    {
568
 
      my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
569
 
      error= -1;
 
233
      if (! is_if_not_exists)
 
234
      {
 
235
        my_error(ER_DB_CREATE_EXISTS, MYF(0), path);
 
236
        error= true;
 
237
        goto exit;
 
238
      }
 
239
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
240
                          ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
 
241
                          path);
 
242
      session->my_ok();
 
243
      error= false;
570
244
      goto exit;
571
245
    }
572
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
573
 
                        ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
574
 
    if (!silent)
575
 
      my_ok(thd);
576
 
    error= 0;
 
246
 
 
247
    my_error(ER_CANT_CREATE_DB, MYF(0), path, errno);
 
248
    error= true;
577
249
    goto exit;
578
250
  }
579
 
  else
580
 
  {
581
 
    if (errno != ENOENT)
582
 
    {
583
 
      my_error(EE_STAT, MYF(0), path, errno);
584
 
      goto exit;
585
 
    }
586
 
    if (my_mkdir(path,0777,MYF(0)) < 0)
587
 
    {
588
 
      my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
589
 
      error= -1;
590
 
      goto exit;
591
 
    }
592
 
  }
593
251
 
594
 
  path[path_len-1]= FN_LIBCHAR;
595
 
  strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
596
 
  if (write_db_opt(thd, path, db, create_info))
 
252
  error_erno= write_schema_file(path, *schema_message);
 
253
  if (error_erno && error_erno != EEXIST)
597
254
  {
598
 
    /*
599
 
      Could not create options file.
600
 
      Restore things to beginning.
601
 
    */
602
 
    path[path_len]= 0;
603
255
    if (rmdir(path) >= 0)
604
256
    {
605
 
      error= -1;
 
257
      error= true;
606
258
      goto exit;
607
259
    }
608
 
    /*
609
 
      We come here when we managed to create the database, but not the option
610
 
      file.  In this case it's best to just continue as if nothing has
611
 
      happened.  (This is a very unlikely senario)
612
 
    */
613
 
  }
614
 
  
615
 
  if (!silent)
616
 
  {
617
 
    char *query;
618
 
    uint query_length;
619
 
 
620
 
    if (!thd->query)                            // Only in replication
621
 
    {
622
 
      query=         tmp_query;
623
 
      query_length= (uint) (strxmov(tmp_query,"create database `",
624
 
                                    db, "`", NullS) - tmp_query);
625
 
    }
626
 
    else
627
 
    {
628
 
      query=        thd->query;
629
 
      query_length= thd->query_length;
630
 
    }
631
 
 
632
 
    ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
633
 
                        query, query_length,
634
 
                        db, "");
635
 
 
636
 
    if (mysql_bin_log.is_open())
637
 
    {
638
 
      Query_log_event qinfo(thd, query, query_length, 0, 
639
 
                            /* suppress_use */ true);
640
 
 
641
 
      /*
642
 
        Write should use the database being created as the "current
643
 
        database" and not the threads current database, which is the
644
 
        default. If we do not change the "current database" to the
645
 
        database being created, the CREATE statement will not be
646
 
        replicated when using --binlog-do-db to select databases to be
647
 
        replicated. 
648
 
 
649
 
        An example (--binlog-do-db=sisyfos):
650
 
       
651
 
          CREATE DATABASE bob;        # Not replicated
652
 
          USE bob;                    # 'bob' is the current database
653
 
          CREATE DATABASE sisyfos;    # Not replicated since 'bob' is
654
 
                                      # current database.
655
 
          USE sisyfos;                # Will give error on slave since
656
 
                                      # database does not exist.
657
 
      */
658
 
      qinfo.db     = db;
659
 
      qinfo.db_len = strlen(db);
660
 
 
661
 
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
662
 
      mysql_bin_log.write(&qinfo);
663
 
    }
664
 
    my_ok(thd, result);
665
 
  }
 
260
  }
 
261
  else if (error_erno)
 
262
    error= true;
 
263
 
 
264
  replication_services.rawStatement(session, session->query, session->query_length);
 
265
  session->my_ok(result);
666
266
 
667
267
exit:
668
 
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
669
 
  start_waiting_global_read_lock(thd);
 
268
  pthread_mutex_unlock(&LOCK_create_db);
 
269
  start_waiting_global_read_lock(session);
670
270
exit2:
671
 
  return(error);
 
271
  return error;
672
272
}
673
273
 
674
274
 
675
275
/* db-name is already validated when we come here */
676
276
 
677
 
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
 
277
bool mysql_alter_db(Session *session, const char *db, message::Schema *schema_message)
678
278
{
679
 
  char path[FN_REFLEN+16];
 
279
  ReplicationServices &replication_services= ReplicationServices::singleton();
680
280
  long result=1;
681
 
  int error= false;
 
281
  int error= 0;
 
282
  char   path[FN_REFLEN+16];
 
283
  uint32_t path_len;
682
284
 
683
285
  /*
684
286
    Do not alter database if another thread is holding read lock.
685
 
    Wait for global read lock before acquiring LOCK_mysql_create_db.
 
287
    Wait for global read lock before acquiring LOCK_create_db.
686
288
    After wait_if_global_read_lock() we have protection against another
687
 
    global read lock. If we would acquire LOCK_mysql_create_db first,
 
289
    global read lock. If we would acquire LOCK_create_db first,
688
290
    another thread could step in and get the global read lock before we
689
291
    reach wait_if_global_read_lock(). If this thread tries the same as we
690
 
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
 
292
    (admin a db), it would then go and wait on LOCK_create_db...
691
293
    Furthermore wait_if_global_read_lock() checks if the current thread
692
294
    has the global read lock and refuses the operation with
693
295
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
694
296
  */
695
 
  if ((error=wait_if_global_read_lock(thd,0,1)))
696
 
    goto exit2;
697
 
 
698
 
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
699
 
 
700
 
  /* 
701
 
     Recreate db options file: /dbpath/.db.opt
702
 
     We pass MY_DB_OPT_FILE as "extension" to avoid
703
 
     "table name to file name" encoding.
704
 
  */
705
 
  build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
706
 
  if ((error=write_db_opt(thd, path, db, create_info)))
 
297
  if ((error=wait_if_global_read_lock(session,0,1)))
707
298
    goto exit;
708
299
 
 
300
  assert(schema_message);
 
301
 
 
302
  schema_message->set_name(db);
 
303
 
 
304
  pthread_mutex_lock(&LOCK_create_db);
 
305
 
709
306
  /* Change options if current database is being altered. */
710
 
 
711
 
  if (thd->db && !strcmp(thd->db,db))
712
 
  {
713
 
    thd->db_charset= create_info->default_table_charset ?
714
 
                     create_info->default_table_charset :
715
 
                     thd->variables.collation_server;
716
 
    thd->variables.collation_database= thd->db_charset;
717
 
  }
718
 
 
719
 
  ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
720
 
                      thd->query, thd->query_length,
721
 
                      db, "");
722
 
 
723
 
  if (mysql_bin_log.is_open())
724
 
  {
725
 
    Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
726
 
                          /* suppress_use */ true);
727
 
 
728
 
    /*
729
 
      Write should use the database being created as the "current
730
 
      database" and not the threads current database, which is the
731
 
      default.
732
 
    */
733
 
    qinfo.db     = db;
734
 
    qinfo.db_len = strlen(db);
735
 
 
736
 
    thd->clear_error();
737
 
    /* These DDL methods and logging protected with LOCK_mysql_create_db */
738
 
    mysql_bin_log.write(&qinfo);
739
 
  }
740
 
  my_ok(thd, result);
741
 
 
 
307
  path_len= build_table_filename(path, sizeof(path), db, "", false);
 
308
  path[path_len-1]= 0;                    // Remove last '/' from path
 
309
 
 
310
  error= write_schema_file(path, *schema_message);
 
311
  if (error && error != EEXIST)
 
312
  {
 
313
    /* TODO: find some witty way of getting back an error message */
 
314
    pthread_mutex_unlock(&LOCK_create_db);
 
315
    goto exit;
 
316
  }
 
317
 
 
318
  replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
 
319
  session->my_ok(result);
 
320
 
 
321
  pthread_mutex_unlock(&LOCK_create_db);
 
322
  start_waiting_global_read_lock(session);
742
323
exit:
743
 
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
744
 
  start_waiting_global_read_lock(thd);
745
 
exit2:
746
 
  return(error);
 
324
  return error ? true : false;
747
325
}
748
326
 
749
327
 
752
330
 
753
331
  SYNOPSIS
754
332
    mysql_rm_db()
755
 
    thd                 Thread handle
 
333
    session                     Thread handle
756
334
    db                  Database name in the case given by user
757
335
                        It's already validated and set to lower case
758
336
                        (if needed) when we come here
764
342
    ERROR Error
765
343
*/
766
344
 
767
 
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
 
345
bool mysql_rm_db(Session *session, char *db, bool if_exists)
768
346
{
769
347
  long deleted=0;
770
348
  int error= false;
771
349
  char  path[FN_REFLEN+16];
772
 
  MY_DIR *dirp;
773
 
  uint length;
774
 
  TABLE_LIST* dropped_tables= 0;
 
350
  uint32_t length;
 
351
  TableList *dropped_tables= NULL;
775
352
 
776
353
  if (db && (strcmp(db, "information_schema") == 0))
777
354
  {
778
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
779
 
    return(true);
 
355
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
 
356
    return true;
780
357
  }
781
358
 
 
359
 
782
360
  /*
783
361
    Do not drop database if another thread is holding read lock.
784
 
    Wait for global read lock before acquiring LOCK_mysql_create_db.
 
362
    Wait for global read lock before acquiring LOCK_create_db.
785
363
    After wait_if_global_read_lock() we have protection against another
786
 
    global read lock. If we would acquire LOCK_mysql_create_db first,
 
364
    global read lock. If we would acquire LOCK_create_db first,
787
365
    another thread could step in and get the global read lock before we
788
366
    reach wait_if_global_read_lock(). If this thread tries the same as we
789
 
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
 
367
    (admin a db), it would then go and wait on LOCK_create_db...
790
368
    Furthermore wait_if_global_read_lock() checks if the current thread
791
369
    has the global read lock and refuses the operation with
792
370
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
793
371
  */
794
 
  if (wait_if_global_read_lock(thd, 0, 1))
 
372
  if (wait_if_global_read_lock(session, 0, 1))
795
373
  {
796
 
    error= -1;
797
 
    goto exit2;
 
374
    return -1;
798
375
  }
799
376
 
800
 
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
801
 
 
802
 
  /*
803
 
    This statement will be replicated as a statement, even when using
804
 
    row-based replication. The flag will be reset at the end of the
805
 
    statement.
806
 
  */
807
 
  thd->clear_current_stmt_binlog_row_based();
808
 
 
809
 
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
810
 
  stpcpy(path+length, MY_DB_OPT_FILE);          // Append db option file name
811
 
  del_dbopt(path);                              // Remove dboption hash entry
 
377
  pthread_mutex_lock(&LOCK_create_db);
 
378
 
 
379
  length= build_table_filename(path, sizeof(path),
 
380
                               db, "", false);
 
381
  strcpy(path+length, MY_DB_OPT_FILE);         // Append db option file name
 
382
  unlink(path);
812
383
  path[length]= '\0';                           // Remove file name
813
384
 
814
385
  /* See if the directory exists */
815
 
  if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
 
386
  CachedDirectory dirp(path);
 
387
  if (dirp.fail())
816
388
  {
817
389
    if (!if_exists)
818
390
    {
819
391
      error= -1;
820
 
      my_error(ER_DB_DROP_EXISTS, MYF(0), db);
 
392
      my_error(ER_DB_DROP_EXISTS, MYF(0), path);
821
393
      goto exit;
822
394
    }
823
395
    else
824
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
825
 
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
 
396
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
397
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
 
398
                          path);
826
399
  }
827
400
  else
828
401
  {
829
 
    pthread_mutex_lock(&LOCK_open);
 
402
    pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
830
403
    remove_db_from_cache(db);
831
404
    pthread_mutex_unlock(&LOCK_open);
832
405
 
833
 
    
 
406
 
834
407
    error= -1;
835
 
    if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
836
 
                                       &dropped_tables)) >= 0)
 
408
    deleted= mysql_rm_known_files(session, dirp, db,
 
409
                                  path, &dropped_tables);
 
410
    if (deleted >= 0)
837
411
    {
838
 
      ha_drop_database(path);
 
412
      plugin::StorageEngine::dropDatabase(path);
839
413
      error = 0;
840
414
    }
841
415
  }
842
 
  if (!silent && deleted>=0)
 
416
  if (deleted >= 0)
843
417
  {
844
418
    const char *query;
845
419
    uint32_t query_length;
846
 
    if (!thd->query)
847
 
    {
848
 
      /* The client used the old obsolete mysql_drop_db() call */
849
 
      query= path;
850
 
      query_length= (uint) (strxmov(path, "drop database `", db, "`",
851
 
                                     NullS) - path);
852
 
    }
853
 
    else
854
 
    {
855
 
      query =thd->query;
856
 
      query_length= thd->query_length;
857
 
    }
858
 
    if (mysql_bin_log.is_open())
859
 
    {
860
 
      Query_log_event qinfo(thd, query, query_length, 0, 
861
 
                            /* suppress_use */ true);
862
 
      /*
863
 
        Write should use the database being created as the "current
864
 
        database" and not the threads current database, which is the
865
 
        default.
866
 
      */
867
 
      qinfo.db     = db;
868
 
      qinfo.db_len = strlen(db);
869
 
 
870
 
      thd->clear_error();
871
 
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
872
 
      mysql_bin_log.write(&qinfo);
873
 
    }
874
 
    thd->clear_error();
875
 
    thd->server_status|= SERVER_STATUS_DB_DROPPED;
876
 
    my_ok(thd, (uint32_t) deleted);
877
 
    thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
 
420
 
 
421
    assert(session->query);
 
422
 
 
423
    query= session->query;
 
424
    query_length= session->query_length;
 
425
 
 
426
    ReplicationServices &replication_services= ReplicationServices::singleton();
 
427
    replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
 
428
    session->clear_error();
 
429
    session->server_status|= SERVER_STATUS_DB_DROPPED;
 
430
    session->my_ok((uint32_t) deleted);
 
431
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
878
432
  }
879
 
  else if (mysql_bin_log.is_open())
 
433
  else
880
434
  {
881
435
    char *query, *query_pos, *query_end, *query_data_start;
882
 
    TABLE_LIST *tbl;
883
 
    uint db_len;
 
436
    TableList *tbl;
 
437
    uint32_t db_len;
884
438
 
885
 
    if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
 
439
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
886
440
      goto exit; /* not much else we can do */
887
 
    query_pos= query_data_start= stpcpy(query,"drop table ");
 
441
    query_pos= query_data_start= strcpy(query,"drop table ")+11;
888
442
    query_end= query + MAX_DROP_TABLE_Q_LEN;
889
443
    db_len= strlen(db);
890
444
 
 
445
    ReplicationServices &replication_services= ReplicationServices::singleton();
891
446
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
892
447
    {
893
 
      uint tbl_name_len;
 
448
      uint32_t tbl_name_len;
894
449
 
895
450
      /* 3 for the quotes and the comma*/
896
451
      tbl_name_len= strlen(tbl->table_name) + 3;
897
452
      if (query_pos + tbl_name_len + 1 >= query_end)
898
453
      {
899
 
        /* These DDL methods and logging protected with LOCK_mysql_create_db */
900
 
        write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
 
454
        /* These DDL methods and logging protected with LOCK_create_db */
 
455
        replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
901
456
        query_pos= query_data_start;
902
457
      }
903
458
 
904
459
      *query_pos++ = '`';
905
 
      query_pos= stpcpy(query_pos,tbl->table_name);
 
460
      query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
906
461
      *query_pos++ = '`';
907
462
      *query_pos++ = ',';
908
463
    }
909
464
 
910
465
    if (query_pos != query_data_start)
911
466
    {
912
 
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
913
 
      write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
 
467
      /* These DDL methods and logging protected with LOCK_create_db */
 
468
      replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
914
469
    }
915
470
  }
916
471
 
918
473
  /*
919
474
    If this database was the client's selected database, we silently
920
475
    change the client's selected database to nothing (to have an empty
921
 
    SELECT DATABASE() in the future). For this we free() thd->db and set
 
476
    SELECT DATABASE() in the future). For this we free() session->db and set
922
477
    it to 0.
923
478
  */
924
 
  if (thd->db && !strcmp(thd->db, db))
925
 
    mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
926
 
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
927
 
  start_waiting_global_read_lock(thd);
928
 
exit2:
 
479
  if (! session->db.empty() && session->db.compare(db) == 0)
 
480
    mysql_change_db_impl(session, NULL);
 
481
  pthread_mutex_unlock(&LOCK_create_db);
 
482
  start_waiting_global_read_lock(session);
 
483
  return error;
 
484
}
 
485
 
 
486
 
 
487
static int rm_table_part2(Session *session, TableList *tables)
 
488
{
 
489
  TableList *table;
 
490
  String wrong_tables;
 
491
  int error= 0;
 
492
  bool foreign_key_error= false;
 
493
 
 
494
  pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
 
495
 
 
496
  /*
 
497
    If we have the table in the definition cache, we don't have to check the
 
498
    .frm cursor to find if the table is a normal table (not view) and what
 
499
    engine to use.
 
500
  */
 
501
 
 
502
  for (table= tables; table; table= table->next_local)
 
503
  {
 
504
    TableShare *share;
 
505
    table->db_type= NULL;
 
506
    if ((share= TableShare::getShare(table->db, table->table_name)))
 
507
      table->db_type= share->db_type();
 
508
  }
 
509
 
 
510
  if (lock_table_names_exclusively(session, tables))
 
511
  {
 
512
    pthread_mutex_unlock(&LOCK_open);
 
513
    return 1;
 
514
  }
 
515
 
 
516
  /* Don't give warnings for not found errors, as we already generate notes */
 
517
  session->no_warnings_for_error= 1;
 
518
 
 
519
  for (table= tables; table; table= table->next_local)
 
520
  {
 
521
    char *db=table->db;
 
522
    plugin::StorageEngine *table_type;
 
523
 
 
524
    error= session->drop_temporary_table(table);
 
525
 
 
526
    switch (error) {
 
527
    case  0:
 
528
      // removed temporary table
 
529
      continue;
 
530
    case -1:
 
531
      error= 1;
 
532
      goto err_with_placeholders;
 
533
    default:
 
534
      // temporary table not found
 
535
      error= 0;
 
536
    }
 
537
 
 
538
    table_type= table->db_type;
 
539
 
 
540
    {
 
541
      Table *locked_table;
 
542
      abort_locked_tables(session, db, table->table_name);
 
543
      remove_table_from_cache(session, db, table->table_name,
 
544
                              RTFC_WAIT_OTHER_THREAD_FLAG |
 
545
                              RTFC_CHECK_KILLED_FLAG);
 
546
      /*
 
547
        If the table was used in lock tables, remember it so that
 
548
        unlock_table_names can free it
 
549
      */
 
550
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
 
551
        table->table= locked_table;
 
552
 
 
553
      if (session->killed)
 
554
      {
 
555
        error= -1;
 
556
        goto err_with_placeholders;
 
557
      }
 
558
    }
 
559
 
 
560
    TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : NO_TMP_TABLE);
 
561
 
 
562
    if ((table_type == NULL
 
563
          && (plugin::StorageEngine::getTableDefinition(*session,
 
564
                                                        identifier) != EEXIST)))
 
565
    {
 
566
      // Table was not found on disk and table can't be created from engine
 
567
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
568
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
 
569
                          table->table_name);
 
570
    }
 
571
    else
 
572
    {
 
573
      error= plugin::StorageEngine::dropTable(*session,
 
574
                                              identifier,
 
575
                                              false);
 
576
 
 
577
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
 
578
      {
 
579
        error= 0;
 
580
        session->clear_error();
 
581
      }
 
582
 
 
583
      if (error == HA_ERR_ROW_IS_REFERENCED)
 
584
      {
 
585
        /* the table is referenced by a foreign key constraint */
 
586
        foreign_key_error= true;
 
587
      }
 
588
    }
 
589
 
 
590
    if (error == 0 || (foreign_key_error == false))
 
591
        write_bin_log_drop_table(session, true, db, table->table_name);
 
592
 
 
593
    if (error)
 
594
    {
 
595
      if (wrong_tables.length())
 
596
        wrong_tables.append(',');
 
597
      wrong_tables.append(String(table->table_name,system_charset_info));
 
598
    }
 
599
  }
 
600
  /*
 
601
    It's safe to unlock LOCK_open: we have an exclusive lock
 
602
    on the table name.
 
603
  */
 
604
  pthread_mutex_unlock(&LOCK_open);
 
605
  error= 0;
 
606
  if (wrong_tables.length())
 
607
  {
 
608
    if (!foreign_key_error)
 
609
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
 
610
                      wrong_tables.c_ptr());
 
611
    else
 
612
    {
 
613
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
 
614
    }
 
615
    error= 1;
 
616
  }
 
617
 
 
618
  pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
 
619
err_with_placeholders:
 
620
  unlock_table_names(tables, NULL);
 
621
  pthread_mutex_unlock(&LOCK_open);
 
622
  session->no_warnings_for_error= 0;
 
623
 
929
624
  return(error);
930
625
}
931
626
 
932
627
/*
933
628
  Removes files with known extensions plus.
934
 
  thd MUST be set when calling this function!
 
629
  session MUST be set when calling this function!
935
630
*/
936
631
 
937
 
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
938
 
                                 const char *org_path, uint level,
939
 
                                 TABLE_LIST **dropped_tables)
 
632
static long mysql_rm_known_files(Session *session, CachedDirectory &dirp,
 
633
                                 const string &db,
 
634
                                 const char *org_path,
 
635
                                 TableList **dropped_tables)
940
636
{
941
 
  long deleted=0;
942
 
  uint32_t found_other_files=0;
 
637
 
 
638
 
 
639
  long deleted= 0;
943
640
  char filePath[FN_REFLEN];
944
 
  TABLE_LIST *tot_list=0, **tot_list_next;
 
641
  TableList *tot_list= NULL, **tot_list_next;
945
642
 
946
643
  tot_list_next= &tot_list;
947
644
 
948
 
  for (uint idx=0 ;
949
 
       idx < (uint) dirp->number_off_files && !thd->killed ;
950
 
       idx++)
 
645
  for (CachedDirectory::Entries::const_iterator iter= dirp.getEntries().begin();
 
646
       iter != dirp.getEntries().end() && !session->killed;
 
647
       ++iter)
951
648
  {
952
 
    FILEINFO *file=dirp->dir_entry+idx;
953
 
    char *extension;
 
649
    string filename((*iter)->filename);
954
650
 
955
651
    /* skiping . and .. */
956
 
    if (file->name[0] == '.' && (!file->name[1] ||
957
 
       (file->name[1] == '.' &&  !file->name[2])))
 
652
    if (filename[0] == '.' && (!filename[1] ||
 
653
       (filename[1] == '.' &&  !filename[2])))
958
654
      continue;
959
655
 
960
 
    if (!(extension= strrchr(file->name, '.')))
961
 
      extension= strend(file->name);
962
 
    if (find_type(extension, &deletable_extentions,1+2) <= 0)
963
 
    {
964
 
      if (find_type(extension, ha_known_exts(),1+2) <= 0)
965
 
        found_other_files++;
 
656
    string extension("");
 
657
    size_t ext_pos= filename.rfind('.');
 
658
    if (ext_pos != string::npos)
 
659
    {
 
660
      extension= filename.substr(ext_pos);
 
661
    }
 
662
    if (deletable_extentions.find(extension) == deletable_extentions.end())
 
663
    {
 
664
      /*
 
665
        ass ass ass.
 
666
 
 
667
        strange checking for magic extensions that are then deleted if
 
668
        not reg_ext (i.e. .frm).
 
669
 
 
670
        and (previously) we'd err out on drop database if files not matching
 
671
        engine ha_known_exts() or deletable_extensions were present.
 
672
 
 
673
        presumably this was to avoid deleting other user data... except if that
 
674
        data happened to be in files ending in .BAK, .opt or .TMD. *fun*
 
675
       */
966
676
      continue;
967
677
    }
968
678
    /* just for safety we use files_charset_info */
969
 
    if (db && !my_strcasecmp(files_charset_info,
970
 
                             extension, reg_ext))
 
679
    if (!my_strcasecmp(files_charset_info, extension.c_str(), ".dfe"))
971
680
    {
 
681
      size_t db_len= db.size();
 
682
 
972
683
      /* Drop the table nicely */
973
 
      *extension= 0;                    // Remove extension
974
 
      TABLE_LIST *table_list=(TABLE_LIST*)
975
 
                              thd->calloc(sizeof(*table_list) + 
976
 
                                          strlen(db) + 1 +
977
 
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH + 
978
 
                                          strlen(file->name) + 1);
 
684
      filename.erase(ext_pos);
 
685
      TableList *table_list=(TableList*)
 
686
                             session->calloc(sizeof(*table_list) +
 
687
                                             db_len + 1 +
 
688
                                             filename.size() + 1);
979
689
 
980
690
      if (!table_list)
981
 
        goto err;
 
691
        return -1;
982
692
      table_list->db= (char*) (table_list+1);
983
 
      table_list->table_name= stpcpy(table_list->db, db) + 1;
984
 
      VOID(filename_to_tablename(file->name, table_list->table_name,
985
 
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH +
986
 
                                 strlen(file->name) + 1));
987
 
      table_list->alias= table_list->table_name;        // If lower_case_table_names=2
988
 
      table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
 
693
      table_list->table_name= strcpy(table_list->db, db.c_str()) + db_len + 1;
 
694
      filename_to_tablename(filename.c_str(), table_list->table_name,
 
695
                            filename.size() + 1);
 
696
      table_list->alias= table_list->table_name;  // If lower_case_table_names=2
 
697
      table_list->internal_tmp_table= (strncmp(filename.c_str(),
 
698
                                               TMP_FILE_PREFIX,
 
699
                                               strlen(TMP_FILE_PREFIX)) == 0);
989
700
      /* Link into list */
990
701
      (*tot_list_next)= table_list;
991
702
      tot_list_next= &table_list->next_local;
993
704
    }
994
705
    else
995
706
    {
996
 
      strxmov(filePath, org_path, "/", file->name, NullS);
997
 
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
 
707
      sprintf(filePath, "%s/%s", org_path, filename.c_str());
 
708
      if (internal::my_delete_with_symlink(filePath,MYF(MY_WME)))
998
709
      {
999
 
        goto err;
 
710
        return -1;
1000
711
      }
1001
712
    }
1002
713
  }
1003
 
  if (thd->killed ||
1004
 
      (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
1005
 
    goto err;
1006
 
 
1007
 
  my_dirend(dirp);  
1008
 
  
 
714
  if (session->killed)
 
715
    return -1;
 
716
 
 
717
  if (tot_list)
 
718
  {
 
719
    if (rm_table_part2(session, tot_list))
 
720
      return -1;
 
721
  }
 
722
 
1009
723
  if (dropped_tables)
1010
724
    *dropped_tables= tot_list;
1011
 
  
1012
 
  /*
1013
 
    If the directory is a symbolic link, remove the link first, then
1014
 
    remove the directory the symbolic link pointed at
1015
 
  */
1016
 
  if (found_other_files)
1017
 
  {
1018
 
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
1019
 
    return(-1);
1020
 
  }
1021
 
  else
1022
 
  {
1023
 
    /* Don't give errors if we can't delete 'RAID' directory */
1024
 
    if (rm_dir_w_symlink(org_path, level == 0))
1025
 
      return(-1);
1026
 
  }
1027
 
 
1028
 
  return(deleted);
1029
 
 
1030
 
err:
1031
 
  my_dirend(dirp);
1032
 
  return(-1);
1033
 
}
1034
 
 
1035
 
 
1036
 
/*
1037
 
  Remove directory with symlink
1038
 
 
1039
 
  SYNOPSIS
1040
 
    rm_dir_w_symlink()
1041
 
    org_path    path of derictory
1042
 
    send_error  send errors
1043
 
  RETURN
1044
 
    0 OK
1045
 
    1 ERROR
1046
 
*/
1047
 
 
1048
 
static bool rm_dir_w_symlink(const char *org_path, bool send_error)
1049
 
{
1050
 
  char tmp_path[FN_REFLEN], *pos;
1051
 
  char *path= tmp_path;
1052
 
  unpack_filename(tmp_path, org_path);
1053
 
#ifdef HAVE_READLINK
1054
 
  int error;
1055
 
  char tmp2_path[FN_REFLEN];
1056
 
 
1057
 
  /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1058
 
  pos= strend(path);
1059
 
  if (pos > path && pos[-1] == FN_LIBCHAR)
1060
 
    *--pos=0;
1061
 
 
1062
 
  if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
1063
 
    return(1);
1064
 
  if (!error)
1065
 
  {
1066
 
    if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1067
 
    {
1068
 
      return(send_error);
1069
 
    }
1070
 
    /* Delete directory symbolic link pointed at */
1071
 
    path= tmp2_path;
1072
 
  }
1073
 
#endif
1074
 
  /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1075
 
  pos= strend(path);
1076
 
 
1077
 
  if (pos > path && pos[-1] == FN_LIBCHAR)
1078
 
    *--pos=0;
1079
 
  if (rmdir(path) < 0 && send_error)
1080
 
  {
1081
 
    my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1082
 
    return(1);
1083
 
  }
1084
 
  return(0);
1085
 
}
1086
 
 
1087
 
 
1088
 
/**
1089
 
  @brief Internal implementation: switch current database to a valid one.
1090
 
 
1091
 
  @param thd            Thread context.
1092
 
  @param new_db_name    Name of the database to switch to. The function will
1093
 
                        take ownership of the name (the caller must not free
1094
 
                        the allocated memory). If the name is NULL, we're
1095
 
                        going to switch to NULL db.
1096
 
  @param new_db_charset Character set of the new database.
1097
 
*/
1098
 
 
1099
 
static void mysql_change_db_impl(THD *thd,
1100
 
                                 LEX_STRING *new_db_name,
1101
 
                                 const CHARSET_INFO * const new_db_charset)
1102
 
{
1103
 
  /* 1. Change current database in THD. */
1104
 
 
1105
 
  if (new_db_name == NULL)
1106
 
  {
1107
 
    /*
1108
 
      THD::set_db() does all the job -- it frees previous database name and
1109
 
      sets the new one.
1110
 
    */
1111
 
 
1112
 
    thd->set_db(NULL, 0);
1113
 
  }
1114
 
  else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1115
 
  {
1116
 
    /*
1117
 
      Here we must use THD::set_db(), because we want to copy
1118
 
      INFORMATION_SCHEMA_NAME constant.
1119
 
    */
1120
 
 
1121
 
    thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1122
 
  }
1123
 
  else
1124
 
  {
1125
 
    /*
1126
 
      Here we already have a copy of database name to be used in THD. So,
1127
 
      we just call THD::reset_db(). Since THD::reset_db() does not releases
1128
 
      the previous database name, we should do it explicitly.
1129
 
    */
1130
 
 
1131
 
    x_free(thd->db);
1132
 
 
1133
 
    thd->reset_db(new_db_name->str, new_db_name->length);
1134
 
  }
1135
 
 
1136
 
  /* 3. Update db-charset environment variables. */
1137
 
 
1138
 
  thd->db_charset= new_db_charset;
1139
 
  thd->variables.collation_database= new_db_charset;
1140
 
}
1141
 
 
1142
 
 
1143
 
 
1144
 
/**
1145
 
  Backup the current database name before switch.
1146
 
 
1147
 
  @param[in]      thd             thread handle
1148
 
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1149
 
                                  the old database name, "length" contains the
1150
 
                                  buffer size
1151
 
                                  OUT: if the current (default) database is
1152
 
                                  not NULL, its name is copied to the
1153
 
                                  buffer pointed at by "str"
1154
 
                                  and "length" is updated accordingly.
1155
 
                                  Otherwise "str" is set to NULL and
1156
 
                                  "length" is set to 0.
1157
 
*/
1158
 
 
1159
 
static void backup_current_db_name(THD *thd,
1160
 
                                   LEX_STRING *saved_db_name)
1161
 
{
1162
 
  if (!thd->db)
1163
 
  {
1164
 
    /* No current (default) database selected. */
1165
 
 
1166
 
    saved_db_name->str= NULL;
1167
 
    saved_db_name->length= 0;
1168
 
  }
1169
 
  else
1170
 
  {
1171
 
    strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
1172
 
    saved_db_name->length= thd->db_length;
1173
 
  }
1174
 
}
1175
 
 
1176
 
 
1177
 
/**
1178
 
  Return true if db1_name is equal to db2_name, false otherwise.
1179
 
 
1180
 
  The function allows to compare database names according to the MySQL
1181
 
  rules. The database names db1 and db2 are equal if:
1182
 
     - db1 is NULL and db2 is NULL;
1183
 
     or
1184
 
     - db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1185
 
       db2 in system character set (UTF8).
1186
 
*/
1187
 
 
1188
 
static inline bool
1189
 
cmp_db_names(const char *db1_name,
1190
 
             const char *db2_name)
1191
 
{
1192
 
  return
1193
 
         /* db1 is NULL and db2 is NULL */
1194
 
         (!db1_name && !db2_name) ||
1195
 
 
1196
 
         /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1197
 
         (db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
1198
 
}
1199
 
 
 
725
 
 
726
  if (rmdir(org_path))
 
727
  {
 
728
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, errno);
 
729
    return -1;
 
730
  }
 
731
 
 
732
  return deleted;
 
733
}
1200
734
 
1201
735
/**
1202
736
  @brief Change the current database and its attributes unconditionally.
1203
737
 
1204
 
  @param thd          thread handle
 
738
  @param session          thread handle
1205
739
  @param new_db_name  database name
1206
740
  @param force_switch if force_switch is false, then the operation will fail if
1207
741
 
1227
761
                          @@collation_server, but the operation will fail;
1228
762
 
1229
763
                        - user privileges will not be checked
1230
 
                          (THD::db_access however is updated);
 
764
                          (Session::db_access however is updated);
1231
765
 
1232
766
                          TODO: is this really the intention?
1233
767
                                (see sp-security.test).
1240
774
  @details The function checks that the database name corresponds to a
1241
775
  valid and existent database, checks access rights and changes the current
1242
776
  database with database attributes (@@collation_database session variable,
1243
 
  THD::db_access).
 
777
  Session::db_access).
1244
778
 
1245
779
  This function is not the only way to switch the database that is
1246
780
  currently employed. When the replication slave thread switches the
1247
 
  database before executing a query, it calls thd->set_db directly.
 
781
  database before executing a query, it calls session->set_db directly.
1248
782
  However, if the query, in turn, uses a stored routine, the stored routine
1249
783
  will use this function, even if it's run on the slave.
1250
784
 
1260
794
    @retval true  Error
1261
795
*/
1262
796
 
1263
 
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
 
797
bool mysql_change_db(Session *session, const LEX_STRING *new_db_name, bool force_switch)
1264
798
{
1265
799
  LEX_STRING new_db_file_name;
1266
800
  const CHARSET_INFO *db_default_cl;
1267
801
 
1268
 
  if (new_db_name == NULL ||
1269
 
      new_db_name->length == 0)
1270
 
  {
1271
 
    if (force_switch)
1272
 
    {
1273
 
      /*
1274
 
        This can happen only if we're switching the current database back
1275
 
        after loading stored program. The thing is that loading of stored
1276
 
        program can happen when there is no current database.
1277
 
 
1278
 
        TODO: actually, new_db_name and new_db_name->str seem to be always
1279
 
        non-NULL. In case of stored program, new_db_name->str == "" and
1280
 
        new_db_name->length == 0.
1281
 
      */
1282
 
 
1283
 
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1284
 
 
1285
 
      return(false);
1286
 
    }
1287
 
    else
1288
 
    {
1289
 
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1290
 
 
1291
 
      return(true);
1292
 
    }
1293
 
  }
 
802
  assert(new_db_name);
 
803
  assert(new_db_name->length);
1294
804
 
1295
805
  if (my_strcasecmp(system_charset_info, new_db_name->str,
1296
 
                    INFORMATION_SCHEMA_NAME.str) == 0)
 
806
                    INFORMATION_SCHEMA_NAME.c_str()) == 0)
1297
807
  {
1298
808
    /* Switch the current database to INFORMATION_SCHEMA. */
1299
 
 
1300
 
    mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, system_charset_info);
1301
 
 
1302
 
    return(false);
 
809
    /* const_cast<> is safe here: mysql_change_db_impl does a copy */
 
810
    LEX_STRING is_name= { const_cast<char *>(INFORMATION_SCHEMA_NAME.c_str()),
 
811
                          INFORMATION_SCHEMA_NAME.length() };
 
812
    mysql_change_db_impl(session, &is_name);
 
813
 
 
814
    return false;
1303
815
  }
1304
816
 
1305
817
  /*
1309
821
    TODO: fix check_db_name().
1310
822
  */
1311
823
 
1312
 
  new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
1313
 
                                   MYF(MY_WME));
1314
824
  new_db_file_name.length= new_db_name->length;
1315
 
 
 
825
  new_db_file_name.str= (char *)malloc(new_db_name->length + 1);
1316
826
  if (new_db_file_name.str == NULL)
1317
 
    return(true);                             /* the error is set */
 
827
    return true;                             /* the error is set */
 
828
  memcpy(new_db_file_name.str, new_db_name->str, new_db_name->length);
 
829
  new_db_file_name.str[new_db_name->length]= 0;
 
830
 
1318
831
 
1319
832
  /*
1320
833
    NOTE: if check_db_name() fails, we should throw an error in any case,
1328
841
  if (check_db_name(&new_db_file_name))
1329
842
  {
1330
843
    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1331
 
    my_free(new_db_file_name.str, MYF(0));
 
844
    free(new_db_file_name.str);
1332
845
 
1333
846
    if (force_switch)
1334
 
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
 
847
      mysql_change_db_impl(session, NULL);
1335
848
 
1336
 
    return(true);
 
849
    return true;
1337
850
  }
1338
851
 
1339
852
  if (check_db_dir_existence(new_db_file_name.str))
1342
855
    {
1343
856
      /* Throw a warning and free new_db_file_name. */
1344
857
 
1345
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
858
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1346
859
                          ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1347
860
                          new_db_file_name.str);
1348
861
 
1349
 
      my_free(new_db_file_name.str, MYF(0));
 
862
      free(new_db_file_name.str);
1350
863
 
1351
864
      /* Change db to NULL. */
1352
865
 
1353
 
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
 
866
      mysql_change_db_impl(session, NULL);
1354
867
 
1355
868
      /* The operation succeed. */
1356
869
 
1357
 
      return(false);
 
870
      return false;
1358
871
    }
1359
872
    else
1360
873
    {
1361
874
      /* Report an error and free new_db_file_name. */
1362
875
 
1363
876
      my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1364
 
      my_free(new_db_file_name.str, MYF(0));
 
877
      free(new_db_file_name.str);
1365
878
 
1366
879
      /* The operation failed. */
1367
880
 
1368
 
      return(true);
 
881
      return true;
1369
882
    }
1370
883
  }
1371
884
 
1372
 
  /*
1373
 
    NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1374
 
    attributes and will be freed in THD::~THD().
1375
 
  */
1376
 
 
1377
 
  db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1378
 
 
1379
 
  mysql_change_db_impl(thd, &new_db_file_name, db_default_cl);
1380
 
 
1381
 
  return(false);
1382
 
}
1383
 
 
1384
 
 
1385
 
/**
1386
 
  Change the current database and its attributes if needed.
1387
 
 
1388
 
  @param          thd             thread handle
1389
 
  @param          new_db_name     database name
1390
 
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
1391
 
                                  the old database name, "length" contains the
1392
 
                                  buffer size
1393
 
                                  OUT: if the current (default) database is
1394
 
                                  not NULL, its name is copied to the
1395
 
                                  buffer pointed at by "str"
1396
 
                                  and "length" is updated accordingly.
1397
 
                                  Otherwise "str" is set to NULL and
1398
 
                                  "length" is set to 0.
1399
 
  @param          force_switch    @see mysql_change_db()
1400
 
  @param[out]     cur_db_changed  out-flag to indicate whether the current
1401
 
                                  database has been changed (valid only if
1402
 
                                  the function suceeded)
1403
 
*/
1404
 
 
1405
 
bool mysql_opt_change_db(THD *thd,
1406
 
                         const LEX_STRING *new_db_name,
1407
 
                         LEX_STRING *saved_db_name,
1408
 
                         bool force_switch,
1409
 
                         bool *cur_db_changed)
1410
 
{
1411
 
  *cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
1412
 
 
1413
 
  if (!*cur_db_changed)
1414
 
    return false;
1415
 
 
1416
 
  backup_current_db_name(thd, saved_db_name);
1417
 
 
1418
 
  return mysql_change_db(thd, new_db_name, force_switch);
1419
 
}
1420
 
 
 
885
  db_default_cl= get_default_db_collation(new_db_file_name.str);
 
886
 
 
887
  mysql_change_db_impl(session, &new_db_file_name);
 
888
  free(new_db_file_name.str);
 
889
 
 
890
  return false;
 
891
}
1421
892
 
1422
893
/*
1423
894
  Check if there is directory for the database name.
1434
905
bool check_db_dir_existence(const char *db_name)
1435
906
{
1436
907
  char db_dir_path[FN_REFLEN];
1437
 
  uint db_dir_path_len;
 
908
  uint32_t db_dir_path_len;
1438
909
 
1439
910
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1440
 
                                        db_name, "", "", 0);
 
911
                                        db_name, "", false);
1441
912
 
1442
913
  if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
1443
914
    db_dir_path[db_dir_path_len - 1]= 0;
1444
915
 
1445
916
  /* Check access. */
1446
917
 
1447
 
  return my_access(db_dir_path, F_OK);
1448
 
}
 
918
  return access(db_dir_path, F_OK);
 
919
}
 
920
 
 
921
/**
 
922
  @brief Internal implementation: switch current database to a valid one.
 
923
 
 
924
  @param session            Thread context.
 
925
  @param new_db_name    Name of the database to switch to. The function will
 
926
                        take ownership of the name (the caller must not free
 
927
                        the allocated memory). If the name is NULL, we're
 
928
                        going to switch to NULL db.
 
929
  @param new_db_charset Character set of the new database.
 
930
*/
 
931
 
 
932
static void mysql_change_db_impl(Session *session, LEX_STRING *new_db_name)
 
933
{
 
934
  /* 1. Change current database in Session. */
 
935
 
 
936
  if (new_db_name == NULL)
 
937
  {
 
938
    /*
 
939
      Session::set_db() does all the job -- it frees previous database name and
 
940
      sets the new one.
 
941
    */
 
942
 
 
943
    session->set_db(NULL, 0);
 
944
  }
 
945
  else
 
946
  {
 
947
    /*
 
948
      Here we already have a copy of database name to be used in Session. So,
 
949
      we just call Session::reset_db(). Since Session::reset_db() does not releases
 
950
      the previous database name, we should do it explicitly.
 
951
    */
 
952
 
 
953
    session->set_db(new_db_name->str, new_db_name->length);
 
954
  }
 
955
}
 
956
 
 
957
} /* namespace drizzled */