Repository: pingcap/tidb
File: pkg/expression/util.go (Go)

Code before:
		extractColumns(m, expr, filter)
	}
	result := slices.Collect(maps.Values(m))
	// The keys in a map are unordered, so to ensure stability, we need to sort them here.
	slices.SortFunc(result, func(a, b *Column) int {
		return cmp.Compare(a.UniqueID, b.UniqueID)
	})
	return result
}

// ExtractColumnsMapFromExpressions it the same as ExtractColumnsFromExpressions, but return a map
func ExtractColumnsMapFromExpressions(filter func(*Column) bool, exprs ...Expression) map[int64]*Column {
	if len(exprs) == 0 {
		return nil
	}
	m := make(map[int64]*Column, len(exprs))
	for _, expr := range exprs {
		extractColumns(m, expr, filter)
	}
	return m
}

// ExtractColumnsMapFromExpressionsWithReusedMap it the same as ExtractColumnsFromExpressions, but map can be reused.
func ExtractColumnsMapFromExpressionsWithReusedMap(m map[int64]*Column, filter func(*Column) bool, exprs ...Expression) {
	if len(exprs) == 0 {
		return
	}
	if m == nil {
		m = make(map[int64]*Column, len(exprs))
	}
	for _, expr := range exprs {
		extractColumns(m, expr, filter)
	}
}

func extractColumns(result map[int64]*Column, expr Expression, filter func(*Column) bool) {
	switch v := expr.(type) {
	case *Column:
		if filter == nil || filter(v) {
			result[v.UniqueID] = v
		}
	case *ScalarFunction:
		for _, arg := range v.GetArgs() {
			extractColumns(result, arg, filter)
		}
	}
}

// ExtractEquivalenceColumns detects the equivalence from CNF exprs.
func ExtractEquivalenceColumns(result [][]Expression, exprs []Expression) [][]Expression {
	// exprs are CNF expressions, EQ condition only make sense in the top level of every expr.

Review comment (refactor):
The check `if m == nil` will not affect the original map passed to the function since Go passes maps by reference to their underlying data structure, but the map variable itself is passed by value. If m is nil, creating a new map here won't update the caller's map variable. Consider returning the map or requiring a non-nil map parameter.
```suggestion
// ExtractColumnsMapFromExpressionsWithReusedMap is the same as ExtractColumnsFromExpressions, but map can be reused.
func ExtractColumnsMapFromExpressionsWithReusedMap(m map[int64]*Column, filter func(*Column) bool, exprs ...Expression) map[int64]*Column {
	if len(exprs) == 0 {
		return m
```

Code after:
	for _, expr := range exprs {
		extractColumns(m, expr, filter)
	}
	result := slices.Collect(maps.Values(m))
	// The keys in a map are unordered, so to ensure stability, we need to sort them here.
	slices.SortFunc(result, func(a, b *Column) int {
		return cmp.Compare(a.UniqueID, b.UniqueID)
	})
	return result
}

// ExtractColumnsMapFromExpressions it the same as ExtractColumnsFromExpressions, but return a map
func ExtractColumnsMapFromExpressions(filter func(*Column) bool, exprs ...Expression) map[int64]*Column {
	if len(exprs) == 0 {
		return nil
	}
	m := make(map[int64]*Column, len(exprs))
	for _, expr := range exprs {
		extractColumns(m, expr, filter)
	}
	return m
}

// ExtractColumnsMapFromExpressionsWithReusedMap is the same as ExtractColumnsFromExpressions, but map can be reused.
func ExtractColumnsMapFromExpressionsWithReusedMap(m map[int64]*Column, filter func(*Column) bool, exprs ...Expression) {
	if len(exprs) == 0 {
		return
	}
	if m == nil {
		m = make(map[int64]*Column, len(exprs))
	}
	for _, expr := range exprs {
		extractColumns(m, expr, filter)
	}
}

// ExtractAllColumnsFromExpressions is the same as ExtractColumnsFromExpressions. But this will not remove duplicates.
func ExtractAllColumnsFromExpressions(exprs []Expression, filter func(*Column) bool) []*Column {
	if len(exprs) == 0 {
		return nil
	}
	result := make([]*Column, 0, 8)
	for _, expr := range exprs {
		result = extractColumnsSlices(result, expr, filter)
	}
	return result
}

// ExtractColumnsSetFromExpressions is the same as ExtractColumnsFromExpressions
// it use the FastIntSet to save the Unique ID.
func ExtractColumnsSetFromExpressions(m *intset.FastIntSet, filter func(*Column) bool, exprs ...Expression) {