~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/sql_db.cc

Merged in changes. 
Edited a the comment test case so deal with our version bump.

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
 
#include <string>
20
 
#include <fstream>
21
 
#include <fcntl.h>
22
 
#include <drizzled/message/schema.pb.h>
23
 
#include "drizzled/my_error.h"
24
 
#include "drizzled/internal/my_dir.h"
25
 
#include <drizzled/error.h>
26
 
#include <drizzled/gettext.h>
27
 
#include <drizzled/my_hash.h>
28
 
#include "drizzled/internal/m_string.h"
29
 
#include <drizzled/session.h>
30
 
#include <drizzled/db.h>
31
 
#include <drizzled/sql_base.h>
32
 
#include <drizzled/lock.h>
33
 
#include <drizzled/errmsg_print.h>
34
 
#include <drizzled/replication_services.h>
35
 
#include <drizzled/message/schema.pb.h>
36
 
#include "drizzled/sql_table.h"
37
 
#include "drizzled/plugin/info_schema_table.h"
38
 
#include "drizzled/global_charset_info.h"
39
 
#include "drizzled/pthread_globals.h"
40
 
#include "drizzled/charset.h"
41
 
 
42
 
#include "drizzled/internal/my_sys.h"
43
 
 
44
 
using namespace std;
45
 
using namespace drizzled;
46
 
 
47
 
#define MY_DB_OPT_FILE "db.opt"
 
18
 
 
19
#include "mysql_priv.h"
 
20
#include <mysys_err.h>
 
21
#include <my_dir.h>
 
22
#include <m_ctype.h>
 
23
#include "log.h"
 
24
 
48
25
#define MAX_DROP_TABLE_Q_LEN      1024
49
26
 
50
 
const char *del_exts[]= {".dfe", ".blk", ".arz", ".BAK", ".TMD",".opt", NULL};
 
27
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
51
28
static TYPELIB deletable_extentions=
52
29
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
53
30
 
54
 
static long mysql_rm_known_files(Session *session, MY_DIR *dirp,
55
 
                                 const char *db, const char *path,
56
 
                                 TableList **dropped_tables);
 
31
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
 
32
                                 const char *db, const char *path, uint level, 
 
33
                                 TABLE_LIST **dropped_tables);
 
34
         
 
35
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
 
36
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
 
37
static void mysql_change_db_impl(THD *thd,
 
38
                                 LEX_STRING *new_db_name,
 
39
                                 CHARSET_INFO *new_db_charset);
 
40
 
 
41
 
 
42
/* Database lock hash */
 
43
HASH lock_db_cache;
 
44
pthread_mutex_t LOCK_lock_db;
 
45
int creating_database= 0;  // how many database locks are made
 
46
 
 
47
 
 
48
/* Structure for database lock */
 
49
typedef struct my_dblock_st
 
50
{
 
51
  char *name;        /* Database name        */
 
52
  uint name_length;  /* Database length name */
 
53
} my_dblock_t;
 
54
 
 
55
 
 
56
/*
 
57
  lock_db key.
 
58
*/
 
59
 
 
60
extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, my_bool not_used);
 
61
 
 
62
uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
 
63
                       my_bool not_used __attribute__((unused)))
 
64
{
 
65
  *length= ptr->name_length;
 
66
  return (uchar*) ptr->name;
 
67
}
 
68
 
 
69
 
 
70
/*
 
71
  Free lock_db hash element.
 
72
*/
 
73
 
 
74
extern "C" void lock_db_free_element(void *ptr);
 
75
 
 
76
void lock_db_free_element(void *ptr)
 
77
{
 
78
  my_free(ptr, MYF(0));
 
79
}
 
80
 
 
81
 
 
82
/*
 
83
  Put a database lock entry into the hash.
 
84
  
 
85
  DESCRIPTION
 
86
    Insert a database lock entry into hash.
 
87
    LOCK_db_lock must be previously locked.
 
88
  
 
89
  RETURN VALUES
 
90
    0 on success.
 
91
    1 on error.
 
92
*/
 
93
 
 
94
static my_bool lock_db_insert(const char *dbname, uint length)
 
95
{
 
96
  my_dblock_t *opt;
 
97
  my_bool error= 0;
 
98
  DBUG_ENTER("lock_db_insert");
 
99
  
 
100
  safe_mutex_assert_owner(&LOCK_lock_db);
 
101
 
 
102
  if (!(opt= (my_dblock_t*) hash_search(&lock_db_cache,
 
103
                                        (uchar*) dbname, length)))
 
104
  { 
 
105
    /* Db is not in the hash, insert it */
 
106
    char *tmp_name;
 
107
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
 
108
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
 
109
                         NullS))
 
110
    {
 
111
      error= 1;
 
112
      goto end;
 
113
    }
 
114
    
 
115
    opt->name= tmp_name;
 
116
    strmov(opt->name, dbname);
 
117
    opt->name_length= length;
 
118
    
 
119
    if ((error= my_hash_insert(&lock_db_cache, (uchar*) opt)))
 
120
      my_free(opt, MYF(0));
 
121
  }
 
122
 
 
123
end:
 
124
  DBUG_RETURN(error);
 
125
}
 
126
 
 
127
 
 
128
/*
 
129
  Delete a database lock entry from hash.
 
130
*/
 
131
 
 
132
void lock_db_delete(const char *name, uint length)
 
133
{
 
134
  my_dblock_t *opt;
 
135
  safe_mutex_assert_owner(&LOCK_lock_db);
 
136
  if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
 
137
                                       (const uchar*) name, length)))
 
138
    hash_delete(&lock_db_cache, (uchar*) opt);
 
139
}
 
140
 
 
141
 
 
142
/* Database options hash */
 
143
static HASH dboptions;
 
144
static my_bool dboptions_init= 0;
 
145
static rw_lock_t LOCK_dboptions;
 
146
 
 
147
/* Structure for database options */
 
148
typedef struct my_dbopt_st
 
149
{
 
150
  char *name;                   /* Database name                  */
 
151
  uint name_length;             /* Database length name           */
 
152
  CHARSET_INFO *charset;        /* Database default character set */
 
153
} my_dbopt_t;
 
154
 
 
155
 
 
156
/*
 
157
  Function we use in the creation of our hash to get key.
 
158
*/
 
159
 
 
160
extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
161
                                    my_bool not_used);
 
162
 
 
163
uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
164
                         my_bool not_used __attribute__((unused)))
 
165
{
 
166
  *length= opt->name_length;
 
167
  return (uchar*) opt->name;
 
168
}
 
169
 
 
170
 
 
171
/*
 
172
  Helper function to write a query to binlog used by mysql_rm_db()
 
173
*/
 
174
 
 
175
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
 
176
                                   char *db, uint db_len)
 
177
{
 
178
  Query_log_event qinfo(thd, query, q_len, 0, 0);
 
179
  qinfo.error_code= 0;
 
180
  qinfo.db= db;
 
181
  qinfo.db_len= db_len;
 
182
  mysql_bin_log.write(&qinfo);
 
183
}  
 
184
 
 
185
 
 
186
/*
 
187
  Function to free dboptions hash element
 
188
*/
 
189
 
 
190
extern "C" void free_dbopt(void *dbopt);
 
191
 
 
192
void free_dbopt(void *dbopt)
 
193
{
 
194
  my_free((uchar*) dbopt, MYF(0));
 
195
}
 
196
 
 
197
 
 
198
/* 
 
199
  Initialize database option hash and locked database hash.
 
200
 
 
201
  SYNOPSIS
 
202
    my_database_names()
 
203
 
 
204
  NOTES
 
205
    Must be called before any other database function is called.
 
206
 
 
207
  RETURN
 
208
    0   ok
 
209
    1   Fatal error
 
210
*/
 
211
 
 
212
bool my_database_names_init(void)
 
213
{
 
214
  bool error= 0;
 
215
  (void) my_rwlock_init(&LOCK_dboptions, NULL);
 
216
  if (!dboptions_init)
 
217
  {
 
218
    dboptions_init= 1;
 
219
    error= hash_init(&dboptions, lower_case_table_names ? 
 
220
                     &my_charset_bin : system_charset_info,
 
221
                     32, 0, 0, (hash_get_key) dboptions_get_key,
 
222
                     free_dbopt,0) ||
 
223
           hash_init(&lock_db_cache, lower_case_table_names ? 
 
224
                     &my_charset_bin : system_charset_info,
 
225
                     32, 0, 0, (hash_get_key) lock_db_get_key,
 
226
                     lock_db_free_element,0);
 
227
 
 
228
  }
 
229
  return error;
 
230
}
 
231
 
 
232
 
 
233
 
 
234
/* 
 
235
  Free database option hash and locked databases hash.
 
236
*/
 
237
 
 
238
void my_database_names_free(void)
 
239
{
 
240
  if (dboptions_init)
 
241
  {
 
242
    dboptions_init= 0;
 
243
    hash_free(&dboptions);
 
244
    (void) rwlock_destroy(&LOCK_dboptions);
 
245
    hash_free(&lock_db_cache);
 
246
  }
 
247
}
 
248
 
 
249
 
 
250
/*
 
251
  Cleanup cached options
 
252
*/
 
253
 
 
254
void my_dbopt_cleanup(void)
 
255
{
 
256
  rw_wrlock(&LOCK_dboptions);
 
257
  hash_free(&dboptions);
 
258
  hash_init(&dboptions, lower_case_table_names ? 
 
259
            &my_charset_bin : system_charset_info,
 
260
            32, 0, 0, (hash_get_key) dboptions_get_key,
 
261
            free_dbopt,0);
 
262
  rw_unlock(&LOCK_dboptions);
 
263
}
 
264
 
 
265
 
 
266
/*
 
267
  Find database options in the hash.
 
268
  
 
269
  DESCRIPTION
 
270
    Search a database options in the hash, usings its path.
 
271
    Fills "create" on success.
 
272
  
 
273
  RETURN VALUES
 
274
    0 on success.
 
275
    1 on error.
 
276
*/
 
277
 
 
278
static my_bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
 
279
{
 
280
  my_dbopt_t *opt;
 
281
  uint length;
 
282
  my_bool error= 1;
 
283
  
 
284
  length= (uint) strlen(dbname);
 
285
  
 
286
  rw_rdlock(&LOCK_dboptions);
 
287
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
 
288
  {
 
289
    create->default_table_charset= opt->charset;
 
290
    error= 0;
 
291
  }
 
292
  rw_unlock(&LOCK_dboptions);
 
293
  return error;
 
294
}
 
295
 
 
296
 
 
297
/*
 
298
  Writes database options into the hash.
 
299
  
 
300
  DESCRIPTION
 
301
    Inserts database options into the hash, or updates
 
302
    options if they are already in the hash.
 
303
  
 
304
  RETURN VALUES
 
305
    0 on success.
 
306
    1 on error.
 
307
*/
 
308
 
 
309
static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
 
310
{
 
311
  my_dbopt_t *opt;
 
312
  uint length;
 
313
  my_bool error= 0;
 
314
  DBUG_ENTER("put_dbopt");
 
315
 
 
316
  length= (uint) strlen(dbname);
 
317
  
 
318
  rw_wrlock(&LOCK_dboptions);
 
319
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
 
320
  { 
 
321
    /* Options are not in the hash, insert them */
 
322
    char *tmp_name;
 
323
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
 
324
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
 
325
                         NullS))
 
