~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/sql_db.cc

  • Committer: Patrick Galbraith
  • Date: 2008-07-24 16:57:40 UTC
  • mto: (202.2.4 rename-mysql-to-drizzle)
  • mto: This revision was merged to the branch mainline in revision 212.
  • Revision ID: patg@ishvara-20080724165740-x58yw6zs6d9o17lf
Most everything working with client rename
mysqlslap test still fails... can't connect to the server

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 CSTDINT_H
20
 
#include CINTTYPES_H
21
 
#include <string>
22
 
#include <fstream>
23
 
#include <drizzled/serialize/serialize.h>
24
 
using namespace std;
25
 
#include <drizzled/server_includes.h>
26
 
#include <mysys/mysys_err.h>
27
 
#include <mysys/my_dir.h>
 
18
 
 
19
#include "mysql_priv.h"
 
20
#include <mysys_err.h>
 
21
#include <my_dir.h>
 
22
#include <m_ctype.h>
28
23
#include "log.h"
29
 
#include <drizzled/drizzled_error_messages.h>
30
 
#include <libdrizzle/gettext.h>
31
 
 
32
24
 
33
25
#define MAX_DROP_TABLE_Q_LEN      1024
34
26
 
35
 
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NULL};
 
27
const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
36
28
static TYPELIB deletable_extentions=
37
29
{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
38
30
 
39
31
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
40
 
                                 const char *db, const char *path, uint32_t level, 
41
 
                                 TableList **dropped_tables);
 
32
                                 const char *db, const char *path, uint level, 
 
33
                                 TABLE_LIST **dropped_tables);
42
34
         
43
 
static bool rm_dir_w_symlink(const char *org_path, bool send_error);
 
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);
44
37
static void mysql_change_db_impl(THD *thd,
45
38
                                 LEX_STRING *new_db_name,
46
 
                                 const CHARSET_INFO * const new_db_charset);
 
39
                                 CHARSET_INFO *new_db_charset);
47
40
 
48
41
 
49
42
/* Database lock hash */
56
49
typedef struct my_dblock_st
57
50
{
58
51
  char *name;        /* Database name        */
59
 
  uint32_t name_length;  /* Database length name */
 
52
  uint name_length;  /* Database length name */
60
53
} my_dblock_t;
61
54
 
62
55
 
64
57
  lock_db key.
65
58
*/
66
59
 
67
 
extern "C" unsigned char* lock_db_get_key(my_dblock_t *, size_t *, bool not_used);
 
60
extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, my_bool not_used);
68
61
 
69
 
unsigned char* lock_db_get_key(my_dblock_t *ptr, size_t *length,
70
 
                       bool not_used __attribute__((unused)))
 
62
uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
 
63
                       my_bool not_used __attribute__((unused)))
71
64
{
72
65
  *length= ptr->name_length;
73
 
  return (unsigned char*) ptr->name;
 
66
  return (uchar*) ptr->name;
74
67
}
75
68
 
76
69
 
82
75
 
83
76
void lock_db_free_element(void *ptr)
84
77
{
85
 
  free(ptr);
 
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
  
 
99
  safe_mutex_assert_owner(&LOCK_lock_db);
 
100
 
 
101
  if (!(opt= (my_dblock_t*) hash_search(&lock_db_cache,
 
102
                                        (uchar*) dbname, length)))
 
103
  { 
 
104
    /* Db is not in the hash, insert it */
 
105
    char *tmp_name;
 
106
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
 
107
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
 
108
                         NullS))
 
109
    {
 
110
      error= 1;
 
111
      goto end;
 
112
    }
 
113
    
 
114
    opt->name= tmp_name;
 
115
    strmov(opt->name, dbname);
 
116
    opt->name_length= length;
 
117
    
 
118
    if ((error= my_hash_insert(&lock_db_cache, (uchar*) opt)))
 
119
      my_free(opt, MYF(0));
 
120
  }
 
121
 
 
122
end:
 
123
  return(error);
86
124
}
87
125
 
88
126
 
90
128
  Delete a database lock entry from hash.
91
129
*/
92
130
 
93
 
void lock_db_delete(const char *name, uint32_t length)
 
131
void lock_db_delete(const char *name, uint length)
94
132
{
95
133
  my_dblock_t *opt;
96
134
  safe_mutex_assert_owner(&LOCK_lock_db);
97
135
  if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
98
 
                                       (const unsigned char*) name, length)))
99
 
    hash_delete(&lock_db_cache, (unsigned char*) opt);
 
136
                                       (const uchar*) name, length)))
 
137
    hash_delete(&lock_db_cache, (uchar*) opt);
100
138
}
101
139
 
102
140
 
103
141
/* Database options hash */
104
142
static HASH dboptions;
105
 
static bool dboptions_init= 0;
 
143
static my_bool dboptions_init= 0;
106
144
static rw_lock_t LOCK_dboptions;
107
145
 
108
146
/* Structure for database options */
109
147
typedef struct my_dbopt_st
110
148
{
111
149
  char *name;                   /* Database name                  */
112
 
  uint32_t name_length;         /* Database length name           */
113
 
  const CHARSET_INFO *charset;  /* Database default character set */
 
150
  uint name_length;             /* Database length name           */
 
151
  CHARSET_INFO *charset;        /* Database default character set */
114
152
} my_dbopt_t;
115
153
 
116
154
 
118
156
  Function we use in the creation of our hash to get key.
119
157
*/
120
158
 
121
 
extern "C" unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
122
 
                                    bool not_used);
 
159
extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
160
                                    my_bool not_used);
123
161
 
124
 
