From 9384835087d71b77ef1ee0f197704060c713af2c Mon Sep 17 00:00:00 2001 From: Alexander Nozdrin Date: Wed, 7 Oct 2009 20:39:57 +0400 Subject: [PATCH] A backport of patch for Bug#26704. Original revision is from mysql-6.0-codebase: revno: 2630.3.1 committer: Alexander Nozdrin branch nick: 6.0-rt-bug26704 timestamp: Thu 2008-05-29 21:04:06 +0400 message: A fix for Bug#26704: Failing DROP DATABASE brings mysql-client out of sync. The problem was that we changed current database w/o caring whether it was dropped successfully or not. The fix is not to change current database if we failed to drop it. --- mysql-test/r/drop-no_root.result | 27 ++++++++++++++++++ mysql-test/t/drop-no_root.test | 49 ++++++++++++++++++++++++++++++++ sql/sql_db.cc | 2 +- 3 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/drop-no_root.result create mode 100644 mysql-test/t/drop-no_root.test diff --git a/mysql-test/r/drop-no_root.result b/mysql-test/r/drop-no_root.result new file mode 100644 index 00000000000..d74ce47dedd --- /dev/null +++ b/mysql-test/r/drop-no_root.result @@ -0,0 +1,27 @@ + +# -- +# -- Bug#26704: Failing DROP DATABASE brings mysql-client out of sync. +# -- + +DROP DATABASE IF EXISTS mysql_test; + +CREATE DATABASE mysql_test; +CREATE TABLE mysql_test.t1(c INT); +use mysql_test; + +chmod 000 mysql_test/t1.frm + +DROP DATABASE mysql_test; +ERROR HY000: Error dropping database (can't rmdir './mysql_test', errno: 39) + +SELECT DATABASE(); +DATABASE() +mysql_test + +rm mysql_test/t1.MYD mysql_test/t1.MYI + +DROP DATABASE mysql_test; + +use test; + +# -- End of Bug#26704. diff --git a/mysql-test/t/drop-no_root.test b/mysql-test/t/drop-no_root.test new file mode 100644 index 00000000000..05418b9dbb7 --- /dev/null +++ b/mysql-test/t/drop-no_root.test @@ -0,0 +1,49 @@ +# This test uses chmod, can't be run with root permissions +--source include/not_as_root.inc + +########################################################################### + +--echo +--echo # -- +--echo # -- Bug#26704: Failing DROP DATABASE brings mysql-client out of sync. +--echo # -- + +--echo +--disable_warnings +DROP DATABASE IF EXISTS mysql_test; +--enable_warnings + +--echo +CREATE DATABASE mysql_test; +CREATE TABLE mysql_test.t1(c INT); + +use mysql_test; + +let $MYSQLD_DATADIR= `select @@datadir`; + +--echo +--echo chmod 000 mysql_test/t1.frm +--chmod 0000 $MYSQLD_DATADIR/mysql_test/t1.frm + +--echo +--error ER_DB_DROP_RMDIR +DROP DATABASE mysql_test; + +--echo +SELECT DATABASE(); + +--echo +--echo rm mysql_test/t1.MYD mysql_test/t1.MYI +--exec rm $MYSQLD_DATADIR/mysql_test/t1.MYD +--exec rm $MYSQLD_DATADIR/mysql_test/t1.MYI + +--echo +DROP DATABASE mysql_test; + +--echo +use test; + +--echo +--echo # -- End of Bug#26704. + +########################################################################### diff --git a/sql/sql_db.cc b/sql/sql_db.cc index bcc8fcf54fc..604a2643f43 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1027,7 +1027,7 @@ exit: SELECT DATABASE() in the future). For this we free() thd->db and set it to 0. */ - if (thd->db && !strcmp(thd->db, db)) + if (thd->db && !strcmp(thd->db, db) && error == 0) mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); VOID(pthread_mutex_unlock(&LOCK_mysql_create_db)); start_waiting_global_read_lock(thd);