1/*
2 Copyright (c) 2000, 2014, Oracle and/or its affiliates.
3 Copyright (c) 2009, 2016, MariaDB Corporation
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17
18
19/* create and drop of databases */
20
21#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
22#include "sql_priv.h"
23#include "unireg.h"
24#include "sql_db.h"
25#include "sql_cache.h" // query_cache_*
26#include "lock.h" // lock_schema_name
27#include "sql_table.h" // build_table_filename,
28 // filename_to_tablename
29#include "sql_rename.h" // mysql_rename_tables
30#include "sql_acl.h" // SELECT_ACL, DB_ACLS,
31 // acl_get, check_grant_db
32#include "log_event.h" // Query_log_event
33#include "sql_base.h" // lock_table_names, tdc_remove_table
34#include "sql_handler.h" // mysql_ha_rm_tables
35#include "sql_class.h"
36#include <mysys_err.h>
37#include "sp_head.h"
38#include "sp.h"
39#include "events.h"
40#include "sql_handler.h"
41#include "sql_statistics.h"
42#include <my_dir.h>
43#include <m_ctype.h>
44#include "log.h"
45#ifdef __WIN__
46#include <direct.h>
47#endif
48#include "debug_sync.h"
49
50#define MAX_DROP_TABLE_Q_LEN 1024
51
52const char *del_exts[]= {".BAK", ".opt", NullS};
53static TYPELIB deletable_extentions=
54{array_elements(del_exts)-1,"del_exts", del_exts, NULL};
55
56static bool find_db_tables_and_rm_known_files(THD *, MY_DIR *, const char *,
57 const char *, TABLE_LIST **);
58
59long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
60static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
61static void mysql_change_db_impl(THD *thd,
62 LEX_CSTRING *new_db_name,
63 ulong new_db_access,
64 CHARSET_INFO *new_db_charset);
65static bool mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db,
66 bool if_exists, bool silent);
67
68
69/* Database options hash */
70static HASH dboptions;
71static my_bool dboptions_init= 0;
72static mysql_rwlock_t LOCK_dboptions;
73
74/* Structure for database options */
75typedef struct my_dbopt_st
76{
77 char *name; /* Database name */
78 uint name_length; /* Database length name */
79 CHARSET_INFO *charset; /* Database default character set */
80} my_dbopt_t;
81
82
83/**
84 Return TRUE if db1_name is equal to db2_name, FALSE otherwise.
85
86 The function allows to compare database names according to the MariaDB
87 rules. The database names db1 and db2 are equal if:
88 - db1 is NULL and db2 is NULL;
89 or
90 - db1 is not-NULL, db2 is not-NULL, db1 is equal to db2 in
91 table_alias_charset
92
93 This is the same rules as we use for filenames.
94*/
95
96static inline bool
97cmp_db_names(LEX_CSTRING *db1_name, const LEX_CSTRING *db2_name)
98{
99 return (db1_name->length == db2_name->length &&
100 (db1_name->length == 0 ||
101 my_strcasecmp(table_alias_charset,
102 db1_name->str, db2_name->str) == 0));
103}
104
105
106/*
107 Function we use in the creation of our hash to get key.
108*/
109
110extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
111 my_bool not_used);
112
113uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
114 my_bool not_used __attribute__((unused)))
115{
116 *length= opt->name_length;
117 return (uchar*) opt->name;
118}
119
120
121/*
122 Helper function to write a query to binlog used by mysql_rm_db()
123*/
124
125static inline int write_to_binlog(THD *thd, const char *query, size_t q_len,
126 const char *db, size_t db_len)
127{
128 Query_log_event qinfo(thd, query, q_len, FALSE, TRUE, FALSE, 0);
129 qinfo.db= db;
130 qinfo.db_len= (uint32)db_len;
131 return mysql_bin_log.write(&qinfo);
132}
133
134
135/*
136 Function to free dboptions hash element
137*/
138
139extern "C" void free_dbopt(void *dbopt);
140
141void free_dbopt(void *dbopt)
142{
143 my_free(dbopt);
144}
145
146#ifdef HAVE_PSI_INTERFACE
147static PSI_rwlock_key key_rwlock_LOCK_dboptions;
148
149static PSI_rwlock_info all_database_names_rwlocks[]=
150{
151 { &key_rwlock_LOCK_dboptions, "LOCK_dboptions", PSI_FLAG_GLOBAL}
152};
153
154static void init_database_names_psi_keys(void)
155{
156 const char* category= "sql";
157 int count;
158
159 if (PSI_server == NULL)
160 return;
161
162 count= array_elements(all_database_names_rwlocks);
163 PSI_server->register_rwlock(category, all_database_names_rwlocks, count);
164}
165#endif
166
167/**
168 Initialize database option cache.
169
170 @note Must be called before any other database function is called.
171
172 @retval 0 ok
173 @retval 1 Fatal error
174*/
175
176bool my_dboptions_cache_init(void)
177{
178#ifdef HAVE_PSI_INTERFACE
179 init_database_names_psi_keys();
180#endif
181
182 bool error= 0;
183 mysql_rwlock_init(key_rwlock_LOCK_dboptions, &LOCK_dboptions);
184 if (!dboptions_init)
185 {
186 dboptions_init= 1;
187 error= my_hash_init(&dboptions, table_alias_charset,
188 32, 0, 0, (my_hash_get_key) dboptions_get_key,
189 free_dbopt,0);
190 }
191 return error;
192}
193
194
195
196/**
197 Free database option hash and locked databases hash.
198*/
199
200void my_dboptions_cache_free(void)
201{
202 if (dboptions_init)
203 {
204 dboptions_init= 0;
205 my_hash_free(&dboptions);
206 mysql_rwlock_destroy(&LOCK_dboptions);
207 }
208}
209
210
211/**
212 Cleanup cached options.
213*/
214
215void my_dbopt_cleanup(void)
216{
217 mysql_rwlock_wrlock(&LOCK_dboptions);
218 my_hash_free(&dboptions);
219 my_hash_init(&dboptions, table_alias_charset,
220 32, 0, 0, (my_hash_get_key) dboptions_get_key,
221 free_dbopt,0);
222 mysql_rwlock_unlock(&LOCK_dboptions);
223}
224
225
226/*
227 Find database options in the hash.
228
229 DESCRIPTION
230 Search a database options in the hash, usings its path.
231 Fills "create" on success.
232
233 RETURN VALUES
234 0 on success.
235 1 on error.
236*/
237
238static my_bool get_dbopt(const char *dbname, Schema_specification_st *create)
239{
240 my_dbopt_t *opt;
241 uint length;
242 my_bool error= 1;
243
244 length= (uint) strlen(dbname);
245
246 mysql_rwlock_rdlock(&LOCK_dboptions);
247 if ((opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname, length)))
248 {
249 create->default_table_charset= opt->charset;
250 error= 0;
251 }
252 mysql_rwlock_unlock(&LOCK_dboptions);
253 return error;
254}
255
256
257/*
258 Writes database options into the hash.
259
260 DESCRIPTION
261 Inserts database options into the hash, or updates
262 options if they are already in the hash.
263
264 RETURN VALUES
265 0 on success.
266 1 on error.
267*/
268
269static my_bool put_dbopt(const char *dbname, Schema_specification_st *create)
270{
271 my_dbopt_t *opt;
272 uint length;
273 my_bool error= 0;
274 DBUG_ENTER("put_dbopt");
275
276 length= (uint) strlen(dbname);
277
278 mysql_rwlock_wrlock(&LOCK_dboptions);
279 if (!(opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname,
280 length)))
281 {
282 /* Options are not in the hash, insert them */
283 char *tmp_name;
284 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
285 &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
286 NullS))
287 {
288 error= 1;
289 goto end;
290 }
291
292 opt->name= tmp_name;
293 strmov(opt->name, dbname);
294 opt->name_length= length;
295
296 if (unlikely((error= my_hash_insert(&dboptions, (uchar*) opt))))
297 {
298 my_free(opt);
299 goto end;
300 }
301 }
302
303 /* Update / write options in hash */
304 opt->charset= create->default_table_charset;
305
306end:
307 mysql_rwlock_unlock(&LOCK_dboptions);
308 DBUG_RETURN(error);
309}
310
311
312/*
313 Deletes database options from the hash.
314*/
315
316static void del_dbopt(const char *path)
317{
318 my_dbopt_t *opt;
319 mysql_rwlock_wrlock(&LOCK_dboptions);
320 if ((opt= (my_dbopt_t *)my_hash_search(&dboptions, (const uchar*) path,
321 strlen(path))))
322 my_hash_delete(&dboptions, (uchar*) opt);
323 mysql_rwlock_unlock(&LOCK_dboptions);
324}
325
326
327/*
328 Create database options file:
329
330 DESCRIPTION
331 Currently database default charset is only stored there.
332
333 RETURN VALUES
334 0 ok
335 1 Could not create file or write to it. Error sent through my_error()
336*/
337
338static bool write_db_opt(THD *thd, const char *path,
339 Schema_specification_st *create)
340{
341 File file;
342 char buf[256]; // Should be enough for one option
343 bool error=1;
344
345 if (!create->default_table_charset)
346 create->default_table_charset= thd->variables.collation_server;
347
348 if (put_dbopt(path, create))
349 return 1;
350
351 if ((file= mysql_file_create(key_file_dbopt, path, CREATE_MODE,
352 O_RDWR | O_TRUNC, MYF(MY_WME))) >= 0)
353 {
354 ulong length;
355 length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=",
356 create->default_table_charset->csname,
357 "\ndefault-collation=",
358 create->default_table_charset->name,
359 "\n", NullS) - buf);
360
361 /* Error is written by mysql_file_write */
362 if (!mysql_file_write(file, (uchar*) buf, length, MYF(MY_NABP+MY_WME)))
363 error=0;
364 mysql_file_close(file, MYF(0));
365 }
366 return error;
367}
368
369
370/*
371 Load database options file
372
373 load_db_opt()
374 path Path for option file
375 create Where to store the read options
376
377 DESCRIPTION
378
379 RETURN VALUES
380 0 File found
381 1 No database file or could not open it
382
383*/
384
385bool load_db_opt(THD *thd, const char *path, Schema_specification_st *create)
386{
387 File file;
388 char buf[256];
389 DBUG_ENTER("load_db_opt");
390 bool error=1;
391 size_t nbytes;
392
393 bzero((char*) create,sizeof(*create));
394 create->default_table_charset= thd->variables.collation_server;
395
396 /* Check if options for this database are already in the hash */
397 if (!get_dbopt(path, create))
398 DBUG_RETURN(0);
399
400 /* Otherwise, load options from the .opt file */
401 if ((file= mysql_file_open(key_file_dbopt,
402 path, O_RDONLY | O_SHARE, MYF(0))) < 0)
403 goto err1;
404
405 IO_CACHE cache;
406 if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
407 goto err2;
408
409 while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
410 {
411 char *pos= buf+nbytes-1;
412 /* Remove end space and control characters */
413 while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
414 pos--;
415 *pos=0;
416 if ((pos= strchr(buf, '=')))
417 {
418 if (!strncmp(buf,"default-character-set", (pos-buf)))
419 {
420 /*
421 Try character set name, and if it fails
422 try collation name, probably it's an old
423 4.1.0 db.opt file, which didn't have
424 separate default-character-set and
425 default-collation commands.
426 */
427 if (!(create->default_table_charset=
428 get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
429 !(create->default_table_charset=
430 get_charset_by_name(pos+1, MYF(0))))
431 {
432 sql_print_error("Error while loading database options: '%s':",path);
433 sql_print_error(ER_THD(thd, ER_UNKNOWN_CHARACTER_SET),pos+1);
434 create->default_table_charset= default_charset_info;
435 }
436 }
437 else if (!strncmp(buf,"default-collation", (pos-buf)))
438 {
439 if (!(create->default_table_charset= get_charset_by_name(pos+1,
440 MYF(0))))
441 {
442 sql_print_error("Error while loading database options: '%s':",path);
443 sql_print_error(ER_THD(thd, ER_UNKNOWN_COLLATION),pos+1);
444 create->default_table_charset= default_charset_info;
445 }
446 }
447 }
448 }
449 /*
450 Put the loaded value into the hash.
451 Note that another thread could've added the same
452 entry to the hash after we called get_dbopt(),
453 but it's not an error, as put_dbopt() takes this
454 possibility into account.
455 */
456 error= put_dbopt(path, create);
457
458 end_io_cache(&cache);
459err2:
460 mysql_file_close(file, MYF(0));
461err1:
462 DBUG_RETURN(error);
463}
464
465
466/*
467 Retrieve database options by name. Load database options file or fetch from
468 cache.
469
470 SYNOPSIS
471 load_db_opt_by_name()
472 db_name Database name
473 db_create_info Where to store the database options
474
475 DESCRIPTION
476 load_db_opt_by_name() is a shortcut for load_db_opt().
477
478 NOTE
479 Although load_db_opt_by_name() (and load_db_opt()) returns status of
480 the operation, it is useless usually and should be ignored. The problem
481 is that there are 1) system databases ("mysql") and 2) virtual
482 databases ("information_schema"), which do not contain options file.
483 So, load_db_opt[_by_name]() returns FALSE for these databases, but this
484 is not an error.
485
486 load_db_opt[_by_name]() clears db_create_info structure in any case, so
487 even on failure it contains valid data. So, common use case is just
488 call load_db_opt[_by_name]() without checking return value and use
489 db_create_info right after that.
490
491 RETURN VALUES (read NOTE!)
492 FALSE Success
493 TRUE Failed to retrieve options
494*/
495
496bool load_db_opt_by_name(THD *thd, const char *db_name,
497 Schema_specification_st *db_create_info)
498{
499 char db_opt_path[FN_REFLEN + 1];
500
501 /*
502 Pass an empty file name, and the database options file name as extension
503 to avoid table name to file name encoding.
504 */
505 (void) build_table_filename(db_opt_path, sizeof(db_opt_path) - 1,
506 db_name, "", MY_DB_OPT_FILE, 0);
507
508 return load_db_opt(thd, db_opt_path, db_create_info);
509}
510
511
512/**
513 Return default database collation.
514
515 @param thd Thread context.
516 @param db_name Database name.
517
518 @return CHARSET_INFO object. The operation always return valid character
519 set, even if the database does not exist.
520*/
521
522CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
523{
524 Schema_specification_st db_info;
525
526 if (thd->db.str != NULL && strcmp(db_name, thd->db.str) == 0)
527 return thd->db_charset;
528
529 load_db_opt_by_name(thd, db_name, &db_info);
530
531 /*
532 NOTE: even if load_db_opt_by_name() fails,
533 db_info.default_table_charset contains valid character set
534 (collation_server). We should not fail if load_db_opt_by_name() fails,
535 because it is valid case. If a database has been created just by
536 "mkdir", it does not contain db.opt file, but it is valid database.
537 */
538
539 return db_info.default_table_charset;
540}
541
542
543/*
544 Create a database
545
546 SYNOPSIS
547 mysql_create_db_iternal()
548 thd Thread handler
549 db Name of database to create
550 Function assumes that this is already validated.
551 options DDL options, e.g. IF NOT EXISTS
552 create_info Database create options (like character set)
553 silent Used by replication when internally creating a database.
554 In this case the entry should not be logged.
555
556 SIDE-EFFECTS
557 1. Report back to client that command succeeded (my_ok)
558 2. Report errors to client
559 3. Log event to binary log
560 (The 'silent' flags turns off 1 and 3.)
561
562 RETURN VALUES
563 FALSE ok
564 TRUE Error
565
566*/
567
568static int
569mysql_create_db_internal(THD *thd, const LEX_CSTRING *db,
570 const DDL_options_st &options,
571 Schema_specification_st *create_info,
572 bool silent)
573{
574 char path[FN_REFLEN+16];
575 MY_STAT stat_info;
576 uint path_len;
577 DBUG_ENTER("mysql_create_db");
578
579 /* do not create 'information_schema' db */
580 if (is_infoschema_db(db))
581 {
582 my_error(ER_DB_CREATE_EXISTS, MYF(0), db->str);
583 DBUG_RETURN(-1);
584 }
585
586 char db_tmp[SAFE_NAME_LEN+1];
587 const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
588
589 if (lock_schema_name(thd, dbnorm))
590 DBUG_RETURN(-1);
591
592 /* Check directory */
593 path_len= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
594 path[path_len-1]= 0; // Remove last '/' from path
595
596 long affected_rows= 1;
597 if (!mysql_file_stat(key_file_misc, path, &stat_info, MYF(0)))
598 {
599 // The database directory does not exist, or my_file_stat() failed
600 if (my_errno != ENOENT)
601 {
602 my_error(EE_STAT, MYF(0), path, my_errno);
603 DBUG_RETURN(1);
604 }
605 }
606 else if (options.or_replace())
607 {
608 if (mysql_rm_db_internal(thd, db, 0, true)) // Removing the old database
609 DBUG_RETURN(1);
610 /*
611 Reset the diagnostics m_status.
612 It might be set ot DA_OK in mysql_rm_db.
613 */
614 thd->get_stmt_da()->reset_diagnostics_area();
615 affected_rows= 2;
616 }
617 else if (options.if_not_exists())
618 {
619 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
620 ER_DB_CREATE_EXISTS, ER_THD(thd, ER_DB_CREATE_EXISTS),
621 db->str);
622 affected_rows= 0;
623 goto not_silent;
624 }
625 else
626 {
627 my_error(ER_DB_CREATE_EXISTS, MYF(0), db->str);
628 DBUG_RETURN(-1);
629 }
630
631
632 if (my_mkdir(path, 0777, MYF(0)) < 0)
633 {
634 my_error(ER_CANT_CREATE_DB, MYF(0), db->str, my_errno);
635 DBUG_RETURN(-1);
636 }
637
638 path[path_len-1]= FN_LIBCHAR;
639 strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
640 if (write_db_opt(thd, path, create_info))
641 {
642 /*
643 Could not create options file.
644 Restore things to beginning.
645 */
646 path[path_len]= 0;
647 if (rmdir(path) >= 0)
648 DBUG_RETURN(-1);
649 /*
650 We come here when we managed to create the database, but not the option
651 file. In this case it's best to just continue as if nothing has
652 happened. (This is a very unlikely senario)
653 */
654 thd->clear_error();
655 }
656
657not_silent:
658 if (!silent)
659 {
660 char *query;
661 uint query_length;
662
663 query= thd->query();
664 query_length= thd->query_length();
665 DBUG_ASSERT(query);
666
667 if (mysql_bin_log.is_open())
668 {
669 int errcode= query_error_code(thd, TRUE);
670 Query_log_event qinfo(thd, query, query_length, FALSE, TRUE,
671 /* suppress_use */ TRUE, errcode);
672
673 /*
674 Write should use the database being created as the "current
675 database" and not the threads current database, which is the
676 default. If we do not change the "current database" to the
677 database being created, the CREATE statement will not be
678 replicated when using --binlog-do-db to select databases to be
679 replicated.
680
681 An example (--binlog-do-db=sisyfos):
682
683 CREATE DATABASE bob; # Not replicated
684 USE bob; # 'bob' is the current database
685 CREATE DATABASE sisyfos; # Not replicated since 'bob' is
686 # current database.
687 USE sisyfos; # Will give error on slave since
688 # database does not exist.
689 */
690 qinfo.db = db->str;
691 qinfo.db_len = (uint32)db->length;
692
693 /*
694 These DDL methods and logging are protected with the exclusive
695 metadata lock on the schema
696 */
697 if (mysql_bin_log.write(&qinfo))
698 DBUG_RETURN(-1);
699 }
700 my_ok(thd, affected_rows);
701 }
702
703 DBUG_RETURN(0);
704}
705
706
707/* db-name is already validated when we come here */
708
709static bool
710mysql_alter_db_internal(THD *thd, const LEX_CSTRING *db,
711 Schema_specification_st *create_info)
712{
713 char path[FN_REFLEN+16];
714 long result=1;
715 int error= 0;
716 DBUG_ENTER("mysql_alter_db");
717
718 if (lock_schema_name(thd, db->str))
719 DBUG_RETURN(TRUE);
720
721 /*
722 Recreate db options file: /dbpath/.db.opt
723 We pass MY_DB_OPT_FILE as "extension" to avoid
724 "table name to file name" encoding.
725 */
726 build_table_filename(path, sizeof(path) - 1, db->str, "", MY_DB_OPT_FILE, 0);
727 if (unlikely((error=write_db_opt(thd, path, create_info))))
728 goto exit;
729
730 /* Change options if current database is being altered. */
731
732 if (thd->db.str && !cmp(&thd->db, db))
733 {
734 thd->db_charset= create_info->default_table_charset ?
735 create_info->default_table_charset :
736 thd->variables.collation_server;
737 thd->variables.collation_database= thd->db_charset;
738 }
739
740 if (mysql_bin_log.is_open())
741 {
742 int errcode= query_error_code(thd, TRUE);
743 Query_log_event qinfo(thd, thd->query(), thd->query_length(), FALSE, TRUE,
744 /* suppress_use */ TRUE, errcode);
745 /*
746 Write should use the database being created as the "current
747 database" and not the threads current database, which is the
748 default.
749 */
750 qinfo.db= db->str;
751 qinfo.db_len= (uint)db->length;
752
753 /*
754 These DDL methods and logging are protected with the exclusive
755 metadata lock on the schema.
756 */
757 if (unlikely((error= mysql_bin_log.write(&qinfo))))
758 goto exit;
759 }
760 my_ok(thd, result);
761
762exit:
763 DBUG_RETURN(error);
764}
765
766
767int mysql_create_db(THD *thd, const LEX_CSTRING *db,
768 const DDL_options_st &options,
769 const Schema_specification_st *create_info)
770{
771 /*
772 As mysql_create_db_internal() may modify Db_create_info structure passed
773 to it, we need to use a copy to make execution prepared statement- safe.
774 */
775 Schema_specification_st tmp(*create_info);
776 return mysql_create_db_internal(thd, db, options, &tmp, false);
777}
778
779
780bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
781 const Schema_specification_st *create_info)
782{
783 /*
784 As mysql_alter_db_internal() may modify Db_create_info structure passed
785 to it, we need to use a copy to make execution prepared statement- safe.
786 */
787 Schema_specification_st tmp(*create_info);
788 return mysql_alter_db_internal(thd, db, &tmp);
789}
790
791
792/**
793 Drop all tables, routines and events in a database and the database itself.
794
795 @param thd Thread handle
796 @param db Database name in the case given by user
797 It's already validated and set to lower case
798 (if needed) when we come here
799 @param if_exists Don't give error if database doesn't exists
800 @param silent Don't write the statement to the binary log and don't
801 send ok packet to the client
802
803 @retval false OK (Database dropped)
804 @retval true Error
805*/
806
807static bool
808mysql_rm_db_internal(THD *thd, const LEX_CSTRING *db, bool if_exists, bool silent)
809{
810 ulong deleted_tables= 0;
811 bool error= true, rm_mysql_schema;
812 char path[FN_REFLEN + 16];
813 MY_DIR *dirp;
814 uint length;
815 TABLE_LIST *tables= NULL;
816 TABLE_LIST *table;
817 Drop_table_error_handler err_handler;
818 DBUG_ENTER("mysql_rm_db");
819
820 char db_tmp[SAFE_NAME_LEN+1];
821 const char *dbnorm= normalize_db_name(db->str, db_tmp, sizeof(db_tmp));
822
823 if (lock_schema_name(thd, dbnorm))
824 DBUG_RETURN(true);
825
826 length= build_table_filename(path, sizeof(path) - 1, db->str, "", "", 0);
827 strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
828 del_dbopt(path); // Remove dboption hash entry
829 /*
830 Now remove the db.opt file.
831 The 'find_db_tables_and_rm_known_files' doesn't remove this file
832 if there exists a table with the name 'db', so let's just do it
833 separately. We know this file exists and needs to be deleted anyway.
834 */
835 if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
836 my_errno != ENOENT)
837 {
838 my_error(EE_DELETE, MYF(0), path, my_errno);
839 DBUG_RETURN(true);
840 }
841
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 my_error(ER_DB_DROP_EXISTS, MYF(0), db->str);
850 DBUG_RETURN(true);
851 }
852 else
853 {
854 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
855 ER_DB_DROP_EXISTS, ER_THD(thd, ER_DB_DROP_EXISTS),
856 db->str);
857 error= false;
858 goto update_binlog;
859 }
860 }
861
862 if (find_db_tables_and_rm_known_files(thd, dirp, dbnorm, path, &tables))
863 goto exit;
864
865 /*
866 Disable drop of enabled log tables, must be done before name locking.
867 This check is only needed if we are dropping the "mysql" database.
868 */
869 if ((rm_mysql_schema=
870 (my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db->str) == 0)))
871 {
872 for (table= tables; table; table= table->next_local)
873 if (check_if_log_table(table, TRUE, "DROP"))
874 goto exit;
875 }
876
877 /* Lock all tables and stored routines about to be dropped. */
878 if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout,
879 0) ||
880 lock_db_routines(thd, dbnorm))
881 goto exit;
882
883 if (!in_bootstrap && !rm_mysql_schema)
884 {
885 for (table= tables; table; table= table->next_local)
886 {
887 if (table->open_type == OT_BASE_ONLY ||
888 !thd->find_temporary_table(table))
889 (void) delete_statistics_for_table(thd, &table->db, &table->table_name);
890 }
891 }
892
893 /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */
894 if (tables)
895 mysql_ha_rm_tables(thd, tables);
896
897 for (table= tables; table; table= table->next_local)
898 deleted_tables++;
899
900 thd->push_internal_handler(&err_handler);
901 if (!thd->killed &&
902 !(tables &&
903 mysql_rm_table_no_locks(thd, tables, true, false, true, false, true,
904 false)))
905 {
906 /*
907 We temporarily disable the binary log while dropping the objects
908 in the database. Since the DROP DATABASE statement is always
909 replicated as a statement, execution of it will drop all objects
910 in the database on the slave as well, so there is no need to
911 replicate the removal of the individual objects in the database
912 as well.
913
914 This is more of a safety precaution, since normally no objects
915 should be dropped while the database is being cleaned, but in
916 the event that a change in the code to remove other objects is
917 made, these drops should still not be logged.
918 */
919
920 ha_drop_database(path);
921 tmp_disable_binlog(thd);
922 query_cache_invalidate1(thd, dbnorm);
923 if (!rm_mysql_schema)
924 {
925 (void) sp_drop_db_routines(thd, dbnorm); /* @todo Do not ignore errors */
926#ifdef HAVE_EVENT_SCHEDULER
927 Events::drop_schema_events(thd, dbnorm);
928#endif
929 }
930 reenable_binlog(thd);
931
932 /*
933 If the directory is a symbolic link, remove the link first, then
934 remove the directory the symbolic link pointed at
935 */
936 error= rm_dir_w_symlink(path, true);
937 }
938 thd->pop_internal_handler();
939
940update_binlog:
941 if (!silent && likely(!error))
942 {
943 const char *query;
944 ulong query_length;
945
946 query= thd->query();
947 query_length= thd->query_length();
948 DBUG_ASSERT(query);
949
950 if (mysql_bin_log.is_open())
951 {
952 int errcode= query_error_code(thd, TRUE);
953 Query_log_event qinfo(thd, query, query_length, FALSE, TRUE,
954 /* suppress_use */ TRUE, errcode);
955 /*
956 Write should use the database being created as the "current
957 database" and not the threads current database, which is the
958 default.
959 */
960 qinfo.db = db->str;
961 qinfo.db_len = (uint32)db->length;
962
963 /*
964 These DDL methods and logging are protected with the exclusive
965 metadata lock on the schema.
966 */
967 if (mysql_bin_log.write(&qinfo))
968 {
969 error= true;
970 goto exit;
971 }
972 }
973 thd->clear_error();
974 thd->server_status|= SERVER_STATUS_DB_DROPPED;
975 my_ok(thd, deleted_tables);
976 }
977 else if (mysql_bin_log.is_open() && !silent)
978 {
979 char *query, *query_pos, *query_end, *query_data_start;
980 TABLE_LIST *tbl;
981
982 if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
983 goto exit; /* not much else we can do */
984 query_pos= query_data_start= strmov(query,"DROP TABLE IF EXISTS ");
985 query_end= query + MAX_DROP_TABLE_Q_LEN;
986
987 for (tbl= tables; tbl; tbl= tbl->next_local)
988 {
989 size_t tbl_name_len;
990 char quoted_name[FN_REFLEN+3];
991
992 // Only write drop table to the binlog for tables that no longer exist.
993 if (ha_table_exists(thd, &tbl->db, &tbl->table_name))
994 continue;
995
996 tbl_name_len= my_snprintf(quoted_name, sizeof(quoted_name), "%`s",
997 tbl->table_name.str);
998 tbl_name_len++; /* +1 for the comma */
999 if (query_pos + tbl_name_len + 1 >= query_end)
1000 {
1001 /*
1002 These DDL methods and logging are protected with the exclusive
1003 metadata lock on the schema.
1004 */
1005 if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
1006 {
1007 error= true;
1008 goto exit;
1009 }
1010 query_pos= query_data_start;
1011 }
1012
1013 query_pos= strmov(query_pos, quoted_name);
1014 *query_pos++ = ',';
1015 }
1016
1017 if (query_pos != query_data_start)
1018 {
1019 /*
1020 These DDL methods and logging are protected with the exclusive
1021 metadata lock on the schema.
1022 */
1023 if (write_to_binlog(thd, query, (uint)(query_pos -1 - query), db->str, db->length))
1024 {
1025 error= true;
1026 goto exit;
1027 }
1028 }
1029 }
1030
1031exit:
1032 /*
1033 If this database was the client's selected database, we silently
1034 change the client's selected database to nothing (to have an empty
1035 SELECT DATABASE() in the future). For this we free() thd->db and set
1036 it to 0.
1037 */
1038 if (unlikely(thd->db.str && cmp_db_names(&thd->db, db) && !error))
1039 {
1040 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1041 SESSION_TRACKER_CHANGED(thd, CURRENT_SCHEMA_TRACKER, NULL);
1042 }
1043 my_dirend(dirp);
1044 DBUG_RETURN(error);
1045}
1046
1047
1048bool mysql_rm_db(THD *thd, const LEX_CSTRING *db, bool if_exists)
1049{
1050 return mysql_rm_db_internal(thd, db, if_exists, false);
1051}
1052
1053
1054static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
1055 const char *dbname,
1056 const char *path,
1057 TABLE_LIST **tables)
1058{
1059 char filePath[FN_REFLEN];
1060 LEX_CSTRING db= { dbname, strlen(dbname) };
1061 TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global;
1062 DBUG_ENTER("find_db_tables_and_rm_known_files");
1063 DBUG_PRINT("enter",("path: %s", path));
1064
1065 /* first, get the list of tables */
1066 Dynamic_array<LEX_CSTRING*> files(dirp->number_of_files);
1067 Discovered_table_list tl(thd, &files);
1068 if (ha_discover_table_names(thd, &db, dirp, &tl, true))
1069 DBUG_RETURN(1);
1070
1071 /* Now put the tables in the list */
1072 tot_list_next_local= tot_list_next_global= &tot_list;
1073
1074 for (size_t idx=0; idx < files.elements(); idx++)
1075 {
1076 LEX_CSTRING *table= files.at(idx);
1077
1078 /* Drop the table nicely */
1079 TABLE_LIST *table_list=(TABLE_LIST*)thd->calloc(sizeof(*table_list));
1080
1081 if (!table_list)
1082 DBUG_RETURN(true);
1083 table_list->db= db;
1084 table_list->table_name= *table;
1085 table_list->open_type= OT_BASE_ONLY;
1086
1087 /* To be able to correctly look up the table in the table cache. */
1088 if (lower_case_table_names)
1089 table_list->table_name.length= my_casedn_str(files_charset_info,
1090 (char*) table_list->table_name.str);
1091
1092 table_list->alias= table_list->table_name; // If lower_case_table_names=2
1093 table_list->mdl_request.init(MDL_key::TABLE, table_list->db.str,
1094 table_list->table_name.str, MDL_EXCLUSIVE,
1095 MDL_TRANSACTION);
1096 /* Link into list */
1097 (*tot_list_next_local)= table_list;
1098 (*tot_list_next_global)= table_list;
1099 tot_list_next_local= &table_list->next_local;
1100 tot_list_next_global= &table_list->next_global;
1101 }
1102 *tables= tot_list;
1103
1104 /* and at last delete all non-table files */
1105 for (uint idx=0 ;
1106 idx < (uint) dirp->number_of_files && !thd->killed ;
1107 idx++)
1108 {
1109 FILEINFO *file=dirp->dir_entry+idx;
1110 char *extension;
1111 DBUG_PRINT("info",("Examining: %s", file->name));
1112
1113 if (file->name[0] == 'a' && file->name[1] == 'r' &&
1114 file->name[2] == 'c' && file->name[3] == '\0')
1115 {
1116 /* .frm archive:
1117 Those archives are obsolete, but following code should
1118 exist to remove existent "arc" directories.
1119 */
1120 char newpath[FN_REFLEN];
1121 MY_DIR *new_dirp;
1122 strxmov(newpath, path, "/", "arc", NullS);
1123 (void) unpack_filename(newpath, newpath);
1124 if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
1125 {
1126 DBUG_PRINT("my",("Archive subdir found: %s", newpath));
1127 if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
1128 DBUG_RETURN(true);
1129 }
1130 continue;
1131 }
1132 if (!(extension= strrchr(file->name, '.')))
1133 extension= strend(file->name);
1134 if (find_type(extension, &deletable_extentions, FIND_TYPE_NO_PREFIX) > 0)
1135 {
1136 strxmov(filePath, path, "/", file->name, NullS);
1137 /*
1138 We ignore ENOENT error in order to skip files that was deleted
1139 by concurrently running statement like REPAIR TABLE ...
1140 */
1141 if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(0)) &&
1142 my_errno != ENOENT)
1143 {
1144 my_error(EE_DELETE, MYF(0), filePath, my_errno);
1145 DBUG_RETURN(true);
1146 }
1147 }
1148 }
1149
1150 DBUG_RETURN(false);
1151}
1152
1153
1154/*
1155 Remove directory with symlink
1156
1157 SYNOPSIS
1158 rm_dir_w_symlink()
1159 org_path path of derictory
1160 send_error send errors
1161 RETURN
1162 0 OK
1163 1 ERROR
1164*/
1165
1166static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
1167{
1168 char tmp_path[FN_REFLEN], *pos;
1169 char *path= tmp_path;
1170 DBUG_ENTER("rm_dir_w_symlink");
1171 unpack_filename(tmp_path, org_path);
1172#ifdef HAVE_READLINK
1173 int error;
1174 char tmp2_path[FN_REFLEN];
1175
1176 /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1177 pos= strend(path);
1178 if (pos > path && pos[-1] == FN_LIBCHAR)
1179 *--pos=0;
1180
1181 if (unlikely((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0))
1182 DBUG_RETURN(1);
1183 if (likely(!error))
1184 {
1185 if (mysql_file_delete(key_file_misc, path, MYF(send_error ? MY_WME : 0)))
1186 {
1187 DBUG_RETURN(send_error);
1188 }
1189 /* Delete directory symbolic link pointed at */
1190 path= tmp2_path;
1191 }
1192#endif
1193 /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1194 pos= strend(path);
1195
1196 if (pos > path && pos[-1] == FN_LIBCHAR)
1197 *--pos=0;
1198 if (unlikely(rmdir(path) < 0 && send_error))
1199 {
1200 my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1201 DBUG_RETURN(1);
1202 }
1203 DBUG_RETURN(0);
1204}
1205
1206
1207/*
1208 Remove .frm archives from directory
1209
1210 SYNOPSIS
1211 thd thread handler
1212 dirp list of files in archive directory
1213 db data base name
1214 org_path path of archive directory
1215
1216 RETURN
1217 > 0 number of removed files
1218 -1 error
1219
1220 NOTE
1221 A support of "arc" directories is obsolete, however this
1222 function should exist to remove existent "arc" directories.
1223*/
1224long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path)
1225{
1226 long deleted= 0;
1227 ulong found_other_files= 0;
1228 char filePath[FN_REFLEN];
1229 DBUG_ENTER("mysql_rm_arc_files");
1230 DBUG_PRINT("enter", ("path: %s", org_path));
1231
1232 for (uint idx=0 ;
1233 idx < (uint) dirp->number_of_files && !thd->killed ;
1234 idx++)
1235 {
1236 FILEINFO *file=dirp->dir_entry+idx;
1237 char *extension, *revision;
1238 DBUG_PRINT("info",("Examining: %s", file->name));
1239
1240 extension= fn_ext(file->name);
1241 if (extension[0] != '.' ||
1242 extension[1] != 'f' || extension[2] != 'r' ||
1243 extension[3] != 'm' || extension[4] != '-')
1244 {
1245 found_other_files++;
1246 continue;
1247 }
1248 revision= extension+5;
1249 while (*revision && my_isdigit(system_charset_info, *revision))
1250 revision++;
1251 if (*revision)
1252 {
1253 found_other_files++;
1254 continue;
1255 }
1256 strxmov(filePath, org_path, "/", file->name, NullS);
1257 if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(MY_WME)))
1258 {
1259 goto err;
1260 }
1261 deleted++;
1262 }
1263 if (thd->killed)
1264 goto err;
1265
1266 my_dirend(dirp);
1267
1268 /*
1269 If the directory is a symbolic link, remove the link first, then
1270 remove the directory the symbolic link pointed at
1271 */
1272 if (!found_other_files &&
1273 rm_dir_w_symlink(org_path, 0))
1274 DBUG_RETURN(-1);
1275 DBUG_RETURN(deleted);
1276
1277err:
1278 my_dirend(dirp);
1279 DBUG_RETURN(-1);
1280}
1281
1282
1283/**
1284 @brief Internal implementation: switch current database to a valid one.
1285
1286 @param thd Thread context.
1287 @param new_db_name Name of the database to switch to. The function will
1288 take ownership of the name (the caller must not free
1289 the allocated memory). If the name is NULL, we're
1290 going to switch to NULL db.
1291 @param new_db_access Privileges of the new database.
1292 @param new_db_charset Character set of the new database.
1293*/
1294
1295static void mysql_change_db_impl(THD *thd,
1296 LEX_CSTRING *new_db_name,
1297 ulong new_db_access,
1298 CHARSET_INFO *new_db_charset)
1299{
1300 /* 1. Change current database in THD. */
1301
1302 if (new_db_name == NULL)
1303 {
1304 /*
1305 THD::set_db() does all the job -- it frees previous database name and
1306 sets the new one.
1307 */
1308
1309 thd->set_db(&null_clex_str);
1310 }
1311 else if (new_db_name->str == INFORMATION_SCHEMA_NAME.str)
1312 {
1313 /*
1314 Here we must use THD::set_db(), because we want to copy
1315 INFORMATION_SCHEMA_NAME constant.
1316 */
1317
1318 thd->set_db(&INFORMATION_SCHEMA_NAME);
1319 }
1320 else
1321 {
1322 /*
1323 Here we already have a copy of database name to be used in THD. So,
1324 we just call THD::reset_db(). Since THD::reset_db() does not releases
1325 the previous database name, we should do it explicitly.
1326 */
1327 thd->set_db(&null_clex_str);
1328 thd->reset_db(new_db_name);
1329 }
1330
1331 /* 2. Update security context. */
1332
1333#ifndef NO_EMBEDDED_ACCESS_CHECKS
1334 thd->security_ctx->db_access= new_db_access;
1335#endif
1336
1337 /* 3. Update db-charset environment variables. */
1338
1339 thd->db_charset= new_db_charset;
1340 thd->variables.collation_database= new_db_charset;
1341}
1342
1343
1344
1345/**
1346 Backup the current database name before switch.
1347
1348 @param[in] thd thread handle
1349 @param[in, out] saved_db_name IN: "str" points to a buffer where to store
1350 the old database name, "length" contains the
1351 buffer size
1352 OUT: if the current (default) database is
1353 not NULL, its name is copied to the
1354 buffer pointed at by "str"
1355 and "length" is updated accordingly.
1356 Otherwise "str" is set to NULL and
1357 "length" is set to 0.
1358*/
1359
1360static void backup_current_db_name(THD *thd,
1361 LEX_STRING *saved_db_name)
1362{
1363 DBUG_ASSERT(saved_db_name->length >= SAFE_NAME_LEN +1);
1364 if (!thd->db.str)
1365 {
1366 /* No current (default) database selected. */
1367 saved_db_name->str= 0;
1368 saved_db_name->length= 0;
1369 }
1370 else
1371 {
1372 memcpy(saved_db_name->str, thd->db.str, thd->db.length + 1);
1373 saved_db_name->length= thd->db.length;
1374 }
1375}
1376
1377
1378/**
1379 @brief Change the current database and its attributes unconditionally.
1380
1381 @param thd thread handle
1382 @param new_db_name database name
1383 @param force_switch if force_switch is FALSE, then the operation will fail if
1384
1385 - new_db_name is NULL or empty;
1386
1387 - OR new database name is invalid
1388 (check_db_name() failed);
1389
1390 - OR user has no privilege on the new database;
1391
1392 - OR new database does not exist;
1393
1394 if force_switch is TRUE, then
1395
1396 - if new_db_name is NULL or empty, the current
1397 database will be NULL, @@collation_database will
1398 be set to @@collation_server, the operation will
1399 succeed.
1400
1401 - if new database name is invalid
1402 (check_db_name() failed), the current database
1403 will be NULL, @@collation_database will be set to
1404 @@collation_server, but the operation will fail;
1405
1406 - user privileges will not be checked
1407 (THD::db_access however is updated);
1408
1409 TODO: is this really the intention?
1410 (see sp-security.test).
1411
1412 - if new database does not exist,the current database
1413 will be NULL, @@collation_database will be set to
1414 @@collation_server, a warning will be thrown, the
1415 operation will succeed.
1416
1417 @details The function checks that the database name corresponds to a
1418 valid and existent database, checks access rights and changes the current
1419 database with database attributes (@@collation_database session variable,
1420 THD::db_access).
1421
1422 This function is not the only way to switch the database that is
1423 currently employed. When the replication slave thread switches the
1424 database before executing a query, it calls thd->set_db directly.
1425 However, if the query, in turn, uses a stored routine, the stored routine
1426 will use this function, even if it's run on the slave.
1427
1428 This function allocates the name of the database on the system heap: this
1429 is necessary to be able to uniformly change the database from any module
1430 of the server. Up to 5.0 different modules were using different memory to
1431 store the name of the database, and this led to memory corruption:
1432 a stack pointer set by Stored Procedures was used by replication after
1433 the stack address was long gone.
1434
1435 @return Operation status
1436 @retval FALSE Success
1437 @retval TRUE Error
1438*/
1439
1440bool mysql_change_db(THD *thd, const LEX_CSTRING *new_db_name,
1441 bool force_switch)
1442{
1443 LEX_CSTRING new_db_file_name;
1444
1445 Security_context *sctx= thd->security_ctx;
1446 ulong db_access= sctx->db_access;
1447 CHARSET_INFO *db_default_cl;
1448 DBUG_ENTER("mysql_change_db");
1449
1450 if (new_db_name->length == 0)
1451 {
1452 if (force_switch)
1453 {
1454 /*
1455 This can happen only if we're switching the current database back
1456 after loading stored program. The thing is that loading of stored
1457 program can happen when there is no current database.
1458
1459 In case of stored program, new_db_name->str == "" and
1460 new_db_name->length == 0.
1461 */
1462
1463 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1464
1465 goto done;
1466 }
1467 else
1468 {
1469 my_message(ER_NO_DB_ERROR, ER_THD(thd, ER_NO_DB_ERROR), MYF(0));
1470
1471 DBUG_RETURN(TRUE);
1472 }
1473 }
1474 DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
1475
1476 if (is_infoschema_db(new_db_name))
1477 {
1478 /* Switch the current database to INFORMATION_SCHEMA. */
1479
1480 mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL,
1481 system_charset_info);
1482 goto done;
1483 }
1484
1485 /*
1486 Now we need to make a copy because check_db_name requires a
1487 non-constant argument. Actually, it takes database file name.
1488
1489 TODO: fix check_db_name().
1490 */
1491
1492 new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
1493 MYF(MY_WME));
1494 new_db_file_name.length= new_db_name->length;
1495
1496 if (new_db_file_name.str == NULL)
1497 DBUG_RETURN(TRUE); /* the error is set */
1498
1499 /*
1500 NOTE: if check_db_name() fails, we should throw an error in any case,
1501 even if we are called from sp_head::execute().
1502
1503 It's next to impossible however to get this error when we are called
1504 from sp_head::execute(). But let's switch the current database to NULL
1505 in this case to be sure.
1506 The cast below ok here as new_db_file_name was just allocated
1507 */
1508
1509 if (check_db_name((LEX_STRING*) &new_db_file_name))
1510 {
1511 my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1512 my_free(const_cast<char*>(new_db_file_name.str));
1513
1514 if (force_switch)
1515 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1516
1517 DBUG_RETURN(TRUE);
1518 }
1519
1520 DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
1521
1522#ifndef NO_EMBEDDED_ACCESS_CHECKS
1523 if (test_all_bits(sctx->master_access, DB_ACLS))
1524 db_access= DB_ACLS;
1525 else
1526 {
1527 db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user,
1528 new_db_file_name.str, FALSE) | sctx->master_access;
1529 if (sctx->priv_role[0])
1530 {
1531 /* include a possible currently set role for access */
1532 db_access|= acl_get("", "", sctx->priv_role, new_db_file_name.str, FALSE);
1533 }
1534 }
1535
1536 if (!force_switch &&
1537 !(db_access & DB_ACLS) &&
1538 check_grant_db(thd, new_db_file_name.str))
1539 {
1540 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1541 sctx->priv_user,
1542 sctx->priv_host,
1543 new_db_file_name.str);
1544 general_log_print(thd, COM_INIT_DB, ER_THD(thd, ER_DBACCESS_DENIED_ERROR),
1545 sctx->priv_user, sctx->priv_host, new_db_file_name.str);
1546 my_free(const_cast<char*>(new_db_file_name.str));
1547 DBUG_RETURN(TRUE);
1548 }
1549#endif
1550
1551 DEBUG_SYNC(thd, "before_db_dir_check");
1552
1553 if (check_db_dir_existence(new_db_file_name.str))
1554 {
1555 if (force_switch)
1556 {
1557 /* Throw a warning and free new_db_file_name. */
1558
1559 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
1560 ER_BAD_DB_ERROR, ER_THD(thd, ER_BAD_DB_ERROR),
1561 new_db_file_name.str);
1562
1563 my_free(const_cast<char*>(new_db_file_name.str));
1564
1565 /* Change db to NULL. */
1566
1567 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1568
1569 /* The operation succeed. */
1570 goto done;
1571 }
1572 else
1573 {
1574 /* Report an error and free new_db_file_name. */
1575
1576 my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1577 my_free(const_cast<char*>(new_db_file_name.str));
1578
1579 /* The operation failed. */
1580
1581 DBUG_RETURN(TRUE);
1582 }
1583 }
1584
1585 /*
1586 NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1587 attributes and will be freed in THD::~THD().
1588 */
1589
1590 db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1591
1592 mysql_change_db_impl(thd, &new_db_file_name, db_access, db_default_cl);
1593
1594done:
1595 SESSION_TRACKER_CHANGED(thd, CURRENT_SCHEMA_TRACKER, NULL);
1596 SESSION_TRACKER_CHANGED(thd, SESSION_STATE_CHANGE_TRACKER, NULL);
1597 DBUG_RETURN(FALSE);
1598}
1599
1600
1601/**
1602 Change the current database and its attributes if needed.
1603
1604 @param thd thread handle
1605 @param new_db_name database name
1606 @param[in, out] saved_db_name IN: "str" points to a buffer where to store
1607 the old database name, "length" contains the
1608 buffer size
1609 OUT: if the current (default) database is
1610 not NULL, its name is copied to the
1611 buffer pointed at by "str"
1612 and "length" is updated accordingly.
1613 Otherwise "str" is set to NULL and
1614 "length" is set to 0.
1615 @param force_switch @see mysql_change_db()
1616 @param[out] cur_db_changed out-flag to indicate whether the current
1617 database has been changed (valid only if
1618 the function suceeded)
1619*/
1620
1621bool mysql_opt_change_db(THD *thd,
1622 const LEX_CSTRING *new_db_name,
1623 LEX_STRING *saved_db_name,
1624 bool force_switch,
1625 bool *cur_db_changed)
1626{
1627 *cur_db_changed= !cmp_db_names(&thd->db, new_db_name);
1628
1629 if (!*cur_db_changed)
1630 return FALSE;
1631
1632 backup_current_db_name(thd, saved_db_name);
1633
1634 return mysql_change_db(thd, new_db_name, force_switch);
1635}
1636
1637
1638/**
1639 Upgrade a 5.0 database.
1640 This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1641 ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1642
1643 If we have managed to rename (move) tables to the new database
1644 but something failed on a later step, then we store the
1645 RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1646 the sense that it will rename all or none of the tables.
1647
1648 @param thd Current thread
1649 @param old_db 5.0 database name, in #mysql50#name format
1650 @return 0 on success, 1 on error
1651*/
1652
1653bool mysql_upgrade_db(THD *thd, const LEX_CSTRING *old_db)
1654{
1655 bool error= 0, change_to_newdb= 0;
1656 char path[FN_REFLEN+16];
1657 uint length;
1658 Schema_specification_st create_info;
1659 MY_DIR *dirp;
1660 TABLE_LIST *table_list;
1661 SELECT_LEX *sl= thd->lex->current_select;
1662 LEX_CSTRING new_db;
1663 DBUG_ENTER("mysql_upgrade_db");
1664
1665 if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1666 (strncmp(old_db->str,
1667 MYSQL50_TABLE_NAME_PREFIX,
1668 MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
1669 {
1670 my_error(ER_WRONG_USAGE, MYF(0),
1671 "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1672 "name");
1673 DBUG_RETURN(1);
1674 }
1675
1676 /* `#mysql50#<name>` converted to encoded `<name>` */
1677 new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1678 new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1679
1680 /* Lock the old name, the new name will be locked by mysql_create_db().*/
1681 if (lock_schema_name(thd, old_db->str))
1682 DBUG_RETURN(1);
1683
1684 /*
1685 Let's remember if we should do "USE newdb" afterwards.
1686 thd->db will be cleared in mysql_rename_db()
1687 */
1688 if (thd->db.str && !cmp(&thd->db, old_db))
1689 change_to_newdb= 1;
1690
1691 build_table_filename(path, sizeof(path)-1,
1692 old_db->str, "", MY_DB_OPT_FILE, 0);
1693 if ((load_db_opt(thd, path, &create_info)))
1694 create_info.default_table_charset= thd->variables.collation_server;
1695
1696 length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
1697 if (length && path[length-1] == FN_LIBCHAR)
1698 path[length-1]=0; // remove ending '\'
1699 if (unlikely((error= my_access(path,F_OK))))
1700 {
1701 my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
1702 goto exit;
1703 }
1704
1705 /* Step1: Create the new database */
1706 if (unlikely((error= mysql_create_db_internal(thd, &new_db,
1707 DDL_options(), &create_info,
1708 1))))
1709 goto exit;
1710
1711 /* Step2: Move tables to the new database */
1712 if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1713 {
1714 uint nfiles= (uint) dirp->number_of_files;
1715 for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
1716 {
1717 FILEINFO *file= dirp->dir_entry + idx;
1718 char *extension, tname[FN_REFLEN + 1];
1719 LEX_CSTRING table_str;
1720 DBUG_PRINT("info",("Examining: %s", file->name));
1721
1722 /* skiping non-FRM files */
1723 if (!(extension= (char*) fn_frm_ext(file->name)))
1724 continue;
1725
1726 /* A frm file found, add the table info rename list */
1727 *extension= '\0';
1728
1729 table_str.length= filename_to_tablename(file->name,
1730 tname, sizeof(tname)-1);
1731 table_str.str= (char*) thd->memdup(tname, table_str.length + 1);
1732 Table_ident *old_ident= new Table_ident(thd, old_db, &table_str, 0);
1733 Table_ident *new_ident= new Table_ident(thd, &new_db, &table_str, 0);
1734 if (!old_ident || !new_ident ||
1735 !sl->add_table_to_list(thd, old_ident, NULL,
1736 TL_OPTION_UPDATING, TL_IGNORE,
1737 MDL_EXCLUSIVE) ||
1738 !sl->add_table_to_list(thd, new_ident, NULL,
1739 TL_OPTION_UPDATING, TL_IGNORE,
1740 MDL_EXCLUSIVE))
1741 {
1742 error= 1;
1743 my_dirend(dirp);
1744 goto exit;
1745 }
1746 }
1747 my_dirend(dirp);
1748 }
1749
1750 if ((table_list= thd->lex->query_tables) &&
1751 (error= mysql_rename_tables(thd, table_list, 1)))
1752 {
1753 /*
1754 Failed to move all tables from the old database to the new one.
1755 In the best case mysql_rename_tables() moved all tables back to the old
1756 database. In the worst case mysql_rename_tables() moved some tables
1757 to the new database, then failed, then started to move the tables back,
1758 and then failed again. In this situation we have some tables in the
1759 old database and some tables in the new database.
1760 Let's delete the option file, and then the new database directory.
1761 If some tables were left in the new directory, rmdir() will fail.
1762 It garantees we never loose any tables.
1763 */
1764 build_table_filename(path, sizeof(path)-1,
1765 new_db.str,"",MY_DB_OPT_FILE, 0);
1766 mysql_file_delete(key_file_dbopt, path, MYF(MY_WME));
1767 length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
1768 if (length && path[length-1] == FN_LIBCHAR)
1769 path[length-1]=0; // remove ending '\'
1770 rmdir(path);
1771 goto exit;
1772 }
1773
1774
1775 /*
1776 Step3: move all remaining files to the new db's directory.
1777 Skip db opt file: it's been created by mysql_create_db() in
1778 the new directory, and will be dropped by mysql_rm_db() in the old one.
1779 Trigger TRN and TRG files are be moved as regular files at the moment,
1780 without any special treatment.
1781
1782 Triggers without explicit database qualifiers in table names work fine:
1783 use d1;
1784 create trigger trg1 before insert on t2 for each row set @a:=1
1785 rename database d1 to d2;
1786
1787 TODO: Triggers, having the renamed database explicitly written
1788 in the table qualifiers.
1789 1. when the same database is renamed:
1790 create trigger d1.trg1 before insert on d1.t1 for each row set @a:=1;
1791 rename database d1 to d2;
1792 Problem: After database renaming, the trigger's body
1793 still points to the old database d1.
1794 2. when another database is renamed:
1795 create trigger d3.trg1 before insert on d3.t1 for each row
1796 insert into d1.t1 values (...);
1797 rename database d1 to d2;
1798 Problem: After renaming d1 to d2, the trigger's body
1799 in the database d3 still points to database d1.
1800 */
1801
1802 if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1803 {
1804 uint nfiles= (uint) dirp->number_of_files;
1805 for (uint idx=0 ; idx < nfiles ; idx++)
1806 {
1807 FILEINFO *file= dirp->dir_entry + idx;
1808 char oldname[FN_REFLEN + 1], newname[FN_REFLEN + 1];
1809 DBUG_PRINT("info",("Examining: %s", file->name));
1810
1811 /* skiping MY_DB_OPT_FILE */
1812 if (!my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
1813 continue;
1814
1815 /* pass empty file name, and file->name as extension to avoid encoding */
1816 build_table_filename(oldname, sizeof(oldname)-1,
1817 old_db->str, "", file->name, 0);
1818 build_table_filename(newname, sizeof(newname)-1,
1819 new_db.str, "", file->name, 0);
1820 mysql_file_rename(key_file_misc, oldname, newname, MYF(MY_WME));
1821 }
1822 my_dirend(dirp);
1823 }
1824
1825 /*
1826 Step7: drop the old database.
1827 query_cache_invalidate(olddb) is done inside mysql_rm_db(), no need
1828 to execute them again.
1829 mysql_rm_db() also "unuses" if we drop the current database.
1830 */
1831 error= mysql_rm_db_internal(thd, old_db, 0, true);
1832
1833 /* Step8: logging */
1834 if (mysql_bin_log.is_open())
1835 {
1836 int errcode= query_error_code(thd, TRUE);
1837 Query_log_event qinfo(thd, thd->query(), thd->query_length(),
1838 FALSE, TRUE, TRUE, errcode);
1839 thd->clear_error();
1840 error|= mysql_bin_log.write(&qinfo);
1841 }
1842
1843 /* Step9: Let's do "use newdb" if we renamed the current database */
1844 if (change_to_newdb)
1845 error|= mysql_change_db(thd, & new_db, FALSE);
1846
1847exit:
1848 DBUG_RETURN(error);
1849}
1850
1851
1852
1853/*
1854 Check if there is directory for the database name.
1855
1856 SYNOPSIS
1857 check_db_dir_existence()
1858 db_name database name
1859
1860 RETURN VALUES
1861 FALSE There is directory for the specified database name.
1862 TRUE The directory does not exist.
1863*/
1864
1865bool check_db_dir_existence(const char *db_name)
1866{
1867 char db_dir_path[FN_REFLEN + 1];
1868 uint db_dir_path_len;
1869
1870 db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path) - 1,
1871 db_name, "", "", 0);
1872
1873 if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
1874 db_dir_path[db_dir_path_len - 1]= 0;
1875
1876 /* Check access. */
1877
1878 return my_access(db_dir_path, F_OK);
1879}
1880
1881
1882const char *normalize_db_name(const char *db, char *buffer, size_t buffer_size)
1883{
1884 DBUG_ASSERT(buffer_size > 1);
1885 if (!lower_case_table_names)
1886 return db;
1887 strmake(buffer, db, buffer_size - 1);
1888 my_casedn_str(system_charset_info, buffer);
1889 return buffer;
1890}
1891