326
    {
 
327
      error= 1;
 
328
      goto end;
 
329
    }
 
330
    
 
331
    opt->name= tmp_name;
 
332
    strmov(opt->name, dbname);
 
333
    opt->name_length= length;
 
334
    
 
335
    if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
 
336
    {
 
337
      my_free(opt, MYF(0));
 
338
      goto end;
 
339
    }
 
340
  }
 
341
 
 
342
  /* Update / write options in hash */
 
343
  opt->charset= create->default_table_charset;
 
344
 
 
345
end:
 
346
  rw_unlock(&LOCK_dboptions);  
 
347
  DBUG_RETURN(error);
 
348
}
 
349
 
 
350
 
 
351
/*
 
352
  Deletes database options from the hash.
 
353
*/
 
354
 
 
355
void del_dbopt(const char *path)
 
356
{
 
357
  my_dbopt_t *opt;
 
358
  rw_wrlock(&LOCK_dboptions);
 
359
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
 
360
                                      strlen(path))))
 
361
    hash_delete(&dboptions, (uchar*) opt);
 
362
  rw_unlock(&LOCK_dboptions);
 
363
}
 
364
 
 
365
 
 
366
/*
 
367
  Create database options file:
 
368
 
 
369
  DESCRIPTION
 
370
    Currently database default charset is only stored there.
 
371
 
 
372
  RETURN VALUES
 
373
  0     ok
 
374
  1     Could not create file or write to it.  Error sent through my_error()
 
375
*/
 
376
 
 
377
static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
 
378
{
 
379
  register File file;
 
380
  char buf[256]; // Should be enough for one option
 
381
  bool error=1;
 
382
 
 
383
  if (!create->default_table_charset)
 
384
    create->default_table_charset= thd->variables.collation_server;
 
385
 
 
386
  if (put_dbopt(path, create))
 
387
    return 1;
 
388
 
 
389
  if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
 
390
  {
 
391
    ulong length;
 
392
    length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=",
 
393
                              create->default_table_charset->csname,
 
394
                              "\ndefault-collation=",
 
395
                              create->default_table_charset->name,
 
396
                              "\n", NullS) - buf);
 
397
 
 
398
    /* Error is written by my_write */
 
399
    if (!my_write(file,(uchar*) buf, length, MYF(MY_NABP+MY_WME)))
 
400
      error=0;
 
401
    my_close(file,MYF(0));
 
402
  }
 
403
  return error;
 
404
}
 
405
 
 
406
 
 
407
/*
 
408
  Load database options file
 
409
 
 
410
  load_db_opt()
 
411
  path          Path for option file
 
412
  create        Where to store the read options
 
413
 
 
414
  DESCRIPTION
 
415
 
 
416
  RETURN VALUES
 
417
  0     File found
 
418
  1     No database file or could not open it
 
419
 
 
420
*/
 
421
 
 
422
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
 
423
{
 
424
  File file;
 
425
  char buf[256];
 
426
  DBUG_ENTER("load_db_opt");
 
427
  bool error=1;
 
428
  uint nbytes;
 
429
 
 
430
  bzero((char*) create,sizeof(*create));
 
431
  create->default_table_charset= thd->variables.collation_server;
 
432
 
 
433
  /* Check if options for this database are already in the hash */
 
434
  if (!get_dbopt(path, create))
 
435
    DBUG_RETURN(0);
 
436
 
 
437
  /* Otherwise, load options from the .opt file */
 
438
  if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
439
    goto err1;
 
440
 
 
441
  IO_CACHE cache;
 
442
  if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
 
443
    goto err2;
 
444
 
 
445
  while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
 
446
  {
 
447
    char *pos= buf+nbytes-1;
 
448
    /* Remove end space and control characters */
 
449
    while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
 
450
      pos--;
 
451
    *pos=0;
 
452
    if ((pos= strchr(buf, '=')))
 
453
    {
 
454
      if (!strncmp(buf,"default-character-set", (pos-buf)))
 
455
      {
 
456
        /*
 
457
           Try character set name, and if it fails
 
458
           try collation name, probably it's an old
 
459
           4.1.0 db.opt file, which didn't have
 
460
           separate default-character-set and
 
461
           default-collation commands.
 
462
        */
 
463
        if (!(create->default_table_charset=
 
464
        get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
 
465
            !(create->default_table_charset=
 
466
              get_charset_by_name(pos+1, MYF(0))))
 
467
        {
 
468
          sql_print_error("Error while loading database options: '%s':",path);
 
469
          sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
 
470
          create->default_table_charset= default_charset_info;
 
471
        }
 
472
      }
 
473
      else if (!strncmp(buf,"default-collation", (pos-buf)))
 
474
      {
 
475
        if (!(create->default_table_charset= get_charset_by_name(pos+1,
 
476
                                                           MYF(0))))
 
477
        {
 
478
          sql_print_error("Error while loading database options: '%s':",path);
 
479
          sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
 
480
          create->default_table_charset= default_charset_info;
 
481
        }
 
482
      }
 
483
    }
 
484
  }
 
485
  /*
 
486
    Put the loaded value into the hash.
 
487
    Note that another thread could've added the same
 
488
    entry to the hash after we called get_dbopt(),
 
489
    but it's not an error, as put_dbopt() takes this
 
490
    possibility into account.
 
491
  */
 
492
  error= put_dbopt(path, create);
 
493
 
 
494
  end_io_cache(&cache);
 
495
err2:
 
496
  my_close(file,MYF(0));
 
497
err1:
 
498
  DBUG_RETURN(error);
 
499
}
 
500
 
 
501
 
 
502
/*
 
503
  Retrieve database options by name. Load database options file or fetch from
 
504
  cache.
 
505
 
 
506
  SYNOPSIS
 
507
    load_db_opt_by_name()
 
508
    db_name         Database name
 
509
    db_create_info  Where to store the database options
 
510
 
 
511
  DESCRIPTION
 
512
    load_db_opt_by_name() is a shortcut for load_db_opt().
 
513
 
 
514
  NOTE
 
515
    Although load_db_opt_by_name() (and load_db_opt()) returns status of
 
516
    the operation, it is useless usually and should be ignored. The problem
 
517
    is that there are 1) system databases ("mysql") and 2) virtual
 
518
    databases ("information_schema"), which do not contain options file.
 
519
    So, load_db_opt[_by_name]() returns FALSE for these databases, but this
 
520
    is not an error.
 
521
 
 
522
    load_db_opt[_by_name]() clears db_create_info structure in any case, so
 
523
    even on failure it contains valid data. So, common use case is just
 
524
    call load_db_opt[_by_name]() without checking return value and use
 
525
    db_create_info right after that.
 
526
 
 
527
  RETURN VALUES (read NOTE!)
 
528
    FALSE   Success
 
529
    TRUE    Failed to retrieve options
 
530
*/
 
531
 
 
532
bool load_db_opt_by_name(THD *thd, const char *db_name,
 
533
                         HA_CREATE_INFO *db_create_info)
 
534
{
 
535
  char db_opt_path[FN_REFLEN];
 
536
 
 
537
  /*
 
538
    Pass an empty file name, and the database options file name as extension
 
539
    to avoid table name to file name encoding.
 
540
  */
 
541
  (void) build_table_filename(db_opt_path, sizeof(db_opt_path),
 
542
                              db_name, "", MY_DB_OPT_FILE, 0);
 
543
 
 
544
  return load_db_opt(thd, db_opt_path, db_create_info);
 
545
}
 
546
 
57
547
 
58
548
/**
59
549
  Return default database collation.
60
550
 
61
 
  @param session     Thread context.
 
551
  @param thd     Thread context.
62
552
  @param db_name Database name.
63
553
 
64
554
  @return CHARSET_INFO object. The operation always return valid character
65
555
    set, even if the database does not exist.
66
556
*/
67
557
 
68
 
const CHARSET_INFO *get_default_db_collation(const char *db_name)
69
 
{
70
 
  message::Schema db;
71
 
 
72
 
  get_database_metadata(db_name, &db);
73
 
 
74
 
  /* If for some reason the db.opt file lacks a collation,
75
 
     we just return the default */
76
 
 
77
 
  if (db.has_collation())
78
 
  {
79
 
    const string buffer= db.collation();
80
 
    const CHARSET_INFO* cs= get_charset_by_name(buffer.c_str());
81
 
 
82
 
    if (!cs)
83
 
    {
84
 
      errmsg_printf(ERRMSG_LVL_ERROR,
85
 
                    _("Error while loading database options: '%s':"),db_name);
86
 
      errmsg_printf(ERRMSG_LVL_ERROR, ER(ER_UNKNOWN_COLLATION), buffer.c_str());
87
 
 
88
 
      return default_charset_info;
89
 
    }
90
 
 
91
 
    return cs;
92
 
  }
93
 
 
94
 
  return default_charset_info;
95
 
}
96
 
 
97
 
/* path is path to database, not schema file */
98
 
static int write_schema_file(const DatabasePathName &path, const message::Schema &db)
99
 
{
100
 
  char schema_file_tmp[FN_REFLEN];
101
 
  string schema_file(path.to_string());
102
 
 
103
 
  snprintf(schema_file_tmp, FN_REFLEN, "%s%c%s.tmpXXXXXX", path.to_string().c_str(), FN_LIBCHAR, MY_DB_OPT_FILE);
104
 
 
105
 
  schema_file.append(1, FN_LIBCHAR);
106
 
  schema_file.append(MY_DB_OPT_FILE);
107
 
 
108
 
  int fd= mkstemp(schema_file_tmp);
109
 
 
110
 
  if (fd==-1)
111
 
    return errno;
112
 
 
113
 
 
114
 
  if (!db.SerializeToFileDescriptor(fd))
115
 
  {
116
 
    close(fd);
117
 
    unlink(schema_file_tmp);
118
 
    return -1;
119
 
  }
120
 
 
121
 
  if (rename(schema_file_tmp, schema_file.c_str()) == -1)
122
 
  {
123
 
    close(fd);
124
 
    return errno;
125
 
  }
126
 
 
127
 
  close(fd);
128
 
  return 0;
129
 
}
130
 
 
131
 
int get_database_metadata(const char *dbname, message::Schema *db)
132
 
{
133
 
  char db_opt_path[FN_REFLEN];
134
 
  size_t length;
 
558
CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
 
559
{
 
560
  HA_CREATE_INFO db_info;
 
561
 
 
562
  if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
 
563
    return thd->db_charset;
 
564
 
 
565
  load_db_opt_by_name(thd, db_name, &db_info);
135
566
 
136
567
  /*
137
 
    Pass an empty file name, and the database options file name as extension
138
 
    to avoid table name to file name encoding.
 
568
    NOTE: even if load_db_opt_by_name() fails,
 
569
    db_info.default_table_charset contains valid character set
 
570
    (collation_server). We should not fail if load_db_opt_by_name() fails,
 
571
    because it is valid case. If a database has been created just by
 
572
    "mkdir", it does not contain db.opt file, but it is valid database.
139
573
  */
140
 
  length= build_table_filename(db_opt_path, sizeof(db_opt_path),
141
 
                              dbname, "", false);
142
 
  strcpy(db_opt_path + length, MY_DB_OPT_FILE);
143
 
 
144
 
  int fd= open(db_opt_path, O_RDONLY);
145
 
 
146
 
  if (fd == -1)
147
 
    return errno;
148
 
 
149
 
  if (!db->ParseFromFileDescriptor(fd))
150
 
  {
151
 
    close(fd);
152
 
    return -1;
153
 
  }
154
 
  close(fd);
155
 
 
156
 
  return 0;
 
574
 
 
575
  return db_info.default_table_charset;
157
576
}
158
577
 
 
578
 
159
579
/*
160
580
  Create a database
161
581
 
162
582
  SYNOPSIS
163
583
  mysql_create_db()
164
 
  session               Thread handler
 
584
  thd           Thread handler
165
585
  db            Name of database to create
166
586
                Function assumes that this is already validated.
167
587
  create_info   Database create options (like character set)
 
588
  silent        Used by replication when internally creating a database.
 
589
                In this case the entry should not be logged.
168
590
 
169
591
  SIDE-EFFECTS
170
592
   1. Report back to client that command succeeded (my_ok)
171
593
   2. Report errors to client
172
594
   3. Log event to binary log
 
595
   (The 'silent' flags turns off 1 and 3.)
173
596
 
174
597
  RETURN VALUES
175
 
  false ok
176
 
  true  Error
 
598
  FALSE ok
 
599
  TRUE  Error
177
600
 
178
601
*/
179
602
 
180
 
bool mysql_create_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message, bool is_if_not_exists)
 
603
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
 
604
                     bool silent)
