diff options
author | unknown <marko@hundin.mysql.fi> | 2004-04-02 16:25:48 +0300 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2004-04-02 16:25:48 +0300 |
commit | fac3642cc850d86dd927dec456aea19bae706918 (patch) | |
tree | 751da20f73c4984ede631acbed2ecfa9bcfe50f6 | |
parent | ca68cb6625029607663412584aa361fe563fd9a5 (diff) | |
download | mariadb-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.c | 8 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 2 | ||||
-rw-r--r-- | innobase/include/dict0dict.h | 11 | ||||
-rw-r--r-- | innobase/include/row0mysql.h | 3 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 22 | ||||
-rw-r--r-- | innobase/trx/trx0roll.c | 2 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 7 |
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 |