Commit 0779e2cb authored by Aleksey Midenkov's avatar Aleksey Midenkov

MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table

When f.ex. table is partitioned by HASH(a) and we rename column `a' to
`b' partitioning filter stays unchanged: HASH(a). That's the wrong
behavior.

The patch updates partitioning filter in accordance to the new columns
names. That includes partition/subpartition expression and
partition/subpartition field list.
parent 4eb8c35b
......@@ -200,4 +200,15 @@ pk
2
delete from t1;
drop table t1;
#
# MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table
#
create table t (a int, b int) partition by list (b) (partition p1 values in (1, 2));
insert into t values (0, 1), (2, 2);
alter table t change b f int, change a b int, algorithm=nocopy;
check table t;
Table Op Msg_type Msg_text
test.t check status OK
delete from t order by b limit 1;
drop table t;
# End of 10.3 tests
......@@ -185,4 +185,15 @@ select * from t1 partition(p1);
delete from t1;
drop table t1;
--echo #
--echo # MDEV-28576 RENAME COLUMN with NOCOPY algorithm leads to corrupt partitioned table
--echo #
create table t (a int, b int) partition by list (b) (partition p1 values in (1, 2));
insert into t values (0, 1), (2, 2);
alter table t change b f int, change a b int, algorithm=nocopy;
check table t;
delete from t order by b limit 1;
# cleanup
drop table t;
--echo # End of 10.3 tests
......@@ -7975,6 +7975,20 @@ void append_drop_column(THD *thd, String *str, Field *field)
}
static inline
void rename_field_in_list(Create_field *field, List<const char> *field_list)
{
DBUG_ASSERT(field->change.str);
List_iterator<const char> it(*field_list);
while (const char *name= it++)
{
if (my_strcasecmp(system_charset_info, name, field->change.str))
continue;
it.replace(field->field_name.str);
}
}
/**
Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
......@@ -8284,6 +8298,39 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
new_create_tail.push_back(def, thd->mem_root);
}
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (alter_info->flags & ALTER_RENAME_COLUMN)
{
if (thd->work_part_info)
{
partition_info *part_info= thd->work_part_info;
List_iterator<Create_field> def_it(column_rename_param.fields);
const bool part_field_list= !part_info->part_field_list.is_empty();
const bool subpart_field_list= !part_info->subpart_field_list.is_empty();
if (part_info->part_expr)
part_info->part_expr->walk(&Item::rename_fields_processor, 1,
&column_rename_param);
if (part_info->subpart_expr)
part_info->subpart_expr->walk(&Item::rename_fields_processor, 1,
&column_rename_param);
if (part_field_list || subpart_field_list)
{
while (Create_field *def= def_it++)
{
if (def->change.str)
{
if (part_field_list)
rename_field_in_list(def, &part_info->part_field_list);
if (subpart_field_list)
rename_field_in_list(def, &part_info->subpart_field_list);
} /* if (def->change.str) */
} /* while (def) */
} /* if (part_field_list || subpart_field_list) */
} /* if (part_info) */
}
#endif
dropped_sys_vers_fields &= VERS_SYSTEM_FIELD;
if ((dropped_sys_vers_fields ||
alter_info->flags & ALTER_DROP_PERIOD) &&
......
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