181
605
{
182
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
 
606
  char   path[FN_REFLEN+16];
 
607
  char   tmp_query[FN_REFLEN+16];
183
608
  long result= 1;
184
 
  int error_erno;
185
 
  bool error= false;
186
 
  DatabasePathName database_path(database_name);
 
609
  int error= 0;
 
610
  struct stat stat_info;
 
611
  uint create_options= create_info ? create_info->options : 0;
 
612
  uint path_len;
 
613
  DBUG_ENTER("mysql_create_db");
187
614
 
188
615
  /* do not create 'information_schema' db */
189
 
  if (!my_strcasecmp(system_charset_info, database_name.to_string().c_str(), INFORMATION_SCHEMA_NAME.c_str()))
 
616
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
190
617
  {
191
 
    my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
192
 
    return(-1);
 
618
    my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
 
619
    DBUG_RETURN(-1);
193
620
  }
194
621
 
195
 
  assert(database_name.isValid());
196
 
  schema_message->set_name(database_name.to_string());
197
 
 
198
622
  /*
199
623
    Do not create database if another thread is holding read lock.
200
 
    Wait for global read lock before acquiring LOCK_create_db.
 
624
    Wait for global read lock before acquiring LOCK_mysql_create_db.
201
625
    After wait_if_global_read_lock() we have protection against another
202
 
    global read lock. If we would acquire LOCK_create_db first,
 
626
    global read lock. If we would acquire LOCK_mysql_create_db first,
203
627
    another thread could step in and get the global read lock before we
204
628
    reach wait_if_global_read_lock(). If this thread tries the same as we
205
 
    (admin a db), it would then go and wait on LOCK_create_db...
 
629
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
206
630
    Furthermore wait_if_global_read_lock() checks if the current thread
207
631
    has the global read lock and refuses the operation with
208
632
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
209
633
  */
210
 
  if (wait_if_global_read_lock(session, 0, 1))
 
634
  if (wait_if_global_read_lock(thd, 0, 1))
211
635
  {
212
 
    error= true;
 
636
    error= -1;
213
637
    goto exit2;
214
638
  }
215
639
 
216
 
  pthread_mutex_lock(&LOCK_create_db);
217
 
 
218
 
  if (mkdir(database_path.to_string().c_str(),0777) == -1)
 
640
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
 
641
 
 
642
  /* Check directory */
 
643
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
 
644
  path[path_len-1]= 0;                    // Remove last '/' from path
 
645
 
 
646
  if (!stat(path,&stat_info))
219
647
  {
220
 
    if (errno == EEXIST)
 
648
    if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
221
649
    {
222
 
      if (! is_if_not_exists)
223
 
      {
224
 
        my_error(ER_DB_CREATE_EXISTS, MYF(0), database_name.to_string().c_str());
225
 
        error= true;
226
 
        goto exit;
227
 
      }
228
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
229
 
                          ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS),
230
 
                          database_name.to_string().c_str());
231
 
      session->my_ok();
232
 
      error= false;
 
650
      my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
 
651
      error= -1;
233
652
      goto exit;
234
653
    }
235
 
 
236
 
    my_error(ER_CANT_CREATE_DB, MYF(0), database_name.to_string().c_str(), errno);
237
 
    error= true;
 
654
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
655
                        ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
 
656
    if (!silent)
 
657
      my_ok(thd);
 
658
    error= 0;
238
659
    goto exit;
239
660
  }
240
 
 
241
 
  error_erno= write_schema_file(database_path, *schema_message);
242
 
  if (error_erno && error_erno != EEXIST)
243
 
  {
244
 
    if (rmdir(database_path.to_string().c_str()) >= 0)
245
 
    {
246
 
      error= true;
247
 
      goto exit;
248
 
    }
249
 
  }
250
 
  else if (error_erno)
251
 
    error= true;
252
 
 
253
 
  replication_services.rawStatement(session, session->query, session->query_length);
254
 
  session->my_ok(result);
 
661
  else
 
662
  {
 
663
    if (errno != ENOENT)
 
664
    {
 
665
      my_error(EE_STAT, MYF(0), path, errno);
 
666
      goto exit;
 
667
    }
 
668
    if (my_mkdir(path,0777,MYF(0)) < 0)
 
669
    {
 
670
      my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
 
671
      error= -1;
 
672
      goto exit;
 
673
    }
 
674
  }
 
675
 
 
676
  path[path_len-1]= FN_LIBCHAR;
 
677
  strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
 
678
  if (write_db_opt(thd, path, create_info))
 
679
  {
 
680
    /*
 
681
      Could not create options file.
 
682
      Restore things to beginning.
 
683
    */
 
684
    path[path_len]= 0;
 
685
    if (rmdir(path) >= 0)
 
686
    {
 
687
      error= -1;
 
688
      goto exit;
 
689
    }
 
690
    /*
 
691
      We come here when we managed to create the database, but not the option
 
692
      file.  In this case it's best to just continue as if nothing has
 
693
      happened.  (This is a very unlikely senario)
 
694
    */
 
695
  }
 
696
  
 
697
  if (!silent)
 
698
  {
 
699
    char *query;
 
700
    uint query_length;
 
701
 
 
702
    if (!thd->query)                            // Only in replication
 
703
    {
 
704
      query=         tmp_query;
 
705
      query_length= (uint) (strxmov(tmp_query,"create database `",
 
706
                                    db, "`", NullS) - tmp_query);
 
707
    }
 
708
    else
 
709
    {
 
710
      query=        thd->query;
 
711
      query_length= thd->query_length;
 
712
    }
 
713
 
 
714
    ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
 
715
                        query, query_length,
 
716
                        db, "");
 
717
 
 
718
    if (mysql_bin_log.is_open())
 
719
    {
 
720
      Query_log_event qinfo(thd, query, query_length, 0, 
 
721
                            /* suppress_use */ TRUE);
 
722
 
 
723
      /*
 
724
        Write should use the database being created as the "current
 
725
        database" and not the threads current database, which is the
 
726
        default. If we do not change the "current database" to the
 
727
        database being created, the CREATE statement will not be
 
728
        replicated when using --binlog-do-db to select databases to be
 
729
        replicated. 
 
730
 
 
731
        An example (--binlog-do-db=sisyfos):
 
732
       
 
733
          CREATE DATABASE bob;        # Not replicated
 
734
          USE bob;                    # 'bob' is the current database
 
735
          CREATE DATABASE sisyfos;    # Not replicated since 'bob' is
 
736
                                      # current database.
 
737
          USE sisyfos;                # Will give error on slave since
 
738
                                      # database does not exist.
 
739
      */
 
740
      qinfo.db     = db;
 
741
      qinfo.db_len = strlen(db);
 
742
 
 
743
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
 
744
      mysql_bin_log.write(&qinfo);
 
745
    }
 
746
    my_ok(thd, result);
 
747
  }
255
748
 
256
749
exit:
257
 
  pthread_mutex_unlock(&LOCK_create_db);
258
 
  start_waiting_global_read_lock(session);
 
750
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
 
751
  start_waiting_global_read_lock(thd);
259
752
exit2:
260
 
  return error;
 
753
  DBUG_RETURN(error);
261
754
}
262
755
 
263
756
 
264
757
/* db-name is already validated when we come here */
265
758
 
266
 
bool mysql_alter_db(Session *session, const NormalisedDatabaseName &database_name, message::Schema *schema_message)
 
759
bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
267
760
{
268
 
  ReplicationServices &replication_services= ReplicationServices::singleton();
 
761
  char path[FN_REFLEN+16];
269
762
  long result=1;
270
763
  int error= 0;
271
 
  DatabasePathName database_path(database_name);
 
764
  DBUG_ENTER("mysql_alter_db");
272
765
 
273
766
  /*
274
767
    Do not alter database if another thread is holding read lock.
275
 
    Wait for global read lock before acquiring LOCK_create_db.
 
768
    Wait for global read lock before acquiring LOCK_mysql_create_db.
276
769
    After wait_if_global_read_lock() we have protection against another
277
 
    global read lock. If we would acquire LOCK_create_db first,
 
770
    global read lock. If we would acquire LOCK_mysql_create_db first,
278
771
    another thread could step in and get the global read lock before we
279
772
    reach wait_if_global_read_lock(). If this thread tries the same as we
280
 
    (admin a db), it would then go and wait on LOCK_create_db...
 
773
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
281
774
    Furthermore wait_if_global_read_lock() checks if the current thread
282
775
    has the global read lock and refuses the operation with
283
776
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
284
777
  */
285
 
  if ((error=wait_if_global_read_lock(session,0,1)))
286
 
    goto exit;
287
 
 
288
 
  assert(schema_message);
289
 
  assert(database_name.isValid());
290
 
 
291
 
  schema_message->set_name(database_name.to_string());
292
 
 
293
 
  pthread_mutex_lock(&LOCK_create_db);
294
 
 
295
 
  error= write_schema_file(database_path, *schema_message);
296
 
  if (error && error != EEXIST)
297
 
  {
298
 
    /* TODO: find some witty way of getting back an error message */
299
 
    pthread_mutex_unlock(&LOCK_create_db);
300
 
    goto exit;
301
 
  }
302
 
 
303
 
  replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
304
 
  session->my_ok(result);
305
 
 
306
 
  pthread_mutex_unlock(&LOCK_create_db);
307
 
  start_waiting_global_read_lock(session);
 
778
  if ((error=wait_if_global_read_lock(thd,0,1)))
 
779
    goto exit2;
 
780
 
 
781
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
 
782
 
 
783
  /* 
 
784
     Recreate db options file: /dbpath/.db.opt
 
785
     We pass MY_DB_OPT_FILE as "extension" to avoid
 
786
     "table name to file name" encoding.
 
787
  */
 
788
  build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
 
789
  if ((error=write_db_opt(thd, path, create_info)))
 
790
    goto exit;
 
791
 
 
792
  /* Change options if current database is being altered. */
 
793
 
 
794
  if (thd->db && !strcmp(thd->db,db))
 
795
  {
 
796
    thd->db_charset= create_info->default_table_charset ?
 
797
                     create_info->default_table_charset :
 
798
                     thd->variables.collation_server;
 
799
    thd->variables.collation_database= thd->db_charset;
 
800
  }
 
801
 
 
802
  ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
 
803
                      thd->query, thd->query_length,
 
804
                      db, "");
 
