mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / sql / sql_db.cc
blob4ddfad7206edfa757c72ac8e434982a7abcd1b20
1 /*
2 Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 /* create and drop of databases */
21 #include "mysql_priv.h"
22 #include <mysys_err.h>
23 #include "sp.h"
24 #include "events.h"
25 #include <my_dir.h>
26 #include <m_ctype.h>
27 #include "log.h"
28 #include "log_event.h"
29 #ifdef __WIN__
30 #include <direct.h>
31 #endif
32 #include "debug_sync.h"
34 #define MAX_DROP_TABLE_Q_LEN 1024
36 const char *del_exts[]= {".frm", ".BAK", ".TMD",".opt", NullS};
37 static TYPELIB deletable_extentions=
38 {array_elements(del_exts)-1,"del_exts", del_exts, NULL};
40 static long mysql_rm_known_files(THD *thd, MY_DIR *dirp,
41 const char *db, const char *path, uint level,
42 TABLE_LIST **dropped_tables);
44 long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path);
45 static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error);
46 static void mysql_change_db_impl(THD *thd,
47 LEX_STRING *new_db_name,
48 ulong new_db_access,
49 CHARSET_INFO *new_db_charset);
52 /* Database lock hash */
53 HASH lock_db_cache;
54 pthread_mutex_t LOCK_lock_db;
55 int creating_database= 0; // how many database locks are made
58 /* Structure for database lock */
59 typedef struct my_dblock_st
61 char *name; /* Database name */
62 uint name_length; /* Database length name */
63 } my_dblock_t;
67 lock_db key.
70 extern "C" uchar* lock_db_get_key(my_dblock_t *, size_t *, my_bool not_used);
72 uchar* lock_db_get_key(my_dblock_t *ptr, size_t *length,
73 my_bool not_used __attribute__((unused)))
75 *length= ptr->name_length;
76 return (uchar*) ptr->name;
81 Free lock_db hash element.
84 extern "C" void lock_db_free_element(void *ptr);
86 void lock_db_free_element(void *ptr)
88 my_free(ptr, MYF(0));
93 Put a database lock entry into the hash.
95 DESCRIPTION
96 Insert a database lock entry into hash.
97 LOCK_db_lock must be previously locked.
99 RETURN VALUES
100 0 on success.
101 1 on error.
104 static my_bool lock_db_insert(const char *dbname, uint length)
106 my_dblock_t *opt;
107 my_bool error= 0;
108 DBUG_ENTER("lock_db_insert");
110 safe_mutex_assert_owner(&LOCK_lock_db);
112 if (!(opt= (my_dblock_t*) hash_search(&lock_db_cache,
113 (uchar*) dbname, length)))
115 /* Db is not in the hash, insert it */
116 char *tmp_name;
117 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
118 &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
119 NullS))
121 error= 1;
122 goto end;
125 opt->name= tmp_name;
126 strmov(opt->name, dbname);
127 opt->name_length= length;
129 if ((error= my_hash_insert(&lock_db_cache, (uchar*) opt)))
130 my_free(opt, MYF(0));
133 end:
134 DBUG_RETURN(error);
139 Delete a database lock entry from hash.
142 void lock_db_delete(const char *name, uint length)
144 my_dblock_t *opt;
145 safe_mutex_assert_owner(&LOCK_lock_db);
146 if ((opt= (my_dblock_t *)hash_search(&lock_db_cache,
147 (const uchar*) name, length)))
148 hash_delete(&lock_db_cache, (uchar*) opt);
152 /* Database options hash */
153 static HASH dboptions;
154 static my_bool dboptions_init= 0;
155 static rw_lock_t LOCK_dboptions;
157 /* Structure for database options */
158 typedef struct my_dbopt_st
160 char *name; /* Database name */
161 uint name_length; /* Database length name */
162 CHARSET_INFO *charset; /* Database default character set */
163 } my_dbopt_t;
167 Function we use in the creation of our hash to get key.
170 extern "C" uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
171 my_bool not_used);
173 uchar* dboptions_get_key(my_dbopt_t *opt, size_t *length,
174 my_bool not_used __attribute__((unused)))
176 *length= opt->name_length;
177 return (uchar*) opt->name;
182 Helper function to write a query to binlog used by mysql_rm_db()
185 static inline int write_to_binlog(THD *thd, char *query, uint q_len,
186 char *db, uint db_len)
188 Query_log_event qinfo(thd, query, q_len, 0, 0, 0);
189 qinfo.db= db;
190 qinfo.db_len= db_len;
191 return mysql_bin_log.write(&qinfo);
196 Function to free dboptions hash element
199 extern "C" void free_dbopt(void *dbopt);
201 void free_dbopt(void *dbopt)
203 my_free((uchar*) dbopt, MYF(0));
208 Initialize database option hash and locked database hash.
210 SYNOPSIS
211 my_database_names()
213 NOTES
214 Must be called before any other database function is called.
216 RETURN
217 0 ok
218 1 Fatal error
221 bool my_database_names_init(void)
223 bool error= 0;
224 (void) my_rwlock_init(&LOCK_dboptions, NULL);
225 if (!dboptions_init)
227 dboptions_init= 1;
228 error= hash_init(&dboptions, lower_case_table_names ?
229 &my_charset_bin : system_charset_info,
230 32, 0, 0, (hash_get_key) dboptions_get_key,
231 free_dbopt,0) ||
232 hash_init(&lock_db_cache, lower_case_table_names ?
233 &my_charset_bin : system_charset_info,
234 32, 0, 0, (hash_get_key) lock_db_get_key,
235 lock_db_free_element,0);
238 return error;
244 Free database option hash and locked databases hash.
247 void my_database_names_free(void)
249 if (dboptions_init)
251 dboptions_init= 0;
252 hash_free(&dboptions);
253 (void) rwlock_destroy(&LOCK_dboptions);
254 hash_free(&lock_db_cache);
260 Cleanup cached options
263 void my_dbopt_cleanup(void)
265 rw_wrlock(&LOCK_dboptions);
266 hash_free(&dboptions);
267 hash_init(&dboptions, lower_case_table_names ?
268 &my_charset_bin : system_charset_info,
269 32, 0, 0, (hash_get_key) dboptions_get_key,
270 free_dbopt,0);
271 rw_unlock(&LOCK_dboptions);
276 Find database options in the hash.
278 DESCRIPTION
279 Search a database options in the hash, usings its path.
280 Fills "create" on success.
282 RETURN VALUES
283 0 on success.
284 1 on error.
287 static my_bool get_dbopt(const char *dbname, HA_CREATE_INFO *create)
289 my_dbopt_t *opt;
290 uint length;
291 my_bool error= 1;
293 length= (uint) strlen(dbname);
295 rw_rdlock(&LOCK_dboptions);
296 if ((opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
298 create->default_table_charset= opt->charset;
299 error= 0;
301 rw_unlock(&LOCK_dboptions);
302 return error;
307 Writes database options into the hash.
309 DESCRIPTION
310 Inserts database options into the hash, or updates
311 options if they are already in the hash.
313 RETURN VALUES
314 0 on success.
315 1 on error.
318 static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create)
320 my_dbopt_t *opt;
321 uint length;
322 my_bool error= 0;
323 DBUG_ENTER("put_dbopt");
325 length= (uint) strlen(dbname);
327 rw_wrlock(&LOCK_dboptions);
328 if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (uchar*) dbname, length)))
330 /* Options are not in the hash, insert them */
331 char *tmp_name;
332 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
333 &opt, (uint) sizeof(*opt), &tmp_name, (uint) length+1,
334 NullS))
336 error= 1;
337 goto end;
340 opt->name= tmp_name;
341 strmov(opt->name, dbname);
342 opt->name_length= length;
344 if ((error= my_hash_insert(&dboptions, (uchar*) opt)))
346 my_free(opt, MYF(0));
347 goto end;
351 /* Update / write options in hash */
352 opt->charset= create->default_table_charset;
354 end:
355 rw_unlock(&LOCK_dboptions);
356 DBUG_RETURN(error);
361 Deletes database options from the hash.
364 void del_dbopt(const char *path)
366 my_dbopt_t *opt;
367 rw_wrlock(&LOCK_dboptions);
368 if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const uchar*) path,
369 strlen(path))))
370 hash_delete(&dboptions, (uchar*) opt);
371 rw_unlock(&LOCK_dboptions);
376 Create database options file:
378 DESCRIPTION
379 Currently database default charset is only stored there.
381 RETURN VALUES
382 0 ok
383 1 Could not create file or write to it. Error sent through my_error()
386 static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
388 register File file;
389 char buf[256]; // Should be enough for one option
390 bool error=1;
392 if (!create->default_table_charset)
393 create->default_table_charset= thd->variables.collation_server;
395 if (put_dbopt(path, create))
396 return 1;
398 if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0)
400 ulong length;
401 length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=",
402 create->default_table_charset->csname,
403 "\ndefault-collation=",
404 create->default_table_charset->name,
405 "\n", NullS) - buf);
407 /* Error is written by my_write */
408 if (!my_write(file,(uchar*) buf, length, MYF(MY_NABP+MY_WME)))
409 error=0;
410 my_close(file,MYF(0));
412 return error;
417 Load database options file
419 load_db_opt()
420 path Path for option file
421 create Where to store the read options
423 DESCRIPTION
425 RETURN VALUES
426 0 File found
427 1 No database file or could not open it
431 bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create)
433 File file;
434 char buf[256];
435 DBUG_ENTER("load_db_opt");
436 bool error=1;
437 uint nbytes;
439 bzero((char*) create,sizeof(*create));
440 create->default_table_charset= thd->variables.collation_server;
442 /* Check if options for this database are already in the hash */
443 if (!get_dbopt(path, create))
444 DBUG_RETURN(0);
446 /* Otherwise, load options from the .opt file */
447 if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
448 goto err1;
450 IO_CACHE cache;
451 if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0)))
452 goto err2;
454 while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0)
456 char *pos= buf+nbytes-1;
457 /* Remove end space and control characters */
458 while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1]))
459 pos--;
460 *pos=0;
461 if ((pos= strchr(buf, '=')))
463 if (!strncmp(buf,"default-character-set", (pos-buf)))
466 Try character set name, and if it fails
467 try collation name, probably it's an old
468 4.1.0 db.opt file, which didn't have
469 separate default-character-set and
470 default-collation commands.
472 if (!(create->default_table_charset=
473 get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) &&
474 !(create->default_table_charset=
475 get_charset_by_name(pos+1, MYF(0))))
477 sql_print_error("Error while loading database options: '%s':",path);
478 sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1);
479 create->default_table_charset= default_charset_info;
482 else if (!strncmp(buf,"default-collation", (pos-buf)))
484 if (!(create->default_table_charset= get_charset_by_name(pos+1,
485 MYF(0))))
487 sql_print_error("Error while loading database options: '%s':",path);
488 sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1);
489 create->default_table_charset= default_charset_info;
495 Put the loaded value into the hash.
496 Note that another thread could've added the same
497 entry to the hash after we called get_dbopt(),
498 but it's not an error, as put_dbopt() takes this
499 possibility into account.
501 error= put_dbopt(path, create);
503 end_io_cache(&cache);
504 err2:
505 my_close(file,MYF(0));
506 err1:
507 DBUG_RETURN(error);
512 Retrieve database options by name. Load database options file or fetch from
513 cache.
515 SYNOPSIS
516 load_db_opt_by_name()
517 db_name Database name
518 db_create_info Where to store the database options
520 DESCRIPTION
521 load_db_opt_by_name() is a shortcut for load_db_opt().
523 NOTE
524 Although load_db_opt_by_name() (and load_db_opt()) returns status of
525 the operation, it is useless usually and should be ignored. The problem
526 is that there are 1) system databases ("mysql") and 2) virtual
527 databases ("information_schema"), which do not contain options file.
528 So, load_db_opt[_by_name]() returns FALSE for these databases, but this
529 is not an error.
531 load_db_opt[_by_name]() clears db_create_info structure in any case, so
532 even on failure it contains valid data. So, common use case is just
533 call load_db_opt[_by_name]() without checking return value and use
534 db_create_info right after that.
536 RETURN VALUES (read NOTE!)
537 FALSE Success
538 TRUE Failed to retrieve options
541 bool load_db_opt_by_name(THD *thd, const char *db_name,
542 HA_CREATE_INFO *db_create_info)
544 char db_opt_path[FN_REFLEN + 1];
547 Pass an empty file name, and the database options file name as extension
548 to avoid table name to file name encoding.
550 (void) build_table_filename(db_opt_path, sizeof(db_opt_path) - 1,
551 db_name, "", MY_DB_OPT_FILE, 0);
553 return load_db_opt(thd, db_opt_path, db_create_info);
558 Return default database collation.
560 @param thd Thread context.
561 @param db_name Database name.
563 @return CHARSET_INFO object. The operation always return valid character
564 set, even if the database does not exist.
567 CHARSET_INFO *get_default_db_collation(THD *thd, const char *db_name)
569 HA_CREATE_INFO db_info;
571 if (thd->db != NULL && strcmp(db_name, thd->db) == 0)
572 return thd->db_charset;
574 load_db_opt_by_name(thd, db_name, &db_info);
577 NOTE: even if load_db_opt_by_name() fails,
578 db_info.default_table_charset contains valid character set
579 (collation_server). We should not fail if load_db_opt_by_name() fails,
580 because it is valid case. If a database has been created just by
581 "mkdir", it does not contain db.opt file, but it is valid database.
584 return db_info.default_table_charset;
589 Create a database
591 SYNOPSIS
592 mysql_create_db()
593 thd Thread handler
594 db Name of database to create
595 Function assumes that this is already validated.
596 create_info Database create options (like character set)
597 silent Used by replication when internally creating a database.
598 In this case the entry should not be logged.
600 SIDE-EFFECTS
601 1. Report back to client that command succeeded (my_ok)
602 2. Report errors to client
603 3. Log event to binary log
604 (The 'silent' flags turns off 1 and 3.)
606 RETURN VALUES
607 FALSE ok
608 TRUE Error
612 int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
613 bool silent)
615 char path[FN_REFLEN+16];
616 char tmp_query[FN_REFLEN+16];
617 long result= 1;
618 int error= 0;
619 MY_STAT stat_info;
620 uint create_options= create_info ? create_info->options : 0;
621 uint path_len;
622 DBUG_ENTER("mysql_create_db");
624 /* do not create 'information_schema' db */
625 if (is_schema_db(db))
627 my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
628 DBUG_RETURN(-1);
632 Do not create database if another thread is holding read lock.
633 Wait for global read lock before acquiring LOCK_mysql_create_db.
634 After wait_if_global_read_lock() we have protection against another
635 global read lock. If we would acquire LOCK_mysql_create_db first,
636 another thread could step in and get the global read lock before we
637 reach wait_if_global_read_lock(). If this thread tries the same as we
638 (admin a db), it would then go and wait on LOCK_mysql_create_db...
639 Furthermore wait_if_global_read_lock() checks if the current thread
640 has the global read lock and refuses the operation with
641 ER_CANT_UPDATE_WITH_READLOCK if applicable.
643 if (wait_if_global_read_lock(thd, 0, 1))
645 error= -1;
646 goto exit2;
650 Close and mark for re-open all HANDLER tables which are marked for flush
651 or which there are pending conflicing locks against. This is needed to
652 prevent deadlocks.
654 if (thd->handler_tables_hash.records)
656 pthread_mutex_lock(&LOCK_open);
657 mysql_ha_flush(thd);
658 pthread_mutex_unlock(&LOCK_open);
661 VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
663 /* Check directory */
664 path_len= build_table_filename(path, sizeof(path) - 1, db, "", "", 0);
665 path[path_len-1]= 0; // Remove last '/' from path
667 if (my_stat(path,&stat_info,MYF(0)))
669 if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS))
671 my_error(ER_DB_CREATE_EXISTS, MYF(0), db);
672 error= -1;
673 goto exit;
675 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
676 ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db);
677 error= 0;
678 goto not_silent;
680 else
682 if (my_errno != ENOENT)
684 my_error(EE_STAT, MYF(0), path, my_errno);
685 goto exit;
687 if (my_mkdir(path,0777,MYF(0)) < 0)
689 my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno);
690 error= -1;
691 goto exit;
695 path[path_len-1]= FN_LIBCHAR;
696 strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1);
697 if (write_db_opt(thd, path, create_info))
700 Could not create options file.
701 Restore things to beginning.
703 path[path_len]= 0;
704 if (rmdir(path) >= 0)
706 error= -1;
707 goto exit;
710 We come here when we managed to create the database, but not the option
711 file. In this case it's best to just continue as if nothing has
712 happened. (This is a very unlikely senario)
714 thd->clear_error();
717 not_silent:
718 if (!silent)
720 char *query;
721 uint query_length;
722 char db_name_quoted[2 * FN_REFLEN + sizeof("create database ") + 2];
723 int id_len= 0;
725 if (!thd->query()) // Only in replication
727 id_len= my_strmov_quoted_identifier(thd, (char *) db_name_quoted, db,
729 db_name_quoted[id_len]= '\0';
730 query= tmp_query;
731 query_length= (uint) (strxmov(tmp_query,"create database ",
732 db_name_quoted, NullS) - tmp_query);
734 else
736 query= thd->query();
737 query_length= thd->query_length();
740 ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
741 query, query_length,
742 db, "");
744 if (mysql_bin_log.is_open())
746 int errcode= query_error_code(thd, TRUE);
747 Query_log_event qinfo(thd, query, query_length, 0,
748 /* suppress_use */ TRUE, errcode);
751 Write should use the database being created as the "current
752 database" and not the threads current database, which is the
753 default. If we do not change the "current database" to the
754 database being created, the CREATE statement will not be
755 replicated when using --binlog-do-db to select databases to be
756 replicated.
758 An example (--binlog-do-db=sisyfos):
760 CREATE DATABASE bob; # Not replicated
761 USE bob; # 'bob' is the current database
762 CREATE DATABASE sisyfos; # Not replicated since 'bob' is
763 # current database.
764 USE sisyfos; # Will give error on slave since
765 # database does not exist.
767 qinfo.db = db;
768 qinfo.db_len = strlen(db);
770 /* These DDL methods and logging protected with LOCK_mysql_create_db */
771 if (mysql_bin_log.write(&qinfo))
773 error= -1;
774 goto exit;
777 my_ok(thd, result);
780 exit:
781 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
782 start_waiting_global_read_lock(thd);
783 exit2:
784 DBUG_RETURN(error);
788 /* db-name is already validated when we come here */
790 bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
792 char path[FN_REFLEN+16];
793 long result=1;
794 int error= 0;
795 DBUG_ENTER("mysql_alter_db");
798 Do not alter database if another thread is holding read lock.
799 Wait for global read lock before acquiring LOCK_mysql_create_db.
800 After wait_if_global_read_lock() we have protection against another
801 global read lock. If we would acquire LOCK_mysql_create_db first,
802 another thread could step in and get the global read lock before we
803 reach wait_if_global_read_lock(). If this thread tries the same as we
804 (admin a db), it would then go and wait on LOCK_mysql_create_db...
805 Furthermore wait_if_global_read_lock() checks if the current thread
806 has the global read lock and refuses the operation with
807 ER_CANT_UPDATE_WITH_READLOCK if applicable.
809 if ((error=wait_if_global_read_lock(thd,0,1)))
810 goto exit2;
813 Close and mark for re-open all HANDLER tables which are marked for flush
814 or which there are pending conflicing locks against. This is needed to
815 prevent deadlocks.
817 if (thd->handler_tables_hash.records)
819 pthread_mutex_lock(&LOCK_open);
820 mysql_ha_flush(thd);
821 pthread_mutex_unlock(&LOCK_open);
824 VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
827 Recreate db options file: /dbpath/.db.opt
828 We pass MY_DB_OPT_FILE as "extension" to avoid
829 "table name to file name" encoding.
831 build_table_filename(path, sizeof(path) - 1, db, "", MY_DB_OPT_FILE, 0);
832 if ((error=write_db_opt(thd, path, create_info)))
833 goto exit;
835 /* Change options if current database is being altered. */
837 if (thd->db && !strcmp(thd->db,db))
839 thd->db_charset= create_info->default_table_charset ?
840 create_info->default_table_charset :
841 thd->variables.collation_server;
842 thd->variables.collation_database= thd->db_charset;
845 ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB,
846 thd->query(), thd->query_length(),
847 db, "");
849 if (mysql_bin_log.is_open())
851 thd->clear_error();
852 Query_log_event qinfo(thd, thd->query(), thd->query_length(), 0,
853 /* suppress_use */ TRUE, 0);
856 Write should use the database being created as the "current
857 database" and not the threads current database, which is the
858 default.
860 qinfo.db = db;
861 qinfo.db_len = strlen(db);
863 /* These DDL methods and logging protected with LOCK_mysql_create_db */
864 if ((error= mysql_bin_log.write(&qinfo)))
865 goto exit;
867 my_ok(thd, result);
869 exit:
870 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
871 start_waiting_global_read_lock(thd);
872 exit2:
873 DBUG_RETURN(error);
878 Drop all tables in a database and the database itself
880 SYNOPSIS
881 mysql_rm_db()
882 thd Thread handle
883 db Database name in the case given by user
884 It's already validated and set to lower case
885 (if needed) when we come here
886 if_exists Don't give error if database doesn't exists
887 silent Don't generate errors
889 RETURN
890 FALSE ok (Database dropped)
891 ERROR Error
894 bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
896 long deleted=0;
897 int error= 0;
898 char path[2 * FN_REFLEN + 16];
899 MY_DIR *dirp;
900 uint length;
901 TABLE_LIST* dropped_tables= 0;
902 DBUG_ENTER("mysql_rm_db");
905 Do not drop database if another thread is holding read lock.
906 Wait for global read lock before acquiring LOCK_mysql_create_db.
907 After wait_if_global_read_lock() we have protection against another
908 global read lock. If we would acquire LOCK_mysql_create_db first,
909 another thread could step in and get the global read lock before we
910 reach wait_if_global_read_lock(). If this thread tries the same as we
911 (admin a db), it would then go and wait on LOCK_mysql_create_db...
912 Furthermore wait_if_global_read_lock() checks if the current thread
913 has the global read lock and refuses the operation with
914 ER_CANT_UPDATE_WITH_READLOCK if applicable.
916 if (wait_if_global_read_lock(thd, 0, 1))
918 error= -1;
919 goto exit2;
923 Close and mark for re-open all HANDLER tables which are marked for flush
924 or which there are pending conflicing locks against. This is needed to
925 prevent deadlocks.
927 if (thd->handler_tables_hash.records)
929 pthread_mutex_lock(&LOCK_open);
930 mysql_ha_flush(thd);
931 pthread_mutex_unlock(&LOCK_open);
934 VOID(pthread_mutex_lock(&LOCK_mysql_create_db));
936 length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0);
937 strmov(path+length, MY_DB_OPT_FILE); // Append db option file name
938 del_dbopt(path); // Remove dboption hash entry
939 path[length]= '\0'; // Remove file name
941 /* See if the directory exists */
942 if (!(dirp= my_dir(path,MYF(MY_DONT_SORT))))
944 if (!if_exists)
946 error= -1;
947 my_error(ER_DB_DROP_EXISTS, MYF(0), db);
948 goto exit;
950 else
951 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
952 ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db);
954 else
956 pthread_mutex_lock(&LOCK_open);
957 remove_db_from_cache(db);
958 pthread_mutex_unlock(&LOCK_open);
960 error= -1;
962 We temporarily disable the binary log while dropping the objects
963 in the database. Since the DROP DATABASE statement is always
964 replicated as a statement, execution of it will drop all objects
965 in the database on the slave as well, so there is no need to
966 replicate the removal of the individual objects in the database
967 as well.
969 This is more of a safety precaution, since normally no objects
970 should be dropped while the database is being cleaned, but in
971 the event that a change in the code to remove other objects is
972 made, these drops should still not be logged.
974 Notice that the binary log have to be enabled over the call to
975 ha_drop_database(), since NDB otherwise detects the binary log
976 as disabled and will not log the drop database statement on any
977 other connected server.
979 if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0,
980 &dropped_tables)) >= 0)
982 ha_drop_database(path);
983 tmp_disable_binlog(thd);
984 query_cache_invalidate1(db);
985 (void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */
986 #ifdef HAVE_EVENT_SCHEDULER
987 Events::drop_schema_events(thd, db);
988 #endif
989 error = 0;
990 reenable_binlog(thd);
994 if (!silent && deleted>=0)
996 const char *query;
997 ulong query_length;
998 // quoted db name + wraping quote
999 char buffer_temp [2 * FN_REFLEN + 2];
1000 int id_len= 0;
1002 if (!thd->query())
1004 /* The client used the old obsolete mysql_drop_db() call */
1005 query= path;
1006 id_len= my_strmov_quoted_identifier(thd, buffer_temp, db, strlen(db));
1007 buffer_temp[id_len] ='\0';
1008 query_length= (uint) (strxmov(path, "DROP DATABASE ", buffer_temp, "",
1009 NullS) - path);
1011 else
1013 query= thd->query();
1014 query_length= thd->query_length();
1016 if (mysql_bin_log.is_open())
1018 thd->clear_error();
1019 Query_log_event qinfo(thd, query, query_length, 0,
1020 /* suppress_use */ TRUE, 0);
1022 Write should use the database being created as the "current
1023 database" and not the threads current database, which is the
1024 default.
1026 qinfo.db = db;
1027 qinfo.db_len = strlen(db);
1029 /* These DDL methods and logging protected with LOCK_mysql_create_db */
1030 if (mysql_bin_log.write(&qinfo))
1032 error= -1;
1033 goto exit;
1036 thd->clear_error();
1037 thd->server_status|= SERVER_STATUS_DB_DROPPED;
1038 my_ok(thd, (ulong) deleted);
1039 thd->server_status&= ~SERVER_STATUS_DB_DROPPED;
1041 else if (mysql_bin_log.is_open())
1043 char *query, *query_pos, *query_end, *query_data_start;
1044 char temp_identifier[ 2 * FN_REFLEN + 2];
1045 TABLE_LIST *tbl;
1046 uint db_len, id_length=0;
1048 if (!(query= (char*) thd->alloc(MAX_DROP_TABLE_Q_LEN)))
1049 goto exit; /* not much else we can do */
1050 query_pos= query_data_start= strmov(query,"DROP TABLE ");
1051 query_end= query + MAX_DROP_TABLE_Q_LEN;
1052 db_len= strlen(db);
1054 for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
1056 uint tbl_name_len;
1058 /* 3 for the quotes and the comma*/
1059 tbl_name_len= strlen(tbl->table_name) + 3;
1060 if (query_pos + tbl_name_len + 1 >= query_end)
1062 /* These DDL methods and logging protected with LOCK_mysql_create_db */
1063 if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
1065 error= -1;
1066 goto exit;
1068 query_pos= query_data_start;
1070 id_length= my_strmov_quoted_identifier(thd, (char *)temp_identifier,
1071 tbl->table_name, 0);
1072 temp_identifier[id_length]= '\0';
1073 query_pos= strmov(query_pos,(char *)&temp_identifier);
1074 *query_pos++ = ',';
1077 if (query_pos != query_data_start)
1079 /* These DDL methods and logging protected with LOCK_mysql_create_db */
1080 if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len))
1082 error= -1;
1083 goto exit;
1088 exit:
1090 If this database was the client's selected database, we silently
1091 change the client's selected database to nothing (to have an empty
1092 SELECT DATABASE() in the future). For this we free() thd->db and set
1093 it to 0.
1095 if (thd->db && !strcmp(thd->db, db))
1096 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1097 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db));
1098 start_waiting_global_read_lock(thd);
1099 exit2:
1100 DBUG_RETURN(error);
1104 Removes files with known extensions plus all found subdirectories that
1105 are 2 hex digits (raid directories).
1106 thd MUST be set when calling this function!
1109 static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
1110 const char *org_path, uint level,
1111 TABLE_LIST **dropped_tables)
1113 long deleted=0;
1114 ulong found_other_files=0;
1115 char filePath[FN_REFLEN];
1116 TABLE_LIST *tot_list=0, **tot_list_next;
1117 List<String> raid_dirs;
1118 DBUG_ENTER("mysql_rm_known_files");
1119 DBUG_PRINT("enter",("path: %s", org_path));
1121 tot_list_next= &tot_list;
1123 for (uint idx=0 ;
1124 idx < (uint) dirp->number_off_files && !thd->killed ;
1125 idx++)
1127 FILEINFO *file=dirp->dir_entry+idx;
1128 char *extension;
1129 DBUG_PRINT("info",("Examining: %s", file->name));
1131 /* skiping . and .. */
1132 if (file->name[0] == '.' && (!file->name[1] ||
1133 (file->name[1] == '.' && !file->name[2])))
1134 continue;
1136 /* Check if file is a raid directory */
1137 if ((my_isdigit(system_charset_info, file->name[0]) ||
1138 (file->name[0] >= 'a' && file->name[0] <= 'f')) &&
1139 (my_isdigit(system_charset_info, file->name[1]) ||
1140 (file->name[1] >= 'a' && file->name[1] <= 'f')) &&
1141 !file->name[2] && !level)
1143 char newpath[FN_REFLEN], *copy_of_path;
1144 MY_DIR *new_dirp;
1145 String *dir;
1146 uint length;
1148 strxmov(newpath,org_path,"/",file->name,NullS);
1149 length= unpack_filename(newpath,newpath);
1150 if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT))))
1152 DBUG_PRINT("my",("New subdir found: %s", newpath));
1153 if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0)
1154 goto err;
1155 if (!(copy_of_path= (char*) thd->memdup(newpath, length+1)) ||
1156 !(dir= new (thd->mem_root) String(copy_of_path, length,
1157 &my_charset_bin)) ||
1158 raid_dirs.push_back(dir))
1159 goto err;
1160 continue;
1162 found_other_files++;
1163 continue;
1165 else if (file->name[0] == 'a' && file->name[1] == 'r' &&
1166 file->name[2] == 'c' && file->name[3] == '\0')
1168 /* .frm archive:
1169 Those archives are obsolete, but following code should
1170 exist to remove existent "arc" directories.
1172 char newpath[FN_REFLEN];
1173 MY_DIR *new_dirp;
1174 strxmov(newpath, org_path, "/", "arc", NullS);
1175 (void) unpack_filename(newpath, newpath);
1176 if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT))))
1178 DBUG_PRINT("my",("Archive subdir found: %s", newpath));
1179 if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0)
1180 goto err;
1181 continue;
1183 found_other_files++;
1184 continue;
1186 if (!(extension= strrchr(file->name, '.')))
1187 extension= strend(file->name);
1188 if (find_type(extension, &deletable_extentions,1+2) <= 0)
1190 if (find_type(extension, ha_known_exts(),1+2) <= 0)
1191 found_other_files++;
1192 continue;
1194 /* just for safety we use files_charset_info */
1195 if (db && !my_strcasecmp(files_charset_info,
1196 extension, reg_ext))
1198 /* Drop the table nicely */
1199 *extension= 0; // Remove extension
1200 TABLE_LIST *table_list=(TABLE_LIST*)
1201 thd->calloc(sizeof(*table_list) +
1202 strlen(db) + 1 +
1203 MYSQL50_TABLE_NAME_PREFIX_LENGTH +
1204 strlen(file->name) + 1);
1206 if (!table_list)
1207 goto err;
1208 table_list->db= (char*) (table_list+1);
1209 table_list->table_name= strmov(table_list->db, db) + 1;
1210 VOID(filename_to_tablename(file->name, table_list->table_name,
1211 MYSQL50_TABLE_NAME_PREFIX_LENGTH +
1212 strlen(file->name) + 1));
1214 /* To be able to correctly look up the table in the table cache. */
1215 if (lower_case_table_names)
1216 table_list->table_name_length= my_casedn_str(files_charset_info,
1217 table_list->table_name);
1219 table_list->alias= table_list->table_name; // If lower_case_table_names=2
1220 table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
1221 /* Link into list */
1222 (*tot_list_next)= table_list;
1223 tot_list_next= &table_list->next_local;
1224 deleted++;
1226 else
1228 strxmov(filePath, org_path, "/", file->name, NullS);
1230 We ignore ENOENT error in order to skip files that was deleted
1231 by concurrently running statement like REAPIR TABLE ...
1233 if (my_delete_with_symlink(filePath, MYF(0)) &&
1234 my_errno != ENOENT)
1236 my_error(EE_DELETE, MYF(0), filePath, my_errno);
1237 goto err;
1242 if (thd->killed)
1243 goto err;
1245 if (tot_list)
1247 int res= 0;
1248 Drop_table_error_handler err_handler(thd->get_internal_handler());
1250 thd->push_internal_handler(&err_handler);
1251 res= mysql_rm_table_part2(thd, tot_list, 1, 0, 1, 1);
1252 thd->pop_internal_handler();
1253 if (res)
1254 goto err;
1257 /* Remove RAID directories */
1259 List_iterator<String> it(raid_dirs);
1260 String *dir;
1261 while ((dir= it++))
1262 if (rmdir(dir->c_ptr()) < 0)
1263 found_other_files++;
1265 my_dirend(dirp);
1267 if (dropped_tables)
1268 *dropped_tables= tot_list;
1271 If the directory is a symbolic link, remove the link first, then
1272 remove the directory the symbolic link pointed at
1274 if (found_other_files)
1276 my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST);
1277 DBUG_RETURN(-1);
1279 else
1281 /* Don't give errors if we can't delete 'RAID' directory */
1282 if (rm_dir_w_symlink(org_path, level == 0))
1283 DBUG_RETURN(-1);
1286 DBUG_RETURN(deleted);
1288 err:
1289 my_dirend(dirp);
1290 DBUG_RETURN(-1);
1295 Remove directory with symlink
1297 SYNOPSIS
1298 rm_dir_w_symlink()
1299 org_path path of derictory
1300 send_error send errors
1301 RETURN
1302 0 OK
1303 1 ERROR
1306 static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
1308 char tmp_path[FN_REFLEN], *pos;
1309 char *path= tmp_path;
1310 DBUG_ENTER("rm_dir_w_symlink");
1311 unpack_filename(tmp_path, org_path);
1312 #ifdef HAVE_READLINK
1313 int error;
1314 char tmp2_path[FN_REFLEN];
1316 /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */
1317 pos= strend(path);
1318 if (pos > path && pos[-1] == FN_LIBCHAR)
1319 *--pos=0;
1321 if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0)
1322 DBUG_RETURN(1);
1323 if (!error)
1325 if (my_delete(path, MYF(send_error ? MY_WME : 0)))
1327 DBUG_RETURN(send_error);
1329 /* Delete directory symbolic link pointed at */
1330 path= tmp2_path;
1332 #endif
1333 /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */
1334 pos= strend(path);
1336 if (pos > path && pos[-1] == FN_LIBCHAR)
1337 *--pos=0;
1338 if (rmdir(path) < 0 && send_error)
1340 my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno);
1341 DBUG_RETURN(1);
1343 DBUG_RETURN(0);
1348 Remove .frm archives from directory
1350 SYNOPSIS
1351 thd thread handler
1352 dirp list of files in archive directory
1353 db data base name
1354 org_path path of archive directory
1356 RETURN
1357 > 0 number of removed files
1358 -1 error
1360 NOTE
1361 A support of "arc" directories is obsolete, however this
1362 function should exist to remove existent "arc" directories.
1364 long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path)
1366 long deleted= 0;
1367 ulong found_other_files= 0;
1368 char filePath[FN_REFLEN];
1369 DBUG_ENTER("mysql_rm_arc_files");
1370 DBUG_PRINT("enter", ("path: %s", org_path));
1372 for (uint idx=0 ;
1373 idx < (uint) dirp->number_off_files && !thd->killed ;
1374 idx++)
1376 FILEINFO *file=dirp->dir_entry+idx;
1377 char *extension, *revision;
1378 DBUG_PRINT("info",("Examining: %s", file->name));
1380 /* skiping . and .. */
1381 if (file->name[0] == '.' && (!file->name[1] ||
1382 (file->name[1] == '.' && !file->name[2])))
1383 continue;
1385 extension= fn_ext(file->name);
1386 if (extension[0] != '.' ||
1387 extension[1] != 'f' || extension[2] != 'r' ||
1388 extension[3] != 'm' || extension[4] != '-')
1390 found_other_files++;
1391 continue;
1393 revision= extension+5;
1394 while (*revision && my_isdigit(system_charset_info, *revision))
1395 revision++;
1396 if (*revision)
1398 found_other_files++;
1399 continue;
1401 strxmov(filePath, org_path, "/", file->name, NullS);
1402 if (my_delete_with_symlink(filePath,MYF(MY_WME)))
1404 goto err;
1406 deleted++;
1408 if (thd->killed)
1409 goto err;
1411 my_dirend(dirp);
1414 If the directory is a symbolic link, remove the link first, then
1415 remove the directory the symbolic link pointed at
1417 if (!found_other_files &&
1418 rm_dir_w_symlink(org_path, 0))
1419 DBUG_RETURN(-1);
1420 DBUG_RETURN(deleted);
1422 err:
1423 my_dirend(dirp);
1424 DBUG_RETURN(-1);
1429 @brief Internal implementation: switch current database to a valid one.
1431 @param thd Thread context.
1432 @param new_db_name Name of the database to switch to. The function will
1433 take ownership of the name (the caller must not free
1434 the allocated memory). If the name is NULL, we're
1435 going to switch to NULL db.
1436 @param new_db_access Privileges of the new database.
1437 @param new_db_charset Character set of the new database.
1440 static void mysql_change_db_impl(THD *thd,
1441 LEX_STRING *new_db_name,
1442 ulong new_db_access,
1443 CHARSET_INFO *new_db_charset)
1445 /* 1. Change current database in THD. */
1447 if (new_db_name == NULL)
1450 THD::set_db() does all the job -- it frees previous database name and
1451 sets the new one.
1454 thd->set_db(NULL, 0);
1456 else if (new_db_name == &INFORMATION_SCHEMA_NAME)
1459 Here we must use THD::set_db(), because we want to copy
1460 INFORMATION_SCHEMA_NAME constant.
1463 thd->set_db(INFORMATION_SCHEMA_NAME.str, INFORMATION_SCHEMA_NAME.length);
1465 else
1468 Here we already have a copy of database name to be used in THD. So,
1469 we just call THD::reset_db(). Since THD::reset_db() does not releases
1470 the previous database name, we should do it explicitly.
1472 pthread_mutex_lock(&thd->LOCK_thd_data);
1473 if (thd->db)
1474 x_free(thd->db);
1475 DEBUG_SYNC(thd, "after_freeing_thd_db");
1476 thd->reset_db(new_db_name->str, new_db_name->length);
1477 pthread_mutex_unlock(&thd->LOCK_thd_data);
1480 /* 2. Update security context. */
1482 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1483 thd->security_ctx->db_access= new_db_access;
1484 #endif
1486 /* 3. Update db-charset environment variables. */
1488 thd->db_charset= new_db_charset;
1489 thd->variables.collation_database= new_db_charset;
1495 Backup the current database name before switch.
1497 @param[in] thd thread handle
1498 @param[in, out] saved_db_name IN: "str" points to a buffer where to store
1499 the old database name, "length" contains the
1500 buffer size
1501 OUT: if the current (default) database is
1502 not NULL, its name is copied to the
1503 buffer pointed at by "str"
1504 and "length" is updated accordingly.
1505 Otherwise "str" is set to NULL and
1506 "length" is set to 0.
1509 static void backup_current_db_name(THD *thd,
1510 LEX_STRING *saved_db_name)
1512 if (!thd->db)
1514 /* No current (default) database selected. */
1516 saved_db_name->str= NULL;
1517 saved_db_name->length= 0;
1519 else
1521 strmake(saved_db_name->str, thd->db, saved_db_name->length - 1);
1522 saved_db_name->length= thd->db_length;
1528 Return TRUE if db1_name is equal to db2_name, FALSE otherwise.
1530 The function allows to compare database names according to the MySQL
1531 rules. The database names db1 and db2 are equal if:
1532 - db1 is NULL and db2 is NULL;
1534 - db1 is not-NULL, db2 is not-NULL, db1 is equal (ignoring case) to
1535 db2 in system character set (UTF8).
1538 static inline bool
1539 cmp_db_names(const char *db1_name,
1540 const char *db2_name)
1542 return
1543 /* db1 is NULL and db2 is NULL */
1544 (!db1_name && !db2_name) ||
1546 /* db1 is not-NULL, db2 is not-NULL, db1 == db2. */
1547 (db1_name && db2_name &&
1548 my_strcasecmp(system_charset_info, db1_name, db2_name) == 0);
1553 @brief Change the current database and its attributes unconditionally.
1555 @param thd thread handle
1556 @param new_db_name database name
1557 @param force_switch if force_switch is FALSE, then the operation will fail if
1559 - new_db_name is NULL or empty;
1561 - OR new database name is invalid
1562 (check_db_name() failed);
1564 - OR user has no privilege on the new database;
1566 - OR new database does not exist;
1568 if force_switch is TRUE, then
1570 - if new_db_name is NULL or empty, the current
1571 database will be NULL, @@collation_database will
1572 be set to @@collation_server, the operation will
1573 succeed.
1575 - if new database name is invalid
1576 (check_db_name() failed), the current database
1577 will be NULL, @@collation_database will be set to
1578 @@collation_server, but the operation will fail;
1580 - user privileges will not be checked
1581 (THD::db_access however is updated);
1583 TODO: is this really the intention?
1584 (see sp-security.test).
1586 - if new database does not exist,the current database
1587 will be NULL, @@collation_database will be set to
1588 @@collation_server, a warning will be thrown, the
1589 operation will succeed.
1591 @details The function checks that the database name corresponds to a
1592 valid and existent database, checks access rights and changes the current
1593 database with database attributes (@@collation_database session variable,
1594 THD::db_access).
1596 This function is not the only way to switch the database that is
1597 currently employed. When the replication slave thread switches the
1598 database before executing a query, it calls thd->set_db directly.
1599 However, if the query, in turn, uses a stored routine, the stored routine
1600 will use this function, even if it's run on the slave.
1602 This function allocates the name of the database on the system heap: this
1603 is necessary to be able to uniformly change the database from any module
1604 of the server. Up to 5.0 different modules were using different memory to
1605 store the name of the database, and this led to memory corruption:
1606 a stack pointer set by Stored Procedures was used by replication after
1607 the stack address was long gone.
1609 @return Operation status
1610 @retval FALSE Success
1611 @retval TRUE Error
1614 bool mysql_change_db(THD *thd, const LEX_STRING *new_db_name, bool force_switch)
1616 LEX_STRING new_db_file_name;
1618 Security_context *sctx= thd->security_ctx;
1619 ulong db_access= sctx->db_access;
1620 CHARSET_INFO *db_default_cl;
1622 DBUG_ENTER("mysql_change_db");
1623 DBUG_PRINT("enter",("name: '%s'", new_db_name->str));
1625 if (new_db_name == NULL ||
1626 new_db_name->length == 0)
1628 if (force_switch)
1631 This can happen only if we're switching the current database back
1632 after loading stored program. The thing is that loading of stored
1633 program can happen when there is no current database.
1635 TODO: actually, new_db_name and new_db_name->str seem to be always
1636 non-NULL. In case of stored program, new_db_name->str == "" and
1637 new_db_name->length == 0.
1640 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1642 DBUG_RETURN(FALSE);
1644 else
1646 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
1648 DBUG_RETURN(TRUE);
1652 if (is_schema_db(new_db_name->str, new_db_name->length))
1654 /* Switch the current database to INFORMATION_SCHEMA. */
1656 mysql_change_db_impl(thd, &INFORMATION_SCHEMA_NAME, SELECT_ACL,
1657 system_charset_info);
1659 DBUG_RETURN(FALSE);
1663 Now we need to make a copy because check_db_name requires a
1664 non-constant argument. Actually, it takes database file name.
1666 TODO: fix check_db_name().
1669 new_db_file_name.str= my_strndup(new_db_name->str, new_db_name->length,
1670 MYF(MY_WME));
1671 new_db_file_name.length= new_db_name->length;
1673 if (new_db_file_name.str == NULL)
1674 DBUG_RETURN(TRUE); /* the error is set */
1677 NOTE: if check_db_name() fails, we should throw an error in any case,
1678 even if we are called from sp_head::execute().
1680 It's next to impossible however to get this error when we are called
1681 from sp_head::execute(). But let's switch the current database to NULL
1682 in this case to be sure.
1685 if (check_db_name(&new_db_file_name))
1687 my_error(ER_WRONG_DB_NAME, MYF(0), new_db_file_name.str);
1688 my_free(new_db_file_name.str, MYF(0));
1690 if (force_switch)
1691 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1693 DBUG_RETURN(TRUE);
1696 DBUG_PRINT("info",("Use database: %s", new_db_file_name.str));
1698 #ifndef NO_EMBEDDED_ACCESS_CHECKS
1699 db_access=
1700 test_all_bits(sctx->master_access, DB_ACLS) ?
1701 DB_ACLS :
1702 acl_get(sctx->host,
1703 sctx->ip,
1704 sctx->priv_user,
1705 new_db_file_name.str,
1706 FALSE) | sctx->master_access;
1708 if (!force_switch &&
1709 !(db_access & DB_ACLS) &&
1710 check_grant_db(thd, new_db_file_name.str))
1712 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
1713 sctx->priv_user,
1714 sctx->priv_host,
1715 new_db_file_name.str);
1716 general_log_print(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
1717 sctx->priv_user, sctx->priv_host, new_db_file_name.str);
1718 my_free(new_db_file_name.str, MYF(0));
1719 DBUG_RETURN(TRUE);
1721 #endif
1723 DEBUG_SYNC(thd, "before_db_dir_check");
1725 if (check_db_dir_existence(new_db_file_name.str))
1727 if (force_switch)
1729 /* Throw a warning and free new_db_file_name. */
1731 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
1732 ER_BAD_DB_ERROR, ER(ER_BAD_DB_ERROR),
1733 new_db_file_name.str);
1735 my_free(new_db_file_name.str, MYF(0));
1737 /* Change db to NULL. */
1739 mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server);
1741 /* The operation succeed. */
1743 DBUG_RETURN(FALSE);
1745 else
1747 /* Report an error and free new_db_file_name. */
1749 my_error(ER_BAD_DB_ERROR, MYF(0), new_db_file_name.str);
1750 my_free(new_db_file_name.str, MYF(0));
1752 /* The operation failed. */
1754 DBUG_RETURN(TRUE);
1759 NOTE: in mysql_change_db_impl() new_db_file_name is assigned to THD
1760 attributes and will be freed in THD::~THD().
1763 db_default_cl= get_default_db_collation(thd, new_db_file_name.str);
1765 mysql_change_db_impl(thd, &new_db_file_name, db_access, db_default_cl);
1767 DBUG_RETURN(FALSE);
1772 Change the current database and its attributes if needed.
1774 @param thd thread handle
1775 @param new_db_name database name
1776 @param[in, out] saved_db_name IN: "str" points to a buffer where to store
1777 the old database name, "length" contains the
1778 buffer size
1779 OUT: if the current (default) database is
1780 not NULL, its name is copied to the
1781 buffer pointed at by "str"
1782 and "length" is updated accordingly.
1783 Otherwise "str" is set to NULL and
1784 "length" is set to 0.
1785 @param force_switch @see mysql_change_db()
1786 @param[out] cur_db_changed out-flag to indicate whether the current
1787 database has been changed (valid only if
1788 the function suceeded)
1791 bool mysql_opt_change_db(THD *thd,
1792 const LEX_STRING *new_db_name,
1793 LEX_STRING *saved_db_name,
1794 bool force_switch,
1795 bool *cur_db_changed)
1797 *cur_db_changed= !cmp_db_names(thd->db, new_db_name->str);
1799 if (!*cur_db_changed)
1800 return FALSE;
1802 backup_current_db_name(thd, saved_db_name);
1804 return mysql_change_db(thd, new_db_name, force_switch);
1808 static int
1809 lock_databases(THD *thd, const char *db1, uint length1,
1810 const char *db2, uint length2)
1812 pthread_mutex_lock(&LOCK_lock_db);
1813 while (!thd->killed &&
1814 (hash_search(&lock_db_cache,(uchar*) db1, length1) ||
1815 hash_search(&lock_db_cache,(uchar*) db2, length2)))
1817 wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1818 pthread_mutex_lock(&LOCK_lock_db);
1821 if (thd->killed)
1823 pthread_mutex_unlock(&LOCK_lock_db);
1824 return 1;
1827 lock_db_insert(db1, length1);
1828 lock_db_insert(db2, length2);
1829 creating_database++;
1832 Wait if a concurent thread is creating a table at the same time.
1833 The assumption here is that it will not take too long until
1834 there is a point in time when a table is not created.
1837 while (!thd->killed && creating_table)
1839 wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
1840 pthread_mutex_lock(&LOCK_lock_db);
1843 if (thd->killed)
1845 lock_db_delete(db1, length1);
1846 lock_db_delete(db2, length2);
1847 creating_database--;
1848 pthread_mutex_unlock(&LOCK_lock_db);
1849 pthread_cond_signal(&COND_refresh);
1850 return(1);
1854 We can unlock now as the hash will protect against anyone creating a table
1855 in the databases we are using
1857 pthread_mutex_unlock(&LOCK_lock_db);
1858 return 0;
1863 Upgrade a 5.0 database.
1864 This function is invoked whenever an ALTER DATABASE UPGRADE query is executed:
1865 ALTER DATABASE 'olddb' UPGRADE DATA DIRECTORY NAME.
1867 If we have managed to rename (move) tables to the new database
1868 but something failed on a later step, then we store the
1869 RENAME DATABASE event in the log. mysql_rename_db() is atomic in
1870 the sense that it will rename all or none of the tables.
1872 @param thd Current thread
1873 @param old_db 5.0 database name, in #mysql50#name format
1874 @return 0 on success, 1 on error
1876 bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db)
1878 int error= 0, change_to_newdb= 0;
1879 char path[FN_REFLEN+16];
1880 uint length;
1881 HA_CREATE_INFO create_info;
1882 MY_DIR *dirp;
1883 TABLE_LIST *table_list;
1884 SELECT_LEX *sl= thd->lex->current_select;
1885 LEX_STRING new_db;
1886 DBUG_ENTER("mysql_upgrade_db");
1888 if ((old_db->length <= MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
1889 (strncmp(old_db->str,
1890 MYSQL50_TABLE_NAME_PREFIX,
1891 MYSQL50_TABLE_NAME_PREFIX_LENGTH) != 0))
1893 my_error(ER_WRONG_USAGE, MYF(0),
1894 "ALTER DATABASE UPGRADE DATA DIRECTORY NAME",
1895 "name");
1896 DBUG_RETURN(1);
1899 /* `#mysql50#<name>` converted to encoded `<name>` */
1900 new_db.str= old_db->str + MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1901 new_db.length= old_db->length - MYSQL50_TABLE_NAME_PREFIX_LENGTH;
1903 if (lock_databases(thd, old_db->str, old_db->length,
1904 new_db.str, new_db.length))
1905 DBUG_RETURN(1);
1908 Let's remember if we should do "USE newdb" afterwards.
1909 thd->db will be cleared in mysql_rename_db()
1911 if (thd->db && !strcmp(thd->db, old_db->str))
1912 change_to_newdb= 1;
1914 build_table_filename(path, sizeof(path)-1,
1915 old_db->str, "", MY_DB_OPT_FILE, 0);
1916 if ((load_db_opt(thd, path, &create_info)))
1917 create_info.default_table_charset= thd->variables.collation_server;
1919 length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0);
1920 if (length && path[length-1] == FN_LIBCHAR)
1921 path[length-1]=0; // remove ending '\'
1922 if ((error= my_access(path,F_OK)))
1924 my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str);
1925 goto exit;
1928 /* Step1: Create the new database */
1929 if ((error= mysql_create_db(thd, new_db.str, &create_info, 1)))
1930 goto exit;
1932 /* Step2: Move tables to the new database */
1933 if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
1935 uint nfiles= (uint) dirp->number_off_files;
1936 for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++)
1938 FILEINFO *file= dirp->dir_entry + idx;
1939 char *extension, tname[FN_REFLEN + 1];
1940 LEX_STRING table_str;
1941 DBUG_PRINT("info",("Examining: %s", file->name));
1943 /* skiping non-FRM files */
1944 if (my_strcasecmp(files_charset_info,
1945 (extension= fn_rext(file->name)), reg_ext))
1946 continue;
1948 /* A frm file found, add the table info rename list */
1949 *extension= '\0';
1951 table_str.length= filename_to_tablename(file->name,
1952 tname, sizeof(tname)-1);
1953 table_str.str= (char*) sql_memdup(tname, table_str.length + 1);
1954 Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0);
1955 Table_ident *new_ident= new Table_ident(thd, new_db, table_str, 0);
1956 if (!old_ident || !new_ident ||
1957 !sl->add_table_to_list(thd, old_ident, NULL,
1958 TL_OPTION_UPDATING, TL_IGNORE) ||
1959 !sl->add_table_to_list(thd, new_ident, NULL,
1960 TL_OPTION_UPDATING, TL_IGNORE))
1962 error= 1;
1963 my_dirend(dirp);
1964 goto exit;
1967 my_dirend(dirp);
1970 if ((table_list= thd->lex->query_tables) &&
1971 (error= mysql_rename_tables(thd, table_list, 1)))
1974 Failed to move all tables from the old database to the new one.
1975 In the best case mysql_rename_tables() moved all tables back to the old
1976 database. In the worst case mysql_rename_tables() moved some tables
1977 to the new database, then failed, then started to move the tables back,
1978 and then failed again. In this situation we have some tables in the
1979 old database and some tables in the new database.
1980 Let's delete the option file, and then the new database directory.
1981 If some tables were left in the new directory, rmdir() will fail.
1982 It garantees we never loose any tables.
1984 build_table_filename(path, sizeof(path)-1,
1985 new_db.str,"",MY_DB_OPT_FILE, 0);
1986 my_delete(path, MYF(MY_WME));
1987 length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0);
1988 if (length && path[length-1] == FN_LIBCHAR)
1989 path[length-1]=0; // remove ending '\'
1990 rmdir(path);
1991 goto exit;
1996 Step3: move all remaining files to the new db's directory.
1997 Skip db opt file: it's been created by mysql_create_db() in
1998 the new directory, and will be dropped by mysql_rm_db() in the old one.
1999 Trigger TRN and TRG files are be moved as regular files at the moment,
2000 without any special treatment.
2002 Triggers without explicit database qualifiers in table names work fine:
2003 use d1;
2004 create trigger trg1 before insert on t2 for each row set @a:=1
2005 rename database d1 to d2;
2007 TODO: Triggers, having the renamed database explicitely written
2008 in the table qualifiers.
2009 1. when the same database is renamed:
2010 create trigger d1.trg1 before insert on d1.t1 for each row set @a:=1;
2011 rename database d1 to d2;
2012 Problem: After database renaming, the trigger's body
2013 still points to the old database d1.
2014 2. when another database is renamed:
2015 create trigger d3.trg1 before insert on d3.t1 for each row
2016 insert into d1.t1 values (...);
2017 rename database d1 to d2;
2018 Problem: After renaming d1 to d2, the trigger's body
2019 in the database d3 still points to database d1.
2022 if ((dirp = my_dir(path,MYF(MY_DONT_SORT))))
2024 uint nfiles= (uint) dirp->number_off_files;
2025 for (uint idx=0 ; idx < nfiles ; idx++)
2027 FILEINFO *file= dirp->dir_entry + idx;
2028 char oldname[FN_REFLEN + 1], newname[FN_REFLEN + 1];
2029 DBUG_PRINT("info",("Examining: %s", file->name));
2031 /* skiping . and .. and MY_DB_OPT_FILE */
2032 if ((file->name[0] == '.' &&
2033 (!file->name[1] || (file->name[1] == '.' && !file->name[2]))) ||
2034 !my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE))
2035 continue;
2037 /* pass empty file name, and file->name as extension to avoid encoding */
2038 build_table_filename(oldname, sizeof(oldname)-1,
2039 old_db->str, "", file->name, 0);
2040 build_table_filename(newname, sizeof(newname)-1,
2041 new_db.str, "", file->name, 0);
2042 my_rename(oldname, newname, MYF(MY_WME));
2044 my_dirend(dirp);
2048 Step7: drop the old database.
2049 remove_db_from_cache(olddb) and query_cache_invalidate(olddb)
2050 are done inside mysql_rm_db(), no needs to execute them again.
2051 mysql_rm_db() also "unuses" if we drop the current database.
2053 error= mysql_rm_db(thd, old_db->str, 0, 1);
2055 /* Step8: logging */
2056 if (mysql_bin_log.is_open())
2058 int errcode= query_error_code(thd, TRUE);
2059 Query_log_event qinfo(thd, thd->query(), thd->query_length(),
2060 0, TRUE, errcode);
2061 thd->clear_error();
2062 error|= mysql_bin_log.write(&qinfo);
2065 /* Step9: Let's do "use newdb" if we renamed the current database */
2066 if (change_to_newdb)
2067 error|= mysql_change_db(thd, & new_db, FALSE);
2069 exit:
2070 pthread_mutex_lock(&LOCK_lock_db);
2071 /* Remove the databases from db lock cache */
2072 lock_db_delete(old_db->str, old_db->length);
2073 lock_db_delete(new_db.str, new_db.length);
2074 creating_database--;
2075 /* Signal waiting CREATE TABLE's to continue */
2076 pthread_cond_signal(&COND_refresh);
2077 pthread_mutex_unlock(&LOCK_lock_db);
2079 DBUG_RETURN(error);
2085 Check if there is directory for the database name.
2087 SYNOPSIS
2088 check_db_dir_existence()
2089 db_name database name
2091 RETURN VALUES
2092 FALSE There is directory for the specified database name.
2093 TRUE The directory does not exist.
2096 bool check_db_dir_existence(const char *db_name)
2098 char db_dir_path[FN_REFLEN + 1];
2099 uint db_dir_path_len;
2101 db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path) - 1,
2102 db_name, "", "", 0);
2104 if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR)
2105 db_dir_path[db_dir_path_len - 1]= 0;
2107 /* Check access. */
2109 return my_access(db_dir_path, F_OK);