stats: fix a panic bug. (#4257)
This commit is contained in:
@ -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",
|
||||
|
||||
@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user