805
 
 
806
  if (mysql_bin_log.is_open())
 
807
  {
 
808
    Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
 
809
                          /* suppress_use */ TRUE);
 
810
 
 
811
    /*
 
812
      Write should use the database being created as the "current
 
813
      database" and not the threads current database, which is the
 
814
      default.
 
815
    */
 
816
    qinfo.db     = db;
 
817
    qinfo.db_len = strlen(db);
 
818
 
 
819
    thd->clear_error();
 
820
    /* These DDL methods and logging protected with LOCK_mysql_create_db */
 
821
    mysql_bin_log.write(&qinfo);
 
822
  }
 
823
  my_ok(thd, result);
 
824
 
308
825
exit:
309
 
  return error ? true : false;
 
826
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
 
827
  start_waiting_global_read_lock(thd);
 
828
exit2:
 
829
  DBUG_RETURN(error);
310
830
}
311
831
 
312
832
 
315
835
 
316
836
  SYNOPSIS
317
837
    mysql_rm_db()
318
 
    session                     Thread handle
 
838
    thd                 Thread handle
319
839
    db                  Database name in the case given by user
320
840
                        It's already validated and set to lower case
321
841
                        (if needed) when we come here
323
843
    silent              Don't generate errors
324
844
 
325
845
  RETURN
326
 
    false ok (Database dropped)
 
846
    FALSE ok (Database dropped)
327
847
    ERROR Error
328
848
*/
329
849
 
330
 
bool mysql_rm_db(Session *session, const NormalisedDatabaseName &database_name, bool if_exists)
 
850
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
331
851
{
332
852
  long deleted=0;
333
 
  int error= false;
 
853
  int error= 0;
334
854
  char  path[FN_REFLEN+16];
335
855
  MY_DIR *dirp;
336
 
  uint32_t length;
337
 
  TableList *dropped_tables= NULL;
 
856
  uint length;
 
857
  TABLE_LIST* dropped_tables= 0;
 
858
  DBUG_ENTER("mysql_rm_db");
338
859
 
339
 
  if (database_name.to_string().compare(INFORMATION_SCHEMA_NAME) == 0)
 
860
  if (db && (strcmp(db, "information_schema") == 0))
340
861
  {
341
 
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.c_str());
342
 
    return true;
 
862
    my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), "", "", INFORMATION_SCHEMA_NAME.str);
 
863
    DBUG_RETURN(TRUE);
343
864
  }
344
865
 
345
866
  /*
346
867
    Do not drop database if another thread is holding read lock.
347
 
    Wait for global read lock before acquiring LOCK_create_db.
 
868
    Wait for global read lock before acquiring LOCK_mysql_create_db.
348
869
    After wait_if_global_read_lock() we have protection against another
349
 
    global read lock. If we would acquire LOCK_create_db first,
 
870
    global read lock. If we would acquire LOCK_mysql_create_db first,
350
871
    another thread could step in and get the global read lock before we
351
872
    reach wait_if_global_read_lock(). If this thread tries the same as we
352
 
    (admin a db), it would then go and wait on LOCK_create_db...
 
873
    (admin a db), it would then go and wait on LOCK_mysql_create_db...
353
874
    Furthermore wait_if_global_read_lock() checks if the current thread
354
875
    has the global read lock and refuses the operation with
355
876
    ER_CANT_UPDATE_WITH_READLOCK if applicable.
356
877
  */
357
 
  if (wait_if_global_read_lock(session, 0, 1))
 
878
  if (wait_if_global_read_lock(thd, 0, 1))
358
879
  {
359
880
    error= -1;
360
881
    goto exit2;
361
882
  }
362
883
 
363
 
  pthread_mutex_lock(&LOCK_create_db);
364
 
 
365
 
  length= build_table_filename(path, sizeof(path),
366
 
                               database_name.to_string().c_str(), "", false);
367
 
  strcpy(path+length, MY_DB_OPT_FILE);         // Append db option file name
368
 
  unlink(path);
 
884
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
 
885
 
 
886
  /*
 
887
    This statement will be replicated as a statement, even when using
 
888
    row-based replication. The flag will be reset at the end of the
 
889
    statement.
 
890
  */
 
891
  thd->clear_current_stmt_binlog_row_based();
 
892
 
 
893
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
 
894
  strmov(path+length, MY_DB_OPT_FILE);          // Append db option file name
 
895
  del_dbopt(path);                              // Remove dboption hash entry
369
896
  path[length]= '\0';                           // Remove file name
370
897
 
371
898
  /* See if the directory exists */
374
901
    if (!if_exists)
375
902
    {
376
903
      error= -1;
377
 
      my_error(ER_DB_DROP_EXISTS, MYF(0), database_name.to_string().c_str());
 
904
      my_error(ER_DB_DROP_EXISTS, MYF(0), db);
378
905
      goto exit;
379
906
    }
380
907
    else
381
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
382
 
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS),
383
 
                          database_name.to_string().c_str());
 
908
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 
909
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
384
910
  }
385
911
  else
386
912
  {
387
 
    pthread_mutex_lock(&LOCK_open); /* After deleting database, remove all cache entries related to schema */
388
 
    remove_db_from_cache(database_name.to_string().c_str());
 
913
    pthread_mutex_lock(&LOCK_open);
 
914
    remove_db_from_cache(db);
389
915
    pthread_mutex_unlock(&LOCK_open);
390
916
 
391
 
 
 
917
    
392
918
    error= -1;
393
 
    if ((deleted= mysql_rm_known_files(session, dirp, database_name.to_string().c_str(), path, &dropped_tables)) >= 0)
 
919
    if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
 
920
                                       &dropped_tables)) >= 0)
394
921
    {
395
 
      plugin::StorageEngine::dropDatabase(path);
 
922
      ha_drop_database(path);
396
923
      error = 0;
397
924
    }
398
925
  }
399
 
  if (deleted >= 0)
 
926
  if (!silent && deleted>=0)
400
927
  {
401
928
    const char *query;
402
 
    uint32_t query_length;
403
 
 
404
 
    assert(session->query);
405
 
 
406
 
    query= session->query;
407
 
    query_length= session->query_length;
408
 
 
409
 
    ReplicationServices &replication_services= ReplicationServices::singleton();
410
 
    replication_services.rawStatement(session, session->getQueryString(), session->getQueryLength());
411
 
    session->clear_error();
412
 
    session->server_status|= SERVER_STATUS_DB_DROPPED;
413
 
    session->my_ok((uint32_t) deleted);
414
 
    session->server_status&= ~SERVER_STATUS_DB_DROPPED;
 
929
    ulong query_length;
 
930
    if (!thd->query)
 
931
    {
 
932
      /* The client used the old obsolete mysql_drop_db() call */
 
933
      query= path;
 
934
      query_length= (uint) (strxmov(path, "drop database `", db, "`",
 
935
                                     NullS) - path);
 
936
    }
 
937
    else
 
938
    {
 
939
      query =thd->query;
 
940
      query_length= thd->query_length;
 
941
    }
 
942
    if (mysql_bin_log.is_open())
 
943
    {
 
944
      Query_log_event qinfo(thd, query, query_length, 0, 
 
945
                            /* suppress_use */ TRUE);
 
946
      /*
 
947
        Write should use the database being created as the "current
 
948
        database" and not the threads current database, which is the
 
949
        default.
 
950
      */
 
951
      qinfo.db     = db;
 
952
      qinfo.db_len = strlen(db);
 
953
 
 
954
      thd->clear_error();
 
955
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
 
956
      mysql_bin_log.write(&qinfo);
 
957
    }
 
958
    thd->clear_error();
 
959
    thd->server_status|= SERVER_STATUS_DB_DROPPED;
 
960
    my_ok(thd, (ulong) deleted);
 
961
    thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
415
962
  }
416
 
  else
 
963
  else if (mysql_bin_log.is_open())
417
964
  {
418
965
    char *query, *query_pos, *query_end, *query_data_start;
419
 
    TableList *tbl;
420
 
    uint32_t db_len;
 
966
    TABLE_LIST *tbl;
 
967
    uint db_len;
421
968
 
422
 
    if (!(query= (char*) session->alloc(MAX_DROP_TABLE_Q_LEN)))
 
969
    if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
423
970
      goto exit; /* not much else we can do */
424
 
    query_pos= query_data_start= strcpy(query,"drop table ")+11;
 
971
    query_pos= query_data_start= strmov(query,"drop table ");
425
972
    query_end= query + MAX_DROP_TABLE_Q_LEN;
426
 
    db_len= database_name.to_string().length();
 
973
    db_len= strlen(db);
427
974
 
428
 
    ReplicationServices &replication_services= ReplicationServices::singleton();
429
975
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
430
976
    {
431
 
      uint32_t tbl_name_len;
 
977
      uint tbl_name_len;
432
978
 
433
979
      /* 3 for the quotes and the comma*/
434
980
      tbl_name_len= strlen(tbl->table_name) + 3;
435
981
      if (query_pos + tbl_name_len + 1 >= query_end)
436
982
      {
437
 
        /* These DDL methods and logging protected with LOCK_create_db */
438
 
        replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
 
983
        /* These DDL methods and logging protected with LOCK_mysql_create_db */
 
984
        write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
439
985
        query_pos= query_data_start;
440
986
      }
441
987
 
442
988
      *query_pos++ = '`';
443
 
      query_pos= strcpy(query_pos,tbl->table_name) + (tbl_name_len-3);
 
989
      query_pos= strmov(query_pos,tbl->table_name);
444
990
      *query_pos++ = '`';
445
991
      *query_pos++ = ',';
446
992
    }
447
993
 
448
994
    if (query_pos != query_data_start)
449
995
    {
450
 
      /* These DDL methods and logging protected with LOCK_create_db */
451
 
      replication_services.rawStatement(session, query, (size_t) (query_pos -1 - query));
 
996
      /* These DDL methods and logging protected with LOCK_mysql_create_db */
 
997
      write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
452
998
    }
453
999
  }
454
1000
 
456
1002
  /*
457
1003
    If this database was the client's selected database, we silently
458
1004
    change the client's selected database to nothing (to have an empty
459
 
    SELECT DATABASE() in the future). For this we free() session->db and set
 
1005
    SELECT DATABASE() in the future). For this we free() thd->db and set
460
1006
    it to 0.
461
1007
  */
462
 
  if (! session->db.empty() && session->db.compare(database_name.to_string()) == 0)
463
 
    session->clear_db();
464
 
  pthread_mutex_unlock(&LOCK_create_db);
465
 
  start_waiting_global_read_lock(session);
 
1008
  if (thd->db && !strcmp(thd->db, db))
 
1009
    mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
 
1010
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
 
1011
  start_waiting_global_read_lock(thd);
466
1012
exit2:
467
 
  return(error);
468
 
}
469
 
 
470
 
 
471
 
static int rm_table_part2(Session *session, TableList *tables)
472
 
