diff --git a/executor/batch_point_get.go b/executor/batch_point_get.go index e41dadbb28cb0..c4fdca29b4bb3 100644 --- a/executor/batch_point_get.go +++ b/executor/batch_point_get.go @@ -15,11 +15,13 @@ package executor import ( "context" + "fmt" "sort" "sync/atomic" "github.com/pingcap/failpoint" "github.com/pingcap/parser/model" + "github.com/pingcap/parser/mysql" "github.com/pingcap/tidb/kv" "github.com/pingcap/tidb/sessionctx" "github.com/pingcap/tidb/sessionctx/variable" @@ -251,12 +253,36 @@ func (e *BatchPointGetExec) initialize(ctx context.Context) error { failpoint.InjectContext(ctx, "batchPointGetRepeatableReadTest-step2", nil) }) } else if e.keepOrder { - sort.Slice(e.handles, func(i int, j int) bool { + less := func(i int, j int) bool { if e.desc { return e.handles[i].Compare(e.handles[j]) > 0 } return e.handles[i].Compare(e.handles[j]) < 0 - }) + + } + if e.tblInfo.PKIsHandle && mysql.HasUnsignedFlag(e.tblInfo.GetPkColInfo().Flag) { + uintComparator := func(i, h kv.Handle) int { + if !i.IsInt() || !h.IsInt() { + panic(fmt.Sprintf("both handles need be IntHandle, but got %T and %T ", i, h)) + } + ihVal := uint64(i.IntValue()) + hVal := uint64(h.IntValue()) + if ihVal > hVal { + return 1 + } + if ihVal < hVal { + return -1 + } + return 0 + } + less = func(i int, j int) bool { + if e.desc { + return uintComparator(e.handles[i], e.handles[j]) > 0 + } + return uintComparator(e.handles[i], e.handles[j]) < 0 + } + } + sort.Slice(e.handles, less) } keys := make([]kv.Key, len(e.handles)) diff --git a/executor/batch_point_get_test.go b/executor/batch_point_get_test.go index fc2d30538db2f..468ba2e974cda 100644 --- a/executor/batch_point_get_test.go +++ b/executor/batch_point_get_test.go @@ -150,3 +150,15 @@ func (s *testBatchPointGetSuite) TestIssue18843(c *C) { tk.MustQuery("select * from t18843 where f in (null)").Check(testkit.Rows()) tk.MustQuery("select * from t18843 where f is null").Check(testkit.Rows("2 ")) } + +func (s *testBatchPointGetSuite) TestBatchPointGetUnsignedHandleWithSort(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustExec("drop table if exists t2") + tk.MustExec("create table t2 (id bigint(20) unsigned, primary key(id))") + tk.MustExec("insert into t2 values (8738875760185212610)") + tk.MustExec("insert into t2 values (9814441339970117597)") + tk.MustExec("insert into t2 values (1)") + tk.MustQuery("select id from t2 where id in (8738875760185212610, 1, 9814441339970117597) order by id").Check(testkit.Rows("1", "8738875760185212610", "9814441339970117597")) + tk.MustQuery("select id from t2 where id in (8738875760185212610, 1, 9814441339970117597) order by id desc").Check(testkit.Rows("9814441339970117597", "8738875760185212610", "1")) +}