From 41f728bc5081f2847d77e2508661ab3257f1d5f2 Mon Sep 17 00:00:00 2001 From: lidezhu Date: Wed, 1 Dec 2021 12:35:51 +0800 Subject: [PATCH 1/2] Fix potential data loss when widen pk when pk is handle --- .../Transaction/RegionBlockReader.cpp | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/dbms/src/Storages/Transaction/RegionBlockReader.cpp b/dbms/src/Storages/Transaction/RegionBlockReader.cpp index d4c7a35a055..a994513c94e 100644 --- a/dbms/src/Storages/Transaction/RegionBlockReader.cpp +++ b/dbms/src/Storages/Transaction/RegionBlockReader.cpp @@ -349,7 +349,25 @@ bool setColumnValues(ColumnUInt8 & delmark_col, } } else - column_map.getMutableColumnPtr(pk_column_ids[0])->insert(Field(static_cast(pk))); + { + // The pk_type must be Int32/Uint32 or more narrow type + // so cannot tell its' exact type here, just use `insert(Field)` + HandleID handle_value(static_cast(pk)); + auto & pk_column = column_map.getMutableColumnPtr(pk_column_ids[0]); + pk_column->insert(Field(handle_value)); + if (unlikely(pk_column->getInt(index) != handle_value)) + { + if (!force_decode) + { + return false; + } + else + { + throw Exception("Detected overflow value when decoding pk column of type " + pk_column->getName(), + ErrorCodes::LOGICAL_ERROR); + } + } + } index++; } decoded_data.checkValid(); From 6d3fcb1c530c8423dd365c082487d949b5005e6c Mon Sep 17 00:00:00 2001 From: lidezhu Date: Wed, 1 Dec 2021 12:37:55 +0800 Subject: [PATCH 2/2] add widen_pk.test --- tests/fullstack-test2/ddl/widen_pk.test | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/fullstack-test2/ddl/widen_pk.test diff --git a/tests/fullstack-test2/ddl/widen_pk.test b/tests/fullstack-test2/ddl/widen_pk.test new file mode 100644 index 00000000000..2fdb5ec98ba --- /dev/null +++ b/tests/fullstack-test2/ddl/widen_pk.test @@ -0,0 +1,28 @@ +mysql> drop table if exists test.t +mysql> create table test.t(a int primary key) +mysql> alter table test.t set tiflash replica 1 + +func> wait_table test t + +mysql> insert into test.t values(1); + +mysql> select /*+ read_from_storage(tiflash[t]) */ * from test.t; ++---+ +| a | ++---+ +| 1 | ++---+ + +>> DBGInvoke __enable_schema_sync_service('false') + +mysql> alter table test.t modify column a bigint; + +mysql> insert into test.t values(9223372036854775807); + +mysql> select /*+ read_from_storage(tiflash[t]) */ * from test.t; ++---------------------+ +| a | ++---------------------+ +| 1 | +| 9223372036854775807 | ++---------------------+