{
473
 
  TableList *table;
474
 
  String wrong_tables;
475
 
  int error= 0;
476
 
  bool foreign_key_error= false;
477
 
 
478
 
  pthread_mutex_lock(&LOCK_open); /* Part 2 of rm a table */
479
 
 
480
 
  /*
481
 
    If we have the table in the definition cache, we don't have to check the
482
 
    .frm cursor to find if the table is a normal table (not view) and what
483
 
    engine to use.
484
 
  */
485
 
 
486
 
  for (table= tables; table; table= table->next_local)
487
 
  {
488
 
    TableShare *share;
489
 
    table->db_type= NULL;
490
 
    if ((share= TableShare::getShare(table->db, table->table_name)))
491
 
      table->db_type= share->db_type();
492
 
  }
493
 
 
494
 
  if (lock_table_names_exclusively(session, tables))
495
 
  {
496
 
    pthread_mutex_unlock(&LOCK_open);
497
 
    return 1;
498
 
  }
499
 
 
500
 
  /* Don't give warnings for not found errors, as we already generate notes */
501
 
  session->no_warnings_for_error= 1;
502
 
 
503
 
  for (table= tables; table; table= table->next_local)
504
 
  {
505
 
    char *db=table->db;
506
 
    plugin::StorageEngine *table_type;
507
 
 
508
 
    error= session->drop_temporary_table(table);
509
 
 
510
 
    switch (error) {
511
 
    case  0:
512
 
      // removed temporary table
513
 
      continue;
514
 
    case -1:
515
 
      error= 1;
516
 
      goto err_with_placeholders;
517
 
    default:
518
 
      // temporary table not found
519
 
      error= 0;
520
 
    }
521
 
 
522
 
    table_type= table->db_type;
523
 
 
524
 
    {
525
 
      Table *locked_table;
526
 
      abort_locked_tables(session, db, table->table_name);
527
 
      remove_table_from_cache(session, db, table->table_name,
528
 
                              RTFC_WAIT_OTHER_THREAD_FLAG |
529
 
                              RTFC_CHECK_KILLED_FLAG);
530
 
      /*
531
 
        If the table was used in lock tables, remember it so that
532
 
        unlock_table_names can free it
533
 
      */
534
 
      if ((locked_table= drop_locked_tables(session, db, table->table_name)))
535
 
        table->table= locked_table;
536
 
 
537
 
      if (session->killed)
538
 
      {
539
 
        error= -1;
540
 
        goto err_with_placeholders;
541
 
      }
542
 
    }
543
 
 
544
 
    TableIdentifier identifier(db, table->table_name, table->internal_tmp_table ? INTERNAL_TMP_TABLE : NO_TMP_TABLE);
545
 
 
546
 
    if ((table_type == NULL
547
 
          && (plugin::StorageEngine::getTableDefinition(*session,
548
 
                                                        identifier) != EEXIST)))
549
 
    {
550
 
      // Table was not found on disk and table can't be created from engine
551
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
552
 
                          ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
553
 
                          table->table_name);
554
 
    }
555
 
    else
556
 
    {
557
 
      error= plugin::StorageEngine::dropTable(*session,
558
 
                                              identifier,
559
 
                                              false);
560
 
 
561
 
      if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE))
562
 
      {
563
 
        error= 0;
564
 
        session->clear_error();
565
 
      }
566
 
 
567
 
      if (error == HA_ERR_ROW_IS_REFERENCED)
568
 
      {
569
 
        /* the table is referenced by a foreign key constraint */
570
 
        foreign_key_error= true;
571
 
      }
572
 
    }
573
 
 
574
 
    if (error == 0 || (foreign_key_error == false))
575
 
        write_bin_log_drop_table(session, true, db, table->table_name);
576
 
 
577
 
    if (error)
578
 
    {
579
 
      if (wrong_tables.length())
580
 
        wrong_tables.append(',');
581
 
      wrong_tables.append(String(table->table_name,system_charset_info));
582
 
    }
583
 
  }
584
 
  /*
585
 
    It's safe to unlock LOCK_open: we have an exclusive lock
586
 
    on the table name.
587
 
  */
588
 
  pthread_mutex_unlock(&LOCK_open);
589
 
  error= 0;
590
 
  if (wrong_tables.length())
591
 
  {
592
 
    if (!foreign_key_error)
593
 
      my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
594
 
                      wrong_tables.c_ptr());
595
 
    else
596
 
    {
597
 
      my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
598
 
    }
599
 
    error= 1;
600
 
  }
601
 
 
602
 
  pthread_mutex_lock(&LOCK_open); /* final bit in rm table lock */
603
 
err_with_placeholders:
604
 
  unlock_table_names(tables, NULL);
605
 
  pthread_mutex_unlock(&LOCK_open);
606
 
  session->no_warnings_for_error= 0;
607
 
 
608
 
  return(error);
 
1013
  DBUG_RETURN(error);
609
1014
}
610
1015
 
611
1016
/*
612
 
  Removes files with known extensions plus.
613
 
  session MUST be set when calling this function!
 
1017
  Removes files with known extensions plus all found subdirectories that
 
1018
  are 2 hex digits (raid directories).
 
1019
  thd MUST be set when calling this function!
614
1020
*/
615
1021
 
616
 
static long mysql_rm_known_files(Session *session, MY_DIR *dirp, const char *db,
617
 
                                 const char *org_path,
618
 
                                 TableList **dropped_tables)
 
1022
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
 
1023
                                 const char *org_path, uint level,
 
1024
                                 TABLE_LIST **dropped_tables)
619
1025
{
620
 
  long deleted= 0;
 
1026
  long deleted=0;
 
1027
  ulong found_other_files=0;
621
1028
  char filePath[FN_REFLEN];
622
 
  TableList *tot_list= NULL, **tot_list_next;
 
1029
  TABLE_LIST *tot_list=0, **tot_list_next;
 
1030
  List<String> raid_dirs;
 
1031
  DBUG_ENTER("mysql_rm_known_files");
 
1032
  DBUG_PRINT("enter",("path: %s", org_path));
623
1033
 
624
1034
  tot_list_next= &tot_list;
625
1035
 
626
 
  for (uint32_t idx= 0;
627
 
       idx < (uint32_t) dirp->number_off_files && !session->killed ;
 
1036
  for (uint idx=0 ;
 
1037
       idx < (uint) dirp->number_off_files && !thd->killed ;
628
1038
       idx++)
629
1039
  {
630
1040
    FILEINFO *file=dirp->dir_entry+idx;
631
1041
    char *extension;
 
1042
    DBUG_PRINT("info",("Examining: %s", file->name));
632
1043
 
633
1044
    /* skiping . and .. */
634
1045
    if (file->name[0] == '.' && (!file->name[1] ||
635
1046
       (file->name[1] == '.' &&  !file->name[2])))
636
1047
      continue;
637
1048
 
 
1049
    /* Check if file is a raid directory */
 
1050
    if ((my_isdigit(system_charset_info, file->name[0]) ||
 
1051
         (file->name[0] >= 'a' && file->name[0] <= 'f')) &&
 
1052
        (my_isdigit(system_charset_info, file->name[1]) ||
 
1053
         (file->name[1] >= 'a' && file->name[1] <= 'f')) &&
 
1054
        !file->name[2] && !level)
 
1055
    {
 
1056
      char newpath[FN_REFLEN], *copy_of_path;
 
1057
      MY_DIR *new_dirp;
 
1058
      String *dir;
 
1059
      uint length;
 
1060
 
 
1061
      strxmov(newpath,org_path,"/",file->name,NullS);
 
1062
      length= unpack_filename(newpath,newpath);
 
1063
      if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
 
1064
      {
 
1065
        DBUG_PRINT("my",("New subdir found: %s", newpath));
 
1066
        if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0)
 
1067
          goto err;
 
1068
        if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) ||
 
1069
            !(dir= new (thd->mem_root) String(copy_of_path, length,
 
1070
                                               &my_charset_bin)) ||
 
1071
            raid_dirs.push_back(dir))
 
1072
          goto err;
 
1073
        continue;
 
1074
      }
 
1075
      found_other_files++;
 
1076
      continue;
 
1077
    }
 
1078
    else if (file->name[0] == 'a' && file->name[1] == 'r' &&
 
1079
             file->name[2] == 'c' && file->name[3] == '\0')
 
1080
    {
 
1081
      /* .frm archive */
 
1082
      char newpath[FN_REFLEN];
 
1083
      MY_DIR *new_dirp;
 
1084
      strxmov(newpath, org_path, "/", "arc", NullS);
 
1085
      (void) unpack_filename(newpath, newpath);
 
1086
      if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
 
1087
      {
 
1088
        DBUG_PRINT("my",("Archive subdir found: %s", newpath));
 
1089
        if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
 
1090
          goto err;
 
1091
        continue;
 
1092
      }
 
1093
      found_other_files++;
 
1094
      continue;
 
1095
    }
638
1096
    if (!(extension= strrchr(file->name, '.')))
639
 
      extension= strchr(file->name, '\0');
 
1097
      extension= strend(file->name);
640
1098
    if (find_type(extension, &deletable_extentions,1+2) <= 0)
641
1099
    {
642
 
      /*
643
 
        ass ass ass.
644
 
 
645
 
        strange checking for magic extensions that are then deleted if
646
 
        not reg_ext (i.e. .frm).
647
 
 
648
 
        and (previously) we'd err out on drop database if files not matching
649
 
        engine ha_known_exts() or deletable_extensions were present.
650
 
 
651
 
        presumably this was to avoid deleting other user data... except if that
652
 
        data happened to be in files ending in .BAK, .opt or .TMD. *fun*
653
 
       */
 
1100
      if (find_type(extension, ha_known_exts(),1+2) <= 0)
 
1101
        found_other_files++;
654
1102
      continue;
655
1103
    }
656
1104
    /* just for safety we use files_charset_info */
657
1105
    if (db && !my_strcasecmp(files_charset_info,
658
 
                             extension, ".dfe"))
 
1106
                             extension, reg_ext))
659
1107
    {
660
 
      uint32_t db_len= strlen(db);
661
 
 
662
1108
      /* Drop the table nicely */
663
1109
      *extension= 0;                    // Remove extension
664
 
      TableList *table_list=(TableList*)
665
 
                              session->calloc(sizeof(*table_list) +
666
 
                                          db_len + 1 +
 
1110
      TABLE_LIST *table_list=(TABLE_LIST*)
 
1111
                              thd->calloc(sizeof(*table_list) + 
 
1112
                                          strlen(db) + 1 +
 
1113
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH + 
667
1114
                                          strlen(file->name) + 1);
668
1115
 
669
1116
      if (!table_list)
670
1117
        goto err;
671
1118
      table_list->db= (char*) (table_list+1);
672
 
      table_list->table_name= strcpy(table_list->db, db) + db_len + 1;
673
 
      filename_to_tablename(file->name, table_list->table_name,
674
 
                            strlen(file->name) + 1);
675
 
      table_list->alias= table_list->table_name;  // If lower_case_table_names=2
676
 
      table_list->internal_tmp_table= (strncmp(file->name,
677
 
                                               TMP_FILE_PREFIX,
678
 
                                               strlen(TMP_FILE_PREFIX)) == 0);
 
1119
      table_list->table_name= strmov(table_list->db, db) + 1;
 
1120
      VOID(filename_to_tablename(file->name, table_list->table_name,
 
1121
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH +
 
1122
                                 strlen(file->name) + 1));
 
1123
      table_list->alias= table_list->table_name;        // If lower_case_table_names=2
 
1124
      table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
679
1125
      /* Link into list */
680
1126
      (*tot_list_next)= table_list;
681
1127
      tot_list_next= &table_list->next_local;
683
1129
    }
684
1130
    else
685
1131
    {
686
 
      sprintf(filePath, "%s/%s", org_path, file->name);
 
1132
      strxmov(filePath, org_path, "/", file->name, NullS);
687
1133
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
688
1134
      {
689
1135
        goto err;
690
1136
      }
691
1137
    }
692
1138
  }
