Skip to content

Commit

Permalink
feat: eliminate group by constant optimizer rule
Browse files Browse the repository at this point in the history
  • Loading branch information
korowa committed May 19, 2024
1 parent d419752 commit f71fcd6
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 0 deletions.
95 changes: 95 additions & 0 deletions datafusion/optimizer/src/eliminate_group_by_constant.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

//! [`EliminateGroupByConstant`] removes Literal expressions from `GROUP BY` clause
use crate::optimizer::ApplyOrder;
use crate::{OptimizerConfig, OptimizerRule};

use datafusion_common::tree_node::Transformed;
use datafusion_common::{internal_err, Result};
use datafusion_expr::{Aggregate, Expr, LogicalPlan, LogicalPlanBuilder};

/// Optimizer rule that removes Literal expressions from `GROUP BY` clause
#[derive(Default)]
pub struct EliminateGroupByConstant {}

impl EliminateGroupByConstant {
pub fn new() -> Self {
Self {}
}
}

impl OptimizerRule for EliminateGroupByConstant {
fn supports_rewrite(&self) -> bool {
true
}

fn rewrite(
&self,
plan: LogicalPlan,
_config: &dyn OptimizerConfig,
) -> Result<Transformed<LogicalPlan>> {
match plan {
LogicalPlan::Aggregate(aggregate) => {
let (const_group_expr, nonconst_group_expr): (Vec<_>, Vec<_>) = aggregate
.group_expr
.iter()
.partition(|expr| matches!(expr, Expr::Literal(_)));

if const_group_expr.is_empty() {
return Ok(Transformed::no(LogicalPlan::Aggregate(aggregate)));
}

let simplified_aggregate = LogicalPlan::Aggregate(Aggregate::try_new(
aggregate.input,
nonconst_group_expr.into_iter().cloned().collect(),
aggregate.aggr_expr.clone(),
)?);

let projection_expr = aggregate
.group_expr
.into_iter()
.chain(aggregate.aggr_expr.into_iter());

let projection = LogicalPlanBuilder::from(simplified_aggregate)
.project(projection_expr)?
.build()?;

Ok(Transformed::yes(projection))
}
_ => Ok(Transformed::no(plan)),
}
}

fn try_optimize(
&self,
_plan: &LogicalPlan,
_config: &dyn OptimizerConfig,
) -> Result<Option<LogicalPlan>> {
internal_err!("Should have called EliminateGroupByConstant::rewrite")
}

fn name(&self) -> &str {
"eliminate_group_by_constant"
}

fn apply_order(&self) -> Option<ApplyOrder> {
Some(ApplyOrder::BottomUp)
}
}


1 change: 1 addition & 0 deletions datafusion/optimizer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ pub mod decorrelate_predicate_subquery;
pub mod eliminate_cross_join;
pub mod eliminate_duplicated_expr;
pub mod eliminate_filter;
pub mod eliminate_group_by_constant;
pub mod eliminate_join;
pub mod eliminate_limit;
pub mod eliminate_nested_union;
Expand Down
2 changes: 2 additions & 0 deletions datafusion/optimizer/src/optimizer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::decorrelate_predicate_subquery::DecorrelatePredicateSubquery;
use crate::eliminate_cross_join::EliminateCrossJoin;
use crate::eliminate_duplicated_expr::EliminateDuplicatedExpr;
use crate::eliminate_filter::EliminateFilter;
use crate::eliminate_group_by_constant::EliminateGroupByConstant;
use crate::eliminate_join::EliminateJoin;
use crate::eliminate_limit::EliminateLimit;
use crate::eliminate_nested_union::EliminateNestedUnion;
Expand Down Expand Up @@ -262,6 +263,7 @@ impl Optimizer {
Arc::new(SimplifyExpressions::new()),
Arc::new(UnwrapCastInComparison::new()),
Arc::new(CommonSubexprEliminate::new()),
Arc::new(EliminateGroupByConstant::new()),
Arc::new(OptimizeProjections::new()),
];

Expand Down

0 comments on commit f71fcd6

Please sign in to comment.