From 1460e245031bd22bce5f175063650b987f36f035 Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 24 Nov 2021 20:08:06 +0800 Subject: [PATCH 01/10] complete --- expression/builtin.go | 47 ++++++++++++++++-------------- expression/builtin_compare_test.go | 4 +++ expression/integration_test.go | 9 ++++++ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/expression/builtin.go b/expression/builtin.go index 316e3a2ecb462..a4cbf5edd183d 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -130,28 +130,6 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex return } - for i := range args { - switch argTps[i] { - case types.ETInt: - args[i] = WrapWithCastAsInt(ctx, args[i]) - case types.ETReal: - args[i] = WrapWithCastAsReal(ctx, args[i]) - case types.ETDecimal: - args[i] = WrapWithCastAsDecimal(ctx, args[i]) - case types.ETString: - args[i] = WrapWithCastAsString(ctx, args[i]) - args[i] = HandleBinaryLiteral(ctx, args[i], ec, funcName) - case types.ETDatetime: - args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeDatetime)) - case types.ETTimestamp: - args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeTimestamp)) - case types.ETDuration: - args[i] = WrapWithCastAsDuration(ctx, args[i]) - case types.ETJson: - args[i] = WrapWithCastAsJSON(ctx, args[i]) - } - } - var fieldType *types.FieldType switch retType { case types.ETInt: @@ -214,12 +192,37 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex Flag: mysql.BinaryFlag, } } + if mysql.HasBinaryFlag(fieldType.Flag) && fieldType.Tp != mysql.TypeJSON { fieldType.Charset, fieldType.Collate = charset.CharsetBin, charset.CollationBin } if _, ok := booleanFunctions[funcName]; ok { fieldType.Flag |= mysql.IsBooleanFlag } + + for i := range args { + switch argTps[i] { + case types.ETInt: + args[i] = WrapWithCastAsInt(ctx, args[i]) + case types.ETReal: + args[i] = WrapWithCastAsReal(ctx, args[i]) + case types.ETDecimal: + args[i] = WrapWithCastAsDecimal(ctx, args[i]) + case types.ETString: + args[i] = WrapWithCastAsString(ctx, args[i]) + args[i] = HandleBinaryLiteral(ctx, args[i], ec, funcName) + case types.ETDatetime: + args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeDatetime)) + case types.ETTimestamp: + args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeTimestamp)) + case types.ETDuration: + args[i] = WrapWithCastAsDuration(ctx, args[i]) + case types.ETJson: + args[i] = WrapWithCastAsJSON(ctx, args[i]) + } + fieldType.Flag |= args[i].GetType().Flag + } + bf = baseBuiltinFunc{ bufAllocator: newLocalColumnPool(), childrenVectorizedOnce: new(sync.Once), diff --git a/expression/builtin_compare_test.go b/expression/builtin_compare_test.go index c2e8ecc9fd64e..7e7fe1a4a44fa 100644 --- a/expression/builtin_compare_test.go +++ b/expression/builtin_compare_test.go @@ -294,6 +294,10 @@ func TestGreatestLeastFunc(t *testing.T) { []interface{}{1, 2, 3, 4}, int64(4), int64(1), false, false, }, + { + []interface{}{uint64(9223372036854775808), uint64(9223372036854775809)}, + uint64(9223372036854775809), uint64(9223372036854775808), false, false, + }, { []interface{}{"a", "b", "c"}, "c", "a", false, false, diff --git a/expression/integration_test.go b/expression/integration_test.go index eca90299fd12b..6a8c317755565 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -10644,3 +10644,12 @@ func (s *testIntegrationSuite) TestIssue29513(c *C) { tk.MustQuery("select '123' union select cast(a as char) from t;").Sort().Check(testkit.Rows("123", "45678")) tk.MustQuery("select '123' union select cast(a as char(2)) from t;").Sort().Check(testkit.Rows("123", "45")) } + +func (s *testIntegrationSuite) TestIssue30101(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 bigint unsigned, c2 bigint unsigned);") + tk.MustExec("insert into t1 values(9223372036854775808, 9223372036854775809);") + tk.MustQuery("select greatest(c1, c2) from t1;").Sort().Check(testkit.Rows("9223372036854775809")) +} From e2e605879aec3dfe179c656c51b4b52eada4d582 Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 24 Nov 2021 20:24:01 +0800 Subject: [PATCH 02/10] reduce the explosion radius --- expression/builtin.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/expression/builtin.go b/expression/builtin.go index a4cbf5edd183d..563effce0f9f5 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -220,7 +220,9 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex case types.ETJson: args[i] = WrapWithCastAsJSON(ctx, args[i]) } - fieldType.Flag |= args[i].GetType().Flag + if mysql.HasUnsignedFlag(args[i].GetType().Flag) { + fieldType.Flag |= mysql.UnsignedFlag + } } bf = baseBuiltinFunc{ From 193841015d6fc249c75052707327aa7ec98fe04c Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 24 Nov 2021 20:24:55 +0800 Subject: [PATCH 03/10] fix --- expression/builtin.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/builtin.go b/expression/builtin.go index 563effce0f9f5..32b0c48a1fc32 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -220,7 +220,7 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex case types.ETJson: args[i] = WrapWithCastAsJSON(ctx, args[i]) } - if mysql.HasUnsignedFlag(args[i].GetType().Flag) { + if !mysql.HasUnsignedFlag(fieldType.Flag) && mysql.HasUnsignedFlag(args[i].GetType().Flag) { fieldType.Flag |= mysql.UnsignedFlag } } From 6a0c27034d393568f213e7658728b5a849f43fac Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 24 Nov 2021 21:38:14 +0800 Subject: [PATCH 04/10] fix the compare logic --- expression/builtin.go | 2 +- expression/builtin_compare.go | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/expression/builtin.go b/expression/builtin.go index 32b0c48a1fc32..563effce0f9f5 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -220,7 +220,7 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex case types.ETJson: args[i] = WrapWithCastAsJSON(ctx, args[i]) } - if !mysql.HasUnsignedFlag(fieldType.Flag) && mysql.HasUnsignedFlag(args[i].GetType().Flag) { + if mysql.HasUnsignedFlag(args[i].GetType().Flag) { fieldType.Flag |= mysql.UnsignedFlag } } diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 1090ca0e14eea..3cbd2ef45f817 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -478,6 +478,13 @@ func (c *greatestFunctionClass) getFunction(ctx sessionctx.Context, args []Expre } switch tp { case types.ETInt: + //default signed, if one field is unsigned, return unsigned result + for _, arg := range args { + if mysql.HasUnsignedFlag(arg.GetType().Flag) { + bf.tp.Flag |= mysql.UnsignedFlag + break + } + } sig = &builtinGreatestIntSig{bf} sig.setPbCode(tipb.ScalarFuncSig_GreatestInt) case types.ETReal: @@ -745,6 +752,14 @@ func (c *leastFunctionClass) getFunction(ctx sessionctx.Context, args []Expressi } switch tp { case types.ETInt: + // default unsigned, if one field is signed, return signed result + bf.tp.Flag |= mysql.UnsignedFlag + for _, arg := range args { + if !mysql.HasUnsignedFlag(arg.GetType().Flag) { + bf.tp.Flag &= ^mysql.UnsignedFlag + break + } + } sig = &builtinLeastIntSig{bf} sig.setPbCode(tipb.ScalarFuncSig_LeastInt) case types.ETReal: From 6a6cd3f3bc568c16eb23ec2329ba8efe7c008f29 Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 24 Nov 2021 21:40:57 +0800 Subject: [PATCH 05/10] =?UTF-8?q?restore=20=20=20=20=20=20=20=20=20?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20expression/builtin.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- expression/builtin.go | 49 +++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/expression/builtin.go b/expression/builtin.go index 563effce0f9f5..316e3a2ecb462 100644 --- a/expression/builtin.go +++ b/expression/builtin.go @@ -130,6 +130,28 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex return } + for i := range args { + switch argTps[i] { + case types.ETInt: + args[i] = WrapWithCastAsInt(ctx, args[i]) + case types.ETReal: + args[i] = WrapWithCastAsReal(ctx, args[i]) + case types.ETDecimal: + args[i] = WrapWithCastAsDecimal(ctx, args[i]) + case types.ETString: + args[i] = WrapWithCastAsString(ctx, args[i]) + args[i] = HandleBinaryLiteral(ctx, args[i], ec, funcName) + case types.ETDatetime: + args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeDatetime)) + case types.ETTimestamp: + args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeTimestamp)) + case types.ETDuration: + args[i] = WrapWithCastAsDuration(ctx, args[i]) + case types.ETJson: + args[i] = WrapWithCastAsJSON(ctx, args[i]) + } + } + var fieldType *types.FieldType switch retType { case types.ETInt: @@ -192,39 +214,12 @@ func newBaseBuiltinFuncWithTp(ctx sessionctx.Context, funcName string, args []Ex Flag: mysql.BinaryFlag, } } - if mysql.HasBinaryFlag(fieldType.Flag) && fieldType.Tp != mysql.TypeJSON { fieldType.Charset, fieldType.Collate = charset.CharsetBin, charset.CollationBin } if _, ok := booleanFunctions[funcName]; ok { fieldType.Flag |= mysql.IsBooleanFlag } - - for i := range args { - switch argTps[i] { - case types.ETInt: - args[i] = WrapWithCastAsInt(ctx, args[i]) - case types.ETReal: - args[i] = WrapWithCastAsReal(ctx, args[i]) - case types.ETDecimal: - args[i] = WrapWithCastAsDecimal(ctx, args[i]) - case types.ETString: - args[i] = WrapWithCastAsString(ctx, args[i]) - args[i] = HandleBinaryLiteral(ctx, args[i], ec, funcName) - case types.ETDatetime: - args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeDatetime)) - case types.ETTimestamp: - args[i] = WrapWithCastAsTime(ctx, args[i], types.NewFieldType(mysql.TypeTimestamp)) - case types.ETDuration: - args[i] = WrapWithCastAsDuration(ctx, args[i]) - case types.ETJson: - args[i] = WrapWithCastAsJSON(ctx, args[i]) - } - if mysql.HasUnsignedFlag(args[i].GetType().Flag) { - fieldType.Flag |= mysql.UnsignedFlag - } - } - bf = baseBuiltinFunc{ bufAllocator: newLocalColumnPool(), childrenVectorizedOnce: new(sync.Once), From 928ccf0eae48631871da1c83e981b669414ab6c8 Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 24 Nov 2021 22:20:57 +0800 Subject: [PATCH 06/10] add edge case --- expression/builtin_compare_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/expression/builtin_compare_test.go b/expression/builtin_compare_test.go index 7e7fe1a4a44fa..c16f484c498dd 100644 --- a/expression/builtin_compare_test.go +++ b/expression/builtin_compare_test.go @@ -279,6 +279,8 @@ func TestGreatestLeastFunc(t *testing.T) { sc := ctx.GetSessionVars().StmtCtx originIgnoreTruncate := sc.IgnoreTruncate sc.IgnoreTruncate = true + decG := &types.MyDecimal{} + decL := &types.MyDecimal{} defer func() { sc.IgnoreTruncate = originIgnoreTruncate }() @@ -291,13 +293,17 @@ func TestGreatestLeastFunc(t *testing.T) { getErr bool }{ { - []interface{}{1, 2, 3, 4}, - int64(4), int64(1), false, false, + []interface{}{int64(-9223372036854775808), uint64(9223372036854775809)}, + decG.FromUint(9223372036854775809), decL.FromInt(-9223372036854775808), false, false, }, { []interface{}{uint64(9223372036854775808), uint64(9223372036854775809)}, uint64(9223372036854775809), uint64(9223372036854775808), false, false, }, + { + []interface{}{1, 2, 3, 4}, + int64(4), int64(1), false, false, + }, { []interface{}{"a", "b", "c"}, "c", "a", false, false, From 3876948e4428b7d9c4dce4facef934c9de252415 Mon Sep 17 00:00:00 2001 From: sylzd Date: Tue, 30 Nov 2021 16:55:58 +0800 Subject: [PATCH 07/10] extract to func --- expression/builtin_compare.go | 41 +++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 3cbd2ef45f817..03189922c4af1 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -15,6 +15,7 @@ package expression import ( + "github.com/pingcap/errors" "math" "strings" @@ -478,11 +479,11 @@ func (c *greatestFunctionClass) getFunction(ctx sessionctx.Context, args []Expre } switch tp { case types.ETInt: - //default signed, if one field is unsigned, return unsigned result - for _, arg := range args { - if mysql.HasUnsignedFlag(arg.GetType().Flag) { + if signed, err := isResIntSigned(c.funcName, args); err == nil { + if signed { + bf.tp.Flag &= ^mysql.UnsignedFlag + } else { bf.tp.Flag |= mysql.UnsignedFlag - break } } sig = &builtinGreatestIntSig{bf} @@ -752,12 +753,11 @@ func (c *leastFunctionClass) getFunction(ctx sessionctx.Context, args []Expressi } switch tp { case types.ETInt: - // default unsigned, if one field is signed, return signed result - bf.tp.Flag |= mysql.UnsignedFlag - for _, arg := range args { - if !mysql.HasUnsignedFlag(arg.GetType().Flag) { + if signed, err := isResIntSigned(c.funcName, args); err == nil { + if signed { bf.tp.Flag &= ^mysql.UnsignedFlag - break + } else { + bf.tp.Flag |= mysql.UnsignedFlag } } sig = &builtinLeastIntSig{bf} @@ -2892,3 +2892,26 @@ func CompareJSON(sctx sessionctx.Context, lhsArg, rhsArg Expression, lhsRow, rhs } return int64(json.CompareBinary(arg0, arg1)), false, nil } + +// isResIntSigned return true if result should be unsigned, false if result should be signed, error to keep original +func isResIntSigned(funcName string, args []Expression) (bool, error) { + switch funcName { + case ast.Greatest: + //if one field is unsigned return unsigned result, otherwise signed + for _, arg := range args { + if mysql.HasUnsignedFlag(arg.GetType().Flag) { + return false, nil + } + } + return true, nil + case ast.Least: + // if one field is signed return signed result, otherwise unsigned + for _, arg := range args { + if !mysql.HasUnsignedFlag(arg.GetType().Flag) { + return true, nil + } + } + return false, nil + } + return true, errors.New("can not check if signed, keep original") +} From 80edc81b4fa607ede67c9ab011a741d8b4c994dd Mon Sep 17 00:00:00 2001 From: sylzd Date: Tue, 30 Nov 2021 20:56:44 +0800 Subject: [PATCH 08/10] fix lint --- expression/builtin_compare.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 03189922c4af1..9fa40a1613770 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -15,10 +15,10 @@ package expression import ( - "github.com/pingcap/errors" "math" "strings" + "github.com/pingcap/errors" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/opcode" From e9856879fcd3d6e3899a59b58854403feb715867 Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 1 Dec 2021 16:23:28 +0800 Subject: [PATCH 09/10] add infer testcases & optimize the code of bool check --- expression/builtin_compare.go | 54 ++++++++++++++--------------------- expression/typeinfer_test.go | 7 +++++ 2 files changed, 29 insertions(+), 32 deletions(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index 9fa40a1613770..e0e06704ac2c0 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -18,7 +18,6 @@ import ( "math" "strings" - "github.com/pingcap/errors" "github.com/pingcap/tidb/parser/ast" "github.com/pingcap/tidb/parser/mysql" "github.com/pingcap/tidb/parser/opcode" @@ -479,13 +478,14 @@ func (c *greatestFunctionClass) getFunction(ctx sessionctx.Context, args []Expre } switch tp { case types.ETInt: - if signed, err := isResIntSigned(c.funcName, args); err == nil { - if signed { - bf.tp.Flag &= ^mysql.UnsignedFlag - } else { - bf.tp.Flag |= mysql.UnsignedFlag - } + // adjust unsigned flag + greastInitUnsignedFlag := false + if isEqualsInitUnsigned(greastInitUnsignedFlag, args) { + bf.tp.Flag &= ^mysql.UnsignedFlag + } else { + bf.tp.Flag |= mysql.UnsignedFlag } + sig = &builtinGreatestIntSig{bf} sig.setPbCode(tipb.ScalarFuncSig_GreatestInt) case types.ETReal: @@ -753,13 +753,14 @@ func (c *leastFunctionClass) getFunction(ctx sessionctx.Context, args []Expressi } switch tp { case types.ETInt: - if signed, err := isResIntSigned(c.funcName, args); err == nil { - if signed { - bf.tp.Flag &= ^mysql.UnsignedFlag - } else { - bf.tp.Flag |= mysql.UnsignedFlag - } + // adjust unsigned flag + leastInitUnsignedFlag := true + if isEqualsInitUnsigned(leastInitUnsignedFlag, args) { + bf.tp.Flag |= mysql.UnsignedFlag + } else { + bf.tp.Flag &= ^mysql.UnsignedFlag } + sig = &builtinLeastIntSig{bf} sig.setPbCode(tipb.ScalarFuncSig_LeastInt) case types.ETReal: @@ -2893,25 +2894,14 @@ func CompareJSON(sctx sessionctx.Context, lhsArg, rhsArg Expression, lhsRow, rhs return int64(json.CompareBinary(arg0, arg1)), false, nil } -// isResIntSigned return true if result should be unsigned, false if result should be signed, error to keep original -func isResIntSigned(funcName string, args []Expression) (bool, error) { - switch funcName { - case ast.Greatest: - //if one field is unsigned return unsigned result, otherwise signed - for _, arg := range args { - if mysql.HasUnsignedFlag(arg.GetType().Flag) { - return false, nil - } - } - return true, nil - case ast.Least: - // if one field is signed return signed result, otherwise unsigned - for _, arg := range args { - if !mysql.HasUnsignedFlag(arg.GetType().Flag) { - return true, nil - } +// isEqualsInitUnsigned can adjust unsigned flag for greatest/least function. +// For greatest, returns unsigned result if there is at least one argument is unsigned. +// For least, returns signed result if there is at least one argument is signed. +func isEqualsInitUnsigned(initUnsigned bool, args []Expression) bool { + for _, arg := range args { + if initUnsigned != mysql.HasUnsignedFlag(arg.GetType().Flag) { + return false } - return false, nil } - return true, errors.New("can not check if signed, keep original") + return true } diff --git a/expression/typeinfer_test.go b/expression/typeinfer_test.go index 8cba8c5ef6b8f..4bc0e7bec8634 100644 --- a/expression/typeinfer_test.go +++ b/expression/typeinfer_test.go @@ -1057,6 +1057,13 @@ func (s *InferTypeSuite) createTestCase4CompareFuncs() []typeInferTestCase { {"interval(c_int_d, c_int_d, c_int_d)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag, mysql.MaxIntWidth, 0}, {"interval(c_int_d, c_float_d, c_double_d)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag, mysql.MaxIntWidth, 0}, + + {"greatest(c_bigint_d, c_ubigint_d, c_int_d)", mysql.TypeNewDecimal, charset.CharsetBin, mysql.BinaryFlag, mysql.MaxIntWidth, 0}, + {"greatest(c_ubigint_d, c_ubigint_d, c_uint_d)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag | mysql.UnsignedFlag, mysql.MaxIntWidth, 0}, + {"greatest(c_uint_d, c_int_d)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag | mysql.UnsignedFlag, 11, 0}, + {"least(c_bigint_d, c_ubigint_d, c_int_d)", mysql.TypeNewDecimal, charset.CharsetBin, mysql.BinaryFlag, mysql.MaxIntWidth, 0}, + {"least(c_ubigint_d, c_ubigint_d, c_uint_d)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag | mysql.UnsignedFlag, mysql.MaxIntWidth, 0}, + {"least(c_uint_d, c_int_d)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag, 11, 0}, } } From d8b230209acc0d92722e6afd0f6868a5057ad89a Mon Sep 17 00:00:00 2001 From: sylzd Date: Wed, 1 Dec 2021 17:40:19 +0800 Subject: [PATCH 10/10] fix func name --- expression/builtin_compare.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/expression/builtin_compare.go b/expression/builtin_compare.go index e0e06704ac2c0..5f72eb058cd2d 100644 --- a/expression/builtin_compare.go +++ b/expression/builtin_compare.go @@ -480,7 +480,7 @@ func (c *greatestFunctionClass) getFunction(ctx sessionctx.Context, args []Expre case types.ETInt: // adjust unsigned flag greastInitUnsignedFlag := false - if isEqualsInitUnsigned(greastInitUnsignedFlag, args) { + if isEqualsInitUnsignedFlag(greastInitUnsignedFlag, args) { bf.tp.Flag &= ^mysql.UnsignedFlag } else { bf.tp.Flag |= mysql.UnsignedFlag @@ -755,7 +755,7 @@ func (c *leastFunctionClass) getFunction(ctx sessionctx.Context, args []Expressi case types.ETInt: // adjust unsigned flag leastInitUnsignedFlag := true - if isEqualsInitUnsigned(leastInitUnsignedFlag, args) { + if isEqualsInitUnsignedFlag(leastInitUnsignedFlag, args) { bf.tp.Flag |= mysql.UnsignedFlag } else { bf.tp.Flag &= ^mysql.UnsignedFlag @@ -2894,10 +2894,10 @@ func CompareJSON(sctx sessionctx.Context, lhsArg, rhsArg Expression, lhsRow, rhs return int64(json.CompareBinary(arg0, arg1)), false, nil } -// isEqualsInitUnsigned can adjust unsigned flag for greatest/least function. +// isEqualsInitUnsignedFlag can adjust unsigned flag for greatest/least function. // For greatest, returns unsigned result if there is at least one argument is unsigned. // For least, returns signed result if there is at least one argument is signed. -func isEqualsInitUnsigned(initUnsigned bool, args []Expression) bool { +func isEqualsInitUnsignedFlag(initUnsigned bool, args []Expression) bool { for _, arg := range args { if initUnsigned != mysql.HasUnsignedFlag(arg.GetType().Flag) { return false