693
 
  if (session->killed)
 
1139
  if (thd->killed ||
 
1140
      (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
694
1141
    goto err;
695
1142
 
696
 
  if (tot_list)
 
1143
  /* Remove RAID directories */
697
1144
  {
698
 
    if (rm_table_part2(session, tot_list))
699
 
      goto err;
 
1145
    List_iterator<String> it(raid_dirs);
 
1146
    String *dir;
 
1147
    while ((dir= it++))
 
1148
      if (rmdir(dir->c_ptr()) < 0)
 
1149
        found_other_files++;
700
1150
  }
701
 
 
702
 
  my_dirend(dirp);
703
 
 
 
1151
  my_dirend(dirp);  
 
1152
  
704
1153
  if (dropped_tables)
705
1154
    *dropped_tables= tot_list;
706
 
 
707
 
  if (rmdir(org_path))
708
 
  {
709
 
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, errno);
710
 
    return -1;
711
 
  }
712
 
 
713
 
  return deleted;
714
 
 
715
 
err:
716
 
  my_dirend(dirp);
717
 
  return -1;
718
 
}
 
1155
  
 
1156
  /*
 
1157
    If the directory is a symbolic link, remove the link first, then
 
1158
    remove the directory the symbolic link pointed at
 
1159
  */
 
1160
  if (found_other_files)
 
1161
  {
 
1162
    my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
 
1163
    DBUG_RETURN(-1);
 
1164
  }
 
1165
  else
 
1166
  {
 
1167
    /* Don't give errors if we can't delete 'RAID' directory */
 
1168
    if (rm_dir_w_symlink(org_path, level == 0))
 
1169
      DBUG_RETURN(-1);
 
1170
  }
 
1171
 
 
1172
  DBUG_RETURN(deleted);
 
1173
 
 
1174
err:
 
1175
  my_dirend(dirp);
 
1176
  DBUG_RETURN(-1);
 
1177
}
 
1178
 
 
1179
 
 
1180
/*
 
1181
  Remove directory with symlink
 
1182
 
 
1183
  SYNOPSIS
 
1184
    rm_dir_w_symlink()
 
1185
    org_path    path of derictory
 
1186
    send_error  send errors
 
1187
  RETURN
 
1188
    0 OK
 
1189
    1 ERROR
 
1190
*/
 
1191
 
 
1192
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
 
1193
{
 
1194
  char tmp_path[FN_REFLEN], *pos;
 
1195
  char *path= tmp_path;
 
1196
  DBUG_ENTER("rm_dir_w_symlink");
 
1197
  unpack_filename(tmp_path, org_path);
 
1198
#ifdef HAVE_READLINK
 
1199
  int error;
 
1200
  char tmp2_path[FN_REFLEN];
 
1201
 
 
1202
  /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
 
1203
  pos= strend(path);
 
1204
  if (pos > path && pos[-1] == FN_LIBCHAR)
 
1205
    *--pos=0;
 
1206
 
 
1207
  if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
 
1208
    DBUG_RETURN(1);
 
1209
  if (!error)
 
1210
  {
 
1211
    if (my_delete(path, MYF(send_error ? MY_WME : 0)))
 
1212
    {
 
1213
      DBUG_RETURN(send_error);
 
1214
    }
 
1215
    /* Delete directory symbolic link pointed at */
 
1216
    path= tmp2_path;
 
1217
  }
 
1218
#endif
 
1219
  /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
 
1220
  pos= strend(path);
 
1221
 
 
1222
  if (pos > path && pos[-1] == FN_LIBCHAR)
 
1223
    *--pos=0;
 
1224
  if (rmdir(path) < 0 && send_error)
 
1225
  {
 
1226
    my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
 
1227
    DBUG_RETURN(1);
 
1228
  }
 
1229
  DBUG_RETURN(0);
 
1230
}
 
1231
 
 
1232
 
 
1233
/*
 
1234
  Remove .frm archives from directory
 
1235
 
 
1236
  SYNOPSIS
 
1237
    thd       thread handler
 
1238
    dirp      list of files in archive directory
 
1239
    db        data base name
 
1240
    org_path  path of archive directory
 
1241
 
 
1242
  RETURN
 
1243
    > 0 number of removed files
 
1244
    -1  error
 
1245
*/
 
1246
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp,
 
1247
                                 const char *org_path)
 
1248
{
 
1249
  long deleted= 0;
 
1250
  ulong found_other_files= 0;
 
1251
  char filePath[FN_REFLEN];
 
1252
  DBUG_ENTER("mysql_rm_arc_files");
 
1253
  DBUG_PRINT("enter", ("path: %s", org_path));
 
1254
 
 
1255
  for (uint idx=0 ;
 
1256
       idx < (uint) dirp->number_off_files && !thd->killed ;
 
1257
       idx++)
 
1258
  {
 
1259
    FILEINFO *file=dirp->dir_entry+idx;
 
1260
    char *extension, *revision;
 
1261
    DBUG_PRINT("info",("Examining: %s", file->name));
 
1262
 
 
1263
    /* skiping . and .. */
 
1264
    if (file->name[0] == '.' && (!file->name[1] ||
 
1265
       (file->name[1] == '.' &&  !file->name[2])))
 
1266
      continue;
 
1267
 
 
1268
    extension= fn_ext(file->name);
 
1269
    if (extension[0] != '.' ||
 
1270
        extension[1] != 'f' || extension[2] != 'r' ||
 
1271
        extension[3] != 'm' || extension[4] != '-')
 
1272
    {
 
1273
      found_other_files++;
 
1274
      continue;
 
1275
    }
 
1276
    revision= extension+5;
 
1277
    while (*revision && my_isdigit(system_charset_info, *revision))
 
1278
      revision++;
 
1279
    if (*revision)
 
1280
    {
 
1281
      found_other_files++;
 
1282
      continue;
 
1283
    }
 
1284
    strxmov(filePath, org_path, "/", file->name, NullS);
 
1285
    if (my_delete_with_symlink(filePath,MYF(MY_WME)))
 
1286
    {
 
1287
      goto err;
 
1288
    }
 
1289
  }
 
1290
  if (thd->killed)
 
1291
    goto err;
 
1292
 
 
1293
  my_dirend(dirp);
 
1294
 
 
1295
  /*
 
1296
    If the directory is a symbolic link, remove the link first, then
 
1297
    remove the directory the symbolic link pointed at
 
1298
  */
 
1299
  if (!found_other_files &&
 
1300
      rm_dir_w_symlink(org_path, 0))
 
1301
    DBUG_RETURN(-1);
 
1302
  DBUG_RETURN(deleted);
 
1303
 
 
1304
err:
 
1305
  my_dirend(dirp);
 
1306
  DBUG_RETURN(-1);
 
1307
}
 
1308
 
 
1309
 
 
1310
/**
 
1311
  @brief Internal implementation: switch current database to a valid one.
 
1312
 
 
1313
  @param thd            Thread context.
 
1314
  @param new_db_name    Name of the database to switch to. The function will
 
1315
                        take ownership of the name (the caller must not free
 
1316
                        the allocated memory). If the name is NULL, we're
 
1317
                        going to switch to NULL db.
 
1318
  @param new_db_charset Character set of the new database.
 
1319
*/
 
1320
 
 
1321
static void mysql_change_db_impl(THD *thd,
 
1322
                                 LEX_STRING *new_db_name,
 
1323
                                 CHARSET_INFO *new_db_charset)
 
1324
{
 
1325
  /* 1. Change current database in THD. */
 
1326
 
 
1327
  if (new_db_name == NULL)
 
1328
  {
 
1329
    /*
 
1330
      THD::set_db() does all the job -- it frees previous database name and
 
1331
      sets the new one.
 
1332
    */
 
1333
 
 
1334
    thd->set_db(NULL, 0);
 
1335
  }
 
1336
  else if (new_db_name == &INFORMATION_SCHEMA_NAME)
 
1337
  {
 
1338
    /*
 
1339
      Here we must use THD::set_db(), because we want to copy
 
1340
      INFORMATION_SCHEMA_NAME constant.
 
1341
    */
 
1342
 
 
1343
    thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
 
1344
  }
 
1345
  else
 
1346
  {
 
1347
    /*
 
1348
      Here we already have a copy of database name to be used in THD. So,
 
1349
      we just call THD::reset_db(). Since THD::reset_db() does not releases
 
1350
      the previous database name, we should do it explicitly.
 
1351
    */
 
1352
 
 
1353
    x_free(thd->db);
 
1354
 
 
1355
    thd->reset_db(new_db_name->str, new_db_name->length);
 
1356
  }
 
1357
 
 
1358
  /* 3. Update db-charset environment variables. */
 
1359
 
 
1360
  thd->db_charset= new_db_charset;
 
1361
  thd->variables.collation_database= new_db_charset;
 
1362
}
 
1363
 
 
1364
 
 
1365
 
 
1366
/**
 
1367
  Backup the current database name before switch.
 
1368
 
 
1369
  @param[in]      thd             thread handle
 
1370
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
 
1371
                                  the old database name, "length" contains the
 
1372
                                  buffer size
 
1373
                                  OUT: if the current (default) database is
 
1374
                                  not NULL, its name is copied to the
 
1375
                                  buffer pointed at by "str"
 
1376
                                  and "length" is updated accordingly.
 
1377
                                  Otherwise "str" is set to NULL and
 
1378
                                  "length" is set to 0.
 
1379
*/
 
1380
 
 
1381
static void backup_current_db_name(THD *thd,
 
1382
                                   LEX_STRING *saved_db_name)
 
1383
{
 
1384
  if (!thd->db)
 
1385
  {
 
1386
    /* No current (default) database selected. */
 
1387
 
 
1388
    saved_db_name->str= NULL;
 
1389
    saved_db_name->length= 0;
 
1390
  }
 
1391
  else
 
1392
  {
 
1393
    strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
 
1394
    saved_db_name->length= thd->db_length;
 
1395
  }
 
1396
}
 
1397
 
 
1398
 
 
1399
/**
 
1400
  Return TRUE if db1_name is equal to db2_name, FALSE otherwise.
 
1401
 
 
1402
  The function allows to compare database names according to the MySQL
 
1403
  rules. The database names db1 and db2 are equal if:
 
1404
     - db1 is NULL and db2 is NULL;
 
1405
     or
 
1406
     - db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
 
1407
       db2 in system character set (UTF8).
 
1408
*/
 
1409
 
 
1410
static inline bool
 
1411
cmp_db_names(const char *db1_name,
 
1412
             const char *db2_name)
 
