Skip to main content

ExtensionPlanner

Trait ExtensionPlanner 

Source
pub trait ExtensionPlanner {
    // Required method
    fn plan_extension<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'life7, 'async_trait>(
        &'life0 self,
        planner: &'life1 dyn PhysicalPlanner,
        node: &'life2 dyn UserDefinedLogicalNode,
        logical_inputs: &'life3 [&'life4 LogicalPlan],
        physical_inputs: &'life5 [Arc<dyn ExecutionPlan>],
        session: &'life6 dyn Session,
        planning_ctx: &'life7 PhysicalPlanningContext,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Arc<dyn ExecutionPlan>>>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             'life4: 'async_trait,
             'life5: 'async_trait,
             'life6: 'async_trait,
             'life7: 'async_trait;

    // Provided method
    fn plan_table_scan<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>(
        &'life0 self,
        _planner: &'life1 dyn PhysicalPlanner,
        _scan: &'life2 TableScan,
        _session: &'life3 dyn Session,
        _planning_ctx: &'life4 PhysicalPlanningContext,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Arc<dyn ExecutionPlan>>>> + Send + 'async_trait>>
       where Self: Sync + 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             'life4: 'async_trait { ... }
}
Expand description

This trait exposes the ability to plan an ExecutionPlan out of a LogicalPlan.

Required Methods§

Source

fn plan_extension<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'life7, 'async_trait>( &'life0 self, planner: &'life1 dyn PhysicalPlanner, node: &'life2 dyn UserDefinedLogicalNode, logical_inputs: &'life3 [&'life4 LogicalPlan], physical_inputs: &'life5 [Arc<dyn ExecutionPlan>], session: &'life6 dyn Session, planning_ctx: &'life7 PhysicalPlanningContext, ) -> Pin<Box<dyn Future<Output = Result<Option<Arc<dyn ExecutionPlan>>>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait, 'life5: 'async_trait, 'life6: 'async_trait, 'life7: 'async_trait,

Create a physical plan for a UserDefinedLogicalNode.

input_dfschema: the logical plan schema for the inputs to this node

Returns an error when the planner knows how to plan the concrete implementation of node but errors while doing so.

Returns None when the planner does not know how to plan the node and wants to delegate the planning to another ExtensionPlanner.

planning_ctx is the PhysicalPlanningContext of the plan subtree currently being converted to a physical plan. Forward it to PhysicalPlanner::create_physical_expr when creating this node’s physical expressions so that scalar subqueries resolve against the same subquery state as the rest of the plan.

Provided Methods§

Source

fn plan_table_scan<'life0, 'life1, 'life2, 'life3, 'life4, 'async_trait>( &'life0 self, _planner: &'life1 dyn PhysicalPlanner, _scan: &'life2 TableScan, _session: &'life3 dyn Session, _planning_ctx: &'life4 PhysicalPlanningContext, ) -> Pin<Box<dyn Future<Output = Result<Option<Arc<dyn ExecutionPlan>>>> + Send + 'async_trait>>
where Self: Sync + 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, 'life4: 'async_trait,

Create a physical plan for a LogicalPlan::TableScan.

This is useful for planning valid TableSources that are not TableProviders.

Returns:

  • Ok(Some(plan)) if the planner knows how to plan the scan
  • Ok(None) if the planner does not know how to plan the scan and wants to delegate the planning to another ExtensionPlanner
  • Err if the planner knows how to plan the scan but errors while doing so
§Example
use std::sync::Arc;
use datafusion::physical_plan::ExecutionPlan;
use datafusion::logical_expr::TableScan;
use datafusion::catalog::Session;
use datafusion::error::Result;
use datafusion_session::{ExtensionPlanner, PhysicalPlanner};
use async_trait::async_trait;

// Your custom table source type
struct MyCustomTableSource { /* ... */ }

// Your custom execution plan
struct MyCustomExec { /* ... */ }

struct MyExtensionPlanner;

#[async_trait]
impl ExtensionPlanner for MyExtensionPlanner {
    async fn plan_extension(
        &self,
        _planner: &dyn PhysicalPlanner,
        _node: &dyn UserDefinedLogicalNode,
        _logical_inputs: &[&LogicalPlan],
        _physical_inputs: &[Arc<dyn ExecutionPlan>],
        _session: &dyn Session,
        _planning_ctx: &PhysicalPlanningContext,
    ) -> Result<Option<Arc<dyn ExecutionPlan>>> {
        Ok(None)
    }

    async fn plan_table_scan(
        &self,
        _planner: &dyn PhysicalPlanner,
        scan: &TableScan,
        _session: &dyn Session,
        _planning_ctx: &PhysicalPlanningContext,
    ) -> Result<Option<Arc<dyn ExecutionPlan>>> {
        // Check if this is your custom table source
        if scan.source.is::<MyCustomTableSource>() {
            // Create a custom execution plan for your table source
            let exec = MyCustomExec::new(
                scan.table_name.clone(),
                Arc::clone(scan.projected_schema.inner()),
            );
            Ok(Some(Arc::new(exec)))
        } else {
            // Return None to let other extension planners handle it
            Ok(None)
        }
    }
}

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§