1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

Fix for bug #12652385 - "61493: REORDERING COLUMNS

TO POSITION FIRST CAN CAUSE DATA TO BE CORRUPTED".
 
ALTER TABLE MODIFY/CHANGE ... FIRST did nothing except renaming
columns if new version of the table had exactly the same 
structure as the old one (i.e. as result of such statement, names 
of columns changed their order as specified but data in columns 
didn't). The same thing happened for ALTER TABLE DROP COLUMN/ADD 
COLUMN statements which were supposed to produce new version of
table with exactly the same structure as the old version of table.
I.e. in the latter case the result was the same as if old column 
was renamed instead of being dropped and new column with default
as value being created.
 
Both these problems were caused by the fact that ALTER TABLE
implementation incorrectly interpreted both these situations as 
simple renaming of columns and assumed that in-place ALTER TABLE
algorithm could have been used for them.
 
This patch fixes this problem by ensuring that in cases when some
column is moved to the first position or some column is dropped
the default ALTER TABLE algorithm involving table copying is 
always used. This is achieved by detecting such situations in
mysql_prepare_alter_table() and setting Alter_info::change_level
to ALTER_TABLE_DATA_CHANGED for them.
This commit is contained in:
Dmitry Lenev
2011-06-17 02:02:52 +04:00
parent da9a249b0a
commit 291cb58ae5
3 changed files with 73 additions and 0 deletions

View File

@@ -6170,6 +6170,12 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (drop)
{
drop_it.remove();
/*
ALTER TABLE DROP COLUMN always changes table data even in cases
when new version of the table has the same structure as the old
one.
*/
alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
continue;
}
/* Check if field is changed */
@@ -6247,7 +6253,14 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (!def->after)
new_create_list.push_back(def);
else if (def->after == first_keyword)
{
new_create_list.push_front(def);
/*
Re-ordering columns in table can't be done using in-place algorithm
as it always changes table data.
*/
alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
}
else
{
Create_field *find;
@@ -6263,6 +6276,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
goto err;
}
find_it.after(def); // Put element after this
/*
Re-ordering columns in table can't be done using in-place algorithm
as it always changes table data.
*/
alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
}
}