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 mod human_readable;
22pub use graphviz::*;
23
24use std::{
25 fmt::{self, Display, Formatter},
26 sync::Arc,
27};
28
29/// Represents which type of plan, when storing multiple
30/// for use in EXPLAIN plans
31#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
32pub enum PlanType {
33 /// The initial LogicalPlan provided to DataFusion
34 InitialLogicalPlan,
35 /// The LogicalPlan which results from applying an analyzer pass
36 AnalyzedLogicalPlan {
37 /// The name of the analyzer which produced this plan
38 analyzer_name: String,
39 },
40 /// The LogicalPlan after all analyzer passes have been applied
41 FinalAnalyzedLogicalPlan,
42 /// The LogicalPlan which results from applying an optimizer pass
43 OptimizedLogicalPlan {
44 /// The name of the optimizer which produced this plan
45 optimizer_name: String,
46 },
47 /// The final, fully optimized LogicalPlan that was converted to a physical plan
48 FinalLogicalPlan,
49 /// The initial physical plan, prepared for execution
50 InitialPhysicalPlan,
51 /// The initial physical plan with stats, prepared for execution
52 InitialPhysicalPlanWithStats,
53 /// The initial physical plan with schema, prepared for execution
54 InitialPhysicalPlanWithSchema,
55 /// The ExecutionPlan which results from applying an optimizer pass
56 OptimizedPhysicalPlan {
57 /// The name of the optimizer which produced this plan
58 optimizer_name: String,
59 },
60 /// The final, fully optimized physical plan which would be executed
61 FinalPhysicalPlan,
62 /// The final with stats, fully optimized physical plan which would be executed
63 FinalPhysicalPlanWithStats,
64 /// The final with schema, fully optimized physical plan which would be executed
65 FinalPhysicalPlanWithSchema,
66 /// An error creating the physical plan
67 PhysicalPlanError,
68}
69
70impl Display for PlanType {
71 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
72 match self {
73 PlanType::InitialLogicalPlan => write!(f, "initial_logical_plan"),
74 PlanType::AnalyzedLogicalPlan { analyzer_name } => {
75 write!(f, "logical_plan after {analyzer_name}")
76 }
77 PlanType::FinalAnalyzedLogicalPlan => write!(f, "analyzed_logical_plan"),
78 PlanType::OptimizedLogicalPlan { optimizer_name } => {
79 write!(f, "logical_plan after {optimizer_name}")
80 }
81 PlanType::FinalLogicalPlan => write!(f, "logical_plan"),
82 PlanType::InitialPhysicalPlan => write!(f, "initial_physical_plan"),
83 PlanType::InitialPhysicalPlanWithStats => {
84 write!(f, "initial_physical_plan_with_stats")
85 }
86 PlanType::InitialPhysicalPlanWithSchema => {
87 write!(f, "initial_physical_plan_with_schema")
88 }
89 PlanType::OptimizedPhysicalPlan { optimizer_name } => {
90 write!(f, "physical_plan after {optimizer_name}")
91 }
92 PlanType::FinalPhysicalPlan => write!(f, "physical_plan"),
93 PlanType::FinalPhysicalPlanWithStats => write!(f, "physical_plan_with_stats"),
94 PlanType::FinalPhysicalPlanWithSchema => {
95 write!(f, "physical_plan_with_schema")
96 }
97 PlanType::PhysicalPlanError => write!(f, "physical_plan_error"),
98 }
99 }
100}
101
102/// Represents some sort of execution plan, in String form
103#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
104pub struct StringifiedPlan {
105 /// An identifier of what type of plan this string represents
106 pub plan_type: PlanType,
107 /// The string representation of the plan
108 pub plan: Arc<String>,
109}
110
111impl StringifiedPlan {
112 /// Create a new Stringified plan of `plan_type` with string
113 /// representation `plan`
114 pub fn new(plan_type: PlanType, plan: impl Into<String>) -> Self {
115 StringifiedPlan {
116 plan_type,
117 plan: Arc::new(plan.into()),
118 }
119 }
120
121 /// Returns true if this plan should be displayed. Generally
122 /// `verbose_mode = true` will display all available plans
123 pub fn should_display(&self, verbose_mode: bool) -> bool {
124 match self.plan_type {
125 PlanType::FinalLogicalPlan
126 | PlanType::FinalPhysicalPlan
127 | PlanType::PhysicalPlanError => true,
128 _ => verbose_mode,
129 }
130 }
131}
132
133/// Trait for something that can be formatted as a stringified plan
134pub trait ToStringifiedPlan {
135 /// Create a stringified plan with the specified type
136 fn to_stringified(&self, plan_type: PlanType) -> StringifiedPlan;
137}