unsigned char* dboptions_get_key(my_dbopt_t *opt, size_t *length,
125
 
                         bool not_used __attribute__((unused)))
 
162
uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
 
163
                         my_bool not_used __attribute__((unused)))
126
164
{
127
165
  *length= opt->name_length;
128
 
  return (unsigned char*) opt->name;
 
166
  return (uchar*) opt->name;
129
167
}
130
168
 
131
169
 
133
171
  Helper function to write a query to binlog used by mysql_rm_db()
134
172
*/
135
173
 
136
 
static inline void write_to_binlog(THD *thd, char *query, uint32_t q_len,
137
 
                                   char *db, uint32_t db_len)
 
174
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
 
175
                                   char *db, uint db_len)
138
176
{
139
177
  Query_log_event qinfo(thd, query, q_len, 0, 0);
140
178
  qinfo.error_code= 0;
152
190
 
153
191
void free_dbopt(void *dbopt)
154
192
{
155
 
  free((unsigned char*) dbopt);
 
193
  my_free((uchar*) dbopt, MYF(0));
156
194
}
157
195
 
158
196
 
172
210
 
173
211
bool my_database_names_init(void)
174
212
{
175
 
  bool error= false;
 
213
  bool error= 0;
176
214
  (void) my_rwlock_init(&LOCK_dboptions, NULL);
177
215
  if (!dboptions_init)
178
216
  {
236
274
    1 on error.
237
275
*/
238
276
 
239
 
static bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
 
277
static my_bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
240
278
{
241
279
  my_dbopt_t *opt;
242
 
  uint32_t length;
243
 
  bool error= true;
 
280
  uint length;
 
281
  my_bool error= 1;
244
282
  
245
283
  length= (uint) strlen(dbname);
246
284
  
247
285
  rw_rdlock(&LOCK_dboptions);
248
 
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
 
286
  if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
249
287
  {
250
288
    create->default_table_charset= opt->charset;
251
 
    error= true;
 
289
    error= 0;
252
290
  }
253
291
  rw_unlock(&LOCK_dboptions);
254
292
  return error;
267
305
    1 on error.
268
306
*/
269
307
 
270
 
static bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
 
308
static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
271
309
{
272
310
  my_dbopt_t *opt;
273
 
  uint32_t length;
274
 
  bool error= false;
 
311
  uint length;
 
312
  my_bool error= 0;
275
313
 
276
314
  length= (uint) strlen(dbname);
277
315
  
278
316
  rw_wrlock(&LOCK_dboptions);
279
 
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (unsigned char*) dbname, length)))
 
317
  if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
280
318
  { 
281
319
    /* Options are not in the hash, insert them */
282
320
    char *tmp_name;
283
321
    if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
284
322
                         &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
285
 
                         NULL))
 
323
                         NullS))
286
324
    {
287
 
      error= true;
 
325
      error= 1;
288
326
      goto end;
289
327
    }
290
328
    
291
329
    opt->name= tmp_name;
292
 
    my_stpcpy(opt->name, dbname);
 
330
    strmov(opt->name, dbname);
293
331
    opt->name_length= length;
294
332
    
295
 
    if ((error= my_hash_insert(&dboptions, (unsigned char*) opt)))
 
333
    if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
296
334
    {
297
 
      free(opt);
 
335
      my_free(opt, MYF(0));
298
336
      goto end;
299
337
    }
300
338
  }
316
354
{
317
355
  my_dbopt_t *opt;
318
356
  rw_wrlock(&LOCK_dboptions);
319
 
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const unsigned char*) path,
 
357
  if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
320
358
                                      strlen(path))))
321
 
    hash_delete(&dboptions, (unsigned char*) opt);
 
359
    hash_delete(&dboptions, (uchar*) opt);
322
360
  rw_unlock(&LOCK_dboptions);
323
361
}
324
362
 
334
372
  1     Could not create file or write to it.  Error sent through my_error()
335
373
*/
336
374
 
337
 
static bool write_db_opt(THD *thd, const char *path, const char *name, HA_CREATE_INFO *create)
 
375
static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
338
376
{
339
 
  bool error= true;
340
 
  drizzle::Schema db;
341
 
 
342
 
  assert(name);
 
377
  register File file;
 
378
  char buf[256]; // Should be enough for one option
 
379
  bool error=1;
343
380
 
344
381
  if (!create->default_table_charset)
345
382
    create->default_table_charset= thd->variables.collation_server;
347
384
  if (put_dbopt(path, create))
348
385
    return 1;
349
386
 
350
 
  db.set_name(name);
351
 
  db.set_characterset(create->default_table_charset->csname);
352
 
  db.set_collation(create->default_table_charset->name);
353
 
 
354
 
  fstream output(path, ios::out | ios::trunc | ios::binary);
355
 
  if (!db.SerializeToOstream(&output)) 
356
 
    error= false;
357
 
 
 
387
  if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
 
388
  {
 
389
    ulong length;
 
390
    length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=",
 
391
                              create->default_table_charset->csname,
 
392
                              "\ndefault-collation=",
 
393
                              create->default_table_charset->name,
 
394
                              "\n", NullS) - buf);
 
395
 
 
396
    /* Error is written by my_write */
 
397
    if (!my_write(file,(uchar*) buf, length, MYF(MY_NABP+MY_WME)))
 
398
      error=0;
 
399
    my_close(file,MYF(0));
 
400
  }
358
401
  return error;
359
402
}
360
403
 
376
419
 
377
420
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
378
421
{
 
422
  File file;
 
423
  char buf[256];
379
424
  bool error=1;
380
 
  drizzle::Schema db;
381
 
  string buffer;
 
425
  uint nbytes;
382
426
 
383
 
  memset(create, 0, sizeof(*create));
 
427
  bzero((char*) create,sizeof(*create));
384
428
  create->default_table_charset= thd->variables.collation_server;
385
429
 
386
430
  /* Check if options for this database are already in the hash */
387
431
  if (!get_dbopt(path, create))
388
432
    return(0);
389
433
 
390
 
  fstream input(path, ios::in | ios::binary);
391
 
  if (!input)
392
 
    goto err1;
393
 
  else if (!db.ParseFromIstream(&input))
394
 
    goto err1;
395
 
 
396
 
  buffer= db.characterset();
397
 
  if (!(create->default_table_charset= get_charset_by_csname(buffer.c_str(), MY_CS_PRIMARY, MYF(0))))
398
 
  {
399
 
    sql_print_error(_("Error while loading database options: '%s':"),path);
400
 
    sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
401
 
    create->default_table_charset= default_charset_info;
402
 
  }
403
 
 
404
 
  buffer= db.collation();
405
 
  if (!(create->default_table_charset= get_charset_by_name(buffer.c_str(), MYF(0))))
406
 
  {
407
 
    sql_print_error(_("Error while loading database options: '%s':"),path);
408
 
    sql_print_error(ER(ER_UNKNOWN_COLLATION), buffer.c_str());
409
 
    create->default_table_charset= default_charset_info;
410
 
  }
411
 
 
 
434
  /* Otherwise, load options from the .opt file */
 
435
  if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
 
436
    goto err1;
 
437
 
 
438
  IO_CACHE cache;
 
439
  if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
 
440
    goto err2;
 
441
 
 
442
  while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
 
443
  {
 
444
    char *pos= buf+nbytes-1;
 
445
    /* Remove end space and control characters */
 
446
    while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
 
447
      pos--;
 
448
    *pos=0;
 
449
    if ((pos= strchr(buf, '=')))
 
450
    {
 
451
      if (!strncmp(buf,"default-character-set", (pos-buf)))
 
452
      {
 
453
        /*
 
454
           Try character set name, and if it fails
 
455
           try collation name, probably it's an old
 
456
           4.1.0 db.opt file, which didn't have
 
457
           separate default-character-set and
 
458
           default-collation commands.
 
459
        */
 
460
        if (!(create->default_table_charset=
 
461
        get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
 
462
            !(create->default_table_charset=
 
463
              get_charset_by_name(pos+1, MYF(0))))
 
464
        {
 
465
          sql_print_error("Error while loading database options: '%s':",path);
 
466
          sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
 
467
          create->default_table_charset= default_charset_info;
 
468
        }
 
469
      }
 
470
      else if (!strncmp(buf,"default-collation", (pos-buf)))
 
471
      {
 
472
        if (!(create->default_table_charset= get_charset_by_name(pos+1,
 
473
                                                           MYF(0))))
 
474
        {
 
475
          sql_print_error("Error while loading database options: '%s':",path);
 
476
          sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
 
477
          create->default_table_charset= default_charset_info;
 
478
        }
 
479
      }
 
480
    }
 
481
  }
412
482
  /*
413
483
    Put the loaded value into the hash.
414
484
    Note that another thread could've added the same
418
488
  */
419
489
  error= put_dbopt(path, create);
420
490
 
 
491
  end_io_cache(&cache);
 
492
err2:
 
493
  my_close(file,MYF(0));
421
494
err1:
422
495
  return(error);
423
496
}
479
552
    set, even if the database does not exist.
480
553
*/
481
554
 
482
 
const CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
 
555
CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
483
556
{
484
557
  HA_CREATE_INFO db_info;
485
558
 
524
597
 
525
598
*/
526
599
 
527
 
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent)
 
600
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
 
601
                     bool silent)
528
602
{
529
603
  char   path[FN_REFLEN+16];
530
604
  char   tmp_query[FN_REFLEN+16];
531
605
  long result= 1;
532
606
  int error= 0;
533
607
  struct stat stat_info;
534
 
  uint32_t create_options= create_info ? create_info->options : 0;
535
 
  uint32_t path_len;
 
608
  uint create_options= create_info ? create_info->options : 0;
 
609
  uint path_len;
536
610
 
537
611
  /* do not create 'information_schema' db */
538
612
  if (!my_strcasecmp(system_charset_info, db, INFORMATION_SCHEMA_NAME.str))
559
633
    goto exit2;
560
634
  }
561
635
 
562
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
636
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
563
637
 
564
638
  /* Check directory */
565
639
  path_len= build_table_filename(path, sizeof(path), db, "", "", 0);
573
647
      error= -1;
574
648
      goto exit;
575
649
    }
576
 
    push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
650
    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
577
651
                        ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
578
652
    if (!silent)
579
653
      my_ok(thd);
597
671
 
598
672
  path[path_len-1]= FN_LIBCHAR;
599
673
  strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
600
 
  if (write_db_opt(thd, path, db, create_info))
 
674
  if (write_db_opt(thd, path, create_info))
