Path: blob/main/crates/polars-mem-engine/src/executors/executor.rs
6940 views
use super::*;12// Executor are the executors of the physical plan and produce DataFrames. They3// combine physical expressions, which produce Series.45/// Executors will evaluate physical expressions and collect them in a DataFrame.6///7/// Executors have other executors as input. By having a tree of executors we can execute the8/// physical plan until the last executor is evaluated.9pub trait Executor: Send + Sync {10fn execute(&mut self, cache: &mut ExecutionState) -> PolarsResult<DataFrame>;1112fn is_cache_prefiller(&self) -> bool {13false14}15}1617type SinkFn =18Box<dyn FnMut(DataFrame, &mut ExecutionState) -> PolarsResult<Option<DataFrame>> + Send + Sync>;19pub struct SinkExecutor {20pub name: String,21pub input: Box<dyn Executor>,22pub f: SinkFn,23}2425impl Executor for SinkExecutor {26fn execute(&mut self, state: &mut ExecutionState) -> PolarsResult<DataFrame> {27state.should_stop()?;28#[cfg(debug_assertions)]29{30if state.verbose() {31eprintln!("run sink_{}", self.name)32}33}34let df = self.input.execute(state)?;3536let profile_name = if state.has_node_timer() {37Cow::Owned(format!(".sink_{}()", &self.name))38} else {39Cow::Borrowed("")40};4142state.clone().record(43|| (self.f)(df, state).map(|df| df.unwrap_or_else(DataFrame::empty)),44profile_name,45)46}47}4849pub struct Dummy {}50impl Executor for Dummy {51fn execute(&mut self, _cache: &mut ExecutionState) -> PolarsResult<DataFrame> {52panic!("should not get here");53}54}5556impl Default for Box<dyn Executor> {57fn default() -> Self {58Box::new(Dummy {})59}60}616263