# At a local mysql-5.1 repository of davi
2662 Davi Arnaut 2008-06-13
Bug#21704: Renaming column does not update FK definition
PLEASE DISREGARD, THIS IS A TENTATIVE PATCH:
This patch introduces a regression as it will always cause
a full table copy to take place when renaming columns. Or in
other words, no more fast alter table.
The problem was that renaming columns that appear in a foreign
key definition does not cause the definition to be updated to
the new column name. This occurred because the server was not
notifying the storage engine of a possible incompatible change
in column names.
The solution is to pass a flag to the storage engine signaling
that a column was renamed. With this flag the engine will be
able to decide whether the change is compatible or not. If
it's incompatible or the rename is not supported, the storage
engine will issue a error.
Patch subimitted Jani Tolonen and Marko Make
modified:
mysql-test/include/mix1.inc
mysql-test/r/innodb_mysql.result
sql/handler.h
sql/sql_table.cc
storage/innobase/handler/ha_innodb.cc
per-file messages:
mysql-test/include/mix1.inc
Add test case as suggested by Marko
mysql-test/r/innodb_mysql.result
Update test case result
sql/handler.h
Add new bit flag to signal that a column was renamed.
sql/sql_table.cc
Signal that a column was renamed.
storage/innobase/handler/ha_innodb.cc
Table is compatible if a column was renamed.
=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc 2008-05-20 07:38:17 +0000
+++ b/mysql-test/include/mix1.inc 2008-06-13 19:24:55 +0000
@@ -1453,4 +1453,30 @@ ALTER TABLE t1 CHANGE id id2 INT;
DROP TABLE t2;
DROP TABLE t1;
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+--enable_warnings
+
+CREATE TABLE t1(id INT PRIMARY KEY NOT NULL)
+ ENGINE=innodb;
+
+CREATE TABLE t2(
+ t1_id INT PRIMARY KEY,
+ CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id))
+ ENGINE=innodb;
+
+--echo
+
+--disable_result_log
+--error ER_ERROR_ON_RENAME
+ALTER TABLE t1 CHANGE id id2 INT NOT NULL;
+--enable_result_log
+
+--echo
+
+DROP TABLE t2;
+DROP TABLE t1;
+
--echo End of 5.1 tests
=== modified file 'mysql-test/r/innodb_mysql.result'
--- a/mysql-test/r/innodb_mysql.result 2008-05-07 05:58:21 +0000
+++ b/mysql-test/r/innodb_mysql.result 2008-06-13 19:24:55 +0000
@@ -1653,6 +1653,19 @@ ALTER TABLE t1 CHANGE id id2 INT;
DROP TABLE t2;
DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+CREATE TABLE t1(id INT PRIMARY KEY NOT NULL)
+ENGINE=innodb;
+CREATE TABLE t2(
+t1_id INT PRIMARY KEY,
+CONSTRAINT fk1 FOREIGN KEY (t1_id) REFERENCES t1(id))
+ENGINE=innodb;
+
+ALTER TABLE t1 CHANGE id id2 INT NOT NULL;
+
+DROP TABLE t2;
+DROP TABLE t1;
End of 5.1 tests
drop table if exists t1, t2, t3;
create table t1(a int);
=== modified file 'sql/handler.h'
--- a/sql/handler.h 2008-03-28 10:14:27 +0000
+++ b/sql/handler.h 2008-06-13 19:24:55 +0000
@@ -325,6 +325,7 @@ enum enum_binlog_command {
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
#define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
+#define HA_CREATE_USED_NEW_COLUMN_NAME (1L << 22)
typedef ulonglong my_xid; // this line is the same as in log_event.h
#define MYSQL_XID_PREFIX "MySQLXid"
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-05-20 07:38:17 +0000
+++ b/sql/sql_table.cc 2008-06-13 19:24:55 +0000
@@ -5263,7 +5263,10 @@ compare_tables(TABLE *table,
if (my_strcasecmp(system_charset_info,
field->field_name,
new_field->field_name))
- field->flags|= FIELD_IS_RENAMED;
+ {
+ field->flags|= FIELD_IS_RENAMED;
+ create_info->used_fields|= HA_CREATE_USED_NEW_COLUMN_NAME;
+ }
/* Evaluate changes bitmap and send to check_if_incompatible_data() */
if (!(tmp= field->is_equal(new_field)))
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc 2008-05-14 08:45:32 +0000
+++ b/storage/innobase/handler/ha_innodb.cc 2008-06-13 19:24:55 +0000
@@ -7929,6 +7929,15 @@ bool ha_innobase::check_if_incompatible_
return COMPATIBLE_DATA_NO;
}
+ /* Check that columns were not renamed, because there is no
+ mechanism for updating column names in the InnoDB data
+ dictionary (and in InnoDB foreign key definitions) when
+ column names are updated in the MySQL data dictionary. */
+ if (info->used_fields & HA_CREATE_USED_NEW_COLUMN_NAME) {
+
+ return(COMPATIBLE_DATA_NO);
+ }
+
/* Check that auto_increment value was not changed */
if ((info->used_fields & HA_CREATE_USED_AUTO) &&
info->auto_increment_value != 0) {
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (davi:2662) Bug#21704 | Davi Arnaut | 13 Jun |