~drizzle-trunk/drizzle/development

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