Skip to content

Commit

Permalink
expression: pass the arg's nullable type to target type for cast func…
Browse files Browse the repository at this point in the history
  • Loading branch information
yibin87 authored Jan 24, 2022
1 parent 18fc286 commit 9ad0fa3
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
5 changes: 5 additions & 0 deletions expression/builtin_cast.go
Original file line number Diff line number Diff line change
Expand Up @@ -1848,6 +1848,11 @@ func BuildCastCollationFunction(ctx sessionctx.Context, expr Expression, ec *Exp

// BuildCastFunction builds a CAST ScalarFunction from the Expression.
func BuildCastFunction(ctx sessionctx.Context, expr Expression, tp *types.FieldType) (res Expression) {
argType := expr.GetType()
// If source argument's nullable, then target type should be nullable
if !mysql.HasNotNullFlag(argType.Flag) {
tp.Flag &= ^mysql.NotNullFlag
}
expr = TryPushCastIntoControlFunctionForHybridType(ctx, expr, tp)
var fc functionClass
switch tp.EvalType() {
Expand Down
18 changes: 18 additions & 0 deletions planner/core/logical_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,24 @@ func (s *testPlanSuite) TestPredicatePushDown(c *C) {
}
}

// Issue: 31399
func (s *testPlanSuite) TestImplicitCastNotNullFlag(c *C) {
defer testleak.AfterTest(c)()
ctx := context.Background()
ca := "select count(*) from t3 group by a having bit_and(b) > 1;"
comment := Commentf("for %s", ca)
stmt, err := s.ParseOneStmt(ca, "", "")
c.Assert(err, IsNil, comment)
p, _, err := BuildLogicalPlanForTest(ctx, s.ctx, stmt, s.is)
c.Assert(err, IsNil)
p, err = logicalOptimize(context.TODO(), flagPredicatePushDown|flagJoinReOrder|flagPrunColumns|flagEliminateProjection, p.(LogicalPlan))
c.Assert(err, IsNil)
// AggFuncs[0] is count; AggFuncs[1] is bit_and, args[0] is return type of the implicit cast
castNotNullFlag := (p.(*LogicalProjection).children[0].(*LogicalSelection).children[0].(*LogicalAggregation).AggFuncs[1].Args[0].GetType().Flag) & mysql.NotNullFlag
var nullableFlag uint = 0
c.Assert(castNotNullFlag, Equals, nullableFlag)
}

func (s *testPlanSuite) TestEliminateProjectionUnderUnion(c *C) {
defer testleak.AfterTest(c)()
ctx := context.Background()
Expand Down

0 comments on commit 9ad0fa3

Please sign in to comment.