MCPcopy Create free account
hub / github.com/apache/datafusion / collect_predicate_constants

Method collect_predicate_constants

datafusion/physical-expr/src/utils/mod.rs:62–105  ·  view source on GitHub ↗

Collects predicate-derived constants from equality conjunctions. For each equality predicate of the form `lhs = rhs`, if either side is already known constant according to `input_eqs`, or is a literal, then the other side is also constant and will be returned as a [`ConstExpr`]. Literals are treated as uniform constants across partitions, so `col = literal` produces a constant for `col` with the

(
        input_eqs: &EquivalenceProperties,
        predicate: &Arc<dyn PhysicalExpr>,
    )

Source from the content-addressed store, hash-verified

60 /// known constant, this returns constants for both `a` (Uniform with value
61 /// 5) and `b` (propagating `c`'s across-partitions value).
62 pub fn collect_predicate_constants(
63 input_eqs: &EquivalenceProperties,
64 predicate: &Arc<dyn PhysicalExpr>,
65 ) -> Vec<ConstExpr> {
66 /// Returns the `AcrossPartitions` value for `expr` if it is constant:
67 /// either already known constant in `input_eqs`, or a `Literal`
68 /// (which is inherently constant across all partitions).
69 fn expr_constant_or_literal(
70 expr: &Arc<dyn PhysicalExpr>,
71 input_eqs: &EquivalenceProperties,
72 ) -> Option<AcrossPartitions> {
73 input_eqs.is_expr_constant(expr).or_else(|| {
74 expr.downcast_ref::<Literal>()
75 .map(|l| AcrossPartitions::Uniform(Some(l.value().clone())))
76 })
77 }
78
79 let mut constants = Vec::new();
80 for conjunction in split_conjunction(predicate) {
81 if let Some(binary) = conjunction.downcast_ref::<BinaryExpr>()
82 && binary.op() == &Operator::Eq
83 {
84 // Check if either side is constant — either already known
85 // constant from the input equivalence properties, or a literal
86 // value (which is inherently constant across all partitions).
87 let left_const = expr_constant_or_literal(binary.left(), input_eqs);
88 let right_const = expr_constant_or_literal(binary.right(), input_eqs);
89
90 if let Some(left_across) = left_const {
91 // LEFT is constant, so RIGHT must also be constant.
92 // Use RIGHT's known across value if available, otherwise
93 // propagate LEFT's (e.g. Uniform from a literal).
94 let across = right_const.unwrap_or(left_across);
95 constants.push(ConstExpr::new(Arc::clone(binary.right()), across));
96 } else if let Some(right_across) = right_const {
97 // RIGHT is constant, so LEFT must also be constant.
98 constants
99 .push(ConstExpr::new(Arc::clone(binary.left()), right_across));
100 }
101 }
102 }
103
104 constants
105 }
106}
107
108/// Create a conjunction of the given predicates.

Callers

nothing calls this directly

Calls 6

newFunction · 0.85
split_conjunctionFunction · 0.70
opMethod · 0.45
leftMethod · 0.45
rightMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected