Commit dec90f5b authored by unknown's avatar unknown
Browse files

InnoDB: Ignore character set mismatch in ALTER TABLE and RENAME TABLE

if foreign_key_checks=0. (Bug #9802)


innobase/dict/dict0dict.c:
  dict_foreign_add_to_cache(): Add flag check_types.
  If the flag is FALSE, ignore character set mismatch.
innobase/dict/dict0load.c:
  dict_load_foreign(), dict_load_foreigns(): Add flag check_types.
  If the flag is FALSE, differences in character sets will be ignored.
innobase/include/dict0dict.h:
  dict_foreign_add_to_cache(): Add flag check_types.
  If the flag is FALSE, differences in character sets will be ignored.
innobase/include/dict0load.h:
  dict_load_foreigns(): Add flag check_types.
  If the flag is FALSE, differences in character sets will be ignored.
innobase/row/row0mysql.c:
  row_table_add_foreign_constraints(), row_rename_table_for_mysql():
  Pass trx->check_foreigns to dict_load_foreigns()
sql/ha_innodb.cc:
  ha_innobase::rename_table(): Clear trx->check_foreign if necessary.
parent 3fcbdd76
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -2167,7 +2167,8 @@ ulint
dict_foreign_add_to_cache(
/*======================*/
					/* out: DB_SUCCESS or error code */
	dict_foreign_t*	foreign)	/* in, own: foreign key constraint */
	dict_foreign_t*	foreign,	/* in, own: foreign key constraint */
	ibool		check_types)	/* in: TRUE=check type compatibility */
{
	dict_table_t*	for_table;
	dict_table_t*	ref_table;
@@ -2203,10 +2204,16 @@ dict_foreign_add_to_cache(
	}

	if (for_in_cache->referenced_table == NULL && ref_table) {
		dict_index_t*	types_idx;
		if (check_types) {
			types_idx = for_in_cache->foreign_index;
		} else {
			types_idx = NULL;
		}
		index = dict_foreign_find_index(ref_table,
			(const char**) for_in_cache->referenced_col_names,
			for_in_cache->n_fields,
			for_in_cache->foreign_index);
			types_idx);

		if (index == NULL) {
			dict_foreign_error_report(ef, for_in_cache,
@@ -2230,10 +2237,16 @@ dict_foreign_add_to_cache(
	}

	if (for_in_cache->foreign_table == NULL && for_table) {
		dict_index_t*	types_idx;
		if (check_types) {
			types_idx = for_in_cache->referenced_index;
		} else {
			types_idx = NULL;
		}
		index = dict_foreign_find_index(for_table,
			(const char**) for_in_cache->foreign_col_names,
			for_in_cache->n_fields,
			for_in_cache->referenced_index);
			types_idx);

		if (index == NULL) {
			dict_foreign_error_report(ef, for_in_cache,
+7 −8
Original line number Diff line number Diff line
@@ -873,7 +873,7 @@ dict_load_table(
	
	dict_load_indexes(table, heap);
	
	err = dict_load_foreigns(table->name);
	err = dict_load_foreigns(table->name, TRUE);
/*
	if (err != DB_SUCCESS) {
	
@@ -1092,8 +1092,9 @@ ulint
dict_load_foreign(
/*==============*/
				/* out: DB_SUCCESS or error code */
	const char*	id)	/* in: foreign constraint id as a
	const char*	id,	/* in: foreign constraint id as a
				null-terminated string */
	ibool		check_types)/* in: TRUE=check type compatibility */
{	
	dict_foreign_t*	foreign;
	dict_table_t*	sys_foreign;
@@ -1105,7 +1106,6 @@ dict_load_foreign(
	rec_t*		rec;
	byte*		field;
	ulint		len;
	ulint		err;
	mtr_t		mtr;
	
#ifdef UNIV_SYNC_DEBUG
@@ -1205,9 +1205,7 @@ dict_load_foreign(
	a new foreign key constraint but loading one from the data
	dictionary. */

	err = dict_foreign_add_to_cache(foreign);

	return(err); 
	return(dict_foreign_add_to_cache(foreign, check_types));
}

/***************************************************************************
@@ -1221,7 +1219,8 @@ ulint
dict_load_foreigns(
/*===============*/
					/* out: DB_SUCCESS or error code */
	const char*	table_name)	/* in: table name */
	const char*	table_name,	/* in: table name */
	ibool		check_types)	/* in: TRUE=check type compatibility */
{
	btr_pcur_t	pcur;
	mem_heap_t* 	heap;
@@ -1320,7 +1319,7 @@ dict_load_foreigns(

	/* Load the foreign constraint definition to the dictionary cache */
	
	err = dict_load_foreign(id);
	err = dict_load_foreign(id, check_types);

	if (err != DB_SUCCESS) {
		btr_pcur_close(&pcur);
+2 −1
Original line number Diff line number Diff line
@@ -189,7 +189,8 @@ ulint
dict_foreign_add_to_cache(
/*======================*/
					/* out: DB_SUCCESS or error code */
	dict_foreign_t*	foreign);	/* in, own: foreign key constraint */
	dict_foreign_t*	foreign,	/* in, own: foreign key constraint */
	ibool		check_types);	/* in: TRUE=check type compatibility */
/*************************************************************************
Checks if a table is referenced by foreign keys. */

+2 −1
Original line number Diff line number Diff line
@@ -81,7 +81,8 @@ ulint
dict_load_foreigns(
/*===============*/
					/* out: DB_SUCCESS or error code */
	const char*	table_name);	/* in: table name */
	const char*	table_name,	/* in: table name */
	ibool		check_types);	/* in: TRUE=check type compatibility */
/************************************************************************
Prints to the standard output information on all tables found in the data
dictionary system table. */
+3 −5
Original line number Diff line number Diff line
@@ -1796,7 +1796,7 @@ row_table_add_foreign_constraints(

	if (err == DB_SUCCESS) {
		/* Check that also referencing constraints are ok */
		err = dict_load_foreigns(name);
		err = dict_load_foreigns(name, trx->check_foreigns);
	}

	if (err != DB_SUCCESS) {
@@ -3204,6 +3204,8 @@ row_rename_table_for_mysql(
			goto funct_exit;
		}

		err = dict_load_foreigns(new_name, trx->check_foreigns);

		if (row_is_mysql_tmp_table_name(old_name)) {

			/* MySQL is doing an ALTER TABLE command and it
@@ -3213,8 +3215,6 @@ row_rename_table_for_mysql(
			table. But we want to load also the foreign key
			constraint definitions for the original table name. */

			err = dict_load_foreigns(new_name);

			if (err != DB_SUCCESS) {
	    			ut_print_timestamp(stderr);
				fputs("  InnoDB: Error: in ALTER TABLE ",
@@ -3233,8 +3233,6 @@ row_rename_table_for_mysql(
				trx->error_state = DB_SUCCESS;
			}
		} else {
			err = dict_load_foreigns(new_name);

			if (err != DB_SUCCESS) {

	    			ut_print_timestamp(stderr);
Loading