Coverage Report

Created: 2024-10-13 08:39

/Users/andrewlamb/Software/datafusion/datafusion/common/src/display/mod.rs
Line
Count
Source (jump to first uncovered line)
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
20
mod graphviz;
21
pub use graphviz::*;
22
23
use 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)]
31
pub 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
}
66
67
impl Display for PlanType {
68
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
69
        match self {
70
            PlanType::InitialLogicalPlan => write!(f, "initial_logical_plan"),
71
            PlanType::AnalyzedLogicalPlan { analyzer_name } => {
72
                write!(f, "logical_plan after {analyzer_name}")
73
            }
74
            PlanType::FinalAnalyzedLogicalPlan => write!(f, "analyzed_logical_plan"),
75
            PlanType::OptimizedLogicalPlan { optimizer_name } => {
76
                write!(f, "logical_plan after {optimizer_name}")
77
            }
78
            PlanType::FinalLogicalPlan => write!(f, "logical_plan"),
79
            PlanType::InitialPhysicalPlan => write!(f, "initial_physical_plan"),
80
            PlanType::InitialPhysicalPlanWithStats => {
81
                write!(f, "initial_physical_plan_with_stats")
82
            }
83
            PlanType::InitialPhysicalPlanWithSchema => {
84
                write!(f, "initial_physical_plan_with_schema")
85
            }
86
            PlanType::OptimizedPhysicalPlan { optimizer_name } => {
87
                write!(f, "physical_plan after {optimizer_name}")
88
            }
89
            PlanType::FinalPhysicalPlan => write!(f, "physical_plan"),
90
            PlanType::FinalPhysicalPlanWithStats => write!(f, "physical_plan_with_stats"),
91
            PlanType::FinalPhysicalPlanWithSchema => {
92
                write!(f, "physical_plan_with_schema")
93
            }
94
        }
95
    }
96
}
97
98
/// Represents some sort of execution plan, in String form
99
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Hash)]
100
pub struct StringifiedPlan {
101
    /// An identifier of what type of plan this string represents
102
    pub plan_type: PlanType,
103
    /// The string representation of the plan
104
    pub plan: Arc<String>,
105
}
106
107
impl StringifiedPlan {
108
    /// Create a new Stringified plan of `plan_type` with string
109
    /// representation `plan`
110
0
    pub fn new(plan_type: PlanType, plan: impl Into<String>) -> Self {
111
0
        StringifiedPlan {
112
0
            plan_type,
113
0
            plan: Arc::new(plan.into()),
114
0
        }
115
0
    }
116
117
    /// Returns true if this plan should be displayed. Generally
118
    /// `verbose_mode = true` will display all available plans
119
    pub fn should_display(&self, verbose_mode: bool) -> bool {
120
        match self.plan_type {
121
            PlanType::FinalLogicalPlan | PlanType::FinalPhysicalPlan => true,
122
            _ => verbose_mode,
123
        }
124
    }
125
}
126
127
/// Trait for something that can be formatted as a stringified plan
128
pub trait ToStringifiedPlan {
129
    /// Create a stringified plan with the specified type
130
    fn to_stringified(&self, plan_type: PlanType) -> StringifiedPlan;
131
}