Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/planner/core/operator/logicalop/logical_aggregation.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,7 +447,7 @@ func (la *LogicalAggregation) ExtractFD() *fd.FDSet {
determinants.Insert(int(one.UniqueID))
groupByColsOutputCols.Insert(int(one.UniqueID))
}
notnull := util.IsNullRejected(la.SCtx(), la.Schema(), x, true)
notnull := util.IsNullRejected(la.SCtx(), la.Schema(), x)
if notnull || determinants.SubsetOf(fds.NotNullCols) {
notnullColsUniqueIDs.Insert(scalarUniqueID)
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/planner/core/operator/logicalop/logical_join.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ func simplifyOuterJoin(p *LogicalJoin, predicates []expression.Expression) {
if expression.ExprFromSchema(expr, outerTable.Schema()) {
continue
}
isOk := util.IsNullRejected(p.SCtx(), innerTable.Schema(), expr, true)
isOk := util.IsNullRejected(p.SCtx(), innerTable.Schema(), expr)
if isOk {
canBeSimplified = true
break
Expand Down Expand Up @@ -720,7 +720,7 @@ func (p *LogicalJoin) ConvertOuterToInnerJoin(predicates []expression.Expression
if p.JoinType == LeftOuterJoin || p.JoinType == RightOuterJoin {
canBeSimplified := false
for _, expr := range predicates {
isOk := util.IsNullRejected(p.SCtx(), innerTable.Schema(), expr, true)
isOk := util.IsNullRejected(p.SCtx(), innerTable.Schema(), expr)
if isOk {
canBeSimplified = true
break
Expand Down Expand Up @@ -1295,13 +1295,13 @@ func (p *LogicalJoin) ExtractOnCondition(
}
if leftCol != nil && rightCol != nil {
if deriveLeft {
if util.IsNullRejected(ctx, leftSchema, expr, true) && !mysql.HasNotNullFlag(leftCol.RetType.GetFlag()) {
if util.IsNullRejected(ctx, leftSchema, expr) && !mysql.HasNotNullFlag(leftCol.RetType.GetFlag()) {
notNullExpr := expression.BuildNotNullExpr(ctx.GetExprCtx(), leftCol)
leftCond = append(leftCond, notNullExpr)
}
}
if deriveRight {
if util.IsNullRejected(ctx, rightSchema, expr, true) && !mysql.HasNotNullFlag(rightCol.RetType.GetFlag()) {
if util.IsNullRejected(ctx, rightSchema, expr) && !mysql.HasNotNullFlag(rightCol.RetType.GetFlag()) {
notNullExpr := expression.BuildNotNullExpr(ctx.GetExprCtx(), rightCol)
rightCond = append(rightCond, notNullExpr)
}
Expand Down Expand Up @@ -1998,7 +1998,7 @@ func deriveNotNullExpr(ctx base.PlanContext, expr expression.Expression, schema
if childCol == nil {
childCol = schema.RetrieveColumn(arg1)
}
if util.IsNullRejected(ctx, schema, expr, true) && !mysql.HasNotNullFlag(childCol.RetType.GetFlag()) {
if util.IsNullRejected(ctx, schema, expr) && !mysql.HasNotNullFlag(childCol.RetType.GetFlag()) {
return expression.BuildNotNullExpr(ctx.GetExprCtx(), childCol)
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion pkg/planner/core/operator/logicalop/logical_projection.go
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,7 @@ func (p *LogicalProjection) ExtractFD() *fd.FDSet {
// the dependent columns in scalar function should be also considered as output columns as well.
outputColsUniqueIDs.Insert(int(one.UniqueID))
}
notnull := util.IsNullRejected(p.SCtx(), p.Schema(), x, true)
notnull := util.IsNullRejected(p.SCtx(), p.Schema(), x)
if notnull || determinants.SubsetOf(fds.NotNullCols) {
notnullColsUniqueIDs.Insert(scalarUniqueID)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/planner/util/funcdep_misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func ExtractNotNullFromConds(conditions []expression.Expression, p base.LogicalP
if len(cols) == 0 {
continue
}
if IsNullRejected(p.SCtx(), p.Schema(), condition, true) {
if IsNullRejected(p.SCtx(), p.Schema(), condition) {
for _, col := range cols {
notnullColsUniqueIDs.Insert(int(col.UniqueID))
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/planner/util/null_misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ import (
// classify that exact value. This recovers cases such as COALESCE/IF/IFNULL
// that may hide NULL but still collapse after nullification. The bridge stays
// conservative for plan-cache-sensitive expressions by refusing to treat
// ParamMarker/DeferredExpr values as static fold results.
// ParamMarker/DeferredExpr values as static fold results. DeferredExpr can
// still be inspected symbolically, but its runtime value must not be folded or
// classified as a compile-time constant.

// nullRejectProof holds the two proof results for a sub-expression.
// See the file-level comment above for the full model.
Expand All @@ -71,7 +73,8 @@ type nullRejectProof struct {
mustNull bool
}

// allConstants checks whether the expression tree consists entirely of constants.
// allConstants checks whether the expression tree can be attempted as a static
// constant tree without lazy constants.
func allConstants(ctx expression.BuildContext, expr expression.Expression) bool {
if expression.MaybeOverOptimized4PlanCache(ctx, []expression.Expression{expr}) {
return false // expression contains non-deterministic parameter
Expand All @@ -92,9 +95,7 @@ func allConstants(ctx expression.BuildContext, expr expression.Expression) bool

// IsNullRejected proves whether `predicate` can be TRUE after every column in
// `innerSchema` is replaced with SQL NULL.
func IsNullRejected(ctx base.PlanContext, innerSchema *expression.Schema, predicate expression.Expression,
skipPlanCacheCheck bool) bool {
_ = skipPlanCacheCheck // kept for API compatibility; the new proof does not use EvaluateExprWithNull
func IsNullRejected(ctx base.PlanContext, innerSchema *expression.Schema, predicate expression.Expression) bool {
predicate = expression.PushDownNot(ctx.GetNullRejectCheckExprCtx(), predicate)
return proveNullRejected(ctx, innerSchema, predicate, true).nonTrue
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/planner/util/null_misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ func TestIsNullRejectedProofModes(t *testing.T) {

for _, tt := range cases {
t.Run(tt.name, func(t *testing.T) {
require.Equal(t, tt.expected, IsNullRejected(sctx, innerSchema, tt.expr, true))
require.Equal(t, tt.expected, IsNullRejected(sctx, innerSchema, tt.expr))
})
}
}
Expand Down