datafusion_distributed/events/
worker_plan_rewrite.rs1use super::common::EventHandlerChain;
2use datafusion::error::Result;
3use datafusion::execution::config::SessionConfig;
4use datafusion::physical_plan::ExecutionPlan;
5use std::sync::Arc;
6
7pub struct WorkerPlanRewriteEvent<'a> {
9 pub plan: Arc<dyn ExecutionPlan>,
11 pub session_config: &'a SessionConfig,
13}
14
15pub struct WorkerPlanRewriteEventResponse {
17 pub plan: Arc<dyn ExecutionPlan>,
20}
21
22impl WorkerPlanRewriteEventResponse {
23 pub fn new(plan: Arc<dyn ExecutionPlan>) -> Self {
25 Self { plan }
26 }
27}
28
29pub trait WorkerPlanRewriteHandler: Send + Sync + 'static {
34 fn rewrite_worker_plan(
36 &self,
37 ev: WorkerPlanRewriteEvent,
38 ) -> Result<WorkerPlanRewriteEventResponse>;
39}
40
41impl<F> WorkerPlanRewriteHandler for F
42where
43 F: Send + Sync + 'static,
44 F: for<'a> Fn(WorkerPlanRewriteEvent<'a>) -> Result<WorkerPlanRewriteEventResponse>,
45{
46 fn rewrite_worker_plan(
47 &self,
48 ev: WorkerPlanRewriteEvent,
49 ) -> Result<WorkerPlanRewriteEventResponse> {
50 self(ev)
51 }
52}
53
54impl WorkerPlanRewriteHandler for Arc<dyn WorkerPlanRewriteHandler> {
55 fn rewrite_worker_plan(
56 &self,
57 ev: WorkerPlanRewriteEvent,
58 ) -> Result<WorkerPlanRewriteEventResponse> {
59 self.as_ref().rewrite_worker_plan(ev)
60 }
61}
62
63pub(crate) type WorkerPlanRewriteHandlers = EventHandlerChain<dyn WorkerPlanRewriteHandler>;
64
65impl WorkerPlanRewriteHandlers {
66 pub(crate) fn handle(ev: WorkerPlanRewriteEvent) -> Result<WorkerPlanRewriteEventResponse> {
67 let WorkerPlanRewriteEvent {
68 plan,
69 session_config,
70 } = ev;
71 let plan = match session_config.get_extension::<WorkerPlanRewriteHandlers>() {
72 Some(handlers) => handlers.try_fold(plan, |plan, handler| {
73 handler
74 .rewrite_worker_plan(WorkerPlanRewriteEvent {
75 plan,
76 session_config,
77 })
78 .map(|response| response.plan)
79 })?,
80 None => plan,
81 };
82 Ok(WorkerPlanRewriteEventResponse::new(plan))
83 }
84}