Repository: pingcap/tidb
File: pkg/planner/core/rule_join_reorder.go (Go)

Code before:
	return
}

// hasOtherJoinCondition checks whether there are non-equality join conditions
// connecting the two plans (i.e. conditions referencing columns from both sides).
// Conditions referencing null-extended columns are excluded since reordering
// across them can change outer-join semantics.
func (s *baseSingleGroupJoinOrderSolver) hasOtherJoinCondition(leftPlan, rightPlan base.LogicalPlan) bool {
	if len(s.otherConds) == 0 {
		return false
	}
	mergedSchema := expression.MergeSchema(leftPlan.Schema(), rightPlan.Schema())
	for _, cond := range s.otherConds {
		if !expression.ExprFromSchema(cond, mergedSchema) {
			continue
		}
		if expression.ExprFromSchema(cond, leftPlan.Schema()) || expression.ExprFromSchema(cond, rightPlan.Schema()) {
			continue
		}
		if s.nullExtendedCols != nil {
			cols := expression.ExtractColumns(cond)
			if slices.ContainsFunc(cols, func(col *expression.Column) bool {
				return s.nullExtendedCols.Contains(col)
			}) {
				continue
			}
		}
		return true
	}
	return false
}

// makeJoin build join tree for the nodes which have equal conditions to connect them.
func (s *baseSingleGroupJoinOrderSolver) makeJoin(leftPlan, rightPlan base.LogicalPlan, eqEdges []*expression.ScalarFunction, joinType *joinTypeWithExtMsg) (base.LogicalPlan, []expression.Expression) {
	remainOtherConds := make([]expression.Expression, len(s.otherConds))
	copy(remainOtherConds, s.otherConds)
	var (
		otherConds []expression.Expression
		leftConds  []expression.Expression
		rightConds []expression.Expression

		// for outer bind conditions
		obOtherConds []expression.Expression
		obLeftConds  []expression.Expression
		obRightConds []expression.Expression
	)
	mergedSchema := expression.MergeSchema(leftPlan.Schema(), rightPlan.Schema())

	remainOtherConds, leftConds = expression.FilterOutInPlace(remainOtherConds, func(expr expression.Expression) bool {
		return expression.ExprFromSchema(expr, leftPlan.Schema()) && !expression.ExprFromSchema(expr, rightPlan.Schema())
	})

Review comment (refactor):
In `hasOtherJoinCondition`, the null-extended-column check currently calls `expression.ExtractColumns(cond)` and then scans the slice. This allocates and walks all columns for every candidate condition. You can avoid the allocation by using `expression.ExprReferenceSchema(cond, s.nullExtendedCols)` (or an equivalent schema-reference check) to detect whether `cond` references any null-extended columns.
```suggestion
		if s.nullExtendedCols != nil && expression.ExprReferenceSchema(cond, s.nullExtendedCols) {
			continue
```

Code after:
	return
}

// hasOtherJoinCondition checks whether there are non-equality join conditions
// connecting the two plans (i.e. conditions referencing columns from both sides).
// Conditions referencing null-extended columns are excluded since reordering
// across them can change outer-join semantics.
func (s *baseSingleGroupJoinOrderSolver) hasOtherJoinCondition(leftPlan, rightPlan base.LogicalPlan) bool {
	if len(s.otherConds) == 0 {
		return false
	}
	mergedSchema := expression.MergeSchema(leftPlan.Schema(), rightPlan.Schema())
	for _, cond := range s.otherConds {
		if !expression.ExprFromSchema(cond, mergedSchema) {
			continue
		}
		if expression.ExprFromSchema(cond, leftPlan.Schema()) || expression.ExprFromSchema(cond, rightPlan.Schema()) {
			continue
		}
		if s.nullExtendedCols != nil && expression.ExprReferenceSchema(cond, s.nullExtendedCols) {
			continue
		}
		return true
	}
	return false
}

// makeJoin build join tree for the nodes which have equal conditions to connect them.
func (s *baseSingleGroupJoinOrderSolver) makeJoin(leftPlan, rightPlan base.LogicalPlan, eqEdges []*expression.ScalarFunction, joinType *joinTypeWithExtMsg) (base.LogicalPlan, []expression.Expression) {
	remainOtherConds := make([]expression.Expression, len(s.otherConds))
	copy(remainOtherConds, s.otherConds)
	var (
		otherConds []expression.Expression
		leftConds  []expression.Expression
		rightConds []expression.Expression

		// for outer bind conditions
		obOtherConds []expression.Expression
		obLeftConds  []expression.Expression
		obRightConds []expression.Expression
	)
	mergedSchema := expression.MergeSchema(leftPlan.Schema(), rightPlan.Schema())

	remainOtherConds, leftConds = expression.FilterOutInPlace(remainOtherConds, func(expr expression.Expression) bool {
		return expression.ExprFromSchema(expr, leftPlan.Schema()) && !expression.ExprFromSchema(expr, rightPlan.Schema())
	})
	remainOtherConds, rightConds = expression.FilterOutInPlace(remainOtherConds, func(expr expression.Expression) bool {
		return expression.ExprFromSchema(expr, rightPlan.Schema()) && !expression.ExprFromSchema(expr, leftPlan.Schema())
	})
	remainOtherConds, otherConds = expression.FilterOutInPlace(remainOtherConds, func(expr expression.Expression) bool {
		return expression.ExprFromSchema(expr, mergedSchema)