Thanks to visit codestin.com
Credit goes to docs.rs

Skip to main content

ExtensionPlanner

Trait ExtensionPlanner 

Source
pub trait ExtensionPlanner {
    // Required method
    fn plan_extension<'life0, 'life1, 'life2, 'life3, 'life4, 'life5, 'life6, 'async_trait>(
        &'life0 self,
        planner: &'life1 dyn PhysicalPlanner,
        node: &'life2 dyn UserDefinedLogicalNode,
        logical_inputs: &'life3 [&'life4 LogicalPlan],
        physical_inputs: &'life5 [Arc<dyn ExecutionPlan>],
        session_state: &'life6 SessionState,
    ) -> 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;

    // Provided method
    fn plan_table_scan<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        _planner: &'life1 dyn PhysicalPlanner,
        _scan: &'life2 TableScan,
        _session_state: &'life3 SessionState,
    ) -> 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 { ... }
}
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, 'async_trait>( &'life0 self, planner: &'life1 dyn PhysicalPlanner, node: &'life2 dyn UserDefinedLogicalNode, logical_inputs: &'life3 [&'life4 LogicalPlan], physical_inputs: &'life5 [Arc<dyn ExecutionPlan>], session_state: &'life6 SessionState, ) -> 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,

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.

Provided Methods§

Source

fn plan_table_scan<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, _planner: &'life1 dyn PhysicalPlanner, _scan: &'life2 TableScan, _session_state: &'life3 SessionState, ) -> 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,

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::execution::context::SessionState;
use datafusion::error::Result;
use datafusion_physical_planner::{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_state: &SessionState,
    ) -> Result<Option<Arc<dyn ExecutionPlan>>> {
        Ok(None)
    }

    async fn plan_table_scan(
        &self,
        _planner: &dyn PhysicalPlanner,
        scan: &TableScan,
        _session_state: &SessionState,
    ) -> Result<Option<Arc<dyn ExecutionPlan>>> {
        // Check if this is your custom table source
        if scan.source.as_any().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)
        }
    }
}

Implementors§