601
675
  {
602
676
    /*
603
677
      Could not create options file.
619
693
  if (!silent)
620
694
  {
621
695
    char *query;
622
 
    uint32_t query_length;
 
696
    uint query_length;
623
697
 
624
698
    if (!thd->query)                            // Only in replication
625
699
    {
626
700
      query=         tmp_query;
627
701
      query_length= (uint) (strxmov(tmp_query,"create database `",
628
 
                                    db, "`", NULL) - tmp_query);
 
702
                                    db, "`", NullS) - tmp_query);
629
703
    }
630
704
    else
631
705
    {
633
707
      query_length= thd->query_length;
634
708
    }
635
709
 
 
710
    ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
 
711
                        query, query_length,
 
712
                        db, "");
 
713
 
636
714
    if (mysql_bin_log.is_open())
637
715
    {
638
716
      Query_log_event qinfo(thd, query, query_length, 0, 
665
743
  }
666
744
 
667
745
exit:
668
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
 
746
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
669
747
  start_waiting_global_read_lock(thd);
670
748
exit2:
671
749
  return(error);
678
756
{
679
757
  char path[FN_REFLEN+16];
680
758
  long result=1;
681
 
  int error= false;
 
759
  int error= 0;
682
760
 
683
761
  /*
684
762
    Do not alter database if another thread is holding read lock.
695
773
  if ((error=wait_if_global_read_lock(thd,0,1)))
696
774
    goto exit2;
697
775
 
698
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
776
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
699
777
 
700
778
  /* 
701
779
     Recreate db options file: /dbpath/.db.opt
703
781
     "table name to file name" encoding.
704
782
  */
705
783
  build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0);
706
 
  if ((error=write_db_opt(thd, path, db, create_info)))
 
784
  if ((error=write_db_opt(thd, path, create_info)))
707
785
    goto exit;
708
786
 
709
787
  /* Change options if current database is being altered. */
716
794
    thd->variables.collation_database= thd->db_charset;
717
795
  }
718
796
 
 
797
  ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
 
798
                      thd->query, thd->query_length,
 
799
                      db, "");
 
800
 
719
801
  if (mysql_bin_log.is_open())
720
802
  {
721
803
    Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
736
818
  my_ok(thd, result);
737
819
 
738
820
exit:
739
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
 
821
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
740
822
  start_waiting_global_read_lock(thd);
741
823
exit2:
742
824
  return(error);
763
845
bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
764
846
{
765
847
  long deleted=0;
766
 
  int error= false;
 
848
  int error= 0;
767
849
  char  path[FN_REFLEN+16];
768
850
  MY_DIR *dirp;
769
 
  uint32_t length;
770
 
  TableList* dropped_tables= 0;
 
851
  uint length;
 
852
  TABLE_LIST* dropped_tables= 0;
771
853
 
772
854
  if (db && (strcmp(db, "information_schema") == 0))
773
855
  {
793
875
    goto exit2;
794
876
  }
795
877
 
796
 
  pthread_mutex_lock(&LOCK_mysql_create_db);
 
878
  VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
797
879
 
798
880
  /*
799
881
    This statement will be replicated as a statement, even when using
803
885
  thd->clear_current_stmt_binlog_row_based();
804
886
 
805
887
  length= build_table_filename(path, sizeof(path), db, "", "", 0);
806
 
  my_stpcpy(path+length, MY_DB_OPT_FILE);               // Append db option file name
 
888
  strmov(path+length, MY_DB_OPT_FILE);          // Append db option file name
807
889
  del_dbopt(path);                              // Remove dboption hash entry
808
890
  path[length]= '\0';                           // Remove file name
809
891
 
817
899
      goto exit;
818
900
    }
819
901
    else
820
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
902
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
821
903
                          ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
822
904
  }
823
905
  else
838
920
  if (!silent && deleted>=0)
839
921
  {
840
922
    const char *query;
841
 
    uint32_t query_length;
 
923
    ulong query_length;
842
924
    if (!thd->query)
843
925
    {
844
926
      /* The client used the old obsolete mysql_drop_db() call */
845
927
      query= path;
846
928
      query_length= (uint) (strxmov(path, "drop database `", db, "`",
847
 
                                     NULL) - path);
 
929
                                     NullS) - path);
848
930
    }
849
931
    else
850
932
    {
869
951
    }
870
952
    thd->clear_error();
871
953
    thd->server_status|= SERVER_STATUS_DB_DROPPED;
872
 
    my_ok(thd, (uint32_t) deleted);
 
954
    my_ok(thd, (ulong) deleted);
873
955
    thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
874
956
  }
875
957
  else if (mysql_bin_log.is_open())
876
958
  {
877
959
    char *query, *query_pos, *query_end, *query_data_start;
878
 
    TableList *tbl;
879
 
    uint32_t db_len;
 
960
    TABLE_LIST *tbl;
 
961
    uint db_len;
880
962
 
881
963
    if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
882
964
      goto exit; /* not much else we can do */
883
 
    query_pos= query_data_start= my_stpcpy(query,"drop table ");
 
965
    query_pos= query_data_start= strmov(query,"drop table ");
884
966
    query_end= query + MAX_DROP_TABLE_Q_LEN;
885
967
    db_len= strlen(db);
886
968
 
887
969
    for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
888
970
    {
889
 
      uint32_t tbl_name_len;
 
971
      uint tbl_name_len;
890
972
 
891
973
      /* 3 for the quotes and the comma*/
892
974
      tbl_name_len= strlen(tbl->table_name) + 3;
898
980
      }
899
981
 
900
982
      *query_pos++ = '`';
901
 
      query_pos= my_stpcpy(query_pos,tbl->table_name);
 
983
      query_pos= strmov(query_pos,tbl->table_name);
902
984
      *query_pos++ = '`';
903
985
      *query_pos++ = ',';
904
986
    }
919
1001
  */
920
1002
  if (thd->db && !strcmp(thd->db, db))
921
1003
    mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
922
 
  pthread_mutex_unlock(&LOCK_mysql_create_db);
 
1004
  VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
923
1005
  start_waiting_global_read_lock(thd);
924
1006
exit2:
925
1007
  return(error);
926
1008
}
927
1009
 
928
1010
/*
929
 
  Removes files with known extensions plus.
 
1011
  Removes files with known extensions plus all found subdirectories that
 
1012
  are 2 hex digits (raid directories).
930
1013
  thd MUST be set when calling this function!
931
1014
*/
932
1015
 
