summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2004-04-02 16:25:48 +0300
committerunknown <marko@hundin.mysql.fi>2004-04-02 16:25:48 +0300
commitfac3642cc850d86dd927dec456aea19bae706918 (patch)
tree751da20f73c4984ede631acbed2ecfa9bcfe50f6
parentca68cb6625029607663412584aa361fe563fd9a5 (diff)
downloadmariadb-git-fac3642cc850d86dd927dec456aea19bae706918.tar.gz
InnoDB: ignore intra-database foreign key references between tables
when dropping database (Bug #3058) innobase/dict/dict0crea.c: Add a parameter to row_drop_table_for_mysql() innobase/dict/dict0dict.c: Make dict_tables_have_same_db() a global function innobase/include/dict0dict.h: Make dict_tables_have_same_db() a global function innobase/include/row0mysql.h: Add a parameter to row_drop_table_for_mysql() innobase/row/row0mysql.c: Add a parameter "drop_db" to row_drop_table_for_mysql() to skip foreign constraint checks on tables in same database innobase/trx/trx0roll.c: Add a parameter to row_drop_table_for_mysql() sql/ha_innodb.cc: Add a parameter "drop_db" to row_drop_table_for_mysql() innobase_drop_database(): allocate namebuf dynamically
-rw-r--r--innobase/dict/dict0crea.c8
-rw-r--r--innobase/dict/dict0dict.c2
-rw-r--r--innobase/include/dict0dict.h11
-rw-r--r--innobase/include/row0mysql.h3
-rw-r--r--innobase/row/row0mysql.c22
-rw-r--r--innobase/trx/trx0roll.c2
-rw-r--r--sql/ha_innodb.cc7
7 files changed, 36 insertions, 19 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 967818a3784..87cdd4f5302 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -999,13 +999,13 @@ dict_create_or_check_foreign_constraint_tables(void)
if (table1) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN table\n");
- row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx);
+ row_drop_table_for_mysql((char*)"SYS_FOREIGN", trx, TRUE);
}
if (table2) {
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN_COLS table\n");
- row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx);
+ row_drop_table_for_mysql((char*)"SYS_FOREIGN_COLS", trx, TRUE);
}
fprintf(stderr,
@@ -1054,8 +1054,8 @@ dict_create_or_check_foreign_constraint_tables(void)
fprintf(stderr,
"InnoDB: dropping incompletely created SYS_FOREIGN tables\n");
- row_drop_table_for_mysql((char *) "SYS_FOREIGN", trx);
- row_drop_table_for_mysql((char *) "SYS_FOREIGN_COLS", trx);
+ row_drop_table_for_mysql((char*)"SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql((char*)"SYS_FOREIGN_COLS", trx, TRUE);
error = DB_MUST_GET_MORE_FILE_SPACE;
}
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 0efb9935800..c0810ad45dc 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -177,7 +177,7 @@ mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign
/************************************************************************
Checks if the database name in two table names is the same. */
-static
+
ibool
dict_tables_have_same_db(
/*=====================*/
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index f0523c5f204..7d7739021e2 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -834,6 +834,17 @@ Releases the dictionary system mutex for MySQL. */
void
dict_mutex_exit_for_mysql(void);
/*===========================*/
+/************************************************************************
+Checks if the database name in two table names is the same. */
+
+ibool
+dict_tables_have_same_db(
+/*=====================*/
+ /* out: TRUE if same db name */
+ const char* name1, /* in: table name in the form
+ dbname '/' tablename */
+ const char* name2); /* in: table name in the form
+ dbname '/' tablename */
/* The following len must be at least 10000 bytes! */
#define DICT_FOREIGN_ERR_BUF_LEN 10000
diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h
index 940b4c61b2f..f28e1b6f048 100644
--- a/innobase/include/row0mysql.h
+++ b/innobase/include/row0mysql.h
@@ -329,7 +329,8 @@ row_drop_table_for_mysql(
/*=====================*/
/* out: error code or DB_SUCCESS */
char* name, /* in: table name */
- trx_t* trx); /* in: transaction handle */
+ trx_t* trx, /* in: transaction handle */
+ ibool drop_db);/* in: TRUE=dropping whole database */
/*************************************************************************
Drops a database for MySQL. */
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c
index 006cce74859..eca586b3a0a 100644
--- a/innobase/row/row0mysql.c
+++ b/innobase/row/row0mysql.c
@@ -1427,7 +1427,7 @@ row_create_table_for_mysql(
fprintf(stderr,
"InnoDB: Warning: cannot create table %s because tablespace full\n",
table->name);
- row_drop_table_for_mysql(table->name, trx);
+ row_drop_table_for_mysql(table->name, trx, FALSE);
} else {
ut_a(err == DB_DUPLICATE_KEY);
@@ -1542,7 +1542,7 @@ error_handling:
trx_general_rollback_for_mysql(trx, FALSE, NULL);
- row_drop_table_for_mysql(index->table_name, trx);
+ row_drop_table_for_mysql(index->table_name, trx, FALSE);
trx->error_state = DB_SUCCESS;
}
@@ -1607,7 +1607,7 @@ row_table_add_foreign_constraints(
trx_general_rollback_for_mysql(trx, FALSE, NULL);
- row_drop_table_for_mysql(name, trx);
+ row_drop_table_for_mysql(name, trx, FALSE);
trx->error_state = DB_SUCCESS;
}
@@ -1638,7 +1638,7 @@ row_drop_table_for_mysql_in_background(
name); */
/* Drop the table in InnoDB */
- error = row_drop_table_for_mysql(name, trx);
+ error = row_drop_table_for_mysql(name, trx, FALSE);
if (error != DB_SUCCESS) {
fprintf(stderr,
@@ -1795,9 +1795,10 @@ output by the master thread. */
int
row_drop_table_for_mysql(
/*=====================*/
- /* out: error code or DB_SUCCESS */
- char* name, /* in: table name */
- trx_t* trx) /* in: transaction handle */
+ /* out: error code or DB_SUCCESS */
+ char* name, /* in: table name */
+ trx_t* trx, /* in: transaction handle */
+ ibool drop_db)/* in: TRUE=dropping whole database */
{
dict_foreign_t* foreign;
dict_table_t* table;
@@ -1981,7 +1982,9 @@ row_drop_table_for_mysql(
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
- if (foreign && trx->check_foreigns) {
+ if (foreign && trx->check_foreigns &&
+ !(drop_db && dict_tables_have_same_db(
+ name, foreign->foreign_table_name))) {
char* buf = dict_foreign_err_buf;
/* We only allow dropping a referenced table if
@@ -2112,7 +2115,6 @@ loop:
ut_a(strcmp(table_name, name) == 0);
table = dict_table_get_low(table_name);
-fprintf(stderr, "drop %p:%s\n", table, table_name);
ut_a(table);
@@ -2135,7 +2137,7 @@ fprintf(stderr, "drop %p:%s\n", table, table_name);
goto loop;
}
- err = row_drop_table_for_mysql(table_name, trx);
+ err = row_drop_table_for_mysql(table_name, trx, TRUE);
mem_free(table_name);
diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c
index 82d101304d5..2adebbc6b4b 100644
--- a/innobase/trx/trx0roll.c
+++ b/innobase/trx/trx0roll.c
@@ -469,7 +469,7 @@ loop:
fprintf(stderr,
"InnoDB: Table found: dropping table %s in recovery\n", table->name);
- err = row_drop_table_for_mysql(table->name, trx);
+ err = row_drop_table_for_mysql(table->name, trx, TRUE);
ut_a(err == (int) DB_SUCCESS);
}
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index b0de417eb2f..5a929237e3b 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -3631,7 +3631,8 @@ ha_innobase::delete_table(
/* Drop the table in InnoDB */
- error = row_drop_table_for_mysql(norm_name, trx);
+ error = row_drop_table_for_mysql(norm_name, trx,
+ thd->lex.sql_command == SQLCOM_DROP_DB);
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs
@@ -3670,7 +3671,7 @@ innobase_drop_database(
trx_t* trx;
char* ptr;
int error;
- char namebuf[10000];
+ char* namebuf;
/* Get the transaction associated with the current thd, or create one
if not yet created */
@@ -3690,6 +3691,7 @@ innobase_drop_database(
}
ptr++;
+ namebuf = my_malloc(len + 2, MYF(0));
memcpy(namebuf, ptr, len);
namebuf[len] = '/';
@@ -3706,6 +3708,7 @@ innobase_drop_database(
}
error = row_drop_database_for_mysql(namebuf, trx);
+ my_free(namebuf, MYF(0));
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs