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;
}
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; }