use super::optimizer::PhysicalOptimizerRule;
use crate::config::ConfigOptions;
use crate::error::Result;
use crate::physical_plan::sorts::sort::SortExec;
use crate::physical_plan::{with_new_children_if_necessary, ExecutionPlan};
use datafusion_physical_expr::PhysicalSortExpr;
use std::sync::Arc;
pub fn optimize_children(
optimizer: &impl PhysicalOptimizerRule,
plan: Arc<dyn ExecutionPlan>,
config: &ConfigOptions,
) -> Result<Arc<dyn ExecutionPlan>> {
let children = plan
.children()
.iter()
.map(|child| optimizer.optimize(Arc::clone(child), config))
.collect::<Result<Vec<_>>>()?;
if children.is_empty() {
Ok(Arc::clone(&plan))
} else {
with_new_children_if_necessary(plan, children)
}
}
pub fn add_sort_above_child(
child: &Arc<dyn ExecutionPlan>,
sort_expr: Vec<PhysicalSortExpr>,
) -> Result<Arc<dyn ExecutionPlan>> {
let new_child = if child.output_partitioning().partition_count() > 1 {
Arc::new(SortExec::new_with_partitioning(
sort_expr,
child.clone(),
true,
None,
)) as Arc<dyn ExecutionPlan>
} else {
Arc::new(SortExec::try_new(sort_expr, child.clone(), None)?)
as Arc<dyn ExecutionPlan>
};
Ok(new_child)
}