Skip to content

Commit

Permalink
planner: make (*AccessPath).OnlyPointRange more succinct (#30520)
Browse files Browse the repository at this point in the history
  • Loading branch information
xuyifangreeneyes authored Dec 13, 2021
1 parent 9a64217 commit b8dcc09
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 36 deletions.
26 changes: 6 additions & 20 deletions planner/util/path.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,35 +151,21 @@ func isColEqCorColOrConstant(ctx sessionctx.Context, filter expression.Expressio

// OnlyPointRange checks whether each range is a point(no interval range exists).
func (path *AccessPath) OnlyPointRange(sctx sessionctx.Context) bool {
noIntervalRange := true
if path.IsIntHandlePath {
for _, ran := range path.Ranges {
if !ran.IsPoint(sctx) {
noIntervalRange = false
break
if !ran.IsPointNullable(sctx.GetSessionVars().StmtCtx) {
return false
}
}
return noIntervalRange
return true
}
haveNullVal := false
for _, ran := range path.Ranges {
// Not point or the not full matched.
if !ran.IsPoint(sctx) || len(ran.HighVal) != len(path.Index.Columns) {
noIntervalRange = false
break
}
// Check whether there's null value.
for i := 0; i < len(path.Index.Columns); i++ {
if ran.HighVal[i].IsNull() {
haveNullVal = true
break
}
}
if haveNullVal {
break
if !ran.IsPointNonNullable(sctx) || len(ran.HighVal) != len(path.Index.Columns) {
return false
}
}
return noIntervalRange && !haveNullVal
return true
}

// Col2Len maps expression.Column.UniqueID to column length
Expand Down
74 changes: 58 additions & 16 deletions planner/util/path_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,61 +12,103 @@
// See the License for the specific language governing permissions and
// limitations under the License.

package util
package util_test

import (
"testing"

"github.com/pingcap/tidb/parser/model"
"github.com/pingcap/tidb/planner/core"
"github.com/pingcap/tidb/planner/util"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/util/ranger"
"github.com/stretchr/testify/require"
)

func TestCompareCol2Len(t *testing.T) {
tests := []struct {
c1 Col2Len
c2 Col2Len
c1 util.Col2Len
c2 util.Col2Len
res int
comparable bool
}{
{
c1: Col2Len{1: -1, 2: -1, 3: -1},
c2: Col2Len{1: -1, 2: 10},
c1: util.Col2Len{1: -1, 2: -1, 3: -1},
c2: util.Col2Len{1: -1, 2: 10},
res: 1,
comparable: true,
},
{
c1: Col2Len{1: 5},
c2: Col2Len{1: 10, 2: -1},
c1: util.Col2Len{1: 5},
c2: util.Col2Len{1: 10, 2: -1},
res: -1,
comparable: true,
},
{
c1: Col2Len{1: -1, 2: -1},
c2: Col2Len{1: -1, 2: 5, 3: -1},
c1: util.Col2Len{1: -1, 2: -1},
c2: util.Col2Len{1: -1, 2: 5, 3: -1},
res: 0,
comparable: false,
},
{
c1: Col2Len{1: -1, 2: 10},
c2: Col2Len{1: -1, 2: 5, 3: -1},
c1: util.Col2Len{1: -1, 2: 10},
c2: util.Col2Len{1: -1, 2: 5, 3: -1},
res: 0,
comparable: false,
},
{
c1: Col2Len{1: -1, 2: 10},
c2: Col2Len{1: -1, 2: 10},
c1: util.Col2Len{1: -1, 2: 10},
c2: util.Col2Len{1: -1, 2: 10},
res: 0,
comparable: true,
},
{
c1: Col2Len{1: -1, 2: -1},
c2: Col2Len{1: -1, 2: 10},
c1: util.Col2Len{1: -1, 2: -1},
c2: util.Col2Len{1: -1, 2: 10},
res: 0,
comparable: false,
},
}
for _, tt := range tests {
res, comparable := CompareCol2Len(tt.c1, tt.c2)
res, comparable := util.CompareCol2Len(tt.c1, tt.c2)
require.Equal(t, tt.res, res)
require.Equal(t, tt.comparable, comparable)
}
}

func TestOnlyPointRange(t *testing.T) {
t.Parallel()
sctx := core.MockContext()
nullDatum := types.MinNotNullDatum()
nullDatum.SetNull()
nullPointRange := ranger.Range{
LowVal: []types.Datum{*nullDatum.Clone()},
HighVal: []types.Datum{*nullDatum.Clone()},
}
onePointRange := ranger.Range{
LowVal: []types.Datum{types.NewIntDatum(1)},
HighVal: []types.Datum{types.NewIntDatum(1)},
}
one2TwoRange := ranger.Range{
LowVal: []types.Datum{types.NewIntDatum(1)},
HighVal: []types.Datum{types.NewIntDatum(2)},
}

intHandlePath := &util.AccessPath{IsIntHandlePath: true}
intHandlePath.Ranges = []*ranger.Range{&nullPointRange, &onePointRange}
require.True(t, intHandlePath.OnlyPointRange(sctx))
intHandlePath.Ranges = []*ranger.Range{&onePointRange, &one2TwoRange}
require.False(t, intHandlePath.OnlyPointRange(sctx))

indexPath := &util.AccessPath{Index: &model.IndexInfo{Columns: make([]*model.IndexColumn, 1)}}
indexPath.Ranges = []*ranger.Range{&onePointRange}
require.True(t, indexPath.OnlyPointRange(sctx))
indexPath.Ranges = []*ranger.Range{&nullPointRange, &onePointRange}
require.False(t, indexPath.OnlyPointRange(sctx))
indexPath.Ranges = []*ranger.Range{&onePointRange, &one2TwoRange}
require.False(t, indexPath.OnlyPointRange(sctx))

indexPath.Index.Columns = make([]*model.IndexColumn, 2)
indexPath.Ranges = []*ranger.Range{&onePointRange}
require.False(t, indexPath.OnlyPointRange(sctx))
}

0 comments on commit b8dcc09

Please sign in to comment.