Commit 6fc42540 authored by Annamalai Gurusami's avatar Annamalai Gurusami

Bug #12902967 CREATING SELF REFERENCING FK ON SAME INDEX

UNHANDLED, CONFUSING ERROR

The main confusion with the error message is that "it 
implies that your data dictionary may now be out of 
sync".  This patch will remove the unwanted and the 
misleading error message by not doing an unnecessary 
operation in the error handling code.  

rb://980 approved by: Dmitry Lenev
parent 31905112
create table t1 (f1 integer primary key) engine innodb;
alter table t1 add constraint c1 foreign key (f1) references t1(f1);
ERROR HY000: Error on rename of '#sql-temporary' to './test/t1' (errno: 150)
InnoDB: which are not compatible with the new table definition.
InnoDB: has or is referenced in foreign key constraints
drop table t1;
# Bug 12902967: Creating self referencing fk on same index unhandled,
# confusing error
#
# Creating a self referencing foreign key on the same
# column/index is an unhandled exception, it should throw a sensible
# error but instead implies that your data dictionary may now be out
# of sync:
--source include/have_innodb.inc
let error_log= $MYSQLTEST_VARDIR/log/mysqld.1.err;
--remove_file $error_log
--source include/restart_mysqld.inc
create table t1 (f1 integer primary key) engine innodb;
# The below statement should produce error message in error log.
# This error message should mention problem with foreign keys
# rather than with data dictionary.
--replace_regex /'\.\/test\/#sql-[0-9a-f_]*'/'#sql-temporary'/
--error ER_ERROR_ON_RENAME
alter table t1 add constraint c1 foreign key (f1) references t1(f1);
perl;
$file = "$ENV{'error_log'}";
open ( FILE, $file) || die "can't open file! ($file)\n";
@lines = <FILE>;
close (FILE);
$count = 0;
foreach $line (reverse @lines) {
if ($line =~ "^InnoDB:") {
++$count;
print "$line";
if ($count == 2) {
break;
}
}
}
EOF
drop table t1;
......@@ -246,10 +246,17 @@ uint explain_filename(THD* thd,
{
part_name_len= tmp_p - part_name - 1;
subpart_name= tmp_p + 3;
tmp_p+= 3;
}
else if ((tmp_p[1] == 'Q' || tmp_p[1] == 'q') &&
(tmp_p[2] == 'L' || tmp_p[2] == 'l') &&
tmp_p[3] == '-')
{
name_type= TEMP;
tmp_p+= 4; /* sql- prefix found */
}
else
res= 2;
tmp_p+= 3;
break;
case 'T':
case 't':
......@@ -6718,21 +6725,47 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
(void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
}
else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
new_alias, FN_FROM_IS_TMP) ||
((new_name != table_name || new_db != db) && // we also do rename
(need_copy_table != ALTER_TABLE_METADATA_ONLY ||
mysql_rename_table(save_old_db_type, db, table_name, new_db,
new_alias, NO_FRM_RENAME)) &&
Table_triggers_list::change_table_name(thd, db, alias, table_name,
new_db, new_alias)))
new_alias, FN_FROM_IS_TMP))
{
/* Try to get everything back. */
error=1;
(void) quick_rm_table(new_db_type,new_db,new_alias, 0);
error= 1;
(void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP);
(void) mysql_rename_table(old_db_type, db, old_name, db, alias,
FN_FROM_IS_TMP);
}
else if (new_name != table_name || new_db != db)
{
if (need_copy_table == ALTER_TABLE_METADATA_ONLY &&
mysql_rename_table(save_old_db_type, db, table_name, new_db,
new_alias, NO_FRM_RENAME))
{
/* Try to get everything back. */
error= 1;
(void) quick_rm_table(new_db_type, new_db, new_alias, 0);
(void) mysql_rename_table(old_db_type, db, old_name, db, alias,
FN_FROM_IS_TMP);
}
else if (Table_triggers_list::change_table_name(thd, db, alias,
table_name, new_db,
new_alias))
{
/* Try to get everything back. */
error= 1;
(void) quick_rm_table(new_db_type, new_db, new_alias, 0);
(void) mysql_rename_table(old_db_type, db, old_name, db,
alias, FN_FROM_IS_TMP);
/*
If we were performing "fast"/in-place ALTER TABLE we also need
to restore old name of table in storage engine as a separate
step, as the above rename affects .FRM only.
*/
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
{
(void) mysql_rename_table(save_old_db_type, new_db, new_alias,
db, table_name, NO_FRM_RENAME);
}
}
}
if (! error)
(void) quick_rm_table(old_db_type, db, old_name, FN_IS_TMP);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment