Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-plan/src/plans/conversion/convert_utils.rs
6940 views
1
use super::*;
2
3
/// Split expression that are ANDed into multiple Filter nodes as the optimizer can then
4
/// push them down independently. Especially if they refer columns from different tables
5
/// this will be more performant.
6
///
7
/// So:
8
/// * `filter[foo == bar & ham == spam]`
9
///
10
/// Becomes:
11
/// * `filter [foo == bar]`
12
/// * `filter [ham == spam]`
13
pub(super) struct SplitPredicates {
14
pub(super) pushable: Vec<Node>,
15
pub(super) fallible: Option<Node>,
16
}
17
18
impl SplitPredicates {
19
/// Returns None if a barrier expression is encountered
20
pub(super) fn new(
21
predicate: Node,
22
expr_arena: &mut Arena<AExpr>,
23
scratch: Option<&mut UnitVec<Node>>,
24
maintain_errors: bool,
25
) -> Option<Self> {
26
let mut local_scratch = unitvec![];
27
let scratch = scratch.unwrap_or(&mut local_scratch);
28
29
let mut pushable = vec![];
30
let mut acc_fallible = unitvec![];
31
32
for predicate in MintermIter::new(predicate, expr_arena) {
33
use ExprPushdownGroup::*;
34
35
let ae = expr_arena.get(predicate);
36
37
match ExprPushdownGroup::Pushable.update_with_expr_rec(ae, expr_arena, Some(scratch)) {
38
Pushable => pushable.push(predicate),
39
40
Fallible => {
41
if maintain_errors {
42
return None;
43
}
44
45
acc_fallible.push(predicate);
46
},
47
48
Barrier => return None,
49
}
50
}
51
52
let fallible = (!acc_fallible.is_empty()).then(|| {
53
let mut node = acc_fallible.pop().unwrap();
54
55
for next_node in acc_fallible.iter() {
56
node = expr_arena.add(AExpr::BinaryExpr {
57
left: node,
58
op: Operator::And,
59
right: *next_node,
60
})
61
}
62
63
node
64
});
65
66
let out = Self { pushable, fallible };
67
68
Some(out)
69
}
70
}
71
72