Skip to content

Commit

Permalink
planner: refine range builder when meet `unsigned_int_col <cmp> -int_…
Browse files Browse the repository at this point in the history
…cnst` (#10471)
  • Loading branch information
b41sh authored and XuHuaiyu committed May 31, 2019
1 parent c76e5ed commit 86dd989
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
28 changes: 28 additions & 0 deletions util/ranger/points.go
Expand Up @@ -250,6 +250,11 @@ func (r *builder) buildFormBinOp(expr *expression.ScalarFunction) []point {
return nil
}

value, op, isValidRange := handleUnsignedIntCol(ft, value, op)
if !isValidRange {
return nil
}

switch op {
case ast.EQ:
startPoint := point{value: value, start: true}
Expand Down Expand Up @@ -339,6 +344,29 @@ func HandlePadCharToFullLength(sc *stmtctx.StatementContext, ft *types.FieldType
}
}

// handleUnsignedIntCol handles the case when unsigned column meets negative integer value.
// The three returned values are: fixed constant value, fixed operator, and a boolean
// which indicates whether the range is valid or not.
func handleUnsignedIntCol(ft *types.FieldType, val types.Datum, op string) (types.Datum, string, bool) {
isUnsigned := mysql.HasUnsignedFlag(ft.Flag)
isIntegerType := mysql.IsIntegerType(ft.Tp)
isNegativeInteger := (val.Kind() == types.KindInt64 && val.GetInt64() < 0)

if !isUnsigned || !isIntegerType || !isNegativeInteger {
return val, op, true
}

// If the operator is GT, GE or NE, the range should be [0, +inf].
// Otherwise the value is out of valid range.
if op == ast.GT || op == ast.GE || op == ast.NE {
op = ast.GE
val.SetUint64(0)
return val, op, true
}

return val, op, false
}

func (r *builder) buildFromIsTrue(expr *expression.ScalarFunction, isNot int) []point {
if isNot == 1 {
// NOT TRUE range is {[null null] [0, 0]}
Expand Down
40 changes: 40 additions & 0 deletions util/ranger/ranger_test.go
Expand Up @@ -660,6 +660,39 @@ func (s *testRangerSuite) TestIndexRangeForUnsignedInt(c *C) {
filterConds: "[]",
resultStr: `[(NULL,1) (2,9223372036854775810) (9223372036854775810,+inf]]`,
},
{
indexPos: 0,
exprStr: `a >= -2147483648`,
accessConds: "[ge(test.t.a, -2147483648)]",
filterConds: "[]",
resultStr: `[[0,+inf]]`,
},
{
indexPos: 0,
exprStr: `a > -2147483648`,
accessConds: "[gt(test.t.a, -2147483648)]",
filterConds: "[]",
resultStr: `[[0,+inf]]`,
},
{
indexPos: 0,
exprStr: `a != -2147483648`,
accessConds: "[ne(test.t.a, -2147483648)]",
filterConds: "[]",
resultStr: `[[0,+inf]]`,
},
{
exprStr: "a < -1 or a < 1",
accessConds: "[or(lt(test.t.a, -1), lt(test.t.a, 1))]",
filterConds: "[]",
resultStr: "[[-inf,1)]",
},
{
exprStr: "a < -1 and a < 1",
accessConds: "[lt(test.t.a, -1) lt(test.t.a, 1)]",
filterConds: "[]",
resultStr: "[]",
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -933,6 +966,13 @@ func (s *testRangerSuite) TestColumnRange(c *C) {
filterConds: "[]",
resultStr: "[(18446744073709500000,+inf]]",
},
{
colPos: 4,
exprStr: `e > -2147483648`,
accessConds: "[gt(test.t.e, -2147483648)]",
filterConds: "[]",
resultStr: "[[0,+inf]]",
},
}

for _, tt := range tests {
Expand Down

0 comments on commit 86dd989

Please sign in to comment.