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::utils::ordering_satisfy;
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(
node: &mut Arc<dyn ExecutionPlan>,
sort_expr: Vec<PhysicalSortExpr>,
) -> Result<()> {
if !ordering_satisfy(node.output_ordering(), Some(&sort_expr), || {
node.equivalence_properties()
}) {
*node = Arc::new(if node.output_partitioning().partition_count() > 1 {
SortExec::new_with_partitioning(sort_expr, node.clone(), true, None)
} else {
SortExec::try_new(sort_expr, node.clone(), None)?
}) as _
}
Ok(())
}