Description:
When update a partition table with a partition key which includes stored generated columns. An Unexpected 1748 error will return if the update change the original rows from one partition to another partition.
This is because partition_key_modified function doesn't consider partition key with stored generated column.
bool partition_key_modified(TABLE *table, const MY_BITMAP *fields) {
Field **fld;
partition_info *part_info = table->part_info;
DBUG_TRACE;
if (!part_info) return false;
if (table->s->db_type()->partition_flags &&
(table->s->db_type()->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
return false;
for (fld = part_info->full_part_field_array; *fld; fld++)
---> if (bitmap_is_set(fields, (*fld)->field_index()) return true;
return false;
}
(gdb) p/t *fields.bitmap
$74 = 11
(gdb) p (*fld)->gcol_info
$75 = (Value_generator *) 0x7f0b00ce0dc0
(gdb) p (*fld)->m_field_index
$76 = 2
How to repeat:
create table t1 (a int, b int, c int as (a + b) stored, primary key (a,b,c)) partition by key(c) partitions 8;
insert into t1 (a,b) values (1,1),(2,2);
update t1 set a = 4, b = 4 where a = 1 and b = 1 and c = 2;
ERROR 1748 (HY000): Found a row not matching the given partition set
Suggested fix:
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 8920efaa..57f0cbf 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2475,8 +2475,14 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields) {
if (table->s->db_type()->partition_flags &&
(table->s->db_type()->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
return false;
- for (fld = part_info->full_part_field_array; *fld; fld++)
+ for (fld = part_info->full_part_field_array; *fld; fld++) {
+ if ((*fld)->gcol_info &&
+ bitmap_is_overlapping(fields, &(*fld)->gcol_info->base_columns_map)) {
+ assert((*fld)->gcol_info->get_field_stored());
+ return true;
+ }
if (bitmap_is_set(fields, (*fld)->field_index())) return true;
+ }
return false;
}