datafusion_common/display/
mod.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18//! Types for plan display
19
20mod graphviz;
21pub use graphviz::*;
22
23use std::{
24    fmt::{self, Display, Formatter},
25    sync::Arc,
26};
27
28/// Represents which type of plan, when storing multiple
29/// for use in EXPLAIN plans
30#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
31pub enum PlanType {
32    /// The initial LogicalPlan provided to DataFusion
33    InitialLogicalPlan,
34    /// The LogicalPlan which results from applying an analyzer pass
35    AnalyzedLogicalPlan {
36        /// The name of the analyzer which produced this plan
37        analyzer_name: String,
38    },
39    /// The LogicalPlan after all analyzer passes have been applied
40    FinalAnalyzedLogicalPlan,
41    /// The LogicalPlan which results from applying an optimizer pass
42    OptimizedLogicalPlan {
43        /// The name of the optimizer which produced this plan
44        optimizer_name: String,
45    },
46    /// The final, fully optimized LogicalPlan that was converted to a physical plan
47    FinalLogicalPlan,
48    /// The initial physical plan, prepared for execution
49    InitialPhysicalPlan,
50    /// The initial physical plan with stats, prepared for execution
51    InitialPhysicalPlanWithStats,
52    /// The initial physical plan with schema, prepared for execution
53    InitialPhysicalPlanWithSchema,
54    /// The ExecutionPlan which results from applying an optimizer pass
55    OptimizedPhysicalPlan {
56        /// The name of the optimizer which produced this plan
57        optimizer_name: String,
58    },
59    /// The final, fully optimized physical plan which would be executed
60    FinalPhysicalPlan,
61    /// The final with stats, fully optimized physical plan which would be executed
62    FinalPhysicalPlanWithStats,
63    /// The final with schema, fully optimized physical plan which would be executed
64    FinalPhysicalPlanWithSchema,
65    /// An error creating the physical plan
66    PhysicalPlanError,
67}
68
69impl Display for PlanType {
70    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
71        match self {
72            PlanType::InitialLogicalPlan => write!(f, "initial_logical_plan"),
73            PlanType::AnalyzedLogicalPlan { analyzer_name } => {
74                write!(f, "logical_plan after {analyzer_name}")
75            }
76            PlanType::FinalAnalyzedLogicalPlan => write!(f, "analyzed_logical_plan"),
77            PlanType::OptimizedLogicalPlan { optimizer_name } => {
78                write!(f, "logical_plan after {optimizer_name}")
79            }
80            PlanType::FinalLogicalPlan => write!(f, "logical_plan"),
81            PlanType::InitialPhysicalPlan => write!(f, "initial_physical_plan"),
82            PlanType::InitialPhysicalPlanWithStats => {
83                write!(f, "initial_physical_plan_with_stats")
84            }
85            PlanType::InitialPhysicalPlanWithSchema => {
86                write!(f, "initial_physical_plan_with_schema")
87            }
88            PlanType::OptimizedPhysicalPlan { optimizer_name } => {
89                write!(f, "physical_plan after {optimizer_name}")
90            }
91            PlanType::FinalPhysicalPlan => write!(f, "physical_plan"),
92            PlanType::FinalPhysicalPlanWithStats => write!(f, "physical_plan_with_stats"),
93            PlanType::FinalPhysicalPlanWithSchema => {
94                write!(f, "physical_plan_with_schema")
95            }
96            PlanType::PhysicalPlanError => write!(f, "physical_plan_error"),
97        }
98    }
99}
100
101/// Represents some sort of execution plan, in String form
102#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
103pub struct StringifiedPlan {
104    /// An identifier of what type of plan this string represents
105    pub plan_type: PlanType,
106    /// The string representation of the plan
107    pub plan: Arc<String>,
108}
109
110impl StringifiedPlan {
111    /// Create a new Stringified plan of `plan_type` with string
112    /// representation `plan`
113    pub fn new(plan_type: PlanType, plan: impl Into<String>) -> Self {
114        StringifiedPlan {
115            plan_type,
116            plan: Arc::new(plan.into()),
117        }
118    }
119
120    /// Returns true if this plan should be displayed. Generally
121    /// `verbose_mode = true` will display all available plans
122    pub fn should_display(&self, verbose_mode: bool) -> bool {
123        match self.plan_type {
124            PlanType::FinalLogicalPlan
125            | PlanType::FinalPhysicalPlan
126            | PlanType::PhysicalPlanError => true,
127            _ => verbose_mode,
128        }
129    }
130}
131
132/// Trait for something that can be formatted as a stringified plan
133pub trait ToStringifiedPlan {
134    /// Create a stringified plan with the specified type
135    fn to_stringified(&self, plan_type: PlanType) -> StringifiedPlan;
136}