933
1016
static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
934
 
                                 const char *org_path, uint32_t level,
935
 
                                 TableList **dropped_tables)
 
1017
                                 const char *org_path, uint level,
 
1018
                                 TABLE_LIST **dropped_tables)
936
1019
{
937
1020
  long deleted=0;
938
 
  uint32_t found_other_files=0;
 
1021
  ulong found_other_files=0;
939
1022
  char filePath[FN_REFLEN];
940
 
  TableList *tot_list=0, **tot_list_next;
 
1023
  TABLE_LIST *tot_list=0, **tot_list_next;
 
1024
  List<String> raid_dirs;
941
1025
 
942
1026
  tot_list_next= &tot_list;
943
1027
 
944
 
  for (uint32_t idx=0 ;
 
1028
  for (uint idx=0 ;
945
1029
       idx < (uint) dirp->number_off_files && !thd->killed ;
946
1030
       idx++)
947
1031
  {
953
1037
       (file->name[1] == '.' &&  !file->name[2])))
954
1038
      continue;
955
1039
 
 
1040
    /* Check if file is a raid directory */
 
1041
    if ((my_isdigit(system_charset_info, file->name[0]) ||
 
1042
         (file->name[0] >= 'a' && file->name[0] <= 'f')) &&
 
1043
        (my_isdigit(system_charset_info, file->name[1]) ||
 
1044
         (file->name[1] >= 'a' && file->name[1] <= 'f')) &&
 
1045
        !file->name[2] && !level)
 
1046
    {
 
1047
      char newpath[FN_REFLEN], *copy_of_path;
 
1048
      MY_DIR *new_dirp;
 
1049
      String *dir;
 
1050
      uint length;
 
1051
 
 
1052
      strxmov(newpath,org_path,"/",file->name,NullS);
 
1053
      length= unpack_filename(newpath,newpath);
 
1054
      if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
 
1055
      {
 
1056
        if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0)
 
1057
          goto err;
 
1058
        if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) ||
 
1059
            !(dir= new (thd->mem_root) String(copy_of_path, length,
 
1060
                                               &my_charset_bin)) ||
 
1061
            raid_dirs.push_back(dir))
 
1062
          goto err;
 
1063
        continue;
 
1064
      }
 
1065
      found_other_files++;
 
1066
      continue;
 
1067
    }
 
1068
    else if (file->name[0] == 'a' && file->name[1] == 'r' &&
 
1069
             file->name[2] == 'c' && file->name[3] == '\0')
 
1070
    {
 
1071
      /* .frm archive */
 
1072
      char newpath[FN_REFLEN];
 
1073
      MY_DIR *new_dirp;
 
1074
      strxmov(newpath, org_path, "/", "arc", NullS);
 
1075
      (void) unpack_filename(newpath, newpath);
 
1076
      if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
 
1077
      {
 
1078
        if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
 
1079
          goto err;
 
1080
        continue;
 
1081
      }
 
1082
      found_other_files++;
 
1083
      continue;
 
1084
    }
956
1085
    if (!(extension= strrchr(file->name, '.')))
957
 
      extension= strchr(file->name, '\0');
 
1086
      extension= strend(file->name);
958
1087
    if (find_type(extension, &deletable_extentions,1+2) <= 0)
