summaryrefslogtreecommitdiff
path: root/sql/sql_db.cc
diff options
context:
space:
mode:
authorJon Olav Hauglid <jon.hauglid@oracle.com>2010-11-16 11:00:12 +0100
committerJon Olav Hauglid <jon.hauglid@oracle.com>2010-11-16 11:00:12 +0100
commita84d7503008e0bb7d1b4dca72eaf42016ed1a5d9 (patch)
tree51b238d7f54d17bf3bd843bab00120cc801d8b9c /sql/sql_db.cc
parent2ef19bdcc420d090d0bed822a884eef40cd347a9 (diff)
downloadmariadb-git-a84d7503008e0bb7d1b4dca72eaf42016ed1a5d9.tar.gz
Bug #57663 Concurrent statement using stored function and DROP DATABASE
breaks SBR This pre-requisite patch refactors the code for dropping tables, used by DROP TABLE and DROP DATABASE. The patch moves the code for acquiring metadata locks out of mysql_rm_table_part2() and makes it the responsibility of the caller. This in preparation of changing the DROP DATABASE implementation to acquire all metadata locks before any changes are made. mysql_rm_table_part2() is renamed mysql_rm_table_no_locks() to reflect the change.
Diffstat (limited to 'sql/sql_db.cc')
-rw-r--r--sql/sql_db.cc36
1 files changed, 35 insertions, 1 deletions
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 2abe4d8d072..1391b2c4d72 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -28,6 +28,8 @@
#include "sql_acl.h" // SELECT_ACL, DB_ACLS,
// acl_get, check_grant_db
#include "log_event.h" // Query_log_event
+#include "sql_base.h" // lock_table_names, tdc_remove_table
+#include "sql_handler.h" // mysql_ha_rm_tables
#include <mysys_err.h>
#include "sp.h"
#include "events.h"
@@ -944,6 +946,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
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));
@@ -1040,8 +1043,39 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
}
}
}
+
+ /*
+ 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;
+ }
+ }
+ }
+
+ /* 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_part2(thd, tot_list, 1, 0, 1, 1)))
+ (tot_list && mysql_rm_table_no_locks(thd, tot_list, true,
+ false, true, true)))
goto err;
my_dirend(dirp);