From 1febce003dcb83700ce2d11164ae3d794d911431 Mon Sep 17 00:00:00 2001 From: Ti Chi Robot Date: Thu, 21 Mar 2024 16:39:50 +0800 Subject: [PATCH] ddl: fix adding multi-value index (#51884) (#51970) close pingcap/tidb#51162 --- pkg/ddl/index.go | 22 +++++++++++++++++- .../addindextest/add_index_test.go | 23 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/pkg/ddl/index.go b/pkg/ddl/index.go index 5445a14cd2574..1d3027ee9c41b 100644 --- a/pkg/ddl/index.go +++ b/pkg/ddl/index.go @@ -1782,6 +1782,7 @@ func writeChunkToLocal( maxIdxColCnt := maxIndexColumnCount(indexes) idxDataBuf := make([]types.Datum, maxIdxColCnt) handleDataBuf := make([]types.Datum, len(c.HandleOutputOffsets)) + var restoreDataBuf []types.Datum count := 0 var lastHandle kv.Handle @@ -1795,8 +1796,24 @@ func writeChunkToLocal( unlock() } }() + needRestoreForIndexes := make([]bool, len(indexes)) + restore := false + for i, index := range indexes { + needRestore := tables.NeedRestoredData(index.Meta().Columns, c.TableInfo.Columns) + needRestoreForIndexes[i] = needRestore + restore = restore || needRestore + } + if restore { + restoreDataBuf = make([]types.Datum, len(c.HandleOutputOffsets)) + } for row := iter.Begin(); row != iter.End(); row = iter.Next() { handleDataBuf := extractDatumByOffsets(row, c.HandleOutputOffsets, c.ExprColumnInfos, handleDataBuf) + if restore { + // restoreDataBuf should not truncate index values. + for i, datum := range handleDataBuf { + restoreDataBuf[i] = *datum.Clone() + } + } h, err := buildHandle(handleDataBuf, c.TableInfo, c.PrimaryKeyInfo, sCtx) if err != nil { return 0, nil, errors.Trace(err) @@ -1806,7 +1823,10 @@ func writeChunkToLocal( idxDataBuf = extractDatumByOffsets( row, copCtx.IndexColumnOutputOffsets(idxID), c.ExprColumnInfos, idxDataBuf) idxData := idxDataBuf[:len(index.Meta().Columns)] - rsData := getRestoreData(c.TableInfo, copCtx.IndexInfo(idxID), c.PrimaryKeyInfo, handleDataBuf) + var rsData []types.Datum + if needRestoreForIndexes[i] { + rsData = getRestoreData(c.TableInfo, copCtx.IndexInfo(idxID), c.PrimaryKeyInfo, restoreDataBuf) + } err = writeOneKVToLocal(ctx, writers[i], index, sCtx, writeBufs, idxData, rsData, h) if err != nil { return 0, nil, errors.Trace(err) diff --git a/tests/realtikvtest/addindextest/add_index_test.go b/tests/realtikvtest/addindextest/add_index_test.go index 284cbeebfb7ad..bac69a1042657 100644 --- a/tests/realtikvtest/addindextest/add_index_test.go +++ b/tests/realtikvtest/addindextest/add_index_test.go @@ -112,3 +112,26 @@ func TestAddForeignKeyWithAutoCreateIndex(t *testing.T) { tk.MustExec("update employee set pid=id-1 where id>1 and pid is null") tk.MustExec("alter table employee add foreign key fk_1(pid) references employee(id)") } + +func TestIssue51162(t *testing.T) { + store := realtikvtest.CreateMockStoreAndSetup(t) + tk := testkit.NewTestKit(t, store) + tk.MustExec("use test") + tk.MustExec("set global tidb_enable_fast_table_check=0") + tk.MustExec(`CREATE TABLE tl ( + col_42 json NOT NULL, + col_43 tinyint(1) DEFAULT NULL, + col_44 char(168) CHARACTER SET gbk COLLATE gbk_bin DEFAULT NULL, + col_45 json DEFAULT NULL, + col_46 text COLLATE utf8mb4_unicode_ci NOT NULL, + col_47 char(43) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'xW2YNb99pse4)', + col_48 time NOT NULL DEFAULT '12:31:25', + PRIMARY KEY (col_47,col_46(2)) /*T![clustered_index] CLUSTERED */ + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;`) + + tk.MustExec(`INSERT INTO tl VALUES + ('[\"1\"]',0,'1','[1]','Wxup81','1','10:14:20');`) + + tk.MustExec("alter table tl add index idx_16(`col_48`,(cast(`col_45` as signed array)),`col_46`(5));") + tk.MustExec("admin check table tl") +}