diff --git a/executor/admin_test.go b/executor/admin_test.go index 1193d27254933..ffc1150e92148 100644 --- a/executor/admin_test.go +++ b/executor/admin_test.go @@ -422,4 +422,10 @@ func (s *testSuite) TestAdminCheckTable(c *C) { tk.MustExec(`insert into test set a='12:10:36';`) tk.MustExec(`admin check table test`) + + // Test timestamp type check table. + tk.MustExec(`drop table if exists test`) + tk.MustExec(`create table test ( a TIMESTAMP, primary key(a) );`) + tk.MustExec(`insert into test set a='2015-08-10 04:18:49';`) + tk.MustExec(`admin check table test;`) } diff --git a/util/admin/admin.go b/util/admin/admin.go index 5ff313d175d67..761dbe5a3bddd 100644 --- a/util/admin/admin.go +++ b/util/admin/admin.go @@ -17,7 +17,6 @@ import ( "fmt" "io" "reflect" - "time" "github.com/juju/errors" "github.com/pingcap/tidb/kv" @@ -355,7 +354,7 @@ func CheckRecordAndIndex(sessCtx sessionctx.Context, txn kv.Transaction, t table return true, nil } - err := iterRecords(txn, t, startKey, cols, filterFunc) + err := iterRecords(sessCtx, txn, t, startKey, cols, filterFunc) if err != nil { return errors.Trace(err) @@ -364,7 +363,7 @@ func CheckRecordAndIndex(sessCtx sessionctx.Context, txn kv.Transaction, t table return nil } -func scanTableData(retriever kv.Retriever, t table.Table, cols []*table.Column, startHandle, limit int64) ( +func scanTableData(sessCtx sessionctx.Context, retriever kv.Retriever, t table.Table, cols []*table.Column, startHandle, limit int64) ( []*RecordData, int64, error) { var records []*RecordData @@ -382,7 +381,7 @@ func scanTableData(retriever kv.Retriever, t table.Table, cols []*table.Column, return false, nil } - err := iterRecords(retriever, t, startKey, cols, filterFunc) + err := iterRecords(sessCtx, retriever, t, startKey, cols, filterFunc) if err != nil { return nil, 0, errors.Trace(err) } @@ -400,23 +399,23 @@ func scanTableData(retriever kv.Retriever, t table.Table, cols []*table.Column, // It returns data and the next startHandle until it doesn't have data, then returns data is nil and // the next startHandle is the handle which can't get data. If startHandle = 0 and limit = -1, // it returns the table data of the whole. -func ScanTableRecord(retriever kv.Retriever, t table.Table, startHandle, limit int64) ( +func ScanTableRecord(sessCtx sessionctx.Context, retriever kv.Retriever, t table.Table, startHandle, limit int64) ( []*RecordData, int64, error) { - return scanTableData(retriever, t, t.Cols(), startHandle, limit) + return scanTableData(sessCtx, retriever, t, t.Cols(), startHandle, limit) } // ScanSnapshotTableRecord scans the ver version of the table data in a limited number. // It returns data and the next startHandle until it doesn't have data, then returns data is nil and // the next startHandle is the handle which can't get data. If startHandle = 0 and limit = -1, // it returns the table data of the whole. -func ScanSnapshotTableRecord(store kv.Storage, ver kv.Version, t table.Table, startHandle, limit int64) ( +func ScanSnapshotTableRecord(sessCtx sessionctx.Context, store kv.Storage, ver kv.Version, t table.Table, startHandle, limit int64) ( []*RecordData, int64, error) { snap, err := store.GetSnapshot(ver) if err != nil { return nil, 0, errors.Trace(err) } - records, nextHandle, err := ScanTableRecord(snap, t, startHandle, limit) + records, nextHandle, err := ScanTableRecord(sessCtx, snap, t, startHandle, limit) return records, nextHandle, errors.Trace(err) } @@ -424,7 +423,7 @@ func ScanSnapshotTableRecord(store kv.Storage, ver kv.Version, t table.Table, st // CompareTableRecord compares data and the corresponding table data one by one. // It returns nil if data is equal to the data that scans from table, otherwise // it returns an error with a different set of records. If exact is false, only compares handle. -func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, exact bool) error { +func CompareTableRecord(sessCtx sessionctx.Context, txn kv.Transaction, t table.Table, data []*RecordData, exact bool) error { m := make(map[int64][]types.Datum, len(data)) for _, r := range data { if _, ok := m[r.Handle]; ok { @@ -455,7 +454,7 @@ func CompareTableRecord(txn kv.Transaction, t table.Table, data []*RecordData, e return true, nil } - err := iterRecords(txn, t, startKey, t.Cols(), filterFunc) + err := iterRecords(sessCtx, txn, t, startKey, t.Cols(), filterFunc) if err != nil { return errors.Trace(err) } @@ -493,7 +492,7 @@ func rowWithCols(sessCtx sessionctx.Context, txn kv.Retriever, t table.Table, h } colTps[col.ID] = &col.FieldType } - row, err := tablecodec.DecodeRow(value, colTps, time.UTC) + row, err := tablecodec.DecodeRow(value, colTps, sessCtx.GetSessionVars().GetTimeZone()) if err != nil { return nil, errors.Trace(err) } @@ -526,7 +525,7 @@ func rowWithCols(sessCtx sessionctx.Context, txn kv.Retriever, t table.Table, h return v, nil } -func iterRecords(retriever kv.Retriever, t table.Table, startKey kv.Key, cols []*table.Column, +func iterRecords(sessCtx sessionctx.Context, retriever kv.Retriever, t table.Table, startKey kv.Key, cols []*table.Column, fn table.RecordIterFunc) error { it, err := retriever.Seek(startKey) if err != nil { @@ -554,7 +553,7 @@ func iterRecords(retriever kv.Retriever, t table.Table, startKey kv.Key, cols [] return errors.Trace(err) } - rowMap, err := tablecodec.DecodeRow(it.Value(), colMap, time.UTC) + rowMap, err := tablecodec.DecodeRow(it.Value(), colMap, sessCtx.GetSessionVars().GetTimeZone()) if err != nil { return errors.Trace(err) } diff --git a/util/admin/admin_test.go b/util/admin/admin_test.go index ef32afc582526..8e43a33740203 100644 --- a/util/admin/admin_test.go +++ b/util/admin/admin_test.go @@ -234,7 +234,7 @@ func (s *testSuite) TestScan(c *C) { record2 := &RecordData{Handle: int64(2), Values: types.MakeDatums(int64(2), int64(20), int64(21))} ver, err := s.store.CurrentVersion() c.Assert(err, IsNil) - records, _, err := ScanSnapshotTableRecord(s.store, ver, tb, int64(1), 1) + records, _, err := ScanSnapshotTableRecord(se, s.store, ver, tb, int64(1), 1) c.Assert(err, IsNil) c.Assert(records, DeepEquals, []*RecordData{record1}) @@ -245,14 +245,14 @@ func (s *testSuite) TestScan(c *C) { txn, err := s.store.Begin() c.Assert(err, IsNil) - records, nextHandle, err := ScanTableRecord(txn, tb, int64(1), 1) + records, nextHandle, err := ScanTableRecord(se, txn, tb, int64(1), 1) c.Assert(err, IsNil) c.Assert(records, DeepEquals, []*RecordData{record1}) - records, nextHandle, err = ScanTableRecord(txn, tb, nextHandle, 1) + records, nextHandle, err = ScanTableRecord(se, txn, tb, nextHandle, 1) c.Assert(err, IsNil) c.Assert(records, DeepEquals, []*RecordData{record2}) startHandle := nextHandle - records, nextHandle, err = ScanTableRecord(txn, tb, startHandle, 1) + records, nextHandle, err = ScanTableRecord(se, txn, tb, startHandle, 1) c.Assert(err, IsNil) c.Assert(records, IsNil) c.Assert(nextHandle, Equals, startHandle) @@ -296,45 +296,45 @@ func (s *testSuite) testTableData(c *C, tb table.Table, rs []*RecordData) { txn, err := s.store.Begin() c.Assert(err, IsNil) - err = CompareTableRecord(txn, tb, rs, true) + err = CompareTableRecord(s.ctx, txn, tb, rs, true) c.Assert(err, IsNil) records := []*RecordData{ {Handle: rs[0].Handle}, {Handle: rs[1].Handle}, } - err = CompareTableRecord(txn, tb, records, false) + err = CompareTableRecord(s.ctx, txn, tb, records, false) c.Assert(err, IsNil) record := &RecordData{Handle: rs[1].Handle, Values: types.MakeDatums(int64(30))} - err = CompareTableRecord(txn, tb, []*RecordData{rs[0], record}, true) + err = CompareTableRecord(s.ctx, txn, tb, []*RecordData{rs[0], record}, true) c.Assert(err, NotNil) diffMsg := newDiffRetError("data", record, rs[1]) c.Assert(err.Error(), DeepEquals, diffMsg) record.Handle = 3 - err = CompareTableRecord(txn, tb, []*RecordData{rs[0], record, rs[1]}, true) + err = CompareTableRecord(s.ctx, txn, tb, []*RecordData{rs[0], record, rs[1]}, true) c.Assert(err, NotNil) diffMsg = newDiffRetError("data", record, nil) c.Assert(err.Error(), DeepEquals, diffMsg) - err = CompareTableRecord(txn, tb, []*RecordData{rs[0], rs[1], record}, true) + err = CompareTableRecord(s.ctx, txn, tb, []*RecordData{rs[0], rs[1], record}, true) c.Assert(err, NotNil) diffMsg = newDiffRetError("data", record, nil) c.Assert(err.Error(), DeepEquals, diffMsg) - err = CompareTableRecord(txn, tb, []*RecordData{rs[0]}, true) + err = CompareTableRecord(s.ctx, txn, tb, []*RecordData{rs[0]}, true) c.Assert(err, NotNil) diffMsg = newDiffRetError("data", nil, rs[1]) c.Assert(err.Error(), DeepEquals, diffMsg) - err = CompareTableRecord(txn, tb, nil, true) + err = CompareTableRecord(s.ctx, txn, tb, nil, true) c.Assert(err, NotNil) diffMsg = newDiffRetError("data", nil, rs[0]) c.Assert(err.Error(), DeepEquals, diffMsg) errRs := append(rs, &RecordData{Handle: int64(1), Values: types.MakeDatums(int64(3))}) - err = CompareTableRecord(txn, tb, errRs, false) + err = CompareTableRecord(s.ctx, txn, tb, errRs, false) c.Assert(err.Error(), DeepEquals, "[admin:2]handle:1 is repeated in data") }