1413
{
 
1414
  return
 
1415
         /* db1 is NULL and db2 is NULL */
 
1416
         (!db1_name && !db2_name) ||
 
1417
 
 
1418
         /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
 
1419
         (db1_name && db2_name && my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
 
1420
}
 
1421
 
719
1422
 
720
1423
/**
721
1424
  @brief Change the current database and its attributes unconditionally.
722
1425
 
723
 
  @param session          thread handle
 
1426
  @param thd          thread handle
724
1427
  @param new_db_name  database name
725
 
  @param force_switch if force_switch is false, then the operation will fail if
 
1428
  @param force_switch if force_switch is FALSE, then the operation will fail if
726
1429
 
727
1430
                        - new_db_name is NULL or empty;
728
1431
 
733
1436
 
734
1437
                        - OR new database does not exist;
735
1438
 
736
 
                      if force_switch is true, then
 
1439
                      if force_switch is TRUE, then
737
1440
 
738
1441
                        - if new_db_name is NULL or empty, the current
739
1442
                          database will be NULL, @@collation_database will
746
1449
                          @@collation_server, but the operation will fail;
747
1450
 
748
1451
                        - user privileges will not be checked
749
 
                          (Session::db_access however is updated);
 
1452
                          (THD::db_access however is updated);
750
1453
 
751
1454
                          TODO: is this really the intention?
752
1455
                                (see sp-security.test).
759
1462
  @details The function checks that the database name corresponds to a
760
1463
  valid and existent database, checks access rights and changes the current
761
1464
  database with database attributes (@@collation_database session variable,
762
 
  Session::db_access).
 
1465
  THD::db_access).
763
1466
 
764
1467
  This function is not the only way to switch the database that is
765
1468
  currently employed. When the replication slave thread switches the
766
 
  database before executing a query, it calls session->set_db directly.
 
1469
  database before executing a query, it calls thd->set_db directly.
767
1470
  However, if the query, in turn, uses a stored routine, the stored routine
768
1471
  will use this function, even if it's run on the slave.
769
1472
 
775
1478
  the stack address was long gone.
776
1479
 
777
1480
  @return Operation status
778
 
    @retval false Success
779
 
    @retval true  Error
 
1481
    @retval FALSE Success
 
1482
    @retval TRUE  Error
780
1483
*/
781
1484
 
782
 
bool mysql_change_db(Session *session, const NormalisedDatabaseName &normalised_database_name, bool force_switch)
 
1485
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
783
1486
{
784
 
  const CHARSET_INFO *db_default_cl;
785
 
 
786
 
  if (my_strcasecmp(system_charset_info, normalised_database_name.to_string().c_str(),
787
 
                    INFORMATION_SCHEMA_NAME.c_str()) == 0)
788
 
  {
789
 
    NonNormalisedDatabaseName non_normalised_i_s(INFORMATION_SCHEMA_NAME);
790
 
    NormalisedDatabaseName is_name(non_normalised_i_s);
791
 
 
792
 
    session->set_db(is_name);
793
 
    return false;
794
 
  }
 
1487
  LEX_STRING new_db_file_name;
 
1488
  CHARSET_INFO *db_default_cl;
 
1489
 
 
1490
  DBUG_ENTER("mysql_change_db");
 
1491
  DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
 
1492
 
 
1493
  if (new_db_name == NULL ||
 
1494
      new_db_name->length == 0)
 
1495
  {
 
1496
    if (force_switch)
 
1497
    {
 
1498
      /*
 
1499
        This can happen only if we're switching the current database back
 
1500
        after loading stored program. The thing is that loading of stored
 
1501
        program can happen when there is no current database.
 
1502
 
 
1503
        TODO: actually, new_db_name and new_db_name->str seem to be always
 
1504
        non-NULL. In case of stored program, new_db_name->str == "" and
 
1505
        new_db_name->length == 0.
 
1506
      */
 
1507
 
 
1508
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
 
1509
 
 
1510
      DBUG_RETURN(FALSE);
 
1511
    }
 
1512
    else
 
1513
    {
 
1514
      my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
 
1515
 
 
1516
      DBUG_RETURN(TRUE);
 
1517
    }
 
1518
  }
 
1519
 
 
1520
  if (my_strcasecmp(system_charset_info, new_db_name->str,
 
1521
                    INFORMATION_SCHEMA_NAME.str) == 0)
 
1522
  {
 
1523
    /* Switch the current database to INFORMATION_SCHEMA. */
 
1524
 
 
1525
    mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, system_charset_info);
 
1526
 
 
1527
    DBUG_RETURN(FALSE);
 
1528
  }
 
1529
 
 
1530
  /*
 
1531
    Now we need to make a copy because check_db_name requires a
 
1532
    non-constant argument. Actually, it takes database file name.
 
1533
 
 
1534
    TODO: fix check_db_name().
 
1535
  */
 
1536
 
 
1537
  new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
 
1538
                                   MYF(MY_WME));
 
1539
  new_db_file_name.length= new_db_name->length;
 
1540
 
 
1541
  if (new_db_file_name.str == NULL)
 
1542
    DBUG_RETURN(TRUE);                             /* the error is set */
795
1543
 
796
1544
  /*
797
1545
    NOTE: if check_db_name() fails, we should throw an error in any case,
801
1549
    from sp_head::execute(). But let's switch the current database to NULL
802
1550
    in this case to be sure.
803
1551
  */
804
 
  if (! normalised_database_name.isValid())
 
1552
 
 
1553
  if (check_db_name(&new_db_file_name))
805
1554
  {
806
 
    my_error(ER_WRONG_DB_NAME, MYF(0),
807
 
             normalised_database_name.to_string().c_str());
 
1555
    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
 
1556
    my_free(new_db_file_name.str, MYF(0));
808
1557
 
809
1558
    if (force_switch)
810
 
      session->clear_db();
 
1559
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
811
1560
 
812
 
    return true;
 
1561
    DBUG_RETURN(TRUE);
813
1562
  }
814
1563
 
815
 
  DatabasePathName database_path(normalised_database_name);
816
 
 
817
 
  if (! database_path.exists())
 
1564
  DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
 
1565
 
 
1566
 
 
1567
  if (check_db_dir_existence(new_db_file_name.str))
818
1568
  {
819
1569
    if (force_switch)
820
1570
    {
821
1571
      /* Throw a warning and free new_db_file_name. */
822
1572
 
823
 
      push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1573
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
824
1574
                          ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
825
 
                          normalised_database_name.to_string().c_str());
 
1575
                          new_db_file_name.str);
 
1576
 
 
1577
      my_free(new_db_file_name.str, MYF(0));
826
1578
 
827
1579
      /* Change db to NULL. */
828
1580
 
829
 
      session->clear_db();
 
1581
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
830
1582
 
831
1583
      /* The operation succeed. */
832
1584
 
833
 
      return false;
 
1585
      DBUG_RETURN(FALSE);
834
1586
    }
835
1587
    else
836
1588
    {
837
1589
      /* Report an error and free new_db_file_name. */
838
1590
 
839
 
      my_error(ER_BAD_DB_ERROR, MYF(0),
840
 
               normalised_database_name.to_string().c_str());
 
1591
      my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
 
1592
      my_free(new_db_file_name.str, MYF(0));
841
1593
 
842
1594
      /* The operation failed. */
843
1595
 
844
 
      return true;
845
 
    }
846
 
  }
847
 
 
848
 
  db_default_cl= get_default_db_collation(normalised_database_name.to_string().c_str());
849
 
 
850
 
  session->set_db(normalised_database_name);
851
 
 
852
 
  return false;
853
 
}
854
 
 
855
 
NormalisedDatabaseName::NormalisedDatabaseName(const NonNormalisedDatabaseName &dbname)
856
 
{
857
 
  const std::string &non_norm_string= dbname.to_string();
858
 
  database_name= (char*)malloc(non_norm_string.size()+1);
859
 
 
860
 
  assert(database_name); /* FIXME: should throw exception */
861
 
 
862
 
  strncpy(database_name, non_norm_string.c_str(), non_norm_string.size()+1);
863
 
 
864
 
  my_casedn_str(files_charset_info, database_name);
865
 
}
866
 
 
867
 
NormalisedDatabaseName::~NormalisedDatabaseName()
868
 
{
869
 
  free(database_name);
870
 
}
871
 
 
872
 
bool NormalisedDatabaseName::isValid() const
873
 
{
874
 
  LEX_STRING db_lexstring;
875
 
 
876
 
  db_lexstring.str= database_name;
877
 
  db_lexstring.length= strlen(database_name);
878
 
 
879
 
  if (db_lexstring.length == 0
880
 
      || db_lexstring.length > NAME_LEN
881
 
      || database_name[db_lexstring.length - 1] == ' ')
882
 
    return false;
883
 
 
884
 
  return (! check_identifier_name(&db_lexstring));
885
 
}
886
 
 
887
 
DatabasePathName::DatabasePathName(const NormalisedDatabaseName &database_name)
 
1596
      DBUG_RETURN(TRUE);
 
1597
    }
 
1598
  }
 
1599
 
 
1600
  /*
 
1601
    NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
 
1602
    attributes and will be freed in THD::~THD().
 
1603
  */
 
1604
 
 
1605
  db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
 
1606
 
 
1607
  mysql_change_db_impl(thd, &new_db_file_name, db_default_cl);
 
1608
 
 
1609
  DBUG_RETURN(FALSE);
 
1610
}
 
1611
 
 
1612
 
 
1613
/**
 
1614
  Change the current database and its attributes if needed.
 
1615
 
 
1616
  @param          thd             thread handle
 
1617
  @param          new_db_name     database name
 
1618
  @param[in, out] saved_db_name   IN: "str" points to a buffer where to store
 
1619
                                  the old database name, "length" contains the
 
1620
                                  buffer size
 
1621
                                  OUT: if the current (default) database is
 
1622
                                  not NULL, its name is copied to the
 
1623
                                  buffer pointed at by "str"
 
1624
                                  and "length" is updated accordingly.
 
1625
                                  Otherwise "str" is set to NULL and
 
1626
                                  "length" is set to 0.
 
1627
  @param          force_switch    @see mysql_change_db()
 
1628
  @param[out]     cur_db_changed  out-flag to indicate whether the current
 
1629
                                  database has been changed (valid only if
 
1630
                                  the function suceeded)
 
1631
*/
 
1632
 
 
1633
bool mysql_opt_change_db(THD *thd,
 
1634
                         const LEX_STRING *new_db_name,
 
1635
                         LEX_STRING *saved_db_name,
 
1636
                         bool force_switch,
 
1637
                         bool *cur_db_changed)
 
1638
{
 
1639
  *cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
 
1640
 
 
1641
  if (!*cur_db_changed)
 
1642
    return FALSE;
 
1643
 
 
1644
  backup_current_db_name(thd, saved_db_name);
 
1645
 
 
1646
  return mysql_change_db(thd, new_db_name, force_switch);
 
1647
}
 
1648
 
 
1649
 
 
1650
static int
 
1651
lock_databases(THD *thd, const char *db1, uint length1,
 
1652
                         const char *db2, uint length2)
 
