From 5c48a21ad081148706e7d2e62f6c583abe4547d5 Mon Sep 17 00:00:00 2001 From: Mustafa Akur <106137913+mustafasrepo@users.noreply.github.com> Date: Wed, 31 Jan 2024 19:44:16 +0300 Subject: [PATCH] add check for unnecessary projection (#9079) --- datafusion/optimizer/src/optimize_projections.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/datafusion/optimizer/src/optimize_projections.rs b/datafusion/optimizer/src/optimize_projections.rs index db0459fd9ab6..d8d7f71d7143 100644 --- a/datafusion/optimizer/src/optimize_projections.rs +++ b/datafusion/optimizer/src/optimize_projections.rs @@ -868,9 +868,7 @@ fn rewrite_projection_given_requirements( return if let Some(input) = optimize_projections(&proj.input, config, &required_indices)? { - if &projection_schema(&input, &exprs_used)? == input.schema() - && exprs_used.iter().all(is_expr_trivial) - { + if is_projection_unnecessary(&input, &exprs_used)? { Ok(Some(input)) } else { Projection::try_new(exprs_used, Arc::new(input)) @@ -880,7 +878,7 @@ fn rewrite_projection_given_requirements( // Projection expression used is different than the existing projection. // In this case, even if the child doesn't change, we should update the // projection to use fewer columns: - if &projection_schema(&proj.input, &exprs_used)? == proj.input.schema() { + if is_projection_unnecessary(&proj.input, &exprs_used)? { Ok(Some(proj.input.as_ref().clone())) } else { Projection::try_new(exprs_used, proj.input.clone()) @@ -892,6 +890,14 @@ fn rewrite_projection_given_requirements( }; } +/// Projection is unnecessary, when +/// - input schema of the projection, output schema of the projection are same, and +/// - all projection expressions are either Column or Literal +fn is_projection_unnecessary(input: &LogicalPlan, proj_exprs: &[Expr]) -> Result { + Ok(&projection_schema(input, proj_exprs)? == input.schema() + && proj_exprs.iter().all(is_expr_trivial)) +} + #[cfg(test)] mod tests { use std::sync::Arc;