Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executor: refineArgs() bug fix when compare int with very small decimal (#23694) #23706

Merged
merged 4 commits into from
Mar 31, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions expression/builtin_compare.go
Original file line number Diff line number Diff line change
Expand Up @@ -1348,8 +1348,13 @@ func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Express
// int non-constant [cmp] non-int constant
if arg0IsInt && !arg0IsCon && !arg1IsInt && arg1IsCon {
arg1, isExceptional = RefineComparedConstant(ctx, *arg0Type, arg1, c.op)
finalArg1 = arg1
if isExceptional && arg1.GetType().EvalType() == types.ETInt {
// Why check not null flag
// eg: int_col > const_val(which is less than min_int32)
// If int_col got null, compare result cannot be true
if !isExceptional || (isExceptional && mysql.HasNotNullFlag(arg0Type.Flag)) {
finalArg1 = arg1
}
if isExceptional && arg1.GetType().EvalType() == types.ETInt && mysql.HasNotNullFlag(arg0Type.Flag) {
// Judge it is inf or -inf
// For int:
// inf: 01111111 & 1 == 1
Expand All @@ -1367,8 +1372,10 @@ func (c *compareFunctionClass) refineArgs(ctx sessionctx.Context, args []Express
// non-int constant [cmp] int non-constant
if arg1IsInt && !arg1IsCon && !arg0IsInt && arg0IsCon {
arg0, isExceptional = RefineComparedConstant(ctx, *arg1Type, arg0, symmetricOp[c.op])
finalArg0 = arg0
if isExceptional && arg0.GetType().EvalType() == types.ETInt {
if !isExceptional || (isExceptional && mysql.HasNotNullFlag(arg1Type.Flag)) {
finalArg0 = arg0
}
if isExceptional && arg0.GetType().EvalType() == types.ETInt && mysql.HasNotNullFlag(arg1Type.Flag) {
if arg0.Value.GetInt64()&1 == 1 {
isNegativeInfinite = true
} else {
Expand Down
2 changes: 1 addition & 1 deletion expression/builtin_compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (
)

func (s *testEvaluatorSuite) TestCompareFunctionWithRefine(c *C) {
tblInfo := newTestTableBuilder("").add("a", mysql.TypeLong).build()
tblInfo := newTestTableBuilder("").add("a", mysql.TypeLong, mysql.NotNullFlag).build()
tests := []struct {
exprStr string
result string
Expand Down
7 changes: 5 additions & 2 deletions expression/expression_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func (s *testEvaluatorSuite) TestNewValuesFunc(c *C) {
}

func (s *testEvaluatorSuite) TestEvaluateExprWithNull(c *C) {
tblInfo := newTestTableBuilder("").add("col0", mysql.TypeLonglong).add("col1", mysql.TypeLonglong).build()
tblInfo := newTestTableBuilder("").add("col0", mysql.TypeLonglong, 0).add("col1", mysql.TypeLonglong, 0).build()
schema := tableInfoToSchemaForTest(tblInfo)
col0 := schema.Columns[0]
col1 := schema.Columns[1]
Expand Down Expand Up @@ -142,15 +142,17 @@ type testTableBuilder struct {
tableName string
columnNames []string
tps []byte
flags []uint
}

func newTestTableBuilder(tableName string) *testTableBuilder {
return &testTableBuilder{tableName: tableName}
}

func (builder *testTableBuilder) add(name string, tp byte) *testTableBuilder {
func (builder *testTableBuilder) add(name string, tp byte, flag uint) *testTableBuilder {
builder.columnNames = append(builder.columnNames, name)
builder.tps = append(builder.tps, tp)
builder.flags = append(builder.flags, flag)
return builder
}

Expand All @@ -165,6 +167,7 @@ func (builder *testTableBuilder) build() *model.TableInfo {
fieldType := types.NewFieldType(tp)
fieldType.Flen, fieldType.Decimal = mysql.GetDefaultFieldLengthAndDecimal(tp)
fieldType.Charset, fieldType.Collate = types.DefaultCharsetForType(tp)
fieldType.Flag = builder.flags[i]
ti.Columns = append(ti.Columns, &model.ColumnInfo{
ID: int64(i + 1),
Name: model.NewCIStr(colName),
Expand Down
18 changes: 18 additions & 0 deletions expression/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8928,3 +8928,21 @@ func (s *testIntegrationSerialSuite) TestCollationForBinaryLiteral(c *C) {
tk.MustQuery("select * from t where col1 not in (0x1B,0x20) order by col1").Check(testkit.Rows("\x1e \xec 6966939640596047133"))
tk.MustExec("drop table t")
}

func (s *testIntegrationSuite) TestIssue23623(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t1;")
tk.MustExec("create table t1(c1 int);")
tk.MustExec("insert into t1 values(-2147483648), (-2147483648), (null);")
tk.MustQuery("select count(*) from t1 where c1 > (select sum(c1) from t1);").Check(testkit.Rows("2"))
}

func (s *testIntegrationSuite) TestApproximatePercentile(c *C) {
tk := testkit.NewTestKit(c, s.store)
tk.MustExec("use test")
tk.MustExec("drop table if exists t")
tk.MustExec("create table t (a bit(10))")
tk.MustExec("insert into t values(b'1111')")
tk.MustQuery("select approx_percentile(a, 10) from t").Check(testkit.Rows("<nil>"))
}
2 changes: 1 addition & 1 deletion planner/core/cbo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ func (s *testAnalyzeSuite) TestPreparedNullParam(c *C) {
testKit := testkit.NewTestKit(c, store)
testKit.MustExec("use test")
testKit.MustExec("drop table if exists t")
testKit.MustExec("create table t (id int, KEY id (id))")
testKit.MustExec("create table t (id int not null, KEY id (id))")
testKit.MustExec("insert into t values (1), (2), (3)")

sql := "select * from t where id = ?"
Expand Down