Path: blob/main/crates/polars-plan/src/plans/optimizer/projection_pushdown/functions/mod.rs
7896 views
#[cfg(feature = "pivot")]1mod unpivot;23#[cfg(feature = "pivot")]4use unpivot::process_unpivot;56use super::*;78#[allow(clippy::too_many_arguments)]9pub(super) fn process_functions(10proj_pd: &mut ProjectionPushDown,11input: Node,12function: FunctionIR,13mut ctx: ProjectionContext,14lp_arena: &mut Arena<IR>,15expr_arena: &mut Arena<AExpr>,16) -> PolarsResult<IR> {17use FunctionIR::*;18match function {19Explode {20columns, options, ..21} => {22columns23.iter()24.for_each(|name| add_str_to_accumulated(name.clone(), &mut ctx, expr_arena));25proj_pd.pushdown_and_assign(input, ctx, lp_arena, expr_arena)?;26Ok(IRBuilder::new(input, expr_arena, lp_arena)27.explode(columns, options)28.build())29},30#[cfg(feature = "pivot")]31Unpivot { ref args, .. } => {32process_unpivot(proj_pd, args, input, ctx, lp_arena, expr_arena)33},34Hint(hint) => {35let hint = hint.project(&ctx.projected_names);36proj_pd.pushdown_and_assign(input, ctx, lp_arena, expr_arena)?;37Ok(match hint {38None => lp_arena.get(input).clone(),39Some(hint) => IRBuilder::new(input, expr_arena, lp_arena)40.hint(hint)41.build(),42})43},44_ => {45if function.allow_projection_pd() && ctx.has_pushed_down() {46let original_acc_projection_len = ctx.acc_projections.len();4748// add columns needed for the function.49for name in function.additional_projection_pd_columns().as_ref() {50let node = expr_arena.add(AExpr::Column(name.clone()));51add_expr_to_accumulated(52node,53&mut ctx.acc_projections,54&mut ctx.projected_names,55expr_arena,56)57}58let expands_schema = matches!(function, FunctionIR::Unnest { .. });5960let local_projections = proj_pd.pushdown_and_assign_check_schema(61input,62ctx,63lp_arena,64expr_arena,65expands_schema,66)?;6768// Remove the cached schema69function.clear_cached_schema();70let lp = IR::MapFunction {71input,72function: function.clone(),73};7475if local_projections.is_empty() {76Ok(lp)77} else {78// if we would project, we would remove pushed down predicates79if local_projections.len() < original_acc_projection_len {80Ok(IRBuilder::from_lp(lp, expr_arena, lp_arena)81.with_columns_simple(local_projections, Default::default())82.build())83// all projections are local84} else {85Ok(IRBuilder::from_lp(lp, expr_arena, lp_arena)86.project_simple_nodes(local_projections)87.unwrap()88.build())89}90}91} else {92let lp = IR::MapFunction {93input,94function: function.clone(),95};96// restart projection pushdown97proj_pd.no_pushdown_restart_opt(lp, ctx, lp_arena, expr_arena)98}99},100}101}102103104