959
1088
    {
960
1089
      if (find_type(extension, ha_known_exts(),1+2) <= 0)
967
1096
    {
968
1097
      /* Drop the table nicely */
969
1098
      *extension= 0;                    // Remove extension
970
 
      TableList *table_list=(TableList*)
 
1099
      TABLE_LIST *table_list=(TABLE_LIST*)
971
1100
                              thd->calloc(sizeof(*table_list) + 
972
1101
                                          strlen(db) + 1 +
973
1102
                                          MYSQL50_TABLE_NAME_PREFIX_LENGTH + 
976
1105
      if (!table_list)
977
1106
        goto err;
978
1107
      table_list->db= (char*) (table_list+1);
979
 
      table_list->table_name= my_stpcpy(table_list->db, db) + 1;
980
 
      filename_to_tablename(file->name, table_list->table_name,
981
 
                            MYSQL50_TABLE_NAME_PREFIX_LENGTH +
982
 
                            strlen(file->name) + 1);
 
1108
      table_list->table_name= strmov(table_list->db, db) + 1;
 
1109
      VOID(filename_to_tablename(file->name, table_list->table_name,
 
1110
                                 MYSQL50_TABLE_NAME_PREFIX_LENGTH +
 
1111
                                 strlen(file->name) + 1));
983
1112
      table_list->alias= table_list->table_name;        // If lower_case_table_names=2
984
1113
      table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
985
1114
      /* Link into list */
989
1118
    }
990
1119
    else
991
1120
    {
992
 
      strxmov(filePath, org_path, "/", file->name, NULL);
 
1121
      strxmov(filePath, org_path, "/", file->name, NullS);
993
1122
      if (my_delete_with_symlink(filePath,MYF(MY_WME)))
994
1123
      {
995
1124
        goto err;
1000
1129
      (tot_list && mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1)))
1001
1130
    goto err;
1002
1131
 
 
1132
  /* Remove RAID directories */
 
1133
  {
 
1134
    List_iterator<String> it(raid_dirs);
 
1135
    String *dir;
 
1136
    while ((dir= it++))
 
1137
      if (rmdir(dir->c_ptr()) < 0)
 
1138
        found_other_files++;
 
1139
  }
1003
1140
  my_dirend(dirp);  
1004
1141
  
1005
1142
  if (dropped_tables)
1041
1178
    1 ERROR
1042
1179
*/
1043
1180
 
1044
 
static bool rm_dir_w_symlink(const char *org_path, bool send_error)
 
1181
static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
1045
1182
{
1046
1183
  char tmp_path[FN_REFLEN], *pos;
1047
1184
  char *path= tmp_path;
1051
1188
  char tmp2_path[FN_REFLEN];
1052
1189
 
1053
1190
  /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1054
 
  pos= strchr(path, '\0');
 
1191
  pos= strend(path);
1055
1192
  if (pos > path && pos[-1] == FN_LIBCHAR)
1056
1193
    *--pos=0;
1057
1194
 
1068
1205
  }
1069
1206
#endif
1070
1207
  /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1071
 
  pos= strchr(path, '\0');
 
1208
  pos= strend(path);
1072
1209
 
1073
1210
  if (pos > path && pos[-1] == FN_LIBCHAR)
1074
1211
    *--pos=0;
1081
1218
}
1082
1219
 
1083
1220
 
 
1221
/*
 
1222
  Remove .frm archives from directory
 
1223
 
 
1224
  SYNOPSIS
 
1225
    thd       thread handler
 
1226
    dirp      list of files in archive directory
 
1227
    db        data base name
 
1228
    org_path  path of archive directory
 
1229
 
 
1230
  RETURN
 
1231
    > 0 number of removed files
 
1232
    -1  error
 
1233
*/
 
1234
static long mysql_rm_arc_files(THD *thd, MY_DIR *dirp,
 
1235
                                 const char *org_path)
 
1236
{
 
1237
  long deleted= 0;
 
1238
  ulong found_other_files= 0;
 
1239
  char filePath[FN_REFLEN];
 
1240
 
 
1241
  for (uint idx=0 ;
 
1242
       idx < (uint) dirp->number_off_files && !thd->killed ;
 
1243
       idx++)
 
1244
  {
 
1245
    FILEINFO *file=dirp->dir_entry+idx;
 
1246
    char *extension, *revision;
 
1247
 
 
1248
    /* skiping . and .. */
 
1249
    if (file->name[0] == '.' && (!file->name[1] ||
 
1250
       (file->name[1] == '.' &&  !file->name[2])))
 
1251
      continue;
 
1252
 
 
1253
    extension= fn_ext(file->name);
 
1254
    if (extension[0] != '.' ||
 
1255
        extension[1] != 'f' || extension[2] != 'r' ||
 
1256
        extension[3] != 'm' || extension[4] != '-')
 
1257
    {
 
1258
      found_other_files++;
 
1259
      continue;
 
1260
    }
 
1261
    revision= extension+5;
 
1262
    while (*revision && my_isdigit(system_charset_info, *revision))
 
1263
      revision++;
 
1264
    if (*revision)
 
1265
    {
 
1266
      found_other_files++;
 
1267
      continue;
 
1268
    }
 
1269
    strxmov(filePath, org_path, "/", file->name, NullS);
 
1270
    if (my_delete_with_symlink(filePath,MYF(MY_WME)))
 
1271
    {
 
1272
      goto err;
 
1273
    }
 
1274
  }
 
1275
  if (thd->killed)
 
1276
    goto err;
 
1277
 
 
1278
  my_dirend(dirp);
 
1279
 
 
1280
  /*
 
1281
    If the directory is a symbolic link, remove the link first, then
 
1282
    remove the directory the symbolic link pointed at
 
1283
  */
 
1284
  if (!found_other_files &&
 
1285
      rm_dir_w_symlink(org_path, 0))
 
1286
    return(-1);
 
1287
  return(deleted);
 
1288
 
 
1289
err:
 
1290
  my_dirend(dirp);
 
1291
  return(-1);
 
1292
}
 
1293
 
 
1294
 
1084
1295
/**
1085
1296
  @brief Internal implementation: switch current database to a valid one.
1086
1297
 
1094
1305
 
1095
1306
static void mysql_change_db_impl(THD *thd,
1096
1307
                                 LEX_STRING *new_db_name,
1097
 
                                 const CHARSET_INFO * const new_db_charset)
 
1308
                                 CHARSET_INFO *new_db_charset)
1098
1309
{
1099
1310
  /* 1. Change current database in THD. */
1100
1311
 
1124
1335
      the previous database name, we should do it explicitly.
1125
1336
    */
1126
1337
 
1127
 
    if (thd->db)
1128
 
      free(thd->db);
 
1338
    x_free(thd->db);
1129
1339
 
1130
1340
    thd->reset_db(new_db_name->str, new_db_name->length);
1131
1341
  }
