use std::sync::Arc;
use datafusion_common::config::ConfigOptions;
use datafusion_common::error::Result;
use datafusion_physical_optimizer::{PhysicalOptimizerContext, PhysicalOptimizerRule};
use datafusion_physical_plan::ExecutionPlan;
use datafusion_physical_plan::limit::GlobalLimitExec;
use crate::physical_optimizer::FFI_PhysicalOptimizerRule;
#[derive(Debug)]
struct AddLimitRule;
impl PhysicalOptimizerRule for AddLimitRule {
fn optimize(
&self,
plan: Arc<dyn ExecutionPlan>,
_config: &ConfigOptions,
) -> Result<Arc<dyn ExecutionPlan>> {
Ok(Arc::new(GlobalLimitExec::new(plan, 0, Some(10))))
}
fn name(&self) -> &str {
"add_limit_rule"
}
fn schema_check(&self) -> bool {
true
}
}
pub(crate) extern "C" fn create_physical_optimizer_rule() -> FFI_PhysicalOptimizerRule {
let rule: Arc<dyn PhysicalOptimizerRule + Send + Sync> = Arc::new(AddLimitRule);
FFI_PhysicalOptimizerRule::new(rule, None)
}
#[derive(Debug)]
struct ContextAwareAddLimitRule;
impl PhysicalOptimizerRule for ContextAwareAddLimitRule {
fn optimize(
&self,
_plan: Arc<dyn ExecutionPlan>,
_config: &ConfigOptions,
) -> Result<Arc<dyn ExecutionPlan>> {
Err(datafusion_common::DataFusionError::Plan(
"optimize should not be called directly; use optimize_with_context"
.to_string(),
))
}
fn optimize_with_context(
&self,
plan: Arc<dyn ExecutionPlan>,
_context: &dyn PhysicalOptimizerContext,
) -> Result<Arc<dyn ExecutionPlan>> {
Ok(Arc::new(GlobalLimitExec::new(plan, 0, Some(10))))
}
fn name(&self) -> &str {
"context_aware_add_limit_rule"
}
fn schema_check(&self) -> bool {
true
}
}
pub(crate) extern "C" fn create_context_aware_optimizer_rule() -> FFI_PhysicalOptimizerRule
{
let rule: Arc<dyn PhysicalOptimizerRule + Send + Sync> =
Arc::new(ContextAwareAddLimitRule);
FFI_PhysicalOptimizerRule::new(rule, None)
}