Skip to content

Commit

Permalink
planner,executor: support global index for IndexScan and IndexLookUpR…
Browse files Browse the repository at this point in the history
…eader (#19821)
  • Loading branch information
ldeng-ustc authored Sep 24, 2020
1 parent 877d871 commit 0b7c716
Show file tree
Hide file tree
Showing 10 changed files with 176 additions and 24 deletions.
45 changes: 45 additions & 0 deletions distsql/request_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ func (builder *RequestBuilder) SetTableHandles(tid int64, handles []kv.Handle) *
return builder
}

// SetPartitionsAndHandles sets "KeyRanges" for "kv.Request" by converting ParitionHandles to KeyRanges.
// handles in slice must be kv.PartitionHandle.
func (builder *RequestBuilder) SetPartitionsAndHandles(handles []kv.Handle) *RequestBuilder {
builder.Request.KeyRanges = PartitionHandlesToKVRanges(handles)
return builder
}

const estimatedRegionRowCount = 100000

// SetDAGRequest sets the request type to "ReqTypeDAG" and construct request data.
Expand Down Expand Up @@ -299,6 +306,44 @@ func TableHandlesToKVRanges(tid int64, handles []kv.Handle) []kv.KeyRange {
return krs
}

// PartitionHandlesToKVRanges convert ParitionHandles to kv ranges.
// Handle in slices must be kv.PartitionHandle
func PartitionHandlesToKVRanges(handles []kv.Handle) []kv.KeyRange {
krs := make([]kv.KeyRange, 0, len(handles))
i := 0
for i < len(handles) {
ph := handles[i].(kv.PartitionHandle)
h := ph.Handle
pid := ph.PartitionID
if commonHandle, ok := h.(*kv.CommonHandle); ok {
ran := kv.KeyRange{
StartKey: tablecodec.EncodeRowKey(pid, commonHandle.Encoded()),
EndKey: tablecodec.EncodeRowKey(pid, append(commonHandle.Encoded(), 0)),
}
krs = append(krs, ran)
i++
continue
}
j := i + 1
for ; j < len(handles) && handles[j-1].IntValue() != math.MaxInt64; j++ {
if handles[j].IntValue() != handles[j-1].IntValue()+1 {
break
}
if handles[j].(kv.PartitionHandle).PartitionID != pid {
break
}
}
low := codec.EncodeInt(nil, handles[i].IntValue())
high := codec.EncodeInt(nil, handles[j-1].IntValue())
high = kv.Key(high).PrefixNext()
startKey := tablecodec.EncodeRowKey(pid, low)
endKey := tablecodec.EncodeRowKey(pid, high)
krs = append(krs, kv.KeyRange{StartKey: startKey, EndKey: endKey})
i = j
}
return krs
}

