Commit fac3642c authored by unknown's avatar unknown
Browse files

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
parent ca68cb66
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -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;
	}
+1 −1
Original line number Diff line number Diff line
@@ -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(
/*=====================*/
+11 −0
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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. */

+12 −10
Original line number Diff line number Diff line
@@ -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 @@ row_create_index_for_mysql(

		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,
@@ -1797,7 +1797,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 */
{
	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 @@ row_drop_database_for_mysql(
		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);

Loading