diff --git a/expression/builtin_cast.go b/expression/builtin_cast.go index a8a5323583c22..899035d5e74b2 100644 --- a/expression/builtin_cast.go +++ b/expression/builtin_cast.go @@ -290,6 +290,9 @@ func (c *castAsStringFunctionClass) getFunction(ctx sessionctx.Context, args []E argTp := args[0].GetType().EvalType() switch argTp { case types.ETInt: + if bf.tp.Flen == types.UnspecifiedLength { + bf.tp.Flen = args[0].GetType().Flen + } sig = &builtinCastIntAsStringSig{bf} sig.setPbCode(tipb.ScalarFuncSig_CastIntAsString) case types.ETReal: diff --git a/expression/integration_test.go b/expression/integration_test.go index e26e8d850ec17..39f09359b68a5 100644 --- a/expression/integration_test.go +++ b/expression/integration_test.go @@ -10267,6 +10267,19 @@ func (s *testIntegrationSuite) TestIssue29417(c *C) { tk.MustQuery("select concat(f1) from t1;").Check(testkit.Rows("-0.12345")) } +func (s *testIntegrationSuite) TestIssue29513(c *C) { + tk := testkit.NewTestKit(c, s.store) + tk.MustExec("use test") + tk.MustQuery("select '123' union select cast(45678 as char);").Sort().Check(testkit.Rows("123", "45678")) + tk.MustQuery("select '123' union select cast(45678 as char(2));").Sort().Check(testkit.Rows("123", "45")) + + tk.MustExec("drop table if exists t") + tk.MustExec("create table t(a int);") + tk.MustExec("insert into t values(45678);") + 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) TestIssue28643(c *C) { tk := testkit.NewTestKit(c, s.store) tk.MustExec("use test") diff --git a/expression/typeinfer_test.go b/expression/typeinfer_test.go index 4293241a5ffbd..30ca35f6bdd20 100644 --- a/expression/typeinfer_test.go +++ b/expression/typeinfer_test.go @@ -180,9 +180,9 @@ func (s *testInferTypeSuite) createTestCase4Constants() []typeInferTestCase { func (s *testInferTypeSuite) createTestCase4Cast() []typeInferTestCase { return []typeInferTestCase{ - {"CAST(c_int_d AS BINARY)", mysql.TypeVarString, charset.CharsetBin, mysql.BinaryFlag, -1, -1}, // TODO: Flen should be 11. + {"CAST(c_int_d AS BINARY)", mysql.TypeVarString, charset.CharsetBin, mysql.BinaryFlag, 11, -1}, {"CAST(c_int_d AS BINARY(5))", mysql.TypeString, charset.CharsetBin, mysql.BinaryFlag, 5, -1}, - {"CAST(c_int_d AS CHAR)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, -1, -1}, // TODO: Flen should be 11. + {"CAST(c_int_d AS CHAR)", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 11, -1}, {"CAST(c_int_d AS CHAR(5))", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 5, -1}, {"CAST(c_int_d AS DATE)", mysql.TypeDate, charset.CharsetBin, mysql.BinaryFlag, 10, 0}, {"CAST(c_int_d AS DATETIME)", mysql.TypeDatetime, charset.CharsetBin, mysql.BinaryFlag, 19, 0}, @@ -405,8 +405,8 @@ func (s *testInferTypeSuite) createTestCase4StrFuncs() []typeInferTestCase { {"reverse(c_int_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 20, types.UnspecifiedLength}, {"reverse(c_bigint_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 20, types.UnspecifiedLength}, - {"reverse(c_float_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, -1, types.UnspecifiedLength}, - {"reverse(c_double_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, -1, types.UnspecifiedLength}, + {"reverse(c_float_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, types.UnspecifiedLength, types.UnspecifiedLength}, + {"reverse(c_double_d )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, types.UnspecifiedLength, types.UnspecifiedLength}, {"reverse(c_decimal )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 9, types.UnspecifiedLength}, {"reverse(c_char )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 20, types.UnspecifiedLength}, {"reverse(c_varchar )", mysql.TypeVarString, charset.CharsetUTF8MB4, 0, 20, types.UnspecifiedLength},