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