1653
{
 
1654
  pthread_mutex_lock(&LOCK_lock_db);
 
1655
  while (!thd->killed &&
 
1656
         (hash_search(&lock_db_cache,(uchar*) db1, length1) ||
 
1657
          hash_search(&lock_db_cache,(uchar*) db2, length2)))
 
1658
  {
 
1659
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1660
    pthread_mutex_lock(&LOCK_lock_db);
 
1661
  }
 
1662
 
 
1663
  if (thd->killed)
 
1664
  {
 
1665
    pthread_mutex_unlock(&LOCK_lock_db);
 
1666
    return 1;
 
1667
  }
 
1668
 
 
1669
  lock_db_insert(db1, length1);
 
1670
  lock_db_insert(db2, length2);
 
1671
  creating_database++;
 
1672
 
 
1673
  /*
 
1674
    Wait if a concurent thread is creating a table at the same time.
 
1675
    The assumption here is that it will not take too long until
 
1676
    there is a point in time when a table is not created.
 
1677
  */
 
1678
 
 
1679
  while (!thd->killed && creating_table)
 
1680
  {
 
1681
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1682
    pthread_mutex_lock(&LOCK_lock_db);
 
1683
  }
 
1684
 
 
1685
  if (thd->killed)
 
1686
  {
 
1687
    lock_db_delete(db1, length1);
 
1688
    lock_db_delete(db2, length2);
 
1689
    creating_database--;
 
1690
    pthread_mutex_unlock(&LOCK_lock_db);
 
1691
    pthread_cond_signal(&COND_refresh);
 
1692
    return(1);
 
1693
  }
 
1694
 
 
1695
  /*
 
1696
    We can unlock now as the hash will protect against anyone creating a table
 
1697
    in the databases we are using
 
1698
  */
 
1699
  pthread_mutex_unlock(&LOCK_lock_db);
 
1700
  return 0;
 
1701
}
 
1702
 
 
1703
 
 
1704
/**
 
1705
  Upgrade a 5.0 database.
 
1706
  This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
 
1707
    ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
 
1708
 
 
1709
  If we have managed to rename (move) tables to the new database
 
1710
  but something failed on a later step, then we store the
 
1711
  RENAME DATABASE event in the log. mysql_rename_db() is atomic in
 
1712
  the sense that it will rename all or none of the tables.
 
1713
 
 
1714
  @param thd Current thread
 
1715
  @param old_db 5.0 database name, in #mysql50#name format
 
1716
  @return 0 on success, 1 on error
 
1717
*/
 
1718
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
 
1719
{
 
1720
  int error= 0, change_to_newdb= 0;
 
1721
  char path[FN_REFLEN+16];
 
1722
  uint length;
 
1723
  HA_CREATE_INFO create_info;
 
1724
  MY_DIR *dirp;
 
1725
  TABLE_LIST *table_list;
 
1726
  SELECT_LEX *sl= thd->lex->current_select;
 
1727
  LEX_STRING new_db;
 
1728
  DBUG_ENTER("mysql_upgrade_db");
 
1729
 
 
1730
  if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
 
1731
      (strncmp(old_db->str,
 
1732
              MYSQL50_TABLE_NAME_PREFIX,
 
1733
              MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
 
1734
  {
 
1735
    my_error(ER_WRONG_USAGE, MYF(0),
 
1736
             "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
 
1737
             "name");
 
1738
    DBUG_RETURN(1);
 
1739
  }
 
1740
 
 
1741
  /* `#mysql50#<name>` converted to encoded `<name>` */
 
1742
  new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
1743
  new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
1744
 
 
1745
  if (lock_databases(thd, old_db->str, old_db->length,
 
1746
                          new_db.str, new_db.length))
 
1747
    DBUG_RETURN(1);
 
1748
 
 
1749
  /*
 
1750
    Let's remember if we should do "USE newdb" afterwards.
 
1751
    thd->db will be cleared in mysql_rename_db()
 
1752
  */
 
1753
  if (thd->db && !strcmp(thd->db, old_db->str))
 
1754
    change_to_newdb= 1;
 
1755
 
 
1756
  build_table_filename(path, sizeof(path)-1,
 
1757
                       old_db->str, "", MY_DB_OPT_FILE, 0);
 
1758
  if ((load_db_opt(thd, path, &create_info)))
 
1759
    create_info.default_table_charset= thd->variables.collation_server;
 
1760
 
 
1761
  length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
 
1762
  if (length && path[length-1] == FN_LIBCHAR)
 
1763
    path[length-1]=0;                            // remove ending '\'
 
1764
  if ((error= my_access(path,F_OK)))
 
1765
  {
 
1766
    my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
 
1767
    goto exit;
 
1768
  }
 
1769
 
 
1770
  /* Step1: Create the new database */
 
1771
  if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
 
1772
    goto exit;
 
1773
 
 
1774
  /* Step2: Move tables to the new database */
 
1775
  if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
 
1776
  {
 
1777
    uint nfiles= (uint) dirp->number_off_files;
 
1778
    for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
 
1779
    {
 
1780
      FILEINFO *file= dirp->dir_entry + idx;
 
1781
      char *extension, tname[FN_REFLEN];
 
1782
      LEX_STRING table_str;
 
1783
      DBUG_PRINT("info",("Examining: %s", file->name));
 
1784
 
 
1785
      /* skiping non-FRM files */
 
1786
      if (my_strcasecmp(files_charset_info,
 
1787
                        (extension= fn_rext(file->name)), reg_ext))
 
1788
        continue;
 
1789
 
 
1790
      /* A frm file found, add the table info rename list */
 
1791
      *extension= '\0';
 
1792
 
 
1793
      table_str.length= filename_to_tablename(file->name,
 
1794
                                              tname, sizeof(tname)-1);
 
1795
      table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
 
1796
      Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
 
1797
      Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
 
1798
      if (!old_ident || !new_ident ||
 
1799
          !sl->add_table_to_list(thd, old_ident, NULL,
 
1800
                                 TL_OPTION_UPDATING, TL_IGNORE) ||
 
1801
          !sl->add_table_to_list(thd, new_ident, NULL,
 
1802
                                 TL_OPTION_UPDATING, TL_IGNORE))
 
1803
      {
 
1804
        error= 1;
 
1805
        my_dirend(dirp);
 
1806
        goto exit;
 
1807
      }
 
1808
    }
 
1809
    my_dirend(dirp);  
 
1810
  }
 
1811
 
 
1812
  if ((table_list= thd->lex->query_tables) &&
 
1813
      (error= mysql_rename_tables(thd, table_list, 1)))
 
1814
  {
 
1815
    /*
 
1816
      Failed to move all tables from the old database to the new one.
 
1817
      In the best case mysql_rename_tables() moved all tables back to the old
 
1818
      database. In the worst case mysql_rename_tables() moved some tables
 
1819
      to the new database, then failed, then started to move the tables back,
 
1820
      and then failed again. In this situation we have some tables in the
 
1821
      old database and some tables in the new database.
 
1822
      Let's delete the option file, and then the new database directory.
 
1823
      If some tables were left in the new directory, rmdir() will fail.
 
1824
      It garantees we never loose any tables.
 
1825
    */
 
1826
    build_table_filename(path, sizeof(path)-1,
 
1827
                         new_db.str,"",MY_DB_OPT_FILE, 0);
 
1828
    my_delete(path, MYF(MY_WME));
 
1829
    length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
 
1830
    if (length && path[length-1] == FN_LIBCHAR)
 
1831
      path[length-1]=0;                            // remove ending '\'
 
1832
    rmdir(path);
 
1833
    goto exit;
 
1834
  }
 
1835
 
 
1836
 
 
1837
  if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
 
1838
  {
 
1839
    uint nfiles= (uint) dirp->number_off_files;
 
1840
    for (uint idx=0 ; idx < nfiles ; idx++)
 
1841
    {
 
1842
      FILEINFO *file= dirp->dir_entry + idx;
 
1843
      char oldname[FN_REFLEN], newname[FN_REFLEN];
 
1844
      DBUG_PRINT("info",("Examining: %s", file->name));
 
1845
 
 
1846
      /* skiping . and .. and MY_DB_OPT_FILE */
 
1847
      if ((file->name[0] == '.' &&
 
1848
           (!file->name[1] || (file->name[1] == '.' && !file->name[2]))) ||
 
1849
          !my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
 
1850
        continue;
 
1851
 
 
1852
      /* pass empty file name, and file->name as extension to avoid encoding */
 
1853
      build_table_filename(oldname, sizeof(oldname)-1,
 
1854
                           old_db->str, "", file->name, 0);
 
1855
      build_table_filename(newname, sizeof(newname)-1,
 
1856
                           new_db.str, "", file->name, 0);
 
1857
      my_rename(oldname, newname, MYF(MY_WME));
 
1858
    }
 
1859
    my_dirend(dirp);
 
1860
  }
 
1861
 
 
1862
  /*
 
1863
    Step7: drop the old database.
 
1864
    remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
 
1865
    are done inside mysql_rm_db(), no needs to execute them again.
 
1866
    mysql_rm_db() also "unuses" if we drop the current database.
 
1867
  */
 
1868
  error= mysql_rm_db(thd, old_db->str, 0, 1);
 
1869
 
 
1870
  /* Step8: logging */
 
1871
  if (mysql_bin_log.is_open())
 
1872
  {
 
1873
    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, TRUE);
 
1874
    thd->clear_error();
 
1875
    mysql_bin_log.write(&qinfo);
 
1876
  }
 
1877
 
 
1878
  /* Step9: Let's do "use newdb" if we renamed the current database */
 
1879
  if (change_to_newdb)
 
1880
    error|= mysql_change_db(thd, & new_db, FALSE);
 
1881
 
 
1882
exit:
 
1883
  pthread_mutex_lock(&LOCK_lock_db);
 
1884
  /* Remove the databases from db lock cache */
 
1885
  lock_db_delete(old_db->str, old_db->length);
 
1886
  lock_db_delete(new_db.str, new_db.length);
 
1887
  creating_database--;
 
1888
  /* Signal waiting CREATE TABLE's to continue */
 
1889
  pthread_cond_signal(&COND_refresh);
 
1890
  pthread_mutex_unlock(&LOCK_lock_db);
 
1891
 
 
1892
  DBUG_RETURN(error);
 
1893
}
 
1894
 
 
1895
 
 
1896
 
 
1897
/*
 
1898
  Check if there is directory for the database name.
 
1899
 
 
1900
  SYNOPSIS
 
1901
    check_db_dir_existence()
 
1902
    db_name   database name
 
1903
 
 
1904
  RETURN VALUES
 
1905
    FALSE   There is directory for the specified database name.
 
1906
    TRUE    The directory does not exist.
 
1907
*/
 
1908
 
 
1909
bool check_db_dir_existence(const char *db_name)
888
1910
{
889
1911
  char db_dir_path[FN_REFLEN];
890
 
  uint32_t db_dir_path_len;
 
1912
  uint db_dir_path_len;
891
1913
 
892
1914
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
893
 
                                        database_name.to_string().c_str(),
894
 
                                        "", false);
 
1915
                                        db_name, "", "", 0);
895
1916
 
896
1917
  if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
897
1918
    db_dir_path[db_dir_path_len - 1]= 0;
898
1919
 
899
 
  database_path.assign(db_dir_path);
900
 
}
 
1920
  /* Check access. */
901
1921
 
902
 
bool DatabasePathName::exists() const
903
 
{
904
 
  /* TODO: handle EIO and other fun errors */
905
 
  return access(database_path.c_str(), F_OK) == 0;
 
1922
  return my_access(db_dir_path, F_OK);
906
1923
}