Path: blob/main/crates/polars-plan/src/plans/conversion/convert_utils.rs
6940 views
use super::*;12/// Split expression that are ANDed into multiple Filter nodes as the optimizer can then3/// push them down independently. Especially if they refer columns from different tables4/// this will be more performant.5///6/// So:7/// * `filter[foo == bar & ham == spam]`8///9/// Becomes:10/// * `filter [foo == bar]`11/// * `filter [ham == spam]`12pub(super) struct SplitPredicates {13pub(super) pushable: Vec<Node>,14pub(super) fallible: Option<Node>,15}1617impl SplitPredicates {18/// Returns None if a barrier expression is encountered19pub(super) fn new(20predicate: Node,21expr_arena: &mut Arena<AExpr>,22scratch: Option<&mut UnitVec<Node>>,23maintain_errors: bool,24) -> Option<Self> {25let mut local_scratch = unitvec![];26let scratch = scratch.unwrap_or(&mut local_scratch);2728let mut pushable = vec![];29let mut acc_fallible = unitvec![];3031for predicate in MintermIter::new(predicate, expr_arena) {32use ExprPushdownGroup::*;3334let ae = expr_arena.get(predicate);3536match ExprPushdownGroup::Pushable.update_with_expr_rec(ae, expr_arena, Some(scratch)) {37Pushable => pushable.push(predicate),3839Fallible => {40if maintain_errors {41return None;42}4344acc_fallible.push(predicate);45},4647Barrier => return None,48}49}5051let fallible = (!acc_fallible.is_empty()).then(|| {52let mut node = acc_fallible.pop().unwrap();5354for next_node in acc_fallible.iter() {55node = expr_arena.add(AExpr::BinaryExpr {56left: node,57op: Operator::And,58right: *next_node,59})60}6162node63});6465let out = Self { pushable, fallible };6667Some(out)68}69}707172