Skip to content

Commit

Permalink
expression: fix the issue that incorrect result for a predicate that …
Browse files Browse the repository at this point in the history
…uses the CHAR() function (#16014) (#16559)
  • Loading branch information
sre-bot committed Apr 30, 2020
1 parent db0310b commit 74b63e2
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 23 deletions.
15 changes: 0 additions & 15 deletions expression/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1796,21 +1796,6 @@ func (s *testVectorizeSuite2) TestVecEvalBool(c *C) {
}
}

func (s *testVectorizeSuite2) TestVecToBool(c *C) {
ctx := mock.NewContext()
buf := chunk.NewColumn(eType2FieldType(types.ETString), 2)
buf.ReserveString(1)
buf.AppendString("999999999999999999923")
c.Assert(toBool(ctx.GetSessionVars().StmtCtx, types.ETString, buf, []int{0, 1}, []int8{0, 0}), NotNil)
buf.ReserveString(1)
buf.AppendString("23")
c.Assert(toBool(ctx.GetSessionVars().StmtCtx, types.ETString, buf, []int{0, 1}, []int8{0, 0}), IsNil)
buf.ReserveString(2)
buf.AppendString("999999999999999999923")
buf.AppendString("23")
c.Assert(toBool(ctx.GetSessionVars().StmtCtx, types.ETString, buf, []int{0, 1}, []int8{0, 0}), NotNil)
}

func BenchmarkVecEvalBool(b *testing.B) {
ctx := mock.NewContext()
selected := make([]bool, 0, 1024)
Expand Down
7 changes: 2 additions & 5 deletions expression/expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,12 +427,9 @@ func toBool(sc *stmtctx.StatementContext, eType types.EvalType, buf *chunk.Colum
if buf.IsNull(i) {
isZero[i] = -1
} else {
iVal, err := types.StrToInt(sc, buf.GetString(i))
iVal, err := types.StrToFloat(sc, buf.GetString(i))
if err != nil {
iVal, err = HandleOverflowOnSelection(sc, iVal, err)
if err != nil {
return err
}
return err
}
if iVal == 0 {
isZero[i] = 0
Expand Down
31 changes: 31 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6143,6 +6143,37 @@ func (s *testIntegrationSerialSuite) TestCollateDDL(c *C) {
tk.MustExec("drop database t;")
}

func (s *testIntegrationSuite) TestIssue15986(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t0")
tk.MustExec("CREATE TABLE t0(c0 int)")
tk.MustExec("INSERT INTO t0 VALUES (0)")
tk.MustQuery("SELECT t0.c0 FROM t0 WHERE CHAR(204355900);").Check(testkit.Rows("0"))
tk.MustQuery("SELECT t0.c0 FROM t0 WHERE not CHAR(204355900);").Check(testkit.Rows())
tk.MustQuery("SELECT t0.c0 FROM t0 WHERE '.0';").Check(testkit.Rows())
tk.MustQuery("SELECT t0.c0 FROM t0 WHERE not '.0';").Check(testkit.Rows("0"))
// If the number does not exceed the range of float64 and its value is not 0, it will be converted to true.
tk.MustQuery("select * from t0 where '.000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000009';").Check(testkit.Rows("0"))
tk.MustQuery("select * from t0 where not '.000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"0000000000000000000000000000000000000000000000000000000000000000009';").Check(testkit.Rows())

// If the number is truncated beyond the range of float64, it will be converted to true when the truncated result is 0.
tk.MustQuery("select * from t0 where '.0000000000000000000000000000000000000000000000000000000" +
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000009';").Check(testkit.Rows())
tk.MustQuery("select * from t0 where not '.0000000000000000000000000000000000000000000000000000000" +
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" +
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000009';").Check(testkit.Rows("0"))
}

func (s *testIntegrationSuite) TestNegativeZeroForHashJoin(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test;")
Expand Down
2 changes: 1 addition & 1 deletion types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1438,7 +1438,7 @@ func (d *Datum) ToBool(sc *stmtctx.StatementContext) (int64, error) {
case KindFloat64:
isZero = RoundFloat(d.GetFloat64()) == 0
case KindString, KindBytes:
iVal, err1 := StrToInt(sc, d.GetString())
iVal, err1 := StrToFloat(sc, d.GetString())
isZero, err = iVal == 0, err1
case KindMysqlTime:
isZero = d.GetMysqlTime().IsZero()
Expand Down
4 changes: 2 additions & 2 deletions types/datum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ func (ts *testDatumSuite) TestToBool(c *C) {
testDatumToBool(c, float64(0.5), 1)
testDatumToBool(c, float64(0.499), 0)
testDatumToBool(c, "", 0)
testDatumToBool(c, "0.1", 0)
testDatumToBool(c, "0.1", 1)
testDatumToBool(c, []byte{}, 0)
testDatumToBool(c, []byte("0.1"), 0)
testDatumToBool(c, []byte("0.1"), 1)
testDatumToBool(c, NewBinaryLiteralFromUint(0, -1), 0)
testDatumToBool(c, Enum{Name: "a", Value: 1}, 1)
testDatumToBool(c, Set{Name: "a", Value: 1}, 1)
Expand Down

0 comments on commit 74b63e2

Please sign in to comment.