Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-plan/src/plans/optimizer/projection_pushdown/generic.rs
7889 views
1
use polars_utils::idx_vec::UnitVec;
2
3
use super::*;
4
5
#[allow(clippy::too_many_arguments)]
6
pub(super) fn process_generic(
7
proj_pd: &mut ProjectionPushDown,
8
lp: IR,
9
ctx: ProjectionContext,
10
lp_arena: &mut Arena<IR>,
11
expr_arena: &mut Arena<AExpr>,
12
) -> PolarsResult<IR> {
13
let inputs = lp.get_inputs();
14
let input_count = inputs.len();
15
16
// let mut first_schema = None;
17
// let mut names = None;
18
19
let new_inputs = inputs
20
.into_iter()
21
.map(|node| {
22
let alp = lp_arena.take(node);
23
let mut alp = proj_pd.push_down(alp, ctx.clone(), lp_arena, expr_arena)?;
24
25
// double projection can mess up the schema ordering
26
// here we ensure the ordering is maintained.
27
//
28
// Consider this query
29
// df1 => a, b
30
// df2 => a, b
31
//
32
// df3 = df1.join(df2, on = a, b)
33
//
34
// concat([df1, df3]).select(a)
35
//
36
// schema after projection pd
37
// df3 => a, b
38
// df1 => a
39
// so we ensure we do the 'a' projection again before we concatenate
40
if !ctx.acc_projections.is_empty() && input_count > 1 {
41
alp = IRBuilder::from_lp(alp, expr_arena, lp_arena)
42
.project_simple_nodes(ctx.acc_projections.iter().map(|e| e.0))
43
.unwrap()
44
.build();
45
}
46
lp_arena.replace(node, alp);
47
Ok(node)
48
})
49
.collect::<PolarsResult<UnitVec<_>>>()?;
50
51
Ok(lp.with_inputs(new_inputs))
52
}
53
54