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>,
)
| 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. |