// IndexRangesToKVRanges converts index ranges to "KeyRange".
func IndexRangesToKVRanges(sc *stmtctx.StatementContext, tid, idxID int64, ranges []*ranger.Range, fb *statistics.QueryFeedback) ([]kv.KeyRange, error) {
if fb == nil || fb.Hist == nil {
Expand Down
26 changes: 24 additions & 2 deletions executor/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -2670,6 +2670,10 @@ func (b *executorBuilder) buildIndexReader(v *plannercore.PhysicalIndexReader) E
return ret
}

if is.Index.Global {
return ret
}

nextPartition := nextPartitionForIndexReader{exec: ret}
exec, err := buildPartitionTable(b, is.Table, &v.PartitionInfo, ret, nextPartition)
if err != nil {
Expand Down Expand Up @@ -2713,7 +2717,17 @@ func buildIndexReq(b *executorBuilder, schemaLen, handleLen int, plans []planner

func buildNoRangeIndexLookUpReader(b *executorBuilder, v *plannercore.PhysicalIndexLookUpReader) (*IndexLookUpExecutor, error) {
is := v.IndexPlans[0].(*plannercore.PhysicalIndexScan)
indexReq, indexStreaming, err := buildIndexReq(b, len(is.Index.Columns), len(v.CommonHandleCols), v.IndexPlans)
var handleLen int
if len(v.CommonHandleCols) != 0 {
handleLen = len(v.CommonHandleCols)
} else {
handleLen = 1
}
if is.Index.Global {
// Should output pid col.
handleLen++
}
indexReq, indexStreaming, err := buildIndexReq(b, len(is.Index.Columns), handleLen, v.IndexPlans)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -2806,6 +2820,10 @@ func (b *executorBuilder) buildIndexLookUpReader(v *plannercore.PhysicalIndexLoo
return ret
}

if is.Index.Global {
return ret
}

nextPartition := nextPartitionForIndexLookUp{exec: ret}
exec, err := buildPartitionTable(b, ts.Table, &v.PartitionInfo, ret, nextPartition)
if err != nil {
Expand Down Expand Up @@ -3100,7 +3118,11 @@ func (builder *dataReaderBuilder) buildTableReaderFromHandles(ctx context.Contex
})
}
var b distsql.RequestBuilder
b.SetTableHandles(getPhysicalTableID(e.table), handles)
if _, ok := handles[0].(kv.PartitionHandle); ok {
b.SetPartitionsAndHandles(handles)
} else {
b.SetTableHandles(getPhysicalTableID(e.table), handles)
}
return builder.buildTableReaderBase(ctx, e, b)
}

Expand Down
16 changes: 14 additions & 2 deletions executor/distsql.go
Original file line number Diff line number Diff line change
Expand Up @@ -459,6 +459,9 @@ func (e *IndexLookUpExecutor) getRetTpsByHandle() []*types.FieldType {
} else {
tps = []*types.FieldType{types.NewFieldType(mysql.TypeLonglong)}
}
if e.index.Global {
tps = append(tps, types.NewFieldType(mysql.TypeLonglong))
}
if e.checkIndexValue != nil {
tps = e.idxColTps
}
Expand Down Expand Up @@ -714,11 +717,15 @@ func (w *indexWorker) fetchHandles(ctx context.Context, result distsql.SelectRes
func (w *indexWorker) extractTaskHandles(ctx context.Context, chk *chunk.Chunk, idxResult distsql.SelectResult, count uint64) (
handles []kv.Handle, retChk *chunk.Chunk, scannedKeys uint64, err error) {
var handleOffset []int
numColsWithoutPid := chk.NumCols()
if w.idxLookup.index.Global {
numColsWithoutPid = numColsWithoutPid - 1
}
for i := range w.idxLookup.handleCols {
handleOffset = append(handleOffset, chk.NumCols()-len(w.idxLookup.handleCols)+i)
handleOffset = append(handleOffset, numColsWithoutPid-len(w.idxLookup.handleCols)+i)
}
if len(handleOffset) == 0 {
handleOffset = []int{chk.NumCols() - 1}
handleOffset = []int{numColsWithoutPid - 1}
}
handles = make([]kv.Handle, 0, w.batchSize)
// PushedLimit would always be nil for CheckIndex or CheckTable, we add this check just for insurance.
Expand Down Expand Up @@ -895,6 +902,11 @@ func (e *IndexLookUpExecutor) getHandle(row chunk.Row, handleIdx []int,
handle = kv.IntHandle(row.GetInt64(handleIdx[0]))
}
}
if e.index.Global {
pidOffset := row.Len() - 1
pid := row.GetInt64(pidOffset)
handle = kv.NewPartitionHandle(pid, handle)
}
return
}

Expand Down
9 changes: 9 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ var _ = SerialSuites(&testSerialSuite1{&baseTestSuite{}})
var _ = SerialSuites(&testSlowQuery{&baseTestSuite{}})
var _ = Suite(&partitionTableSuite{&baseTestSuite{}})
var _ = SerialSuites(&tiflashTestSuite{})
var _ = SerialSuites(&globalIndexSuite{&baseTestSuite{}})
var _ = SerialSuites(&testSerialSuite{&baseTestSuite{}})

type testSuite struct{ *baseTestSuite }
Expand All @@ -142,6 +143,7 @@ type testSuiteWithData struct {
}
type testSlowQuery struct{ *baseTestSuite }
type partitionTableSuite struct{ *baseTestSuite }
type globalIndexSuite struct{ *baseTestSuite }
type testSerialSuite struct{ *baseTestSuite }

type baseTestSuite struct {
Expand Down Expand Up @@ -196,6 +198,13 @@ func (s *baseTestSuite) TearDownSuite(c *C) {
s.store.Close()
}

func (s *globalIndexSuite) SetUpSuite(c *C) {
s.baseTestSuite.SetUpSuite(c)
config.UpdateGlobal(func(conf *config.Config) {
conf.EnableGlobalIndex = true
})
}

func (s *testSuiteP1) TestPessimisticSelectForUpdate(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
Expand Down
24 changes: 24 additions & 0 deletions executor/partition_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,27 @@ PRIMARY KEY (pk1,pk2)) partition by hash(pk2) partitions 4;`)
tk.MustQuery("select /*+ INL_JOIN(dt, rr) */ * from coverage_dt dt join coverage_rr rr on (dt.pk1 = rr.pk1 and dt.pk2 = rr.pk2);").Sort().Check(testkit.Rows("ios 3 ios 3 2", "linux 5 linux 5 1"))
tk.MustQuery("select /*+ INL_MERGE_JOIN(dt, rr) */ * from coverage_dt dt join coverage_rr rr on (dt.pk1 = rr.pk1 and dt.pk2 = rr.pk2);").Sort().Check(testkit.Rows("ios 3 ios 3 2", "linux 5 linux 5 1"))
}

func (s *globalIndexSuite) TestGlobalIndexScan(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop table if exists p")
tk.MustExec(`create table p (id int, c int) partition by range (c) (
partition p0 values less than (4),
partition p1 values less than (7),
partition p2 values less than (10))`)
tk.MustExec("alter table p add unique idx(id)")
tk.MustExec("insert into p values (1,3), (3,4), (5,6), (7,9)")
tk.MustQuery("select id from p use index (idx)").Check(testkit.Rows("1", "3", "5", "7"))
}

func (s *globalIndexSuite) TestGlobalIndexDoubleRead(c *C) {
tk := testkit.NewTestKitWithInit(c, s.store)
tk.MustExec("drop table if exists p")
tk.MustExec(`create table p (id int, c int) partition by range (c) (
partition p0 values less than (4),
partition p1 values less than (7),
partition p2 values less than (10))`)
tk.MustExec("alter table p add unique idx(id)")
tk.MustExec("insert into p values (1,3), (3,4), (5,6), (7,9)")
tk.MustQuery("select * from p use index (idx)").Check(testkit.Rows("1 3", "3 4", "5 6", "7 9"))
}
12 changes: 0 additions & 12 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -406,14 +406,11 @@ github.com/ngaut/unistore v0.0.0-20200918091209-68a2db6bb775/go.mod h1:ZR3NH+Hzq
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.4 h1:vHD/YYe1Wolo78koG299f7V/VAS08c6IpCLn+Ejf/w8=
github.com/olekukonko/tablewriter v0.0.4/go.mod h1:zq6QwlOf5SlnkVbMSr5EoBv3636FWnp+qbPhuoO21uA=
github.com/onsi/ginkgo v1.6.0 h1:Ix8l273rp3QzYgXSR+c8d1fTG7UPgYkOSELPhiY/YGw=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.4.2 h1:3mYCb7aPxS/RU7TI1y4rkEn1oKmPRjNJLNEXgw7MH2I=
github.com/onsi/gomega v1.4.2/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
Expand All @@ -425,7 +422,6 @@ github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsq
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.3.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5 h1:q2e307iGHPdTGp0hoxKjt1H5pDo6utceo3dQVK3I5XQ=
github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 h1:JhzVVoYvbOACxoUmOs6V/G4D5nPVUW73rKvXxP4XUJc=
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
Expand All @@ -439,7 +435,6 @@ github.com/pingcap-incubator/tidb-dashboard v0.0.0-20200710045508-523e95bc5ec9/g
github.com/pingcap-incubator/tidb-dashboard v0.0.0-20200715070228-47f5de8a6992/go.mod h1:9yaAM77sPfa5/f6sdxr3jSkKfIz463KRHyiFHiGjdes=
github.com/pingcap-incubator/tidb-dashboard v0.0.0-20200807020752-01f0abe88e93/go.mod h1:9yaAM77sPfa5/f6sdxr3jSkKfIz463KRHyiFHiGjdes=
github.com/pingcap/badger v1.5.1-0.20200604041313-19c397305fcc/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ=
github.com/pingcap/badger v1.5.1-0.20200714132513-80ba2000f159 h1:cmZSuRbdfOJd3kJjRIClrLbt3nD0xi4oqYR1c/ZrPKg=
github.com/pingcap/badger v1.5.1-0.20200714132513-80ba2000f159/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ=
github.com/pingcap/badger v1.5.1-0.20200810065601-8c92a97807f9/go.mod h1:LyrqUOHZrUDf9oGi1yoz1+qw9ckSIhQb5eMa1acOLNQ=
github.com/pingcap/badger v1.5.1-0.20200908111422-2e78ee155d19 h1:IXpGy7y9HyoShAFmzW2OPF0xCA5EOoSTyZHwsgYk9Ro=
Expand All @@ -451,7 +446,6 @@ github.com/pingcap/br v0.0.0-20200617120402-56e151ad8b67/go.mod h1:/3QzpDG7YTPrD
github.com/pingcap/br v0.0.0-20200727092753-a475692725db/go.mod h1:4iTqZAMbEPmjBggYixqIg2FwIHBQtyImTM/QYlpTBGk=
github.com/pingcap/br v0.0.0-20200803052654-e6f63fc1807a/go.mod h1:8j7vGUfHCETYbeBfASLTDywC3NFSx90z9nuk0PV9rpo=
github.com/pingcap/br v0.0.0-20200805121136-181c081ba6ac/go.mod h1:9P24mNzNmXjggYBm4pnb08slSbua8FA6QIyg68GpuhQ=
github.com/pingcap/br v0.0.0-20200820083933-d9d6207c0aa7 h1:7YWkuK/QY7/nz819lnxb0qDXqLrApDjZHjYPo+tduGA=
github.com/pingcap/br v0.0.0-20200820083933-d9d6207c0aa7/go.mod h1:5ri8663t7CtJuG0kiOKKoBmwk9HOCX5MoKpmh1fW4CE=
github.com/pingcap/br v0.0.0-20200923023944-7456456854e4 h1:f1e1xbBAMc6mOrnBtrPRke52Zxv8zVlyr5g0Tz/pySQ=
github.com/pingcap/br v0.0.0-20200923023944-7456456854e4/go.mod h1:DGsMcZVYt2haeDF/xGerf77c2RpTymgYY5+bMg8uArA=
Expand All @@ -460,15 +454,11 @@ github.com/pingcap/check v0.0.0-20191107115940-caf2b9e6ccf4/go.mod h1:PYMCGwN0JH
github.com/pingcap/check v0.0.0-20191216031241-8a5a85928f12/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc=
github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712 h1:R8gStypOBmpnHEx1qi//SaqxJVI4inOqljg/Aj5/390=
github.com/pingcap/check v0.0.0-20200212061837-5e12011dc712/go.mod h1:PYMCGwN0JHjoqGr3HrZoD+b8Tgx8bKnArhSq8YVzUMc=
github.com/pingcap/errcode v0.0.0-20180921232412-a1a7271709d9 h1:KH4f4Si9XK6/IW50HtoaiLIFHGkapOM6w83za47UYik=
github.com/pingcap/errcode v0.0.0-20180921232412-a1a7271709d9/go.mod h1:4b2X8xSqxIroj/IZ9MX/VGZhAwc11wB9wRIzHvz6SeM=
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.5-0.20190809092503-95897b64e011 h1:58naV4XMEqm0hl9LcYo6cZoGBGiLtefMQMF/vo3XLgQ=
github.com/pingcap/errors v0.11.5-0.20190809092503-95897b64e011/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
github.com/pingcap/errors v0.11.5-0.20200729012136-4e113ddee29e h1:/EGWHNOyEgizEBuAujWsb9vXrPZtt1b7ooDPyjEkjDw=
github.com/pingcap/errors v0.11.5-0.20200729012136-4e113ddee29e/go.mod h1:g4vx//d6VakjJ0mk7iLBlKA8LFavV/sAVINT/1PFxeQ=
github.com/pingcap/errors v0.11.5-0.20200902104258-eba4f1d8f6de h1:mW8hC2yXTpflfyTeJgcN4aJQfwcYODde8YgjBgAy6do=
github.com/pingcap/errors v0.11.5-0.20200902104258-eba4f1d8f6de/go.mod h1:g4vx//d6VakjJ0mk7iLBlKA8LFavV/sAVINT/1PFxeQ=
github.com/pingcap/errors v0.11.5-0.20200917111840-a15ef68f753d h1:TH18wFO5Nq/zUQuWu9ms2urgZnLP69XJYiI2JZAkUGc=
github.com/pingcap/errors v0.11.5-0.20200917111840-a15ef68f753d/go.mod h1:g4vx//d6VakjJ0mk7iLBlKA8LFavV/sAVINT/1PFxeQ=
Expand Down Expand Up @@ -548,7 +538,6 @@ github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200421113014-507d2bb3a15e+incompat
github.com/pingcap/tidb-tools v4.0.0-rc.1.0.20200514040632-f76b3e428e19+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v4.0.0+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v4.0.1+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v4.0.5-0.20200820082341-afeaaaaaa153+incompatible h1:OozchEPztWQsTdLxPSPs6P+Cowbr35J7uy5oRpjbV9E=
github.com/pingcap/tidb-tools v4.0.5-0.20200820082341-afeaaaaaa153+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
github.com/pingcap/tidb-tools v4.0.5-0.20200820092506-34ea90c93237+incompatible h1:qPppnsXVh3KswqRZdSAShGLLPd7dB+5w4lXDnpYn0SQ=
github.com/pingcap/tidb-tools v4.0.5-0.20200820092506-34ea90c93237+incompatible/go.mod h1:XGdcy9+yqlDSEMTpOXnwf3hiTeqrV6MN/u1se9N8yIM=
Expand Down Expand Up @@ -597,7 +586,6 @@ github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sasha-s/go-deadlock v0.2.0/go.mod h1:StQn567HiB1fF2yJ44N9au7wOhrPS3iZqiDbRupzT10=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44 h1:tB9NOR21++IjLyVx3/PCPhWMwqGNCMQEH96A6dMZ/gc=
github.com/sergi/go-diff v1.0.1-0.20180205163309-da645544ed44/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shirou/gopsutil v2.19.10+incompatible h1:lA4Pi29JEVIQIgATSeftHSY0rMGI9CLrl2ZvDLiahto=
github.com/shirou/gopsutil v2.19.10+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
Expand Down
38 changes: 38 additions & 0 deletions kv/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,3 +429,41 @@ func BuildHandleFromDatumRow(sctx *stmtctx.StatementContext, row []types.Datum,
}
return handle, nil
}

// PartitionHandle combines a handle and a PartitionID, used to location a row in partioned table.
// Now only used in global index.
// TODO: support PartitionHandle in HandleMap.
type PartitionHandle struct {
Handle
PartitionID int64
}

// NewPartitionHandle creates a PartitionHandle from a normal handle and a pid.
func NewPartitionHandle(pid int64, h Handle) PartitionHandle {
return PartitionHandle{
Handle: h,
PartitionID: pid,
}
}

// Equal implements the Handle interface.
func (ph PartitionHandle) Equal(h Handle) bool {
if ph2, ok := h.(PartitionHandle); ok {
return ph.PartitionID == ph2.PartitionID && ph.Handle.Equal(ph2.Handle)
}
return false
}

// Compare implements the Handle interface.
func (ph PartitionHandle) Compare(h Handle) int {
if ph2, ok := h.(PartitionHandle); ok {
if ph.PartitionID < ph2.PartitionID {
return -1
}
if ph.PartitionID > ph2.PartitionID {
return 1
}
return ph.Handle.Compare(ph2.Handle)
}
panic("PartitonHandle compares to non-parition Handle")
}
23 changes: 16 additions & 7 deletions planner/core/find_best_task.go
Original file line number Diff line number Diff line change
Expand Up @@ -1073,8 +1073,6 @@ func (is *PhysicalIndexScan) initSchema(idxExprCols []*expression.Column, isDoub
for i := len(is.Index.Columns); i < len(idxExprCols); i++ {
indexCols = append(indexCols, idxExprCols[i])
}
is.SetSchema(expression.NewSchema(indexCols...))
return
}
setHandle := len(indexCols) > len(is.Index.Columns)
if !setHandle {
Expand All @@ -1086,13 +1084,24 @@ func (is *PhysicalIndexScan) initSchema(idxExprCols []*expression.Column, isDoub
}
}
}
// If it's double read case, the first index must return handle. So we should add extra handle column
// if there isn't a handle column.
if isDoubleRead && !setHandle {
if !is.Table.IsCommonHandle {

if isDoubleRead {
// If it's double read case, the first index must return handle. So we should add extra handle column
// if there isn't a handle column.
if !setHandle {
if !is.Table.IsCommonHandle {
indexCols = append(indexCols, &expression.Column{
RetType: types.NewFieldType(mysql.TypeLonglong),
ID: model.ExtraHandleID,
UniqueID: is.ctx.GetSessionVars().AllocPlanColumnID(),
})
}
}
// If index is global, we should add extra column for pid.
if is.Index.Global {
indexCols = append(indexCols, &expression.Column{
RetType: types.NewFieldType(mysql.TypeLonglong),
ID: model.ExtraHandleID,
ID: model.ExtraPidColID,
UniqueID: is.ctx.GetSessionVars().AllocPlanColumnID(),
})
}
Expand Down
2 changes: 2 additions & 0 deletions planner/core/plan_to_pb.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,8 @@ func (p *PhysicalIndexScan) ToPB(ctx sessionctx.Context, _ kv.StoreType) (*tipb.
for _, col := range p.schema.Columns {
if col.ID == model.ExtraHandleID {
columns = append(columns, model.NewExtraHandleColInfo())
} else if col.ID == model.ExtraPidColID {
columns = append(columns, model.NewExtraPartitionIDColInfo())
} else {
columns = append(columns, findColumnInfoByID(tableColumns, col.ID))
}
Expand Down
5 changes: 4 additions & 1 deletion store/mockstore/unistore/cophandler/closure_exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,11 @@ func (e *closureExecutor) initIdxScanCtx(idxScan *tipb.IndexScan) {
e.idxScanCtx.pkStatus = pkColNotExists

e.idxScanCtx.primaryColumnIds = idxScan.PrimaryColumnIds

lastColumn := e.columnInfos[len(e.columnInfos)-1]
if lastColumn.GetColumnId() == model.ExtraPidColID {
lastColumn = e.columnInfos[len(e.columnInfos)-2]
e.idxScanCtx.columnLen--
}

if len(e.idxScanCtx.primaryColumnIds) == 0 {
if lastColumn.GetPkHandle() {
Expand Down

0 comments on commit 0b7c716

Please sign in to comment.