diff --git a/plan/cbo_test.go b/plan/cbo_test.go index f737d74eaf..292df1a8a0 100644 --- a/plan/cbo_test.go +++ b/plan/cbo_test.go @@ -92,6 +92,11 @@ func (s *testAnalyzeSuite) TestIndexRead(c *C) { sql: "select * from t where t.b <= 50", best: "TableReader(Table(t)->Sel([le(test.t.b, 50)]))", }, + // test panic + { + sql: "select * from t where 1 and t.b <= 50", + best: "TableReader(Table(t)->Sel([le(test.t.b, 50)]))", + }, { sql: "select * from t where t.b <= 100 order by t.a limit 1", best: "TableReader(Table(t)->Sel([le(test.t.b, 100)])->Limit)->Limit", diff --git a/statistics/selectivity.go b/statistics/selectivity.go index abd0f1eafc..a653a4c1dd 100644 --- a/statistics/selectivity.go +++ b/statistics/selectivity.go @@ -21,7 +21,6 @@ import ( "github.com/pingcap/tidb/context" "github.com/pingcap/tidb/expression" "github.com/pingcap/tidb/mysql" - "github.com/pingcap/tidb/sessionctx/variable" "github.com/pingcap/tidb/util/ranger" "github.com/pingcap/tidb/util/types" ) @@ -101,7 +100,7 @@ func (t *Table) Selectivity(ctx context.Context, exprs []expression.Expression) col := expression.ColInfo2Col(extractedCols, colInfo.Info) // This column should have histogram. if col != nil && len(colInfo.Histogram.Buckets) > 0 { - maskCovered, ranges, err := getMaskAndRanges(sc, exprs, ranger.ColumnRangeType, nil, col) + maskCovered, ranges, err := getMaskAndRanges(ctx, exprs, ranger.ColumnRangeType, nil, col) if err != nil { return 0, errors.Trace(err) } @@ -115,7 +114,7 @@ func (t *Table) Selectivity(ctx context.Context, exprs []expression.Expression) idxCols, lengths := expression.IndexInfo2Cols(extractedCols, idxInfo.Info) // This index should have histogram. if len(idxCols) > 0 && len(idxInfo.Histogram.Buckets) > 0 { - maskCovered, ranges, err := getMaskAndRanges(sc, exprs, ranger.IndexRangeType, lengths, idxCols...) + maskCovered, ranges, err := getMaskAndRanges(ctx, exprs, ranger.IndexRangeType, lengths, idxCols...) if err != nil { return 0, errors.Trace(err) } @@ -152,20 +151,20 @@ func (t *Table) Selectivity(ctx context.Context, exprs []expression.Expression) return ret, nil } -func getMaskAndRanges(sc *variable.StatementContext, exprs []expression.Expression, rangeType int, +func getMaskAndRanges(ctx context.Context, exprs []expression.Expression, rangeType int, lengths []int, cols ...*expression.Column) (int64, []types.Range, error) { exprsClone := make([]expression.Expression, 0, len(exprs)) for _, expr := range exprs { exprsClone = append(exprsClone, expr.Clone()) } - ranges, accessConds, _, err := ranger.BuildRange(sc, exprsClone, rangeType, cols, lengths) + ranges, accessConds, _, err := ranger.BuildRange(ctx.GetSessionVars().StmtCtx, exprsClone, rangeType, cols, lengths) if err != nil { return 0, nil, errors.Trace(err) } mask := int64(0) for i := range exprs { for j := range accessConds { - if exprs[i].Equal(accessConds[j], nil) { + if exprs[i].Equal(accessConds[j], ctx) { mask |= 1 << uint64(i) break }