From b6ca0ddf8a33bb08ab16d0158a886e67ac301eef Mon Sep 17 00:00:00 2001 From: Yiding Cui Date: Mon, 19 Jun 2017 15:09:37 +0800 Subject: [PATCH] ranger: make Builder unexport (#3496) --- plan/new_physical_plan_builder.go | 6 +-- plan/physical_plan_builder.go | 6 +-- plan/physical_plan_test.go | 5 +- util/ranger/range.go | 86 +++++++++++++++---------------- util/ranger/refiner.go | 34 +++++++----- 5 files changed, 71 insertions(+), 66 deletions(-) diff --git a/plan/new_physical_plan_builder.go b/plan/new_physical_plan_builder.go index 5307a70cce..53175364a7 100644 --- a/plan/new_physical_plan_builder.go +++ b/plan/new_physical_plan_builder.go @@ -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, diff --git a/plan/physical_plan_builder.go b/plan/physical_plan_builder.go index e44d75ad6e..861cbdb60b 100644 --- a/plan/physical_plan_builder.go +++ b/plan/physical_plan_builder.go @@ -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) diff --git a/plan/physical_plan_test.go b/plan/physical_plan_test.go index a6f68878bf..4b8da22530 100644 --- a/plan/physical_plan_test.go +++ b/plan/physical_plan_test.go @@ -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)) } diff --git a/util/ranger/range.go b/util/ranger/range.go index 9c6e0cb190..a131ec0f55 100644 --- a/util/ranger/range.go +++ b/util/ranger/range.go @@ -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 diff --git a/util/ranger/refiner.go b/util/ranger/refiner.go index 86d3d61b04..303b006a23 100644 --- a/util/ranger/refiner.go +++ b/util/ranger/refiner.go @@ -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 {