ranger: make Builder unexport (#3496)

This commit is contained in:
Yiding Cui
2017-06-19 15:09:37 +08:00
committed by GitHub
parent 1bdb72e4ec
commit b6ca0ddf8a
5 changed files with 71 additions and 66 deletions

View File

@ -592,8 +592,7 @@ func (p *DataSource) tryToGetMemTask(prop *requiredProp) (task task, err error)
TableAsName: p.TableAsName,
}.init(p.allocator, p.ctx)
memTable.SetSchema(p.schema)
rb := &ranger.Builder{Sc: p.ctx.GetSessionVars().StmtCtx}
memTable.Ranges = rb.BuildTableRanges(ranger.FullRange)
memTable.Ranges = ranger.FullIntRange()
var retPlan PhysicalPlan = memTable
if len(p.pushedDownConds) > 0 {
sel := Selection{
@ -700,8 +699,7 @@ func (p *DataSource) convertToIndexScan(prop *requiredProp, idx *model.IndexInfo
return nil, errors.Trace(err)
}
} else {
rb := ranger.Builder{Sc: sc}
is.Ranges = rb.BuildIndexRanges(ranger.FullRange, types.NewFieldType(mysql.TypeNull))
is.Ranges = ranger.FullIndexRange()
}
cop := &copTask{
cnt: rowCount,

View File

@ -162,8 +162,7 @@ func (p *DataSource) convert2IndexScan(prop *requiredProperty, index *model.Inde
resultPlan = newSel
}
} else {
rb := ranger.Builder{Sc: p.ctx.GetSessionVars().StmtCtx}
is.Ranges = rb.BuildIndexRanges(ranger.FullRange, types.NewFieldType(mysql.TypeNull))
is.Ranges = ranger.FullIndexRange()
}
is.DoubleRead = !isCoveringIndex(is.Columns, is.Index.Columns, is.Table.PKIsHandle)
return resultPlan.matchProperty(prop, &physicalPlanInfo{count: rowCount, reliable: !statsTbl.Pseudo}), nil
@ -223,8 +222,7 @@ func (p *DataSource) convert2PhysicalPlan(prop *requiredProperty) (*physicalPlan
TableAsName: p.TableAsName,
}.init(p.allocator, p.ctx)
memTable.SetSchema(p.schema)
rb := &ranger.Builder{Sc: p.ctx.GetSessionVars().StmtCtx}
memTable.Ranges = rb.BuildTableRanges(ranger.FullRange)
memTable.Ranges = ranger.FullIntRange()
info = &physicalPlanInfo{p: memTable}
info = enforceProperty(prop, info)
p.storePlanInfo(prop, info)

View File

@ -1051,9 +1051,8 @@ func (s *testPlanSuite) TestIssue3337(c *C) {
tb, _ := is.TableByID(0)
tbl := tb.Meta()
statsTbl := mockStatsTable(tbl, 0)
rb := ranger.Builder{Sc: new(variable.StatementContext)}
ran := rb.BuildIndexRanges(ranger.FullRange, types.NewFieldType(mysql.TypeLonglong))
rowCount, err := statsTbl.GetRowCountByIndexRanges(rb.Sc, 1, ran, 1)
ran := ranger.FullIndexRange()
rowCount, err := statsTbl.GetRowCountByIndexRanges(new(variable.StatementContext), 1, ran, 1)
c.Assert(err, IsNil)
c.Assert(rowCount, Equals, float64(0))
}

View File

@ -107,13 +107,13 @@ func (r *pointSorter) Swap(i, j int) {
r.points[i], r.points[j] = r.points[j], r.points[i]
}
// Builder is the range builder struct.
type Builder struct {
// builder is the range builder struct.
type builder struct {
err error
Sc *variable.StatementContext
sc *variable.StatementContext
}
func (r *Builder) build(expr expression.Expression) []point {
func (r *builder) build(expr expression.Expression) []point {
switch x := expr.(type) {
case *expression.Column:
return r.buildFromColumn(x)
@ -123,15 +123,15 @@ func (r *Builder) build(expr expression.Expression) []point {
return r.buildFromConstant(x)
}
return FullRange
return fullRange
}
func (r *Builder) buildFromConstant(expr *expression.Constant) []point {
func (r *builder) buildFromConstant(expr *expression.Constant) []point {
if expr.Value.IsNull() {
return nil
}
val, err := expr.Value.ToBool(r.Sc)
val, err := expr.Value.ToBool(r.sc)
if err != nil {
r.err = err
return nil
@ -140,10 +140,10 @@ func (r *Builder) buildFromConstant(expr *expression.Constant) []point {
if val == 0 {
return nil
}
return FullRange
return fullRange
}
func (r *Builder) buildFromColumn(expr *expression.Column) []point {
func (r *builder) buildFromColumn(expr *expression.Column) []point {
// column name expression is equivalent to column name is true.
startPoint1 := point{value: types.MinNotNullDatum(), start: true}
endPoint1 := point{excl: true}
@ -154,7 +154,7 @@ func (r *Builder) buildFromColumn(expr *expression.Column) []point {
return []point{startPoint1, endPoint1, startPoint2, endPoint2}
}
func (r *Builder) buildFormBinOp(expr *expression.ScalarFunction) []point {
func (r *builder) buildFormBinOp(expr *expression.ScalarFunction) []point {
// This has been checked that the binary operation is comparison operation, and one of
// the operand is column name expression.
var value types.Datum
@ -212,7 +212,7 @@ func (r *Builder) buildFormBinOp(expr *expression.ScalarFunction) []point {
return nil
}
func (r *Builder) buildFromIsTrue(expr *expression.ScalarFunction, isNot int) []point {
func (r *builder) buildFromIsTrue(expr *expression.ScalarFunction, isNot int) []point {
if isNot == 1 {
// NOT TRUE range is {[null null] [0, 0]}
startPoint1 := point{start: true}
@ -233,7 +233,7 @@ func (r *Builder) buildFromIsTrue(expr *expression.ScalarFunction, isNot int) []
return []point{startPoint1, endPoint1, startPoint2, endPoint2}
}
func (r *Builder) buildFromIsFalse(expr *expression.ScalarFunction, isNot int) []point {
func (r *builder) buildFromIsFalse(expr *expression.ScalarFunction, isNot int) []point {
if isNot == 1 {
// NOT FALSE range is {[-inf, 0), (0, +inf], [null, null]}
startPoint1 := point{start: true}
@ -252,20 +252,20 @@ func (r *Builder) buildFromIsFalse(expr *expression.ScalarFunction, isNot int) [
return []point{startPoint, endPoint}
}
func (r *Builder) newBuildFromIn(expr *expression.ScalarFunction) []point {
func (r *builder) newBuildFromIn(expr *expression.ScalarFunction) []point {
var rangePoints []point
list := expr.GetArgs()[1:]
for _, e := range list {
v, ok := e.(*expression.Constant)
if !ok {
r.err = ErrUnsupportedType.Gen("expr:%v is not constant", e)
return FullRange
return fullRange
}
startPoint := point{value: types.NewDatum(v.Value.GetValue()), start: true}
endPoint := point{value: types.NewDatum(v.Value.GetValue())}
rangePoints = append(rangePoints, startPoint, endPoint)
}
sorter := pointSorter{points: rangePoints, sc: r.Sc}
sorter := pointSorter{points: rangePoints, sc: r.sc}
sort.Sort(&sorter)
if sorter.err != nil {
r.err = sorter.err
@ -297,11 +297,11 @@ func (r *Builder) newBuildFromIn(expr *expression.ScalarFunction) []point {
return distinctRangePoints
}
func (r *Builder) newBuildFromPatternLike(expr *expression.ScalarFunction) []point {
func (r *builder) newBuildFromPatternLike(expr *expression.ScalarFunction) []point {
pattern, err := expr.GetArgs()[1].(*expression.Constant).Value.ToString()
if err != nil {
r.err = errors.Trace(err)
return FullRange
return fullRange
}
if pattern == "" {
startPoint := point{value: types.NewStringDatum(""), start: true}
@ -365,7 +365,7 @@ func (r *Builder) newBuildFromPatternLike(expr *expression.ScalarFunction) []poi
return []point{startPoint, endPoint}
}
func (r *Builder) buildFromNot(expr *expression.ScalarFunction) []point {
func (r *builder) buildFromNot(expr *expression.ScalarFunction) []point {
switch n := expr.FuncName.L; n {
case ast.IsTruth:
return r.buildFromIsTrue(expr, 1)
@ -374,11 +374,11 @@ func (r *Builder) buildFromNot(expr *expression.ScalarFunction) []point {
case ast.In:
// Pattern not in is not supported.
r.err = ErrUnsupportedType.Gen("NOT IN is not supported")
return FullRange
return fullRange
case ast.Like:
// Pattern not like is not supported.
r.err = ErrUnsupportedType.Gen("NOT LIKE is not supported.")
return FullRange
return fullRange
case ast.IsNull:
startPoint := point{value: types.MinNotNullDatum(), start: true}
endPoint := point{value: types.MaxValueDatum()}
@ -387,7 +387,7 @@ func (r *Builder) buildFromNot(expr *expression.ScalarFunction) []point {
return nil
}
func (r *Builder) buildFromScalarFunc(expr *expression.ScalarFunction) []point {
func (r *builder) buildFromScalarFunc(expr *expression.ScalarFunction) []point {
switch op := expr.FuncName.L; op {
case ast.GE, ast.GT, ast.LT, ast.LE, ast.EQ, ast.NE:
return r.buildFormBinOp(expr)
@ -414,16 +414,16 @@ func (r *Builder) buildFromScalarFunc(expr *expression.ScalarFunction) []point {
return nil
}
func (r *Builder) intersection(a, b []point) []point {
func (r *builder) intersection(a, b []point) []point {
return r.merge(a, b, false)
}
func (r *Builder) union(a, b []point) []point {
func (r *builder) union(a, b []point) []point {
return r.merge(a, b, true)
}
func (r *Builder) merge(a, b []point, union bool) []point {
sorter := pointSorter{points: append(a, b...), sc: r.Sc}
func (r *builder) merge(a, b []point, union bool) []point {
sorter := pointSorter{points: append(a, b...), sc: r.sc}
sort.Sort(&sorter)
if sorter.err != nil {
r.err = sorter.err
@ -457,15 +457,15 @@ func (r *Builder) merge(a, b []point, union bool) []point {
return merged
}
// BuildIndexRanges build index ranges from range points.
// buildIndexRanges build index ranges from range points.
// Only the first column in the index is built, extra column ranges will be appended by
// appendIndexRanges.
func (r *Builder) BuildIndexRanges(rangePoints []point, tp *types.FieldType) []*types.IndexRange {
func (r *builder) buildIndexRanges(rangePoints []point, tp *types.FieldType) []*types.IndexRange {
indexRanges := make([]*types.IndexRange, 0, len(rangePoints)/2)
for i := 0; i < len(rangePoints); i += 2 {
startPoint := r.convertPoint(rangePoints[i], tp)
endPoint := r.convertPoint(rangePoints[i+1], tp)
less, err := rangePointLess(r.Sc, startPoint, endPoint)
less, err := rangePointLess(r.sc, startPoint, endPoint)
if err != nil {
r.err = errors.Trace(err)
}
@ -483,16 +483,16 @@ func (r *Builder) BuildIndexRanges(rangePoints []point, tp *types.FieldType) []*
return indexRanges
}
func (r *Builder) convertPoint(point point, tp *types.FieldType) point {
func (r *builder) convertPoint(point point, tp *types.FieldType) point {
switch point.value.Kind() {
case types.KindMaxValue, types.KindMinNotNull:
return point
}
casted, err := point.value.ConvertTo(r.Sc, tp)
casted, err := point.value.ConvertTo(r.sc, tp)
if err != nil {
r.err = errors.Trace(err)
}
valCmpCasted, err := point.value.CompareDatum(r.Sc, casted)
valCmpCasted, err := point.value.CompareDatum(r.sc, casted)
if err != nil {
r.err = errors.Trace(err)
}
@ -532,11 +532,11 @@ func (r *Builder) convertPoint(point point, tp *types.FieldType) point {
// The additional column ranges can only be appended to point ranges.
// for example we have an index (a, b), if the condition is (a > 1 and b = 2)
// then we can not build a conjunctive ranges for this index.
func (r *Builder) appendIndexRanges(origin []*types.IndexRange, rangePoints []point, ft *types.FieldType) []*types.IndexRange {
func (r *builder) appendIndexRanges(origin []*types.IndexRange, rangePoints []point, ft *types.FieldType) []*types.IndexRange {
var newIndexRanges []*types.IndexRange
for i := 0; i < len(origin); i++ {
oRange := origin[i]
if !oRange.IsPoint(r.Sc) {
if !oRange.IsPoint(r.sc) {
newIndexRanges = append(newIndexRanges, oRange)
} else {
newIndexRanges = append(newIndexRanges, r.appendIndexRange(oRange, rangePoints, ft)...)
@ -545,12 +545,12 @@ func (r *Builder) appendIndexRanges(origin []*types.IndexRange, rangePoints []po
return newIndexRanges
}
func (r *Builder) appendIndexRange(origin *types.IndexRange, rangePoints []point, ft *types.FieldType) []*types.IndexRange {
func (r *builder) appendIndexRange(origin *types.IndexRange, rangePoints []point, ft *types.FieldType) []*types.IndexRange {
newRanges := make([]*types.IndexRange, 0, len(rangePoints)/2)
for i := 0; i < len(rangePoints); i += 2 {
startPoint := r.convertPoint(rangePoints[i], ft)
endPoint := r.convertPoint(rangePoints[i+1], ft)
less, err := rangePointLess(r.Sc, startPoint, endPoint)
less, err := rangePointLess(r.sc, startPoint, endPoint)
if err != nil {
r.err = errors.Trace(err)
}
@ -577,21 +577,21 @@ func (r *Builder) appendIndexRange(origin *types.IndexRange, rangePoints []point
return newRanges
}
// BuildTableRanges will construct the range slice with the given range points
func (r *Builder) BuildTableRanges(rangePoints []point) []types.IntColumnRange {
// buildTableRanges will construct the range slice with the given range points
func (r *builder) buildTableRanges(rangePoints []point) []types.IntColumnRange {
tableRanges := make([]types.IntColumnRange, 0, len(rangePoints)/2)
for i := 0; i < len(rangePoints); i += 2 {
startPoint := rangePoints[i]
if startPoint.value.IsNull() || startPoint.value.Kind() == types.KindMinNotNull {
startPoint.value.SetInt64(math.MinInt64)
}
startInt, err := startPoint.value.ToInt64(r.Sc)
startInt, err := startPoint.value.ToInt64(r.sc)
if err != nil {
r.err = errors.Trace(err)
return tableRanges
}
startDatum := types.NewDatum(startInt)
cmp, err := startDatum.CompareDatum(r.Sc, startPoint.value)
cmp, err := startDatum.CompareDatum(r.sc, startPoint.value)
if err != nil {
r.err = errors.Trace(err)
return tableRanges
@ -605,13 +605,13 @@ func (r *Builder) BuildTableRanges(rangePoints []point) []types.IntColumnRange {
} else if endPoint.value.Kind() == types.KindMaxValue {
endPoint.value.SetInt64(math.MaxInt64)
}
endInt, err := endPoint.value.ToInt64(r.Sc)
endInt, err := endPoint.value.ToInt64(r.sc)
if err != nil {
r.err = errors.Trace(err)
return tableRanges
}
endDatum := types.NewDatum(endInt)
cmp, err = endDatum.CompareDatum(r.Sc, endPoint.value)
cmp, err = endDatum.CompareDatum(r.sc, endPoint.value)
if err != nil {
r.err = errors.Trace(err)
return tableRanges
@ -627,12 +627,12 @@ func (r *Builder) BuildTableRanges(rangePoints []point) []types.IntColumnRange {
return tableRanges
}
func (r *Builder) buildColumnRanges(points []point, tp *types.FieldType) []*types.ColumnRange {
func (r *builder) buildColumnRanges(points []point, tp *types.FieldType) []*types.ColumnRange {
columnRanges := make([]*types.ColumnRange, 0, len(points)/2)
for i := 0; i < len(points); i += 2 {
startPoint := r.convertPoint(points[i], tp)
endPoint := r.convertPoint(points[i+1], tp)
less, err := rangePointLess(r.Sc, startPoint, endPoint)
less, err := rangePointLess(r.sc, startPoint, endPoint)
if err != nil {
r.err = errors.Trace(err)
return nil

View File

@ -25,16 +25,26 @@ import (
"github.com/pingcap/tidb/util/types"
)
// FullRange is (-∞, +∞).
var FullRange = []point{
// fullRange is (-∞, +∞).
var fullRange = []point{
{start: true},
{value: types.MaxValueDatum()},
}
// FullIntRange is (-∞, +∞) for IntColumnRange.
func FullIntRange() []types.IntColumnRange {
return []types.IntColumnRange{{LowVal: math.MinInt64, HighVal: math.MaxInt64}}
}
// FullIndexRange is (-∞, +∞) for IndexRange.
func FullIndexRange() []*types.IndexRange {
return []*types.IndexRange{{LowVal: []types.Datum{{}}, HighVal: []types.Datum{types.MaxValueDatum()}}}
}
// BuildIndexRange will build range of index for PhysicalIndexScan
func BuildIndexRange(sc *variable.StatementContext, tblInfo *model.TableInfo, index *model.IndexInfo,
accessInAndEqCount int, accessCondition []expression.Expression) ([]*types.IndexRange, error) {
rb := Builder{Sc: sc}
rb := builder{sc: sc}
var ranges []*types.IndexRange
for i := 0; i < accessInAndEqCount; i++ {
// Build ranges for equal or in access conditions.
@ -42,12 +52,12 @@ func BuildIndexRange(sc *variable.StatementContext, tblInfo *model.TableInfo, in
colOff := index.Columns[i].Offset
tp := &tblInfo.Columns[colOff].FieldType
if i == 0 {
ranges = rb.BuildIndexRanges(point, tp)
ranges = rb.buildIndexRanges(point, tp)
} else {
ranges = rb.appendIndexRanges(ranges, point, tp)
}
}
rangePoints := FullRange
rangePoints := fullRange
// Build rangePoints for non-equal access conditions.
for i := accessInAndEqCount; i < len(accessCondition); i++ {
rangePoints = rb.intersection(rangePoints, rb.build(accessCondition[i]))
@ -55,7 +65,7 @@ func BuildIndexRange(sc *variable.StatementContext, tblInfo *model.TableInfo, in
if accessInAndEqCount == 0 {
colOff := index.Columns[0].Offset
tp := &tblInfo.Columns[colOff].FieldType
ranges = rb.BuildIndexRanges(rangePoints, tp)
ranges = rb.buildIndexRanges(rangePoints, tp)
} else if accessInAndEqCount < len(accessCondition) {
colOff := index.Columns[accessInAndEqCount].Offset
tp := &tblInfo.Columns[colOff].FieldType
@ -282,18 +292,18 @@ func DetachColumnConditions(conditions []expression.Expression, colName model.CI
// BuildTableRange will build range of pk for PhysicalTableScan
func BuildTableRange(accessConditions []expression.Expression, sc *variable.StatementContext) ([]types.IntColumnRange, error) {
if len(accessConditions) == 0 {
return []types.IntColumnRange{{math.MinInt64, math.MaxInt64}}, nil
return FullIntRange(), nil
}
rb := Builder{Sc: sc}
rangePoints := FullRange
rb := builder{sc: sc}
rangePoints := fullRange
for _, cond := range accessConditions {
rangePoints = rb.intersection(rangePoints, rb.build(cond))
if rb.err != nil {
return nil, errors.Trace(rb.err)
}
}
ranges := rb.BuildTableRanges(rangePoints)
ranges := rb.buildTableRanges(rangePoints)
if rb.err != nil {
return nil, errors.Trace(rb.err)
}
@ -308,8 +318,8 @@ func BuildColumnRange(conds []expression.Expression, colName model.CIStr, sc *va
return []*types.ColumnRange{{Low: types.Datum{}, High: types.MaxValueDatum()}}, nil, conds, nil
}
rb := Builder{Sc: sc}
rangePoints := FullRange
rb := builder{sc: sc}
rangePoints := fullRange
for _, cond := range usedConds {
rangePoints = rb.intersection(rangePoints, rb.build(cond))
if rb.err != nil {