use std::fmt::Debug;
use std::sync::Arc;
use crate::aggregate_statistics::AggregateStatistics;
use crate::coalesce_batches::CoalesceBatches;
use crate::combine_partial_final_agg::CombinePartialFinalAggregate;
use crate::enforce_distribution::EnforceDistribution;
use crate::enforce_sorting::EnforceSorting;
use crate::join_selection::JoinSelection;
use crate::limit_pushdown::LimitPushdown;
use crate::limited_distinct_aggregation::LimitedDistinctAggregation;
use crate::output_requirements::OutputRequirements;
use crate::projection_pushdown::ProjectionPushdown;
use crate::sanity_checker::SanityCheckPlan;
use crate::topk_aggregation::TopKAggregation;
use crate::update_aggr_exprs::OptimizeAggregateOrder;
use datafusion_common::config::ConfigOptions;
use datafusion_common::Result;
use datafusion_physical_plan::ExecutionPlan;
pub trait PhysicalOptimizerRule: Debug {
fn optimize(
&self,
plan: Arc<dyn ExecutionPlan>,
config: &ConfigOptions,
) -> Result<Arc<dyn ExecutionPlan>>;
fn name(&self) -> &str;
fn schema_check(&self) -> bool;
}
#[derive(Clone, Debug)]
pub struct PhysicalOptimizer {
pub rules: Vec<Arc<dyn PhysicalOptimizerRule + Send + Sync>>,
}
impl Default for PhysicalOptimizer {
fn default() -> Self {
Self::new()
}
}
impl PhysicalOptimizer {
pub fn new() -> Self {
let rules: Vec<Arc<dyn PhysicalOptimizerRule + Send + Sync>> = vec![
Arc::new(OutputRequirements::new_add_mode()),
Arc::new(AggregateStatistics::new()),
Arc::new(JoinSelection::new()),
Arc::new(LimitedDistinctAggregation::new()),
Arc::new(EnforceDistribution::new()),
Arc::new(CombinePartialFinalAggregate::new()),
Arc::new(EnforceSorting::new()),
Arc::new(OptimizeAggregateOrder::new()),
Arc::new(ProjectionPushdown::new()),
Arc::new(CoalesceBatches::new()),
Arc::new(OutputRequirements::new_remove_mode()),
Arc::new(TopKAggregation::new()),
Arc::new(ProjectionPushdown::new()),
Arc::new(LimitPushdown::new()),
Arc::new(SanityCheckPlan::new()),
];
Self::with_rules(rules)
}
pub fn with_rules(rules: Vec<Arc<dyn PhysicalOptimizerRule + Send + Sync>>) -> Self {
Self { rules }
}
}