diff --git a/expression/builtin_cast.go b/expression/builtin_cast.go index cca97863d8966..2e80e885e8ac5 100644 --- a/expression/builtin_cast.go +++ b/expression/builtin_cast.go @@ -2149,7 +2149,7 @@ func WrapWithCastAsInt(ctx sessionctx.Context, expr Expression) Expression { tp.SetFlen(expr.GetType().GetFlen()) tp.SetDecimal(0) types.SetBinChsClnFlag(tp) - tp.AddFlag(expr.GetType().GetFlag() & mysql.UnsignedFlag) + tp.AddFlag(expr.GetType().GetFlag() & (mysql.UnsignedFlag | mysql.NotNullFlag)) return BuildCastFunction(ctx, expr, tp) } @@ -2163,7 +2163,7 @@ func WrapWithCastAsReal(ctx sessionctx.Context, expr Expression) Expression { tp.SetFlen(mysql.MaxRealWidth) tp.SetDecimal(types.UnspecifiedLength) types.SetBinChsClnFlag(tp) - tp.AddFlag(expr.GetType().GetFlag() & mysql.UnsignedFlag) + tp.AddFlag(expr.GetType().GetFlag() & (mysql.UnsignedFlag | mysql.NotNullFlag)) return BuildCastFunction(ctx, expr, tp) } @@ -2204,7 +2204,7 @@ func WrapWithCastAsDecimal(ctx sessionctx.Context, expr Expression) Expression { tp.SetFlen(mysql.MaxDecimalWidth) } types.SetBinChsClnFlag(tp) - tp.AddFlag(expr.GetType().GetFlag() & mysql.UnsignedFlag) + tp.AddFlag(expr.GetType().GetFlag() & (mysql.UnsignedFlag | mysql.NotNullFlag)) castExpr := BuildCastFunction(ctx, expr, tp) // For const item, we can use find-grained precision and scale by the result. if castExpr.ConstItem(ctx.GetSessionVars().StmtCtx) { diff --git a/expression/expr_to_pb_test.go b/expression/expr_to_pb_test.go index 7b7dce0771248..e43f86b6785a9 100644 --- a/expression/expr_to_pb_test.go +++ b/expression/expr_to_pb_test.go @@ -281,8 +281,8 @@ func TestLikeFunc2Pb(t *testing.T) { pbExprs, err := ExpressionsToPBList(sc, likeFuncs, client) require.NoError(t, err) results := []string{ - `{"tp":10000,"children":[{"tp":5,"val":"c3RyaW5n","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":5,"val":"cGF0dGVybg==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":10000,"val":"CAA=","children":[{"tp":5,"val":"XA==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false}],"sig":30,"field_type":{"tp":8,"flag":128,"flen":-1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}],"sig":4310,"field_type":{"tp":8,"flag":524416,"flen":1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}`, - `{"tp":10000,"children":[{"tp":5,"val":"c3RyaW5n","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":5,"val":"JWFiYyU=","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":10000,"val":"CAA=","children":[{"tp":5,"val":"XA==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false}],"sig":30,"field_type":{"tp":8,"flag":128,"flen":-1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}],"sig":4310,"field_type":{"tp":8,"flag":524416,"flen":1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}`, + `{"tp":10000,"children":[{"tp":5,"val":"c3RyaW5n","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":5,"val":"cGF0dGVybg==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":10000,"val":"CAA=","children":[{"tp":5,"val":"XA==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false}],"sig":30,"field_type":{"tp":8,"flag":129,"flen":-1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}],"sig":4310,"field_type":{"tp":8,"flag":524416,"flen":1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}`, + `{"tp":10000,"children":[{"tp":5,"val":"c3RyaW5n","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":5,"val":"JWFiYyU=","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false},{"tp":10000,"val":"CAA=","children":[{"tp":5,"val":"XA==","sig":0,"field_type":{"tp":254,"flag":1,"flen":-1,"decimal":-1,"collate":-83,"charset":"utf8"},"has_distinct":false}],"sig":30,"field_type":{"tp":8,"flag":129,"flen":-1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}],"sig":4310,"field_type":{"tp":8,"flag":524416,"flen":1,"decimal":0,"collate":-83,"charset":"binary"},"has_distinct":false}`, } for i, pbExpr := range pbExprs { js, err := json.Marshal(pbExpr) diff --git a/expression/typeinfer_test.go b/expression/typeinfer_test.go index d72f7f77547d6..22649133a6edf 100644 --- a/expression/typeinfer_test.go +++ b/expression/typeinfer_test.go @@ -76,7 +76,8 @@ func TestInferType(t *testing.T) { c_set set('a', 'b', 'c'), c_enum enum('a', 'b', 'c'), c_json JSON, - c_year year + c_year year, + c_int_not_null int not null )` testKit.MustExec(sql) testKit.MustExec(`set tidb_enable_noop_functions=1;`) @@ -215,6 +216,9 @@ func (s *InferTypeSuite) createTestCase4Cast() []typeInferTestCase { {"CAST(c_int_d AS TIME)", mysql.TypeDuration, charset.CharsetBin, mysql.BinaryFlag, 10, 0}, {"CAST(c_int_d AS UNSIGNED)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag | mysql.UnsignedFlag, 22, 0}, // TODO: flen should be 11. {"CAST(c_int_d AS UNSIGNED INTEGER)", mysql.TypeLonglong, charset.CharsetBin, mysql.BinaryFlag | mysql.UnsignedFlag, 22, 0}, // TODO: flen should be 11. + // We need to test WrapCast*, however this function is only called when function argument needs to be converted. + {"c_int_not_null + 1.1", mysql.TypeNewDecimal, charset.CharsetBin, mysql.BinaryFlag | mysql.NotNullFlag, 12, 1}, + {"c_int_not_null + 1.1E0", mysql.TypeDouble, charset.CharsetBin, mysql.BinaryFlag | mysql.NotNullFlag, -1, -1}, } }