1260
1470
bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
1261
1471
{
1262
1472
  LEX_STRING new_db_file_name;
1263
 
  const CHARSET_INFO *db_default_cl;
 
1473
  CHARSET_INFO *db_default_cl;
1264
1474
 
1265
1475
  if (new_db_name == NULL ||
1266
1476
      new_db_name->length == 0)
1325
1535
  if (check_db_name(&new_db_file_name))
1326
1536
  {
1327
1537
    my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1328
 
    free(new_db_file_name.str);
 
1538
    my_free(new_db_file_name.str, MYF(0));
1329
1539
 
1330
1540
    if (force_switch)
1331
1541
      mysql_change_db_impl(thd, NULL, thd->variables.collation_server);
1339
1549
    {
1340
1550
      /* Throw a warning and free new_db_file_name. */
1341
1551
 
1342
 
      push_warning_printf(thd, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
 
1552
      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1343
1553
                          ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1344
1554
                          new_db_file_name.str);
1345
1555
 
1346
 
      free(new_db_file_name.str);
 
1556
      my_free(new_db_file_name.str, MYF(0));
1347
1557
 
1348
1558
      /* Change db to NULL. */
1349
1559
 
1358
1568
      /* Report an error and free new_db_file_name. */
1359
1569
 
1360
1570
      my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1361
 
      free(new_db_file_name.str);
 
1571
      my_free(new_db_file_name.str, MYF(0));
1362
1572
 
1363
1573
      /* The operation failed. */
1364
1574
 
1416
1626
}
1417
1627
 
1418
1628
 
 
1629
static int
 
1630
lock_databases(THD *thd, const char *db1, uint length1,
 
1631
                         const char *db2, uint length2)
 
1632
{
 
1633
  pthread_mutex_lock(&LOCK_lock_db);
 
1634
  while (!thd->killed &&
 
1635
         (hash_search(&lock_db_cache,(uchar*) db1, length1) ||
 
1636
          hash_search(&lock_db_cache,(uchar*) db2, length2)))
 
1637
  {
 
1638
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1639
    pthread_mutex_lock(&LOCK_lock_db);
 
1640
  }
 
1641
 
 
1642
  if (thd->killed)
 
1643
  {
 
1644
    pthread_mutex_unlock(&LOCK_lock_db);
 
1645
    return 1;
 
1646
  }
 
1647
 
 
1648
  lock_db_insert(db1, length1);
 
1649
  lock_db_insert(db2, length2);
 
1650
  creating_database++;
 
1651
 
 
1652
  /*
 
1653
    Wait if a concurent thread is creating a table at the same time.
 
1654
    The assumption here is that it will not take too long until
 
1655
    there is a point in time when a table is not created.
 
1656
  */
 
1657
 
 
1658
  while (!thd->killed && creating_table)
 
1659
  {
 
1660
    wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
 
1661
    pthread_mutex_lock(&LOCK_lock_db);
 
1662
  }
 
1663
 
 
1664
  if (thd->killed)
 
1665
  {
 
1666
    lock_db_delete(db1, length1);
 
1667
    lock_db_delete(db2, length2);
 
1668
    creating_database--;
 
1669
    pthread_mutex_unlock(&LOCK_lock_db);
 
1670
    pthread_cond_signal(&COND_refresh);
 
1671
    return(1);
 
1672
  }
 
1673
 
 
1674
  /*
 
1675
    We can unlock now as the hash will protect against anyone creating a table
 
1676
    in the databases we are using
 
1677
  */
 
1678
  pthread_mutex_unlock(&LOCK_lock_db);
 
1679
  return 0;
 
1680
}
 
1681
 
 
1682
 
 
1683
/**
 
1684
  Upgrade a 5.0 database.
 
1685
  This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
 
1686
    ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
 
1687
 
 
1688
  If we have managed to rename (move) tables to the new database
 
1689
  but something failed on a later step, then we store the
 
1690
  RENAME DATABASE event in the log. mysql_rename_db() is atomic in
 
1691
  the sense that it will rename all or none of the tables.
 
1692
 
 
1693
  @param thd Current thread
 
1694
  @param old_db 5.0 database name, in #mysql50#name format
 
1695
  @return 0 on success, 1 on error
 
1696
*/
 
1697
bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
 
1698
{
 
1699
  int error= 0, change_to_newdb= 0;
 
1700
  char path[FN_REFLEN+16];
 
1701
  uint length;
 
1702
  HA_CREATE_INFO create_info;
 
1703
  MY_DIR *dirp;
 
1704
  TABLE_LIST *table_list;
 
1705
  SELECT_LEX *sl= thd->lex->current_select;
 
1706
  LEX_STRING new_db;
 
1707
 
 
1708
  if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
 
1709
      (strncmp(old_db->str,
 
1710
              MYSQL50_TABLE_NAME_PREFIX,
 
1711
              MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
 
1712
  {
 
1713
    my_error(ER_WRONG_USAGE, MYF(0),
 
1714
             "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
 
1715
             "name");
 
1716
    return(1);
 
1717
  }
 
1718
 
 
1719
  /* `#mysql50#<name>` converted to encoded `<name>` */
 
1720
  new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
1721
  new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
 
1722
 
 
1723
  if (lock_databases(thd, old_db->str, old_db->length,
 
1724
                          new_db.str, new_db.length))
 
1725
    return(1);
 
1726
 
 
1727
  /*
 
1728
    Let's remember if we should do "USE newdb" afterwards.
 
1729
    thd->db will be cleared in mysql_rename_db()
 
1730
  */
 
1731
  if (thd->db && !strcmp(thd->db, old_db->str))
 
1732
    change_to_newdb= 1;
 
1733
 
 
1734
  build_table_filename(path, sizeof(path)-1,
 
1735
                       old_db->str, "", MY_DB_OPT_FILE, 0);
 
1736
  if ((load_db_opt(thd, path, &create_info)))
 
1737
    create_info.default_table_charset= thd->variables.collation_server;
 
1738
 
 
1739
  length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
 
1740
  if (length && path[length-1] == FN_LIBCHAR)
 
1741
    path[length-1]=0;                            // remove ending '\'
 
1742
  if ((error= my_access(path,F_OK)))
 
1743
  {
 
1744
    my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
 
1745
    goto exit;
 
1746
  }
 
1747
 
 
1748
  /* Step1: Create the new database */
 
1749
  if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
 
1750
    goto exit;
 
1751
 
 
1752
  /* Step2: Move tables to the new database */
 
1753
  if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
 
1754
  {
 
1755
    uint nfiles= (uint) dirp->number_off_files;
 
1756
    for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
 
1757
    {
 
1758
      FILEINFO *file= dirp->dir_entry + idx;
 
1759
      char *extension, tname[FN_REFLEN];
 
1760
      LEX_STRING table_str;
 
1761
 
 
1762
      /* skiping non-FRM files */
 
1763
      if (my_strcasecmp(files_charset_info,
 
1764
                        (extension= fn_rext(file->name)), reg_ext))
 
1765
        continue;
 
1766
 
 
1767
      /* A frm file found, add the table info rename list */
 
1768
      *extension= '\0';
 
1769
 
 
1770
      table_str.length= filename_to_tablename(file->name,
 
1771
                                              tname, sizeof(tname)-1);
 
1772
      table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
 
1773
      Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
 
1774
      Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
 
1775
      if (!old_ident || !new_ident ||
 
1776
          !sl->add_table_to_list(thd, old_ident, NULL,
 
1777
                                 TL_OPTION_UPDATING, TL_IGNORE) ||
 
1778
          !sl->add_table_to_list(thd, new_ident, NULL,
 
1779
                                 TL_OPTION_UPDATING, TL_IGNORE))
 
1780
      {
 
1781
        error= 1;
 
1782
        my_dirend(dirp);
 
1783
        goto exit;
 
1784
      }
 
1785
    }
 
1786
    my_dirend(dirp);  
 
1787
  }
 
1788
 
 
1789
  if ((table_list= thd->lex->query_tables) &&
 
1790
      (error= mysql_rename_tables(thd, table_list, 1)))
 
1791
  {
 
1792
    /*
 
1793
      Failed to move all tables from the old database to the new one.
 
1794
      In the best case mysql_rename_tables() moved all tables back to the old
 
1795
      database. In the worst case mysql_rename_tables() moved some tables
 
1796
      to the new database, then failed, then started to move the tables back,
 
1797
      and then failed again. In this situation we have some tables in the
 
1798
      old database and some tables in the new database.
 
1799
      Let's delete the option file, and then the new database directory.
 
1800
      If some tables were left in the new directory, rmdir() will fail.
 
1801
      It garantees we never loose any tables.
 
1802
    */
 
1803
    build_table_filename(path, sizeof(path)-1,
 
1804
                         new_db.str,"",MY_DB_OPT_FILE, 0);
 
1805
    my_delete(path, MYF(MY_WME));
 
1806
    length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
 
1807
    if (length && path[length-1] == FN_LIBCHAR)
 
1808
      path[length-1]=0;                            // remove ending '\'
 
1809
    rmdir(path);
 
1810
    goto exit;
 
1811
  }
 
1812
 
 
1813
 
 
1814
  if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
 
1815
  {
 
1816
    uint nfiles= (uint) dirp->number_off_files;
 
1817
    for (uint idx=0 ; idx < nfiles ; idx++)
 
1818
    {
 
1819
      FILEINFO *file= dirp->dir_entry + idx;
 
1820
      char oldname[FN_REFLEN], newname[FN_REFLEN];
 
1821
 
 
1822
      /* skiping . and .. and MY_DB_OPT_FILE */
 
1823
      if ((file->name[0] == '.' &&
 
1824
           (!file->name[1] || (file->name[1] == '.' && !file->name[2]))) ||
 
1825
          !my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
 
1826
        continue;
 
1827
 
 
1828
      /* pass empty file name, and file->name as extension to avoid encoding */
 
1829
      build_table_filename(oldname, sizeof(oldname)-1,
 
1830
                           old_db->str, "", file->name, 0);
 
1831
      build_table_filename(newname, sizeof(newname)-1,
 
1832
                           new_db.str, "", file->name, 0);
 
1833
      my_rename(oldname, newname, MYF(MY_WME));
 
1834
    }
 
1835
    my_dirend(dirp);
 
1836
  }
 
1837
 
 
1838
  /*
 
1839
    Step7: drop the old database.
 
1840
    remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
 
1841
    are done inside mysql_rm_db(), no needs to execute them again.
 
1842
    mysql_rm_db() also "unuses" if we drop the current database.
 
1843
  */
 
1844
  error= mysql_rm_db(thd, old_db->str, 0, 1);
 
1845
 
 
1846
  /* Step8: logging */
 
1847
  if (mysql_bin_log.is_open())
 
1848
  {
 
1849
    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, true);
 
1850
    thd->clear_error();
 
1851
    mysql_bin_log.write(&qinfo);
 
1852
  }
 
1853
 
 
1854
  /* Step9: Let's do "use newdb" if we renamed the current database */
 
1855
  if (change_to_newdb)
 
1856
    error|= mysql_change_db(thd, & new_db, false);
 
1857
 
 
1858
exit:
 
1859
  pthread_mutex_lock(&LOCK_lock_db);
 
1860
  /* Remove the databases from db lock cache */
 
1861
  lock_db_delete(old_db->str, old_db->length);
 
1862
  lock_db_delete(new_db.str, new_db.length);
 
1863
  creating_database--;
 
1864
  /* Signal waiting CREATE TABLE's to continue */
 
1865
  pthread_cond_signal(&COND_refresh);
 
1866
  pthread_mutex_unlock(&LOCK_lock_db);
 
1867
 
 
1868
  return(error);
 
1869
}
 
1870
 
 
1871
 
 
1872
 
1419
1873
/*
1420
1874
  Check if there is directory for the database name.
1421
1875
 
1431
1885
bool check_db_dir_existence(const char *db_name)
1432
1886
{
1433
1887
  char db_dir_path[FN_REFLEN];
1434
 
  uint32_t db_dir_path_len;
 
1888
  uint db_dir_path_len;
1435
1889
 
1436
1890
  db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path),
1437
1891
                                        db_name, "", "", 0);