From 0a0d676bb2799f9d6f617008c6c29f9213875806 Mon Sep 17 00:00:00 2001 From: crazycs Date: Sun, 30 Sep 2018 11:42:06 +0800 Subject: [PATCH] admin: fix admin check table compare bug (#7818) --- executor/admin_test.go | 8 ++++++++ util/admin/admin.go | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/executor/admin_test.go b/executor/admin_test.go index c3f078257285f..0a1282c582388 100644 --- a/executor/admin_test.go +++ b/executor/admin_test.go @@ -498,6 +498,14 @@ func (s *testSuite) TestAdminCheckTable(c *C) { tk.MustExec(`ALTER TABLE t1 ADD INDEX idx5 (c5)`) tk.MustExec(`ALTER TABLE t1 ADD INDEX idx6 (c6)`) tk.MustExec(`admin check table t1`) + + // Test add index on decimal column. + tk.MustExec(`drop table if exists td1;`) + tk.MustExec(`CREATE TABLE td1 (c2 INT NULL DEFAULT '70');`) + tk.MustExec(`INSERT INTO td1 SET c2 = '5';`) + tk.MustExec(`ALTER TABLE td1 ADD COLUMN c4 DECIMAL(12,8) NULL DEFAULT '213.41598062';`) + tk.MustExec(`ALTER TABLE td1 ADD INDEX id2 (c4) ;`) + tk.MustExec(`ADMIN CHECK TABLE td1;`) } func (s *testSuite) TestAdminCheckPrimaryIndex(c *C) { diff --git a/util/admin/admin.go b/util/admin/admin.go index d71434e7bcf3b..3e767f73021d3 100644 --- a/util/admin/admin.go +++ b/util/admin/admin.go @@ -353,6 +353,7 @@ func checkIndexAndRecord(sessCtx sessionctx.Context, txn kv.Transaction, t table if err != nil { return errors.Trace(err) } + sc := new(stmtctx.StatementContext) for { vals1, h, err := it.Next() if terror.ErrorEqual(err, io.EOF) { @@ -375,7 +376,7 @@ func checkIndexAndRecord(sessCtx sessionctx.Context, txn kv.Transaction, t table return errors.Trace(err) } adjustDatumKind(vals1, vals2) - if !reflect.DeepEqual(vals1, vals2) { + if !compareDatumSlice(sc, vals1, vals2) { record1 := &RecordData{Handle: h, Values: vals1} record2 := &RecordData{Handle: h, Values: vals2} return ErrDataInConsistent.GenWithStack("index:%#v != record:%#v", record1, record2) @@ -385,6 +386,25 @@ func checkIndexAndRecord(sessCtx sessionctx.Context, txn kv.Transaction, t table return nil } +func compareDatumSlice(sc *stmtctx.StatementContext, val1s, val2s []types.Datum) bool { + if len(val1s) != len(val2s) { + return false + } + for i, v := range val1s { + if v.Kind() == types.KindMysqlDecimal { + res, err := v.CompareDatum(sc, &val2s[i]) + if err != nil || res != 0 { + return false + } + } else { + if !reflect.DeepEqual(v, val2s[i]) { + return false + } + } + } + return true +} + // CheckRecordAndIndex is exported for testing. func CheckRecordAndIndex(sessCtx sessionctx.Context, txn kv.Transaction, t table.Table, idx table.Index, genExprs map[string]expression.Expression) error { sc := sessCtx.GetSessionVars().StmtCtx