From cfae08adfda37e2106bff07ffc9a4a6fa84cfa8b Mon Sep 17 00:00:00 2001 From: Ruihao Chen Date: Sat, 12 Oct 2024 14:26:25 +0800 Subject: [PATCH 1/4] Fix flen --- pkg/executor/test/issuetest/executor_issue_test.go | 2 ++ pkg/expression/builtin_string.go | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/executor/test/issuetest/executor_issue_test.go b/pkg/executor/test/issuetest/executor_issue_test.go index ea5619bc8d11b..50ce362983176 100644 --- a/pkg/executor/test/issuetest/executor_issue_test.go +++ b/pkg/executor/test/issuetest/executor_issue_test.go @@ -90,6 +90,8 @@ func TestUnionIssue(t *testing.T) { tk.MustExec("drop table if exists t1, t2") tk.MustExec("create table t1 (id int);") tk.MustExec("create table t2 (id int, c int);") + // Issue56587 + tk.MustQuery("select quote(cast('abc' as char)) union all select '1'").Check(testkit.Rows("'abc'", "1")) testCases := []struct { sql string diff --git a/pkg/expression/builtin_string.go b/pkg/expression/builtin_string.go index a6f449e2dc853..5c8ee673534f8 100644 --- a/pkg/expression/builtin_string.go +++ b/pkg/expression/builtin_string.go @@ -2896,7 +2896,12 @@ func (c *quoteFunctionClass) getFunction(ctx BuildContext, args []Expression) (b return nil, err } SetBinFlagOrBinStr(args[0].GetType(ctx.GetEvalCtx()), bf.tp) - bf.tp.SetFlen(2*args[0].GetType(ctx.GetEvalCtx()).GetFlen() + 2) + flen := args[0].GetType(ctx.GetEvalCtx()).GetFlen() + newFlen := 2*flen + 2 + if flen == types.UnspecifiedLength { + newFlen = types.UnspecifiedLength + } + bf.tp.SetFlen(newFlen) if bf.tp.GetFlen() > mysql.MaxBlobWidth { bf.tp.SetFlen(mysql.MaxBlobWidth) } From 37e7e44f798168d9957565932d84fec20bdceb7b Mon Sep 17 00:00:00 2001 From: Ruihao Chen Date: Sat, 12 Oct 2024 15:18:25 +0800 Subject: [PATCH 2/4] Update elt --- pkg/executor/test/issuetest/executor_issue_test.go | 1 + pkg/expression/builtin_string.go | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pkg/executor/test/issuetest/executor_issue_test.go b/pkg/executor/test/issuetest/executor_issue_test.go index 50ce362983176..ae8a049c24e97 100644 --- a/pkg/executor/test/issuetest/executor_issue_test.go +++ b/pkg/executor/test/issuetest/executor_issue_test.go @@ -92,6 +92,7 @@ func TestUnionIssue(t *testing.T) { tk.MustExec("create table t2 (id int, c int);") // Issue56587 tk.MustQuery("select quote(cast('abc' as char)) union all select '1'").Check(testkit.Rows("'abc'", "1")) + tk.MustQuery(`select elt(2, "1", cast('abc' as char)) union all select "12" where false`).Check(testkit.Rows("abc")) testCases := []struct { sql string diff --git a/pkg/expression/builtin_string.go b/pkg/expression/builtin_string.go index 5c8ee673534f8..82cfc5bb6541e 100644 --- a/pkg/expression/builtin_string.go +++ b/pkg/expression/builtin_string.go @@ -3022,7 +3022,8 @@ func (c *eltFunctionClass) getFunction(ctx BuildContext, args []Expression) (bui if types.IsBinaryStr(argType) { types.SetBinChsClnFlag(bf.tp) } - if argType.GetFlen() > bf.tp.GetFlen() { + flen := argType.GetFlen() + if flen == types.UnspecifiedLength || flen > bf.tp.GetFlen() { bf.tp.SetFlen(argType.GetFlen()) } } From e7da03d135e96d889feb1e5851a7b5810dc6c616 Mon Sep 17 00:00:00 2001 From: Ruihao Chen Date: Sat, 12 Oct 2024 15:37:54 +0800 Subject: [PATCH 3/4] Update hex --- pkg/executor/test/issuetest/executor_issue_test.go | 1 + pkg/expression/builtin_string.go | 10 +++++++++- pkg/expression/typeinfer_test.go | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pkg/executor/test/issuetest/executor_issue_test.go b/pkg/executor/test/issuetest/executor_issue_test.go index ae8a049c24e97..3421fe34128d6 100644 --- a/pkg/executor/test/issuetest/executor_issue_test.go +++ b/pkg/executor/test/issuetest/executor_issue_test.go @@ -93,6 +93,7 @@ func TestUnionIssue(t *testing.T) { // Issue56587 tk.MustQuery("select quote(cast('abc' as char)) union all select '1'").Check(testkit.Rows("'abc'", "1")) tk.MustQuery(`select elt(2, "1", cast('abc' as char)) union all select "12" where false`).Check(testkit.Rows("abc")) + tk.MustQuery(`select hex(cast('1' as char)) union all select '1';`).Check(testkit.Rows("31", "1")) testCases := []struct { sql string diff --git a/pkg/expression/builtin_string.go b/pkg/expression/builtin_string.go index 82cfc5bb6541e..9ca70afd52177 100644 --- a/pkg/expression/builtin_string.go +++ b/pkg/expression/builtin_string.go @@ -1604,24 +1604,32 @@ func (c *hexFunctionClass) getFunction(ctx BuildContext, args []Expression) (bui } argTp := args[0].GetType(ctx.GetEvalCtx()).EvalType() + argLen := args[0].GetType(ctx.GetEvalCtx()).GetFlen() switch argTp { case types.ETString, types.ETDatetime, types.ETTimestamp, types.ETDuration, types.ETJson: bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) + bf.tp.SetFlen(types.UnspecifiedLength) if err != nil { return nil, err } argFieldTp := args[0].GetType(ctx.GetEvalCtx()) // Use UTF8MB4 as default. + if argLen != types.UnspecifiedLength { + bf.tp.SetFlen(argLen * 4 * 2) + } bf.tp.SetFlen(argFieldTp.GetFlen() * 4 * 2) sig := &builtinHexStrArgSig{bf} sig.setPbCode(tipb.ScalarFuncSig_HexStrArg) return sig, nil case types.ETInt, types.ETReal, types.ETDecimal: bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETInt) + bf.tp.SetFlen(types.UnspecifiedLength) if err != nil { return nil, err } - bf.tp.SetFlen(args[0].GetType(ctx.GetEvalCtx()).GetFlen() * 2) + if argLen != types.UnspecifiedLength { + bf.tp.SetFlen(argLen * 2) + } charset, collate := ctx.GetCharsetInfo() bf.tp.SetCharset(charset) bf.tp.SetCollate(collate) diff --git a/pkg/expression/typeinfer_test.go b/pkg/expression/typeinfer_test.go index 20b03f145bafa..6264056f8f2da 100644 --- a/pkg/expression/typeinfer_test.go +++ b/pkg/expression/typeinfer_test.go @@ -483,8 +483,8 @@ func (s *InferTypeSuite) createTestCase4StrFuncs() []typeInferTestCase { {"quote(c_int_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 42, types.UnspecifiedLength}, {"quote(c_bigint_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 42, types.UnspecifiedLength}, - {"quote(c_float_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 0, types.UnspecifiedLength}, - {"quote(c_double_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 0, types.UnspecifiedLength}, + {"quote(c_float_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, types.UnspecifiedLength, types.UnspecifiedLength}, + {"quote(c_double_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, types.UnspecifiedLength, types.UnspecifiedLength}, {"convert(c_double_d using utf8mb4)", mysql.TypeLongBlob, charset.CharsetUTF8MB4, 0, mysql.MaxBlobWidth, types.UnspecifiedLength}, {"convert(c_binary using utf8mb4)", mysql.TypeLongBlob, charset.CharsetUTF8MB4, 0, mysql.MaxBlobWidth, types.UnspecifiedLength}, From 5837855ee51383ba71c2e6ad4ac84279bcc00d21 Mon Sep 17 00:00:00 2001 From: Ruihao Chen Date: Thu, 17 Oct 2024 17:02:36 +0800 Subject: [PATCH 4/4] Address comment --- pkg/expression/builtin_string.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pkg/expression/builtin_string.go b/pkg/expression/builtin_string.go index 9ca70afd52177..967e7b99c6867 100644 --- a/pkg/expression/builtin_string.go +++ b/pkg/expression/builtin_string.go @@ -1604,7 +1604,6 @@ func (c *hexFunctionClass) getFunction(ctx BuildContext, args []Expression) (bui } argTp := args[0].GetType(ctx.GetEvalCtx()).EvalType() - argLen := args[0].GetType(ctx.GetEvalCtx()).GetFlen() switch argTp { case types.ETString, types.ETDatetime, types.ETTimestamp, types.ETDuration, types.ETJson: bf, err := newBaseBuiltinFuncWithTp(ctx, c.funcName, args, types.ETString, types.ETString) @@ -1612,12 +1611,11 @@ func (c *hexFunctionClass) getFunction(ctx BuildContext, args []Expression) (bui if err != nil { return nil, err } - argFieldTp := args[0].GetType(ctx.GetEvalCtx()) + argLen := args[0].GetType(ctx.GetEvalCtx()).GetFlen() // Use UTF8MB4 as default. if argLen != types.UnspecifiedLength { bf.tp.SetFlen(argLen * 4 * 2) } - bf.tp.SetFlen(argFieldTp.GetFlen() * 4 * 2) sig := &builtinHexStrArgSig{bf} sig.setPbCode(tipb.ScalarFuncSig_HexStrArg) return sig, nil @@ -1627,6 +1625,7 @@ func (c *hexFunctionClass) getFunction(ctx BuildContext, args []Expression) (bui if err != nil { return nil, err } + argLen := args[0].GetType(ctx.GetEvalCtx()).GetFlen() if argLen != types.UnspecifiedLength { bf.tp.SetFlen(argLen * 2) }