#include "mysql_priv.h"#include <mysys_err.h>#include "sp.h"#include "events.h"#include <my_dir.h>#include <m_ctype.h>Include dependency graph for sql_db.cc:

Go to the source code of this file.
Classes | |
| struct | my_dblock_st |
| struct | my_dbopt_st |
Defines | |
| #define | MAX_DROP_TABLE_Q_LEN 1024 |
Typedefs | |
| typedef my_dblock_st | my_dblock_t |
| typedef my_dbopt_st | my_dbopt_t |
Functions | |
| static long | mysql_rm_known_files (THD *thd, MY_DIR *dirp, const char *db, const char *path, uint level, TABLE_LIST **dropped_tables) |
| static long | mysql_rm_arc_files (THD *thd, MY_DIR *dirp, const char *org_path) |
| static my_bool | rm_dir_w_symlink (const char *org_path, my_bool send_error) |
| static byte * | lock_db_get_key (my_dblock_t *ptr, uint *length, my_bool not_used __attribute__((unused))) |
| static void | lock_db_free_element (void *ptr) |
| static my_bool | lock_db_insert (const char *dbname, uint length) |
| void | lock_db_delete (const char *name, uint length) |
| static byte * | dboptions_get_key (my_dbopt_t *opt, uint *length, my_bool not_used __attribute__((unused))) |
| static void | write_to_binlog (THD *thd, char *query, uint q_len, char *db, uint db_len) |
| static void | free_dbopt (void *dbopt) |
| bool | my_database_names_init (void) |
| void | my_database_names_free (void) |
| void | my_dbopt_cleanup (void) |
| static my_bool | get_dbopt (const char *dbname, HA_CREATE_INFO *create) |
| static my_bool | put_dbopt (const char *dbname, HA_CREATE_INFO *create) |
| void | del_dbopt (const char *path) |
| static bool | write_db_opt (THD *thd, const char *path, HA_CREATE_INFO *create) |
| bool | load_db_opt (THD *thd, const char *path, HA_CREATE_INFO *create) |
| bool | load_db_opt_by_name (THD *thd, const char *db_name, HA_CREATE_INFO *db_create_info) |
| bool | mysql_create_db (THD *thd, char *db, HA_CREATE_INFO *create_info, bool silent) |
| bool | mysql_alter_db (THD *thd, const char *db, HA_CREATE_INFO *create_info) |
| bool | mysql_rm_db (THD *thd, char *db, bool if_exists, bool silent) |
| bool | mysql_change_db (THD *thd, const char *name, bool no_access_check) |
| static int | lock_databases (THD *thd, const char *db1, uint length1, const char *db2, uint length2) |
| bool | mysql_rename_db (THD *thd, LEX_STRING *old_db, LEX_STRING *new_db) |
| bool | check_db_dir_existence (const char *db_name) |
Variables | |
| const char * | del_exts [] = {".frm", ".BAK", ".TMD",".opt", NullS} |
| static TYPELIB | deletable_extentions |
| HASH | lock_db_cache |
| pthread_mutex_t | LOCK_lock_db |
| int | creating_database = 0 |
| static HASH | dboptions |
| static my_bool | dboptions_init = 0 |
| static rw_lock_t | LOCK_dboptions |
| #define MAX_DROP_TABLE_Q_LEN 1024 |
| typedef struct my_dblock_st my_dblock_t |
| typedef struct my_dbopt_st my_dbopt_t |
| bool check_db_dir_existence | ( | const char * | db_name | ) |
Definition at line 1728 of file sql_db.cc.
References build_table_filename(), F_OK, FN_LIBCHAR, FN_REFLEN, and my_access.
Referenced by mysql_change_db(), and mysqld_show_create_db().
01729 { 01730 char db_dir_path[FN_REFLEN]; 01731 uint db_dir_path_len; 01732 01733 db_dir_path_len= build_table_filename(db_dir_path, sizeof(db_dir_path), 01734 db_name, "", "", 0); 01735 01736 if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR) 01737 db_dir_path[db_dir_path_len - 1]= 0; 01738 01739 /* Check access. */ 01740 01741 return my_access(db_dir_path, F_OK); 01742 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static byte* dboptions_get_key | ( | my_dbopt_t * | opt, | |
| uint * | length, | |||
| my_bool not_used | __attribute__((unused)) | |||
| ) | [static] |
Definition at line 161 of file sql_db.cc.
References opt().
Referenced by my_database_names_init(), and my_dbopt_cleanup().
Here is the call graph for this function:

Here is the caller graph for this function:

| void del_dbopt | ( | const char * | path | ) |
Definition at line 351 of file sql_db.cc.
References dboptions, hash_delete(), hash_search(), LOCK_dboptions, opt(), rw_unlock, rw_wrlock, and strlen().
Referenced by mysql_rm_db().
00352 { 00353 my_dbopt_t *opt; 00354 rw_wrlock(&LOCK_dboptions); 00355 if ((opt= (my_dbopt_t *)hash_search(&dboptions, (const byte*) path, 00356 strlen(path)))) 00357 hash_delete(&dboptions, (byte*) opt); 00358 rw_unlock(&LOCK_dboptions); 00359 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void free_dbopt | ( | void * | dbopt | ) | [static] |
Definition at line 188 of file sql_db.cc.
Referenced by my_database_names_init(), and my_dbopt_cleanup().
Here is the caller graph for this function:

| static my_bool get_dbopt | ( | const char * | dbname, | |
| HA_CREATE_INFO * | create | |||
| ) | [static] |
Definition at line 274 of file sql_db.cc.
References dboptions, st_ha_create_information::default_table_charset, error, hash_search(), LOCK_dboptions, opt(), rw_rdlock, rw_unlock, and strlen().
Referenced by load_db_opt().
00275 { 00276 my_dbopt_t *opt; 00277 uint length; 00278 my_bool error= 1; 00279 00280 length= (uint) strlen(dbname); 00281 00282 rw_rdlock(&LOCK_dboptions); 00283 if ((opt= (my_dbopt_t*) hash_search(&dboptions, (byte*) dbname, length))) 00284 { 00285 create->default_table_charset= opt->charset; 00286 error= 0; 00287 } 00288 rw_unlock(&LOCK_dboptions); 00289 return error; 00290 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool load_db_opt | ( | THD * | thd, | |
| const char * | path, | |||
| HA_CREATE_INFO * | create | |||
| ) |
Definition at line 418 of file sql_db.cc.
References buf, bzero, DBUG_ENTER, DBUG_RETURN, default_charset_info, end_io_cache(), ER, ER_UNKNOWN_CHARACTER_SET, ER_UNKNOWN_COLLATION, error, get_charset_by_csname(), get_charset_by_name(), get_dbopt(), init_io_cache(), IO_SIZE, my_b_gets(), my_charset_latin1, my_close(), MY_CS_PRIMARY, my_isgraph, my_open(), MYF, O_SHARE, pos(), put_dbopt(), READ_CACHE, sql_print_error(), and strchr().
Referenced by load_db_opt_by_name(), and mysql_rename_db().
00419 { 00420 File file; 00421 char buf[256]; 00422 DBUG_ENTER("load_db_opt"); 00423 bool error=1; 00424 uint nbytes; 00425 00426 bzero((char*) create,sizeof(*create)); 00427 create->default_table_charset= thd->variables.collation_server; 00428 00429 /* Check if options for this database are already in the hash */ 00430 if (!get_dbopt(path, create)) 00431 DBUG_RETURN(0); 00432 00433 /* Otherwise, load options from the .opt file */ 00434 if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) 00435 goto err1; 00436 00437 IO_CACHE cache; 00438 if (init_io_cache(&cache, file, IO_SIZE, READ_CACHE, 0, 0, MYF(0))) 00439 goto err2; 00440 00441 while ((int) (nbytes= my_b_gets(&cache, (char*) buf, sizeof(buf))) > 0) 00442 { 00443 char *pos= buf+nbytes-1; 00444 /* Remove end space and control characters */ 00445 while (pos > buf && !my_isgraph(&my_charset_latin1, pos[-1])) 00446 pos--; 00447 *pos=0; 00448 if ((pos= strchr(buf, '='))) 00449 { 00450 if (!strncmp(buf,"default-character-set", (pos-buf))) 00451 { 00452 /* 00453 Try character set name, and if it fails 00454 try collation name, probably it's an old 00455 4.1.0 db.opt file, which didn't have 00456 separate default-character-set and 00457 default-collation commands. 00458 */ 00459 if (!(create->default_table_charset= 00460 get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) && 00461 !(create->default_table_charset= 00462 get_charset_by_name(pos+1, MYF(0)))) 00463 { 00464 sql_print_error("Error while loading database options: '%s':",path); 00465 sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1); 00466 create->default_table_charset= default_charset_info; 00467 } 00468 } 00469 else if (!strncmp(buf,"default-collation", (pos-buf))) 00470 { 00471 if (!(create->default_table_charset= get_charset_by_name(pos+1, 00472 MYF(0)))) 00473 { 00474 sql_print_error("Error while loading database options: '%s':",path); 00475 sql_print_error(ER(ER_UNKNOWN_COLLATION),pos+1); 00476 create->default_table_charset= default_charset_info; 00477 } 00478 } 00479 } 00480 } 00481 /* 00482 Put the loaded value into the hash. 00483 Note that another thread could've added the same 00484 entry to the hash after we called get_dbopt(), 00485 but it's not an error, as put_dbopt() takes this 00486 possibility into account. 00487 */ 00488 error= put_dbopt(path, create); 00489 00490 end_io_cache(&cache); 00491 err2: 00492 my_close(file,MYF(0)); 00493 err1: 00494 DBUG_RETURN(error); 00495 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool load_db_opt_by_name | ( | THD * | thd, | |
| const char * | db_name, | |||
| HA_CREATE_INFO * | db_create_info | |||
| ) |
Definition at line 528 of file sql_db.cc.
References build_table_filename(), FN_REFLEN, and load_db_opt().
Referenced by sp_head::fill_field_definition(), fill_schema_shemata(), mysql_change_db(), mysqld_show_create_db(), and set_table_default_charset().
00530 { 00531 char db_opt_path[FN_REFLEN]; 00532 00533 /* 00534 Pass an empty file name, and the database options file name as extension 00535 to avoid table name to file name encoding. 00536 */ 00537 (void) build_table_filename(db_opt_path, sizeof(db_opt_path), 00538 db_name, "", MY_DB_OPT_FILE, 0); 00539 00540 return load_db_opt(thd, db_opt_path, db_create_info); 00541 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int lock_databases | ( | THD * | thd, | |
| const char * | db1, | |||
| uint | length1, | |||
| const char * | db2, | |||
| uint | length2 | |||
| ) | [static] |
Definition at line 1407 of file sql_db.cc.
References COND_refresh, creating_database, creating_table, hash_search(), lock_db_cache, lock_db_delete(), lock_db_insert(), LOCK_lock_db, pthread_mutex_lock, pthread_mutex_unlock, and wait_for_condition().
Referenced by mysql_rename_db().
01409 { 01410 pthread_mutex_lock(&LOCK_lock_db); 01411 while (!thd->killed && 01412 (hash_search(&lock_db_cache,(byte*) db1, length1) || 01413 hash_search(&lock_db_cache,(byte*) db2, length2))) 01414 { 01415 wait_for_condition(thd, &LOCK_lock_db, &COND_refresh); 01416 pthread_mutex_lock(&LOCK_lock_db); 01417 } 01418 01419 if (thd->killed) 01420 { 01421 pthread_mutex_unlock(&LOCK_lock_db); 01422 return 1; 01423 } 01424 01425 lock_db_insert(db1, length1); 01426 lock_db_insert(db2, length2); 01427 creating_database++; 01428 01429 /* 01430 Wait if a concurent thread is creating a table at the same time. 01431 The assumption here is that it will not take too long until 01432 there is a point in time when a table is not created. 01433 */ 01434 01435 while (!thd->killed && creating_table) 01436 { 01437 wait_for_condition(thd, &LOCK_lock_db, &COND_refresh); 01438 pthread_mutex_lock(&LOCK_lock_db); 01439 } 01440 01441 if (thd->killed) 01442 { 01443 lock_db_delete(db1, length1); 01444 lock_db_delete(db2, length2); 01445 creating_database--; 01446 pthread_mutex_unlock(&LOCK_lock_db); 01447 pthread_cond_signal(&COND_refresh); 01448 return(1); 01449 } 01450 01451 /* 01452 We can unlock now as the hash will protect against anyone creating a table 01453 in the databases we are using 01454 */ 01455 pthread_mutex_unlock(&LOCK_lock_db); 01456 return 0; 01457 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void lock_db_delete | ( | const char * | name, | |
| uint | length | |||
| ) |
Definition at line 133 of file sql_db.cc.
References hash_delete(), hash_search(), lock_db_cache, LOCK_lock_db, opt(), and safe_mutex_assert_owner.
Referenced by lock_databases(), and mysql_rename_db().
00134 { 00135 my_dblock_t *opt; 00136 safe_mutex_assert_owner(&LOCK_lock_db); 00137 if ((opt= (my_dblock_t *)hash_search(&lock_db_cache, 00138 (const byte*) name, length))) 00139 hash_delete(&lock_db_cache, (byte*) opt); 00140 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void lock_db_free_element | ( | void * | ptr | ) | [static] |
| static byte* lock_db_get_key | ( | my_dblock_t * | ptr, | |
| uint * | length, | |||
| my_bool not_used | __attribute__((unused)) | |||
| ) | [static] |
Definition at line 62 of file sql_db.cc.
References my_dblock_st::name, and my_dblock_st::name_length.
Referenced by my_database_names_init().
00064 { 00065 *length= ptr->name_length; 00066 return (byte*) ptr->name; 00067 }
Here is the caller graph for this function:

Definition at line 92 of file sql_db.cc.
References DBUG_ENTER, DBUG_RETURN, error, hash_search(), lock_db_cache, LOCK_lock_db, my_free, my_hash_insert(), my_multi_malloc(), MY_WME, MY_ZEROFILL, MYF, NullS, opt(), safe_mutex_assert_owner, and strmov().
Referenced by lock_databases().
00093 { 00094 my_dblock_t *opt; 00095 my_bool error= 0; 00096 DBUG_ENTER("lock_db_insert"); 00097 00098 safe_mutex_assert_owner(&LOCK_lock_db); 00099 00100 if (!(opt= (my_dblock_t*) hash_search(&lock_db_cache, 00101 (byte*) dbname, length))) 00102 { 00103 /* Db is not in the hash, insert it */ 00104 char *tmp_name; 00105 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), 00106 &opt, (uint) sizeof(*opt), &tmp_name, length+1, 00107 NullS)) 00108 { 00109 error= 1; 00110 goto end; 00111 } 00112 00113 opt->name= tmp_name; 00114 strmov(opt->name, dbname); 00115 opt->name_length= length; 00116 00117 if ((error= my_hash_insert(&lock_db_cache, (byte*) opt))) 00118 { 00119 my_free((gptr) opt, MYF(0)); 00120 goto end; 00121 } 00122 } 00123 00124 end: 00125 DBUG_RETURN(error); 00126 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void my_database_names_free | ( | void | ) |
Definition at line 234 of file sql_db.cc.
References dboptions, hash_free(), lock_db_cache, LOCK_dboptions, and rwlock_destroy.
Referenced by clean_up().
00235 { 00236 if (dboptions_init) 00237 { 00238 dboptions_init= 0; 00239 hash_free(&dboptions); 00240 (void) rwlock_destroy(&LOCK_dboptions); 00241 hash_free(&lock_db_cache); 00242 } 00243 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool my_database_names_init | ( | void | ) |
Definition at line 208 of file sql_db.cc.
References dboptions, dboptions_get_key(), error, free_dbopt(), hash_init, lock_db_cache, lock_db_free_element(), lock_db_get_key(), LOCK_dboptions, lower_case_table_names, my_charset_bin, my_rwlock_init, NULL, and system_charset_info.
Referenced by init_common_variables().
00209 { 00210 bool error= 0; 00211 (void) my_rwlock_init(&LOCK_dboptions, NULL); 00212 if (!dboptions_init) 00213 { 00214 dboptions_init= 1; 00215 error= hash_init(&dboptions, lower_case_table_names ? 00216 &my_charset_bin : system_charset_info, 00217 32, 0, 0, (hash_get_key) dboptions_get_key, 00218 free_dbopt,0) || 00219 hash_init(&lock_db_cache, lower_case_table_names ? 00220 &my_charset_bin : system_charset_info, 00221 32, 0, 0, (hash_get_key) lock_db_get_key, 00222 lock_db_free_element,0); 00223 00224 } 00225 return error; 00226 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void my_dbopt_cleanup | ( | void | ) |
Definition at line 250 of file sql_db.cc.
References dboptions, dboptions_get_key(), free_dbopt(), hash_free(), hash_init, LOCK_dboptions, lower_case_table_names, my_charset_bin, rw_unlock, rw_wrlock, and system_charset_info.
Referenced by reload_acl_and_cache().
00251 { 00252 rw_wrlock(&LOCK_dboptions); 00253 hash_free(&dboptions); 00254 hash_init(&dboptions, lower_case_table_names ? 00255 &my_charset_bin : system_charset_info, 00256 32, 0, 0, (hash_get_key) dboptions_get_key, 00257 free_dbopt,0); 00258 rw_unlock(&LOCK_dboptions); 00259 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_alter_db | ( | THD * | thd, | |
| const char * | db, | |||
| HA_CREATE_INFO * | create_info | |||
| ) |
Definition at line 723 of file sql_db.cc.
References build_table_filename(), DBUG_ENTER, DBUG_RETURN, st_ha_create_information::default_table_charset, error, exit, FN_REFLEN, ha_binlog_log_query, MYSQL_LOG::is_open(), LOCK_mysql_create_db, LOGCOM_ALTER_DB, mysql_bin_log, path, pthread_mutex_lock, pthread_mutex_unlock, Query_log_event::query, send_ok(), start_waiting_global_read_lock(), strcmp(), strlen(), TRUE, VOID, wait_if_global_read_lock(), MYSQL_BIN_LOG::write(), and write_db_opt().
Referenced by mysql_execute_command().
00724 { 00725 char path[FN_REFLEN+16]; 00726 long result=1; 00727 int error= 0; 00728 DBUG_ENTER("mysql_alter_db"); 00729 00730 /* 00731 Do not alter database if another thread is holding read lock. 00732 Wait for global read lock before acquiring LOCK_mysql_create_db. 00733 After wait_if_global_read_lock() we have protection against another 00734 global read lock. If we would acquire LOCK_mysql_create_db first, 00735 another thread could step in and get the global read lock before we 00736 reach wait_if_global_read_lock(). If this thread tries the same as we 00737 (admin a db), it would then go and wait on LOCK_mysql_create_db... 00738 Furthermore wait_if_global_read_lock() checks if the current thread 00739 has the global read lock and refuses the operation with 00740 ER_CANT_UPDATE_WITH_READLOCK if applicable. 00741 */ 00742 if ((error=wait_if_global_read_lock(thd,0,1))) 00743 goto exit2; 00744 00745 VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); 00746 00747 /* 00748 Recreate db options file: /dbpath/.db.opt 00749 We pass MY_DB_OPT_FILE as "extension" to avoid 00750 "table name to file name" encoding. 00751 */ 00752 build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE, 0); 00753 if ((error=write_db_opt(thd, path, create_info))) 00754 goto exit; 00755 00756 /* 00757 Change options if current database is being altered 00758 TODO: Delete this code 00759 */ 00760 if (thd->db && !strcmp(thd->db,db)) 00761 { 00762 thd->db_charset= create_info->default_table_charset ? 00763 create_info->default_table_charset : 00764 thd->variables.collation_server; 00765 thd->variables.collation_database= thd->db_charset; 00766 } 00767 00768 ha_binlog_log_query(thd, 0, LOGCOM_ALTER_DB, 00769 thd->query, thd->query_length, 00770 db, ""); 00771 00772 if (mysql_bin_log.is_open()) 00773 { 00774 Query_log_event qinfo(thd, thd->query, thd->query_length, 0, 00775 /* suppress_use */ TRUE); 00776 00777 /* 00778 Write should use the database being created as the "current 00779 database" and not the threads current database, which is the 00780 default. 00781 */ 00782 qinfo.db = db; 00783 qinfo.db_len = strlen(db); 00784 00785 thd->clear_error(); 00786 mysql_bin_log.write(&qinfo); 00787 } 00788 send_ok(thd, result); 00789 00790 exit: 00791 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); 00792 start_waiting_global_read_lock(thd); 00793 exit2: 00794 DBUG_RETURN(error); 00795 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1298 of file sql_db.cc.
References acl_get(), check_db_dir_existence(), check_db_name(), check_grant_db(), COM_INIT_DB, DB_ACLS, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_ha_create_information::default_table_charset, ER, ER_BAD_DB_ERROR, ER_DBACCESS_DENIED_ERROR, ER_NO_DB_ERROR, ER_WRONG_DB_NAME, FALSE, general_log_print(), grant_option, information_schema_name, LINT_INIT, load_db_opt_by_name(), my_error(), my_free, my_message(), my_strcasecmp, my_strdup(), MY_WME, MYF, NULL, SELECT_ACL, LEX_STRING::str, strlen(), system_charset_info, test_all_bits, and x_free.
Referenced by check_user(), db_create_event(), db_create_routine(), db_load_routine(), dispatch_command(), sp_head::execute(), mysql_execute_command(), mysql_rename_db(), and sp_use_new_db().
01299 { 01300 int path_length, db_length; 01301 char *db_name; 01302 bool system_db= 0; 01303 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01304 ulong db_access; 01305 Security_context *sctx= thd->security_ctx; 01306 LINT_INIT(db_access); 01307 #endif 01308 DBUG_ENTER("mysql_change_db"); 01309 DBUG_PRINT("enter",("name: '%s'",name)); 01310 01311 if (name == NULL || name[0] == '\0' && no_access_check == FALSE) 01312 { 01313 my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0)); 01314 DBUG_RETURN(1); /* purecov: inspected */ 01315 } 01316 else if (name[0] == '\0') 01317 { 01318 /* Called from SP to restore the original database, which was NULL */ 01319 DBUG_ASSERT(no_access_check); 01320 system_db= 1; 01321 db_name= NULL; 01322 db_length= 0; 01323 goto end; 01324 } 01325 /* 01326 Now we need to make a copy because check_db_name requires a 01327 non-constant argument. TODO: fix check_db_name. 01328 */ 01329 if ((db_name= my_strdup(name, MYF(MY_WME))) == NULL) 01330 DBUG_RETURN(1); /* the error is set */ 01331 db_length= strlen(db_name); 01332 if (check_db_name(db_name)) 01333 { 01334 my_error(ER_WRONG_DB_NAME, MYF(0), db_name); 01335 my_free(db_name, MYF(0)); 01336 DBUG_RETURN(1); 01337 } 01338 DBUG_PRINT("info",("Use database: %s", db_name)); 01339 if (!my_strcasecmp(system_charset_info, db_name, information_schema_name.str)) 01340 { 01341 system_db= 1; 01342 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01343 db_access= SELECT_ACL; 01344 #endif 01345 goto end; 01346 } 01347 01348 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01349 if (!no_access_check) 01350 { 01351 if (test_all_bits(sctx->master_access, DB_ACLS)) 01352 db_access=DB_ACLS; 01353 else 01354 db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name, 0) | 01355 sctx->master_access); 01356 if (!(db_access & DB_ACLS) && (!grant_option || 01357 check_grant_db(thd,db_name))) 01358 { 01359 my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), 01360 sctx->priv_user, 01361 sctx->priv_host, 01362 db_name); 01363 general_log_print(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR), 01364 sctx->priv_user, sctx->priv_host, db_name); 01365 my_free(db_name,MYF(0)); 01366 DBUG_RETURN(1); 01367 } 01368 } 01369 #endif 01370 01371 if (check_db_dir_existence(db_name)) 01372 { 01373 my_error(ER_BAD_DB_ERROR, MYF(0), db_name); 01374 my_free(db_name, MYF(0)); 01375 DBUG_RETURN(1); 01376 } 01377 01378 end: 01379 x_free(thd->db); 01380 DBUG_ASSERT(db_name == NULL || db_name[0] != '\0'); 01381 thd->reset_db(db_name, db_length); // THD::~THD will free this 01382 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01383 if (!no_access_check) 01384 sctx->db_access= db_access; 01385 #endif 01386 if (system_db) 01387 { 01388 thd->db_charset= system_charset_info; 01389 thd->variables.collation_database= system_charset_info; 01390 } 01391 else 01392 { 01393 HA_CREATE_INFO create; 01394 01395 load_db_opt_by_name(thd, db_name, &create); 01396 01397 thd->db_charset= create.default_table_charset ? 01398 create.default_table_charset : 01399 thd->variables.collation_server; 01400 thd->variables.collation_database= thd->db_charset; 01401 } 01402 DBUG_RETURN(0); 01403 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_create_db | ( | THD * | thd, | |
| char * | db, | |||
| HA_CREATE_INFO * | create_info, | |||
| bool | silent | |||
| ) |
Definition at line 568 of file sql_db.cc.
References build_table_filename(), create_options, DBUG_ENTER, DBUG_RETURN, EE_STAT, ER, ER_CANT_CREATE_DB, ER_DB_CREATE_EXISTS, error, exit, FN_LIBCHAR, FN_REFLEN, ha_binlog_log_query, HA_LEX_CREATE_IF_NOT_EXISTS, information_schema_name, MYSQL_LOG::is_open(), LOCK_mysql_create_db, LOGCOM_CREATE_DB, my_errno, my_error(), my_mkdir(), my_stat(), MY_STAT, my_strcasecmp, MYF, mysql_bin_log, NullS, st_ha_create_information::options, path, pthread_mutex_lock, pthread_mutex_unlock, push_warning_printf(), send_ok(), start_waiting_global_read_lock(), LEX_STRING::str, strlen(), strmake(), strxmov(), system_charset_info, TRUE, VOID, wait_if_global_read_lock(), MYSQL_ERROR::WARN_LEVEL_NOTE, MYSQL_BIN_LOG::write(), and write_db_opt().
Referenced by dispatch_command(), mysql_execute_command(), and mysql_rename_db().
00570 { 00571 char path[FN_REFLEN+16]; 00572 char tmp_query[FN_REFLEN+16]; 00573 long result= 1; 00574 int error= 0; 00575 MY_STAT stat_info; 00576 uint create_options= create_info ? create_info->options : 0; 00577 uint path_len; 00578 DBUG_ENTER("mysql_create_db"); 00579 00580 /* do not create 'information_schema' db */ 00581 if (!my_strcasecmp(system_charset_info, db, information_schema_name.str)) 00582 { 00583 my_error(ER_DB_CREATE_EXISTS, MYF(0), db); 00584 DBUG_RETURN(-1); 00585 } 00586 00587 /* 00588 Do not create database if another thread is holding read lock. 00589 Wait for global read lock before acquiring LOCK_mysql_create_db. 00590 After wait_if_global_read_lock() we have protection against another 00591 global read lock. If we would acquire LOCK_mysql_create_db first, 00592 another thread could step in and get the global read lock before we 00593 reach wait_if_global_read_lock(). If this thread tries the same as we 00594 (admin a db), it would then go and wait on LOCK_mysql_create_db... 00595 Furthermore wait_if_global_read_lock() checks if the current thread 00596 has the global read lock and refuses the operation with 00597 ER_CANT_UPDATE_WITH_READLOCK if applicable. 00598 */ 00599 if (wait_if_global_read_lock(thd, 0, 1)) 00600 { 00601 error= -1; 00602 goto exit2; 00603 } 00604 00605 VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); 00606 00607 /* Check directory */ 00608 path_len= build_table_filename(path, sizeof(path), db, "", "", 0); 00609 path[path_len-1]= 0; // Remove last '/' from path 00610 00611 if (my_stat(path,&stat_info,MYF(0))) 00612 { 00613 if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) 00614 { 00615 my_error(ER_DB_CREATE_EXISTS, MYF(0), db); 00616 error= -1; 00617 goto exit; 00618 } 00619 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 00620 ER_DB_CREATE_EXISTS, ER(ER_DB_CREATE_EXISTS), db); 00621 if (!silent) 00622 send_ok(thd); 00623 error= 0; 00624 goto exit; 00625 } 00626 else 00627 { 00628 if (my_errno != ENOENT) 00629 { 00630 my_error(EE_STAT, MYF(0), path, my_errno); 00631 goto exit; 00632 } 00633 if (my_mkdir(path,0777,MYF(0)) < 0) 00634 { 00635 my_error(ER_CANT_CREATE_DB, MYF(0), db, my_errno); 00636 error= -1; 00637 goto exit; 00638 } 00639 } 00640 00641 path[path_len-1]= FN_LIBCHAR; 00642 strmake(path+path_len, MY_DB_OPT_FILE, sizeof(path)-path_len-1); 00643 if (write_db_opt(thd, path, create_info)) 00644 { 00645 /* 00646 Could not create options file. 00647 Restore things to beginning. 00648 */ 00649 path[path_len]= 0; 00650 if (rmdir(path) >= 0) 00651 { 00652 error= -1; 00653 goto exit; 00654 } 00655 /* 00656 We come here when we managed to create the database, but not the option 00657 file. In this case it's best to just continue as if nothing has 00658 happened. (This is a very unlikely senario) 00659 */ 00660 } 00661 00662 if (!silent) 00663 { 00664 char *query; 00665 uint query_length; 00666 00667 if (!thd->query) // Only in replication 00668 { 00669 query= tmp_query; 00670 query_length= (uint) (strxmov(tmp_query,"create database `", 00671 db, "`", NullS) - tmp_query); 00672 } 00673 else 00674 { 00675 query= thd->query; 00676 query_length= thd->query_length; 00677 } 00678 00679 ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB, 00680 query, query_length, 00681 db, ""); 00682 00683 if (mysql_bin_log.is_open()) 00684 { 00685 Query_log_event qinfo(thd, query, query_length, 0, 00686 /* suppress_use */ TRUE); 00687 00688 /* 00689 Write should use the database being created as the "current 00690 database" and not the threads current database, which is the 00691 default. If we do not change the "current database" to the 00692 database being created, the CREATE statement will not be 00693 replicated when using --binlog-do-db to select databases to be 00694 replicated. 00695 00696 An example (--binlog-do-db=sisyfos): 00697 00698 CREATE DATABASE bob; # Not replicated 00699 USE bob; # 'bob' is the current database 00700 CREATE DATABASE sisyfos; # Not replicated since 'bob' is 00701 # current database. 00702 USE sisyfos; # Will give error on slave since 00703 # database does not exist. 00704 */ 00705 qinfo.db = db; 00706 qinfo.db_len = strlen(db); 00707 00708 mysql_bin_log.write(&qinfo); 00709 } 00710 send_ok(thd, result); 00711 } 00712 00713 exit: 00714 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); 00715 start_waiting_global_read_lock(thd); 00716 exit2: 00717 DBUG_RETURN(error); 00718 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_rename_db | ( | THD * | thd, | |
| LEX_STRING * | old_db, | |||
| LEX_STRING * | new_db | |||
| ) |
Definition at line 1494 of file sql_db.cc.
References build_table_filename(), COND_refresh, creating_database, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_ha_create_information::default_table_charset, st_my_dir::dir_entry, ER_BAD_DB_ERROR, error, exit, F_OK, filename_to_tablename(), files_charset_info, FN_LIBCHAR, FN_REFLEN, fn_rext(), MYSQL_LOG::is_open(), LEX_STRING::length, load_db_opt(), lock_databases(), lock_db_delete(), LOCK_lock_db, my_access, my_delete(), my_dir(), my_dirend(), MY_DONT_SORT, my_error(), my_rename(), my_strcasecmp, MY_WME, MYF, mysql_bin_log, mysql_change_db(), mysql_create_db(), mysql_rename_tables(), mysql_rm_db(), charset_info_st::name, NULL, st_my_dir::number_off_files, path, pthread_mutex_lock, pthread_mutex_unlock, Query_log_event::query, reg_ext, sql_memdup(), LEX_STRING::str, strcmp(), TL_IGNORE, TL_OPTION_UPDATING, TRUE, and MYSQL_BIN_LOG::write().
Referenced by mysql_execute_command().
01495 { 01496 int error= 0, change_to_newdb= 0; 01497 char path[FN_REFLEN+16]; 01498 uint length; 01499 HA_CREATE_INFO create_info; 01500 MY_DIR *dirp; 01501 TABLE_LIST *table_list; 01502 SELECT_LEX *sl= thd->lex->current_select; 01503 DBUG_ENTER("mysql_rename_db"); 01504 01505 if (lock_databases(thd, old_db->str, old_db->length, 01506 new_db->str, new_db->length)) 01507 return 1; 01508 01509 /* 01510 Let's remember if we should do "USE newdb" afterwards. 01511 thd->db will be cleared in mysql_rename_db() 01512 */ 01513 if (thd->db && !strcmp(thd->db, old_db->str)) 01514 change_to_newdb= 1; 01515 01516 build_table_filename(path, sizeof(path)-1, 01517 old_db->str, "", MY_DB_OPT_FILE, 0); 01518 if ((load_db_opt(thd, path, &create_info))) 01519 create_info.default_table_charset= thd->variables.collation_server; 01520 01521 length= build_table_filename(path, sizeof(path)-1, old_db->str, "", "", 0); 01522 if (length && path[length-1] == FN_LIBCHAR) 01523 path[length-1]=0; // remove ending '\' 01524 if ((error= my_access(path,F_OK))) 01525 { 01526 my_error(ER_BAD_DB_ERROR, MYF(0), old_db->str); 01527 goto exit; 01528 } 01529 01530 /* Step1: Create the new database */ 01531 if ((error= mysql_create_db(thd, new_db->str, &create_info, 1))) 01532 goto exit; 01533 01534 /* Step2: Move tables to the new database */ 01535 if ((dirp = my_dir(path,MYF(MY_DONT_SORT)))) 01536 { 01537 uint nfiles= (uint) dirp->number_off_files; 01538 for (uint idx=0 ; idx < nfiles && !thd->killed ; idx++) 01539 { 01540 FILEINFO *file= dirp->dir_entry + idx; 01541 char *extension, tname[FN_REFLEN]; 01542 LEX_STRING table_str; 01543 DBUG_PRINT("info",("Examining: %s", file->name)); 01544 01545 /* skiping non-FRM files */ 01546 if (my_strcasecmp(files_charset_info, 01547 (extension= fn_rext(file->name)), reg_ext)) 01548 continue; 01549 01550 /* A frm file found, add the table info rename list */ 01551 *extension= '\0'; 01552 01553 table_str.length= filename_to_tablename(file->name, 01554 tname, sizeof(tname)-1); 01555 table_str.str= sql_memdup(tname, table_str.length + 1); 01556 Table_ident *old_ident= new Table_ident(thd, *old_db, table_str, 0); 01557 Table_ident *new_ident= new Table_ident(thd, *new_db, table_str, 0); 01558 if (!old_ident || !new_ident || 01559 !sl->add_table_to_list(thd, old_ident, NULL, 01560 TL_OPTION_UPDATING, TL_IGNORE) || 01561 !sl->add_table_to_list(thd, new_ident, NULL, 01562 TL_OPTION_UPDATING, TL_IGNORE)) 01563 { 01564 error= 1; 01565 my_dirend(dirp); 01566 goto exit; 01567 } 01568 } 01569 my_dirend(dirp); 01570 } 01571 01572 if ((table_list= thd->lex->query_tables) && 01573 (error= mysql_rename_tables(thd, table_list, 1))) 01574 { 01575 /* 01576 Failed to move all tables from the old database to the new one. 01577 In the best case mysql_rename_tables() moved all tables back to the old 01578 database. In the worst case mysql_rename_tables() moved some tables 01579 to the new database, then failed, then started to move the tables back, and 01580 then failed again. In this situation we have some tables in the 01581 old database and some tables in the new database. 01582 Let's delete the option file, and then the new database directory. 01583 If some tables were left in the new directory, rmdir() will fail. 01584 It garantees we never loose any tables. 01585 */ 01586 build_table_filename(path, sizeof(path)-1, 01587 new_db->str,"",MY_DB_OPT_FILE, 0); 01588 my_delete(path, MYF(MY_WME)); 01589 length= build_table_filename(path, sizeof(path)-1, new_db->str, "", "", 0); 01590 if (length && path[length-1] == FN_LIBCHAR) 01591 path[length-1]=0; // remove ending '\' 01592 rmdir(path); 01593 goto exit; 01594 } 01595 01596 01597 /* 01598 Step3: move all remaining files to the new db's directory. 01599 Skip db opt file: it's been created by mysql_create_db() in 01600 the new directory, and will be dropped by mysql_rm_db() in the old one. 01601 Trigger TRN and TRG files are be moved as regular files at the moment, 01602 without any special treatment. 01603 01604 Triggers without explicit database qualifiers in table names work fine: 01605 use d1; 01606 create trigger trg1 before insert on t2 for each row set @a:=1 01607 rename database d1 to d2; 01608 01609 TODO: Triggers, having the renamed database explicitely written 01610 in the table qualifiers. 01611 1. when the same database is renamed: 01612 create trigger d1.trg1 before insert on d1.t1 for each row set @a:=1; 01613 rename database d1 to d2; 01614 Problem: After database renaming, the trigger's body 01615 still points to the old database d1. 01616 2. when another database is renamed: 01617 create trigger d3.trg1 before insert on d3.t1 for each row 01618 insert into d1.t1 values (...); 01619 rename database d1 to d2; 01620 Problem: After renaming d1 to d2, the trigger's body 01621 in the database d3 still points to database d1. 01622 */ 01623 01624 if ((dirp = my_dir(path,MYF(MY_DONT_SORT)))) 01625 { 01626 uint nfiles= (uint) dirp->number_off_files; 01627 for (uint idx=0 ; idx < nfiles ; idx++) 01628 { 01629 FILEINFO *file= dirp->dir_entry + idx; 01630 char oldname[FN_REFLEN], newname[FN_REFLEN]; 01631 DBUG_PRINT("info",("Examining: %s", file->name)); 01632 01633 /* skiping . and .. and MY_DB_OPT_FILE */ 01634 if ((file->name[0] == '.' && 01635 (!file->name[1] || (file->name[1] == '.' && !file->name[2]))) || 01636 !my_strcasecmp(files_charset_info, file->name, MY_DB_OPT_FILE)) 01637 continue; 01638 01639 /* pass empty file name, and file->name as extension to avoid encoding */ 01640 build_table_filename(oldname, sizeof(oldname)-1, 01641 old_db->str, "", file->name, 0); 01642 build_table_filename(newname, sizeof(newname)-1, 01643 new_db->str, "", file->name, 0); 01644 my_rename(oldname, newname, MYF(MY_WME)); 01645 } 01646 my_dirend(dirp); 01647 } 01648 01649 /* 01650 Step4: TODO: moving stored procedures in the 'proc' system table 01651 We need a new function: sp_move_db_routines(thd, olddb, newdb) 01652 Which will basically have the same effect with: 01653 UPDATE proc SET db='newdb' WHERE db='olddb' 01654 Note, for 5.0 to 5.1 upgrade purposes we don't really need it. 01655 01656 The biggest problem here is that we can't have a lock on LOCK_open() while 01657 calling open_table() for 'proc'. 01658 01659 Two solutions: 01660 - Start by opening the 'event' and 'proc' (and other) tables for write 01661 even before creating the 'to' database. (This will have the nice 01662 effect of blocking another 'rename database' while the lock is active). 01663 - Use the solution "Disable create of new tables during lock table" 01664 01665 For an example of how to read through all rows, see: 01666 sql_help.cc::search_topics() 01667 */ 01668 01669 /* 01670 Step5: TODO: moving events in the 'event' system table 01671 We need a new function evex_move_db_events(thd, olddb, newdb) 01672 Which will have the same effect with: 01673 UPDATE event SET db='newdb' WHERE db='olddb' 01674 Note, for 5.0 to 5.1 upgrade purposes we don't really need it. 01675 */ 01676 01677 /* 01678 Step6: TODO: moving grants in the 'db', 'tables_priv', 'columns_priv'. 01679 Update each grant table, doing the same with: 01680 UPDATE system_table SET db='newdb' WHERE db='olddb' 01681 */ 01682 01683 /* 01684 Step7: drop the old database. 01685 remove_db_from_cache(olddb) and query_cache_invalidate(olddb) 01686 are done inside mysql_rm_db(), no needs to execute them again. 01687 mysql_rm_db() also "unuses" if we drop the current database. 01688 */ 01689 error= mysql_rm_db(thd, old_db->str, 0, 1); 01690 01691 /* Step8: logging */ 01692 if (mysql_bin_log.is_open()) 01693 { 01694 Query_log_event qinfo(thd, thd->query, thd->query_length, 0, TRUE); 01695 thd->clear_error(); 01696 mysql_bin_log.write(&qinfo); 01697 } 01698 01699 /* Step9: Let's do "use newdb" if we renamed the current database */ 01700 if (change_to_newdb) 01701 error|= mysql_change_db(thd, new_db->str, 0); 01702 01703 exit: 01704 pthread_mutex_lock(&LOCK_lock_db); 01705 /* Remove the databases from db lock cache */ 01706 lock_db_delete(old_db->str, old_db->length); 01707 lock_db_delete(new_db->str, new_db->length); 01708 creating_database--; 01709 /* Signal waiting CREATE TABLE's to continue */ 01710 pthread_cond_signal(&COND_refresh); 01711 pthread_mutex_unlock(&LOCK_lock_db); 01712 01713 DBUG_RETURN(error); 01714 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static long mysql_rm_arc_files | ( | THD * | thd, | |
| MY_DIR * | dirp, | |||
| const char * | org_path | |||
| ) | [static] |
Definition at line 1191 of file sql_db.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_my_dir::dir_entry, err, fn_ext(), FN_REFLEN, my_delete_with_symlink(), my_dirend(), my_isdigit, MY_WME, MYF, fileinfo::name, NullS, st_my_dir::number_off_files, rm_dir_w_symlink(), strxmov(), and system_charset_info.
Referenced by mysql_rm_known_files().
01193 { 01194 long deleted= 0; 01195 ulong found_other_files= 0; 01196 char filePath[FN_REFLEN]; 01197 DBUG_ENTER("mysql_rm_arc_files"); 01198 DBUG_PRINT("enter", ("path: %s", org_path)); 01199 01200 for (uint idx=0 ; 01201 idx < (uint) dirp->number_off_files && !thd->killed ; 01202 idx++) 01203 { 01204 FILEINFO *file=dirp->dir_entry+idx; 01205 char *extension, *revision; 01206 DBUG_PRINT("info",("Examining: %s", file->name)); 01207 01208 /* skiping . and .. */ 01209 if (file->name[0] == '.' && (!file->name[1] || 01210 (file->name[1] == '.' && !file->name[2]))) 01211 continue; 01212 01213 extension= fn_ext(file->name); 01214 if (extension[0] != '.' || 01215 extension[1] != 'f' || extension[2] != 'r' || 01216 extension[3] != 'm' || extension[4] != '-') 01217 { 01218 found_other_files++; 01219 continue; 01220 } 01221 revision= extension+5; 01222 while (*revision && my_isdigit(system_charset_info, *revision)) 01223 revision++; 01224 if (*revision) 01225 { 01226 found_other_files++; 01227 continue; 01228 } 01229 strxmov(filePath, org_path, "/", file->name, NullS); 01230 if (my_delete_with_symlink(filePath,MYF(MY_WME))) 01231 { 01232 goto err; 01233 } 01234 } 01235 if (thd->killed) 01236 goto err; 01237 01238 my_dirend(dirp); 01239 01240 /* 01241 If the directory is a symbolic link, remove the link first, then 01242 remove the directory the symbolic link pointed at 01243 */ 01244 if (!found_other_files && 01245 rm_dir_w_symlink(org_path, 0)) 01246 DBUG_RETURN(-1); 01247 DBUG_RETURN(deleted); 01248 01249 err: 01250 my_dirend(dirp); 01251 DBUG_RETURN(-1); 01252 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 815 of file sql_db.cc.
References build_table_filename(), DBUG_ENTER, DBUG_RETURN, del_dbopt(), Events::drop_schema_events(), ER, ER_DB_DROP_EXISTS, error, exit, FN_REFLEN, ha_drop_database(), MYSQL_LOG::is_open(), LOCK_mysql_create_db, LOCK_open, MAX_DROP_TABLE_Q_LEN, my_dir(), MY_DONT_SORT, my_error(), MYF, mysql_bin_log, mysql_rm_known_files(), st_table_list::next_local, NULL, NullS, path, pthread_mutex_lock, pthread_mutex_unlock, push_warning_printf(), remove_db_from_cache(), send_ok(), SERVER_STATUS_DB_DROPPED, sp_drop_db_routines(), start_waiting_global_read_lock(), strcmp(), strlen(), strmov(), strxmov(), st_table_list::table_name, TRUE, VOID, wait_if_global_read_lock(), MYSQL_ERROR::WARN_LEVEL_NOTE, MYSQL_BIN_LOG::write(), and write_to_binlog().
Referenced by dispatch_command(), mysql_execute_command(), and mysql_rename_db().
00816 { 00817 long deleted=0; 00818 int error= 0; 00819 char path[FN_REFLEN+16]; 00820 MY_DIR *dirp; 00821 uint length; 00822 TABLE_LIST* dropped_tables= 0; 00823 DBUG_ENTER("mysql_rm_db"); 00824 00825 /* 00826 Do not drop database if another thread is holding read lock. 00827 Wait for global read lock before acquiring LOCK_mysql_create_db. 00828 After wait_if_global_read_lock() we have protection against another 00829 global read lock. If we would acquire LOCK_mysql_create_db first, 00830 another thread could step in and get the global read lock before we 00831 reach wait_if_global_read_lock(). If this thread tries the same as we 00832 (admin a db), it would then go and wait on LOCK_mysql_create_db... 00833 Furthermore wait_if_global_read_lock() checks if the current thread 00834 has the global read lock and refuses the operation with 00835 ER_CANT_UPDATE_WITH_READLOCK if applicable. 00836 */ 00837 if (wait_if_global_read_lock(thd, 0, 1)) 00838 { 00839 error= -1; 00840 goto exit2; 00841 } 00842 00843 VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); 00844 00845 length= build_table_filename(path, sizeof(path), db, "", "", 0); 00846 strmov(path+length, MY_DB_OPT_FILE); // Append db option file name 00847 del_dbopt(path); // Remove dboption hash entry 00848 path[length]= '\0'; // Remove file name 00849 00850 /* See if the directory exists */ 00851 if (!(dirp= my_dir(path,MYF(MY_DONT_SORT)))) 00852 { 00853 if (!if_exists) 00854 { 00855 error= -1; 00856 my_error(ER_DB_DROP_EXISTS, MYF(0), db); 00857 goto exit; 00858 } 00859 else 00860 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, 00861 ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db); 00862 } 00863 else 00864 { 00865 pthread_mutex_lock(&LOCK_open); 00866 remove_db_from_cache(db); 00867 pthread_mutex_unlock(&LOCK_open); 00868 00869 00870 error= -1; 00871 if ((deleted= mysql_rm_known_files(thd, dirp, db, path, 0, 00872 &dropped_tables)) >= 0) 00873 { 00874 ha_drop_database(path); 00875 query_cache_invalidate1(db); 00876 error = 0; 00877 } 00878 } 00879 if (!silent && deleted>=0) 00880 { 00881 const char *query; 00882 ulong query_length; 00883 if (!thd->query) 00884 { 00885 /* The client used the old obsolete mysql_drop_db() call */ 00886 query= path; 00887 query_length= (uint) (strxmov(path, "drop database `", db, "`", 00888 NullS) - path); 00889 } 00890 else 00891 { 00892 query =thd->query; 00893 query_length= thd->query_length; 00894 } 00895 if (mysql_bin_log.is_open()) 00896 { 00897 Query_log_event qinfo(thd, query, query_length, 0, 00898 /* suppress_use */ TRUE); 00899 /* 00900 Write should use the database being created as the "current 00901 database" and not the threads current database, which is the 00902 default. 00903 */ 00904 qinfo.db = db; 00905 qinfo.db_len = strlen(db); 00906 00907 thd->clear_error(); 00908 mysql_bin_log.write(&qinfo); 00909 } 00910 thd->server_status|= SERVER_STATUS_DB_DROPPED; 00911 send_ok(thd, (ulong) deleted); 00912 thd->server_status&= ~SERVER_STATUS_DB_DROPPED; 00913 } 00914 else if (mysql_bin_log.is_open()) 00915 { 00916 char *query, *query_pos, *query_end, *query_data_start; 00917 TABLE_LIST *tbl; 00918 uint db_len; 00919 00920 if (!(query= thd->alloc(MAX_DROP_TABLE_Q_LEN))) 00921 goto exit; /* not much else we can do */ 00922 query_pos= query_data_start= strmov(query,"drop table "); 00923 query_end= query + MAX_DROP_TABLE_Q_LEN; 00924 db_len= strlen(db); 00925 00926 for (tbl= dropped_tables; tbl; tbl= tbl->next_local) 00927 { 00928 uint tbl_name_len; 00929 00930 /* 3 for the quotes and the comma*/ 00931 tbl_name_len= strlen(tbl->table_name) + 3; 00932 if (query_pos + tbl_name_len + 1 >= query_end) 00933 { 00934 write_to_binlog(thd, query, query_pos -1 - query, db, db_len); 00935 query_pos= query_data_start; 00936 } 00937 00938 *query_pos++ = '`'; 00939 query_pos= strmov(query_pos,tbl->table_name); 00940 *query_pos++ = '`'; 00941 *query_pos++ = ','; 00942 } 00943 00944 if (query_pos != query_data_start) 00945 { 00946 write_to_binlog(thd, query, query_pos -1 - query, db, db_len); 00947 } 00948 } 00949 00950 exit: 00951 (void)sp_drop_db_routines(thd, db); /* QQ Ignore errors for now */ 00952 error= Events::drop_schema_events(thd, db); 00953 /* 00954 If this database was the client's selected database, we silently 00955 change the client's selected database to nothing (to have an empty 00956 SELECT DATABASE() in the future). For this we free() thd->db and set 00957 it to 0. 00958 */ 00959 if (thd->db && !strcmp(thd->db, db)) 00960 thd->set_db(NULL, 0); 00961 VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); 00962 start_waiting_global_read_lock(thd); 00963 exit2: 00964 DBUG_RETURN(error); 00965 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static long mysql_rm_known_files | ( | THD * | thd, | |
| MY_DIR * | dirp, | |||
| const char * | db, | |||
| const char * | path, | |||
| uint | level, | |||
| TABLE_LIST ** | dropped_tables | |||
| ) | [static] |
Definition at line 973 of file sql_db.cc.
References String::c_ptr(), DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, deletable_extentions, st_my_dir::dir_entry, ER_DB_DROP_RMDIR, err, filename_to_tablename(), files_charset_info, find_type(), FN_REFLEN, ha_known_exts(), my_charset_bin, my_delete_with_symlink(), my_dir(), my_dirend(), MY_DONT_SORT, my_error(), my_isdigit, my_strcasecmp, MY_WME, MYF, mysql_rm_arc_files(), mysql_rm_table_part2_with_lock(), fileinfo::name, NullS, st_my_dir::number_off_files, List< T >::push_back(), reg_ext, rm_dir_w_symlink(), strend(), strlen(), strmov(), strrchr(), strxmov(), system_charset_info, unpack_filename(), and VOID.
Referenced by mysql_rm_db().
00976 { 00977 long deleted=0; 00978 ulong found_other_files=0; 00979 char filePath[FN_REFLEN]; 00980 TABLE_LIST *tot_list=0, **tot_list_next; 00981 List<String> raid_dirs; 00982 DBUG_ENTER("mysql_rm_known_files"); 00983 DBUG_PRINT("enter",("path: %s", org_path)); 00984 00985 tot_list_next= &tot_list; 00986 00987 for (uint idx=0 ; 00988 idx < (uint) dirp->number_off_files && !thd->killed ; 00989 idx++) 00990 { 00991 FILEINFO *file=dirp->dir_entry+idx; 00992 char *extension; 00993 DBUG_PRINT("info",("Examining: %s", file->name)); 00994 00995 /* skiping . and .. */ 00996 if (file->name[0] == '.' && (!file->name[1] || 00997 (file->name[1] == '.' && !file->name[2]))) 00998 continue; 00999 01000 /* Check if file is a raid directory */ 01001 if ((my_isdigit(system_charset_info, file->name[0]) || 01002 (file->name[0] >= 'a' && file->name[0] <= 'f')) && 01003 (my_isdigit(system_charset_info, file->name[1]) || 01004 (file->name[1] >= 'a' && file->name[1] <= 'f')) && 01005 !file->name[2] && !level) 01006 { 01007 char newpath[FN_REFLEN], *copy_of_path; 01008 MY_DIR *new_dirp; 01009 String *dir; 01010 uint length; 01011 01012 strxmov(newpath,org_path,"/",file->name,NullS); 01013 length= unpack_filename(newpath,newpath); 01014 if ((new_dirp = my_dir(newpath,MYF(MY_DONT_SORT)))) 01015 { 01016 DBUG_PRINT("my",("New subdir found: %s", newpath)); 01017 if ((mysql_rm_known_files(thd, new_dirp, NullS, newpath,1,0)) < 0) 01018 goto err; 01019 if (!(copy_of_path= thd->memdup(newpath, length+1)) || 01020 !(dir= new (thd->mem_root) String(copy_of_path, length, 01021 &my_charset_bin)) || 01022 raid_dirs.push_back(dir)) 01023 goto err; 01024 continue; 01025 } 01026 found_other_files++; 01027 continue; 01028 } 01029 else if (file->name[0] == 'a' && file->name[1] == 'r' && 01030 file->name[2] == 'c' && file->name[3] == '\0') 01031 { 01032 /* .frm archive */ 01033 char newpath[FN_REFLEN]; 01034 MY_DIR *new_dirp; 01035 strxmov(newpath, org_path, "/", "arc", NullS); 01036 (void) unpack_filename(newpath, newpath); 01037 if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT)))) 01038 { 01039 DBUG_PRINT("my",("Archive subdir found: %s", newpath)); 01040 if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0) 01041 goto err; 01042 continue; 01043 } 01044 found_other_files++; 01045 continue; 01046 } 01047 if (!(extension= strrchr(file->name, '.'))) 01048 extension= strend(file->name); 01049 if (find_type(extension, &deletable_extentions,1+2) <= 0) 01050 { 01051 if (find_type(extension, ha_known_exts(),1+2) <= 0) 01052 found_other_files++; 01053 continue; 01054 } 01055 /* just for safety we use files_charset_info */ 01056 if (db && !my_strcasecmp(files_charset_info, 01057 extension, reg_ext)) 01058 { 01059 /* Drop the table nicely */ 01060 *extension= 0; // Remove extension 01061 TABLE_LIST *table_list=(TABLE_LIST*) 01062 thd->calloc(sizeof(*table_list)+ strlen(db)+strlen(file->name)+2); 01063 if (!table_list) 01064 goto err; 01065 table_list->db= (char*) (table_list+1); 01066 table_list->table_name= strmov(table_list->db, db) + 1; 01067 VOID(filename_to_tablename(file->name, table_list->table_name, 01068 strlen(file->name) + 1)); 01069 table_list->alias= table_list->table_name; // If lower_case_table_names=2 01070 /* Link into list */ 01071 (*tot_list_next)= table_list; 01072 tot_list_next= &table_list->next_local; 01073 deleted++; 01074 } 01075 else 01076 { 01077 strxmov(filePath, org_path, "/", file->name, NullS); 01078 if (my_delete_with_symlink(filePath,MYF(MY_WME))) 01079 { 01080 goto err; 01081 } 01082 } 01083 } 01084 if (thd->killed || 01085 (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 0, 1))) 01086 goto err; 01087 01088 /* Remove RAID directories */ 01089 { 01090 List_iterator<String> it(raid_dirs); 01091 String *dir; 01092 while ((dir= it++)) 01093 if (rmdir(dir->c_ptr()) < 0) 01094 found_other_files++; 01095 } 01096 my_dirend(dirp); 01097 01098 if (dropped_tables) 01099 *dropped_tables= tot_list; 01100 01101 /* 01102 If the directory is a symbolic link, remove the link first, then 01103 remove the directory the symbolic link pointed at 01104 */ 01105 if (found_other_files) 01106 { 01107 my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); 01108 DBUG_RETURN(-1); 01109 } 01110 else 01111 { 01112 /* Don't give errors if we can't delete 'RAID' directory */ 01113 if (rm_dir_w_symlink(org_path, level == 0)) 01114 DBUG_RETURN(-1); 01115 } 01116 01117 DBUG_RETURN(deleted); 01118 01119 err: 01120 my_dirend(dirp); 01121 DBUG_RETURN(-1); 01122 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static my_bool put_dbopt | ( | const char * | dbname, | |
| HA_CREATE_INFO * | create | |||
| ) | [static] |
Definition at line 305 of file sql_db.cc.
References dboptions, DBUG_ENTER, DBUG_RETURN, st_ha_create_information::default_table_charset, error, hash_search(), LOCK_dboptions, my_free, my_hash_insert(), my_multi_malloc(), MY_WME, MY_ZEROFILL, MYF, NullS, opt(), rw_unlock, rw_wrlock, strlen(), and strmov().
Referenced by load_db_opt(), and write_db_opt().
00306 { 00307 my_dbopt_t *opt; 00308 uint length; 00309 my_bool error= 0; 00310 DBUG_ENTER("put_dbopt"); 00311 00312 length= (uint) strlen(dbname); 00313 00314 rw_wrlock(&LOCK_dboptions); 00315 if (!(opt= (my_dbopt_t*) hash_search(&dboptions, (byte*) dbname, length))) 00316 { 00317 /* Options are not in the hash, insert them */ 00318 char *tmp_name; 00319 if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), 00320 &opt, (uint) sizeof(*opt), &tmp_name, length+1, 00321 NullS)) 00322 { 00323 error= 1; 00324 goto end; 00325 } 00326 00327 opt->name= tmp_name; 00328 strmov(opt->name, dbname); 00329 opt->name_length= length; 00330 00331 if ((error= my_hash_insert(&dboptions, (byte*) opt))) 00332 { 00333 my_free((gptr) opt, MYF(0)); 00334 goto end; 00335 } 00336 } 00337 00338 /* Update / write options in hash */ 00339 opt->charset= create->default_table_charset; 00340 00341 end: 00342 rw_unlock(&LOCK_dboptions); 00343 DBUG_RETURN(error); 00344 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1137 of file sql_db.cc.
References DBUG_ENTER, DBUG_RETURN, ER_DB_DROP_RMDIR, errno, error, FN_LIBCHAR, FN_REFLEN, my_delete(), my_error(), my_readlink(), MY_WME, MYF, path, pos(), strend(), and unpack_filename().
Referenced by mysql_rm_arc_files(), and mysql_rm_known_files().
01138 { 01139 char tmp_path[FN_REFLEN], *pos; 01140 char *path= tmp_path; 01141 DBUG_ENTER("rm_dir_w_symlink"); 01142 unpack_filename(tmp_path, org_path); 01143 #ifdef HAVE_READLINK 01144 int error; 01145 char tmp2_path[FN_REFLEN]; 01146 01147 /* Remove end FN_LIBCHAR as this causes problem on Linux in readlink */ 01148 pos= strend(path); 01149 if (pos > path && pos[-1] == FN_LIBCHAR) 01150 *--pos=0; 01151 01152 if ((error= my_readlink(tmp2_path, path, MYF(MY_WME))) < 0) 01153 DBUG_RETURN(1); 01154 if (!error) 01155 { 01156 if (my_delete(path, MYF(send_error ? MY_WME : 0))) 01157 { 01158 DBUG_RETURN(send_error); 01159 } 01160 /* Delete directory symbolic link pointed at */ 01161 path= tmp2_path; 01162 } 01163 #endif 01164 /* Remove last FN_LIBCHAR to not cause a problem on OS/2 */ 01165 pos= strend(path); 01166 01167 if (pos > path && pos[-1] == FN_LIBCHAR) 01168 *--pos=0; 01169 if (rmdir(path) < 0 && send_error) 01170 { 01171 my_error(ER_DB_DROP_RMDIR, MYF(0), path, errno); 01172 DBUG_RETURN(1); 01173 } 01174 DBUG_RETURN(0); 01175 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool write_db_opt | ( | THD * | thd, | |
| const char * | path, | |||
| HA_CREATE_INFO * | create | |||
| ) | [static] |
Definition at line 373 of file sql_db.cc.
References buf, CREATE_MODE, charset_info_st::csname, st_ha_create_information::default_table_charset, error, my_close(), my_create(), MY_NABP, MY_WME, my_write, MYF, charset_info_st::name, NullS, put_dbopt(), and strxnmov().
Referenced by mysql_alter_db(), and mysql_create_db().
00374 { 00375 register File file; 00376 char buf[256]; // Should be enough for one option 00377 bool error=1; 00378 00379 if (!create->default_table_charset) 00380 create->default_table_charset= thd->variables.collation_server; 00381 00382 if (put_dbopt(path, create)) 00383 return 1; 00384 00385 if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) 00386 { 00387 ulong length; 00388 length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=", 00389 create->default_table_charset->csname, 00390 "\ndefault-collation=", 00391 create->default_table_charset->name, 00392 "\n", NullS) - buf); 00393 00394 /* Error is written by my_write */ 00395 if (!my_write(file,(byte*) buf, length, MYF(MY_NABP+MY_WME))) 00396 error=0; 00397 my_close(file,MYF(0)); 00398 } 00399 return error; 00400 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void write_to_binlog | ( | THD * | thd, | |
| char * | query, | |||
| uint | q_len, | |||
| char * | db, | |||
| uint | db_len | |||
| ) | [inline, static] |
Definition at line 173 of file sql_db.cc.
References Query_log_event::db, Query_log_event::db_len, Query_log_event::error_code, mysql_bin_log, and MYSQL_BIN_LOG::write().
Referenced by mysql_execute_command(), and mysql_rm_db().
00175 { 00176 Query_log_event qinfo(thd, query, q_len, 0, 0); 00177 qinfo.error_code= 0; 00178 qinfo.db= db; 00179 qinfo.db_len= db_len; 00180 mysql_bin_log.write(&qinfo); 00181 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int creating_database = 0 |
Definition at line 47 of file sql_db.cc.
Referenced by lock_databases(), mysql_create_table(), and mysql_rename_db().
Definition at line 144 of file sql_db.cc.
Referenced by del_dbopt(), get_dbopt(), my_database_names_free(), my_database_names_init(), my_dbopt_cleanup(), and put_dbopt().
my_bool dboptions_init = 0 [static] |
| const char* del_exts[] = {".frm", ".BAK", ".TMD",".opt", NullS} |
TYPELIB deletable_extentions [static] |
Initial value:
{array_elements(del_exts)-1,"del_exts", del_exts, NULL}
Definition at line 33 of file sql_db.cc.
Referenced by mysql_rm_known_files().
Definition at line 45 of file sql_db.cc.
Referenced by lock_databases(), lock_db_delete(), lock_db_insert(), my_database_names_free(), my_database_names_init(), and mysql_create_table().
rw_lock_t LOCK_dboptions [static] |
Definition at line 146 of file sql_db.cc.
Referenced by del_dbopt(), get_dbopt(), my_database_names_free(), my_database_names_init(), my_dbopt_cleanup(), and put_dbopt().
| pthread_mutex_t LOCK_lock_db |
Definition at line 46 of file sql_db.cc.
Referenced by clean_up_mutexes(), init_thread_environment(), lock_databases(), lock_db_delete(), lock_db_insert(), mysql_create_table(), and mysql_rename_db().
1.4.7

