Perform an indirect projection of `expr` by consulting the equivalence classes.
(
aug_mapping: &AugmentedMapping,
expr: &Arc<dyn PhysicalExpr>,
)
| 588 | /// Perform an indirect projection of `expr` by consulting the equivalence |
| 589 | /// classes. |
| 590 | fn project_expr_indirect( |
| 591 | aug_mapping: &AugmentedMapping, |
| 592 | expr: &Arc<dyn PhysicalExpr>, |
| 593 | ) -> Option<Arc<dyn PhysicalExpr>> { |
| 594 | // Literals don't need to be projected |
| 595 | if expr.downcast_ref::<Literal>().is_some() { |
| 596 | return Some(Arc::clone(expr)); |
| 597 | } |
| 598 | |
| 599 | // The given expression is not inside the mapping, so we try to project |
| 600 | // indirectly using equivalence classes. |
| 601 | for (targets, eq_class) in aug_mapping.values() { |
| 602 | // If we match an equivalent expression to a source expression in |
| 603 | // the mapping, then we can project. For example, if we have the |
| 604 | // mapping `(a as a1, a + c)` and the equivalence `a == b`, |
| 605 | // expression `b` projects to `a1`. |
| 606 | if eq_class.as_ref().is_some_and(|cls| cls.contains(expr)) { |
| 607 | let (target, _) = targets.first(); |
| 608 | return Some(Arc::clone(target)); |
| 609 | } |
| 610 | } |
| 611 | // Project a non-leaf expression by projecting its children. |
| 612 | let children = expr.children(); |
| 613 | if children.is_empty() { |
| 614 | // A leaf expression should be inside the mapping. |
| 615 | return None; |
| 616 | } |
| 617 | children |
| 618 | .into_iter() |
| 619 | .map(|child| { |
| 620 | // First, we try to project children with an exact match. If |
| 621 | // we are unable to do this, we consult equivalence classes. |
| 622 | if let Some((targets, _)) = aug_mapping.get(child) { |
| 623 | // If we match the source, we can project directly: |
| 624 | let (target, _) = targets.first(); |
| 625 | Some(Arc::clone(target)) |
| 626 | } else { |
| 627 | Self::project_expr_indirect(aug_mapping, child) |
| 628 | } |
| 629 | }) |
| 630 | .collect::<Option<Vec<_>>>() |
| 631 | .map(|children| Arc::clone(expr).with_new_children(children).unwrap()) |
| 632 | } |
| 633 | |
| 634 | fn augment_projection_mapping<'a>( |
| 635 | &'a self, |