From: Jon Olav Hauglid Date: November 17 2010 2:37pm Subject: bzr commit into mysql-5.5-runtime branch (jon.hauglid:3187) Bug#57663 List-Archive: http://lists.mysql.com/commits/124161 X-Bug: 57663 Message-Id: <201011171439.oAH739fT029274@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============2488329539423428637==" --===============2488329539423428637== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-5.5-runtime-refactor/ based on revid:jon.hauglid@stripped 3187 Jon Olav Hauglid 2010-11-17 Bug #57663 Concurrent statement using stored function and DROP DATABASE breaks SBR The problem was that DROP DATABASE ignored any metadata locks on stored functions and procedures held by other connections. This made it possible for DROP DATABASE to drop functions/procedures that were in use by other connections and therefore break statement based replication. (DROP DATABASE could appear in the binlog before a statement using a dropped function/procedure.) This problem was an issue left unresolved by the patch for Bug#30977 where metadata locks for stored functions/procedures were introduced. This patch fixes the problem by making sure DROP DATABASE takes exclusive metadata locks on all stored functions/procedures to be dropped. Test case added to sp-lock.test. modified: mysql-test/r/sp-lock.result mysql-test/t/sp-lock.test sql/sp.cc sql/sp.h sql/sql_db.cc === modified file 'mysql-test/r/sp-lock.result' --- a/mysql-test/r/sp-lock.result 2010-08-06 11:29:37 +0000 +++ b/mysql-test/r/sp-lock.result 2010-11-17 14:37:23 +0000 @@ -735,5 +735,96 @@ END latin1 latin1_swedish_ci latin1_swed # Connection default; DROP PROCEDURE p1; # +# Bug#57663 Concurrent statement using stored function and DROP DATABASE +# breaks SBR +# +DROP DATABASE IF EXISTS db1; +DROP FUNCTION IF EXISTS f1; +# Test 1: Check that DROP DATABASE block if a function is used +# by an active transaction. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); +db1.f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +# Waiting for DROP DATABASE to be blocked by the lock on f1() +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 2: Check that DROP DATABASE blocks if a procedure is +# used by an active transaction. +# Connection default +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() BEGIN END; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN +CALL db1.p1(); +RETURN 1; +END| +START TRANSACTION; +SELECT f1(); +f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +# Waiting for DROP DATABASE to be blocked by the lock on p1() +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 3: Check that DROP DATABASE is not selected as a victim if a +# deadlock is discovered with DML statements. +# Connection default +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); +db1.f1() +1 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection default +# Waiting for DROP DATABASE to be blocked by the lock on f1() +SELECT * FROM db1.t1; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Test 4: Check that active DROP DATABASE blocks stored routine DDL. +# Connection default +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2; +START TRANSACTION; +SELECT db1.f2(); +db1.f2() +2 +# Connection con1 +# Sending: +DROP DATABASE db1; +# Connection con2 +# Waiting for DROP DATABASE to be blocked by the lock on f2() +# Sending: +ALTER FUNCTION db1.f1 COMMENT "test"; +# Connection default +# Waiting for ALTER FUNCTION to be blocked by the schema lock on db1 +COMMIT; +# Connection con1 +# Reaping: DROP DATABASE db1 +# Connection con2 +# Reaping: ALTER FUNCTION f1 COMMENT 'test' +ERROR 42000: FUNCTION db1.f1 does not exist +# Connection default +DROP FUNCTION f1; +# # End of 5.5 tests # === modified file 'mysql-test/t/sp-lock.test' --- a/mysql-test/t/sp-lock.test 2010-08-06 11:29:37 +0000 +++ b/mysql-test/t/sp-lock.test 2010-11-17 14:37:23 +0000 @@ -972,5 +972,170 @@ DROP PROCEDURE p1; --echo # +--echo # Bug#57663 Concurrent statement using stored function and DROP DATABASE +--echo # breaks SBR +--echo # + +--disable_warnings +DROP DATABASE IF EXISTS db1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +connect(con1, localhost, root); +connect(con2, localhost, root); + +--echo # Test 1: Check that DROP DATABASE block if a function is used +--echo # by an active transaction. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +SELECT db1.f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +--echo # Waiting for DROP DATABASE to be blocked by the lock on f1() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 2: Check that DROP DATABASE blocks if a procedure is +--echo # used by an active transaction. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE PROCEDURE db1.p1() BEGIN END; +delimiter |; +CREATE FUNCTION f1() RETURNS INTEGER +BEGIN + CALL db1.p1(); + RETURN 1; +END| +delimiter ;| +START TRANSACTION; +SELECT f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +--echo # Waiting for DROP DATABASE to be blocked by the lock on p1() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored procedure metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 3: Check that DROP DATABASE is not selected as a victim if a +--echo # deadlock is discovered with DML statements. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE TABLE db1.t1 (a INT); +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +START TRANSACTION; +# DROP DATABASE will lock tables (t1) before functions (f1) +SELECT db1.f1(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection default +connection default; +--echo # Waiting for DROP DATABASE to be blocked by the lock on f1() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +--error ER_LOCK_DEADLOCK +SELECT * FROM db1.t1; +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap + +--echo # Test 4: Check that active DROP DATABASE blocks stored routine DDL. + +--echo # Connection default +connection default; +CREATE DATABASE db1; +CREATE FUNCTION db1.f1() RETURNS INTEGER RETURN 1; +CREATE FUNCTION db1.f2() RETURNS INTEGER RETURN 2; +START TRANSACTION; +SELECT db1.f2(); + +--echo # Connection con1 +connection con1; +--echo # Sending: +--send DROP DATABASE db1 + +--echo # Connection con2 +connection con2; +--echo # Waiting for DROP DATABASE to be blocked by the lock on f2() +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for stored function metadata lock' + AND info='DROP DATABASE db1'; +--source include/wait_condition.inc +--echo # Sending: +--send ALTER FUNCTION db1.f1 COMMENT "test" + +--echo # Connection default +connection default; +--echo # Waiting for ALTER FUNCTION to be blocked by the schema lock on db1 +let $wait_condition= SELECT COUNT(*)= 1 FROM information_schema.processlist + WHERE state= 'Waiting for schema metadata lock' + AND info='ALTER FUNCTION db1.f1 COMMENT "test"'; +--source include/wait_condition.inc +COMMIT; + +--echo # Connection con1 +connection con1; +--echo # Reaping: DROP DATABASE db1 +--reap +disconnect con1; +--source include/wait_until_disconnected.inc + +--echo # Connection con2 +connection con2; +--echo # Reaping: ALTER FUNCTION f1 COMMENT 'test' +--error ER_SP_DOES_NOT_EXIST +--reap +disconnect con2; +--source include/wait_until_disconnected.inc + +--echo # Connection default +connection default; +DROP FUNCTION f1; + + +--echo # --echo # End of 5.5 tests --echo # === modified file 'sql/sp.cc' --- a/sql/sp.cc 2010-11-11 17:11:05 +0000 +++ b/sql/sp.cc 2010-11-17 14:37:23 +0000 @@ -1361,6 +1361,106 @@ err: /** + This internal handler is used to trap errors from opening mysql.proc. +*/ + +class Lock_db_routines_error_handler : public Internal_error_handler +{ +public: + bool handle_condition(THD *thd, + uint sql_errno, + const char* sqlstate, + MYSQL_ERROR::enum_warning_level level, + const char* msg, + MYSQL_ERROR ** cond_hdl) + { + if (sql_errno == ER_NO_SUCH_TABLE || + sql_errno == ER_COL_COUNT_DOESNT_MATCH_CORRUPTED) + return true; + return false; + } +}; + + +/** + Acquires exclusive metadata lock on all stored routines in the + given database. + + @note Will also return false (=success) if mysql.proc can't be opened + or is outdated. This allows DROP DATABASE to continue in these + cases. + */ + +bool lock_db_routines(THD *thd, char *db) +{ + TABLE *table; + uint key_len; + int nxtres= 0; + Open_tables_backup open_tables_state_backup; + MDL_request_list mdl_requests; + Lock_db_routines_error_handler err_handler; + DBUG_ENTER("lock_db_routines"); + + /* + mysql.proc will be re-opened during deletion, so we can ignore + errors when opening the table here. The error handler is + used to avoid getting the same warning twice. + */ + thd->push_internal_handler(&err_handler); + table= open_proc_table_for_read(thd, &open_tables_state_backup); + thd->pop_internal_handler(); + if (!table) + { + /* + DROP DATABASE should not fail even if mysql.proc does not exist + or is outdated. We therefore only abort mysql_rm_db() if we + have errors not handled by the error handler. + */ + DBUG_RETURN(thd->is_error() || thd->killed); + } + + table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info); + key_len= table->key_info->key_part[0].store_length; + table->file->ha_index_init(0, 1); + + if (! table->file->index_read_map(table->record[0], + table->field[MYSQL_PROC_FIELD_DB]->ptr, + (key_part_map)1, HA_READ_KEY_EXACT)) + { + do + { + char *sp_name= get_field(thd->mem_root, + table->field[MYSQL_PROC_FIELD_NAME]); + longlong sp_type= table->field[MYSQL_PROC_MYSQL_TYPE]->val_int(); + MDL_request *mdl_request= new (thd->mem_root) MDL_request; + mdl_request->init(sp_type == TYPE_ENUM_FUNCTION ? + MDL_key::FUNCTION : MDL_key::PROCEDURE, + db, sp_name, MDL_EXCLUSIVE, MDL_TRANSACTION); + mdl_requests.push_front(mdl_request); + } while (! (nxtres= table->file->index_next_same(table->record[0], + table->field[MYSQL_PROC_FIELD_DB]->ptr, + key_len))); + } + table->file->ha_index_end(); + if (nxtres != 0 && nxtres != HA_ERR_END_OF_FILE) + { + table->file->print_error(nxtres, MYF(0)); + close_system_tables(thd, &open_tables_state_backup); + DBUG_RETURN(true); + } + close_system_tables(thd, &open_tables_state_backup); + + /* We should already hold a global IX lock and a schema X lock. */ + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::GLOBAL, "", "", + MDL_INTENTION_EXCLUSIVE) && + thd->mdl_context.is_lock_owner(MDL_key::SCHEMA, db, "", + MDL_EXCLUSIVE)); + DBUG_RETURN(thd->mdl_context.acquire_locks(&mdl_requests, + thd->variables.lock_wait_timeout)); +} + + +/** Drop all routines in database 'db' @note Close the thread tables, the calling code might want to === modified file 'sql/sp.h' --- a/sql/sp.h 2010-10-07 16:01:17 +0000 +++ b/sql/sp.h 2010-11-17 14:37:23 +0000 @@ -84,6 +84,18 @@ enum int sp_drop_db_routines(THD *thd, char *db); +/** + Acquires exclusive metadata lock on all stored routines in the + given database. + + @param thd Thread handler + @param db Database name + + @retval false Success + @retval true Failure + */ +bool lock_db_routines(THD *thd, char *db); + sp_head * sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, bool cache_only); === modified file 'sql/sql_db.cc' --- a/sql/sql_db.cc 2010-11-16 10:00:12 +0000 +++ b/sql/sql_db.cc 2010-11-17 14:37:23 +0000 @@ -46,10 +46,12 @@ const char *del_exts[]= {".frm", ".BAK", static TYPELIB deletable_extentions= {array_elements(del_exts)-1,"del_exts", del_exts, NULL}; -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, - const char *db, const char *path, - TABLE_LIST **dropped_tables); - +static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, + const char *db, + const char *path, + TABLE_LIST **tables, + bool *found_other_files); + 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 void mysql_change_db_impl(THD *thd, @@ -738,36 +740,37 @@ exit: } -/* - Drop all tables in a database and the database itself +/** + Drop all tables, routines and events in a database and the database itself. - SYNOPSIS - mysql_rm_db() - thd Thread handle - db Database name in the case given by user - It's already validated and set to lower case - (if needed) when we come here - if_exists Don't give error if database doesn't exists - silent Don't generate errors - - RETURN - FALSE ok (Database dropped) - ERROR Error + @param thd Thread handle + @param db Database name in the case given by user + It's already validated and set to lower case + (if needed) when we come here + @param if_exists Don't give error if database doesn't exists + @param silent Don't write the statement to the binary log and don't + send ok packet to the client + + @retval false OK (Database dropped) + @retval true Error */ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { - long deleted=0; - int error= 0; + ulong deleted_tables= 0; + bool error= true; char path[FN_REFLEN+16]; MY_DIR *dirp; uint length; - TABLE_LIST* dropped_tables= 0; + bool found_other_files= false; + TABLE_LIST *tables= NULL; + TABLE_LIST *table; + Drop_table_error_handler err_handler; DBUG_ENTER("mysql_rm_db"); if (lock_schema_name(thd, db)) - DBUG_RETURN(TRUE); + DBUG_RETURN(true); length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); strmov(path+length, MY_DB_OPT_FILE); // Append db option file name @@ -779,20 +782,72 @@ bool mysql_rm_db(THD *thd,char *db,bool { if (!if_exists) { - error= -1; my_error(ER_DB_DROP_EXISTS, MYF(0), db); - goto exit; + DBUG_RETURN(true); } else + { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_DB_DROP_EXISTS, ER(ER_DB_DROP_EXISTS), db); + error= false; + goto update_binlog; + } } - else + + thd->push_internal_handler(&err_handler); + + if (find_db_tables_and_rm_known_files(thd, dirp, db, path, &tables, + &found_other_files)) { - Drop_table_error_handler err_handler; - thd->push_internal_handler(&err_handler); + thd->pop_internal_handler(); + goto exit; + } - error= -1; + /* + Disable drop of enabled log tables, must be done before name locking. + This check is only needed if we are dropping the "mysql" database. + */ + if ((my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)) + { + for (table= tables; table; table= table->next_local) + { + if (check_if_log_table(table->db_length, table->db, + table->table_name_length, table->table_name, true)) + { + my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); + thd->pop_internal_handler(); + goto exit; + } + } + } + + /* Lock all tables and stored routines about to be dropped. */ + if (lock_table_names(thd, tables, NULL, thd->variables.lock_wait_timeout, + MYSQL_OPEN_SKIP_TEMPORARY) || + lock_db_routines(thd, db)) + { + thd->pop_internal_handler(); + goto exit; + } + + /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */ + if (tables) + mysql_ha_rm_tables(thd, tables); + + for (table= tables; table; table= table->next_local) + { + tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, + false); + deleted_tables++; + } + + if (thd->killed || + (tables && mysql_rm_table_no_locks(thd, tables, true, false, true, true))) + { + tables= NULL; + } + else + { /* We temporarily disable the binary log while dropping the objects in the database. Since the DROP DATABASE statement is always @@ -810,23 +865,30 @@ bool mysql_rm_db(THD *thd,char *db,bool ha_drop_database(), since NDB otherwise detects the binary log as disabled and will not log the drop database statement on any other connected server. - */ - if ((deleted= mysql_rm_known_files(thd, dirp, db, path, - &dropped_tables)) >= 0) - { - ha_drop_database(path); - tmp_disable_binlog(thd); - query_cache_invalidate1(db); - (void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */ + */ + + ha_drop_database(path); + tmp_disable_binlog(thd); + query_cache_invalidate1(db); + (void) sp_drop_db_routines(thd, db); /* @todo Do not ignore errors */ #ifdef HAVE_EVENT_SCHEDULER - Events::drop_schema_events(thd, db); + Events::drop_schema_events(thd, db); #endif - error = 0; - reenable_binlog(thd); - } - thd->pop_internal_handler(); + reenable_binlog(thd); + + /* + If the directory is a symbolic link, remove the link first, then + remove the directory the symbolic link pointed at + */ + if (found_other_files) + my_error(ER_DB_DROP_RMDIR, MYF(0), path, EEXIST); + else + error= rm_dir_w_symlink(path, true); } - if (!silent && deleted>=0) + thd->pop_internal_handler(); + +update_binlog: + if (!silent && !error) { const char *query; ulong query_length; @@ -861,13 +923,13 @@ bool mysql_rm_db(THD *thd,char *db,bool */ if (mysql_bin_log.write(&qinfo)) { - error= -1; + error= true; goto exit; } } thd->clear_error(); thd->server_status|= SERVER_STATUS_DB_DROPPED; - my_ok(thd, (ulong) deleted); + my_ok(thd, deleted_tables); } else if (mysql_bin_log.is_open()) { @@ -881,7 +943,7 @@ bool mysql_rm_db(THD *thd,char *db,bool query_end= query + MAX_DROP_TABLE_Q_LEN; db_len= strlen(db); - for (tbl= dropped_tables; tbl; tbl= tbl->next_local) + for (tbl= tables; tbl; tbl= tbl->next_local) { uint tbl_name_len; @@ -895,7 +957,7 @@ bool mysql_rm_db(THD *thd,char *db,bool */ if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len)) { - error= -1; + error= true; goto exit; } query_pos= query_data_start; @@ -915,7 +977,7 @@ bool mysql_rm_db(THD *thd,char *db,bool */ if (write_to_binlog(thd, query, query_pos -1 - query, db, db_len)) { - error= -1; + error= true; goto exit; } } @@ -928,27 +990,23 @@ exit: SELECT DATABASE() in the future). For this we free() thd->db and set it to 0. */ - if (thd->db && !strcmp(thd->db, db) && error == 0) + if (thd->db && !strcmp(thd->db, db) && !error) mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); + my_dirend(dirp); DBUG_RETURN(error); } -/* - Removes files with known extensions. - thd MUST be set when calling this function! -*/ -static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, - const char *org_path, - TABLE_LIST **dropped_tables) +static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp, + const char *db, + const char *path, + TABLE_LIST **tables, + bool *found_other_files) { - long deleted=0; - ulong found_other_files=0; char filePath[FN_REFLEN]; TABLE_LIST *tot_list=0, **tot_list_next_local, **tot_list_next_global; - TABLE_LIST *table; - DBUG_ENTER("mysql_rm_known_files"); - DBUG_PRINT("enter",("path: %s", org_path)); + DBUG_ENTER("find_db_tables_and_rm_known_files"); + DBUG_PRINT("enter",("path: %s", path)); tot_list_next_local= tot_list_next_global= &tot_list; @@ -974,16 +1032,16 @@ static long mysql_rm_known_files(THD *th */ char newpath[FN_REFLEN]; MY_DIR *new_dirp; - strxmov(newpath, org_path, "/", "arc", NullS); + strxmov(newpath, path, "/", "arc", NullS); (void) unpack_filename(newpath, newpath); if ((new_dirp = my_dir(newpath, MYF(MY_DONT_SORT)))) { DBUG_PRINT("my",("Archive subdir found: %s", newpath)); if ((mysql_rm_arc_files(thd, new_dirp, newpath)) < 0) - goto err; + DBUG_RETURN(true); continue; } - found_other_files++; + *found_other_files= true; continue; } if (!(extension= strrchr(file->name, '.'))) @@ -991,7 +1049,7 @@ static long mysql_rm_known_files(THD *th if (find_type(extension, &deletable_extentions,1+2) <= 0) { if (find_type(extension, ha_known_exts(),1+2) <= 0) - found_other_files++; + *found_other_files= true; continue; } /* just for safety we use files_charset_info */ @@ -1007,7 +1065,7 @@ static long mysql_rm_known_files(THD *th strlen(file->name) + 1); if (!table_list) - goto err; + DBUG_RETURN(true); table_list->db= (char*) (table_list+1); table_list->db_length= strmov(table_list->db, db) - table_list->db; table_list->table_name= table_list->db + table_list->db_length + 1; @@ -1032,77 +1090,16 @@ static long mysql_rm_known_files(THD *th (*tot_list_next_global)= table_list; tot_list_next_local= &table_list->next_local; tot_list_next_global= &table_list->next_global; - deleted++; } else { - strxmov(filePath, org_path, "/", file->name, NullS); + strxmov(filePath, path, "/", file->name, NullS); if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME))) - { - goto err; - } - } - } - - /* - Disable drop of enabled log tables, must be done before name locking. - This check is only needed if we are dropping the "mysql" database. - */ - if ((my_strcasecmp(system_charset_info, MYSQL_SCHEMA_NAME.str, db) == 0)) - { - for (table= tot_list; table; table= table->next_local) - { - if (check_if_log_table(table->db_length, table->db, - table->table_name_length, table->table_name, true)) - { - my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); - goto err; - } + DBUG_RETURN(true); } } - - /* mysql_ha_rm_tables() requires a non-null TABLE_LIST. */ - if (tot_list) - mysql_ha_rm_tables(thd, tot_list); - - if (lock_table_names(thd, tot_list, NULL, thd->variables.lock_wait_timeout, - MYSQL_OPEN_SKIP_TEMPORARY)) - goto err; - - for (table= tot_list; table; table= table->next_local) - tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name, - false); - - if (thd->killed || - (tot_list && mysql_rm_table_no_locks(thd, tot_list, true, - false, true, true))) - goto err; - - my_dirend(dirp); - - if (dropped_tables) - *dropped_tables= tot_list; - - /* - If the directory is a symbolic link, remove the link first, then - remove the directory the symbolic link pointed at - */ - if (found_other_files) - { - my_error(ER_DB_DROP_RMDIR, MYF(0), org_path, EEXIST); - DBUG_RETURN(-1); - } - else - { - if (rm_dir_w_symlink(org_path, true)) - DBUG_RETURN(-1); - } - - DBUG_RETURN(deleted); - -err: - my_dirend(dirp); - DBUG_RETURN(-1); + *tables= tot_list; + DBUG_RETURN(false); } --===============2488329539423428637== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jon.hauglid@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jon.hauglid@stripped # target_branch: file:///export/home/x/mysql-5.5-runtime-refactor/ # testament_sha1: 2814d3d0ac01b776a088e3e9d1d557a167361e24 # timestamp: 2010-11-17 15:37:27 +0100 # source_branch: file:///export/home/x/mysql-5.5-bugfixing/ # base_revision_id: jon.hauglid@stripped\ # kxep9txz2fxy3nmw # # Begin bundle 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 --===============2488329539423428637==--