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}