1use std::collections::BTreeMap;
18use std::sync::Arc;
19
20use mz_compute_types::dataflows::DataflowDescription;
21use mz_expr::explain::ExplainContext;
22use mz_repr::GlobalId;
23use mz_repr::explain::{Explain, ExplainConfig, ExplainError, ExplainFormat, ExprHumanizer};
24use mz_repr::optimize::OptimizerFeatures;
25use mz_transform::dataflow::DataflowMetainfo;
26use mz_transform::notice::OptimizerNotice;
27
28use crate::AdapterError;
29
30pub(crate) mod fast_path;
31pub(crate) mod hir;
32pub(crate) mod insights;
33pub(crate) mod lir;
34pub(crate) mod mir;
35pub(crate) mod optimizer_trace;
36
37pub(crate) struct Explainable<'a, T>(&'a mut T);
40
41impl<'a, T> Explainable<'a, T> {
42 pub(crate) fn new(t: &'a mut T) -> Explainable<'a, T> {
43 Explainable(t)
44 }
45}
46
47pub(crate) fn explain_dataflow<T, O>(
51 mut plan: DataflowDescription<T, (), O>,
52 format: ExplainFormat,
53 config: &ExplainConfig,
54 features: &OptimizerFeatures,
55 humanizer: &dyn ExprHumanizer,
56 cardinality_stats: BTreeMap<GlobalId, usize>,
57 target_cluster: Option<&str>,
58 dataflow_metainfo: &DataflowMetainfo<Arc<OptimizerNotice>>,
59) -> Result<String, AdapterError>
60where
61 for<'a> Explainable<'a, DataflowDescription<T, (), O>>:
62 Explain<'a, Context = ExplainContext<'a>>,
63{
64 let used_indexes = dataflow_metainfo.used_indexes(&plan);
66
67 let optimizer_notices = OptimizerNotice::explain(
68 &dataflow_metainfo.optimizer_notices,
69 humanizer,
70 config.redacted,
71 )
72 .map_err(ExplainError::FormatError)?;
73
74 let context = ExplainContext {
75 config,
76 features,
77 humanizer,
78 cardinality_stats,
79 used_indexes,
80 finishing: Default::default(),
81 duration: Default::default(),
82 target_cluster,
83 optimizer_notices,
84 };
85
86 Ok(Explainable::new(&mut plan).explain(&format, &context)?)
87}
88
89pub(crate) fn explain_plan<T>(
97 mut plan: T,
98 format: ExplainFormat,
99 config: &ExplainConfig,
100 features: &OptimizerFeatures,
101 humanizer: &dyn ExprHumanizer,
102 cardinality_stats: BTreeMap<GlobalId, usize>,
103 target_cluster: Option<&str>,
104) -> Result<String, AdapterError>
105where
106 for<'a> Explainable<'a, T>: Explain<'a, Context = ExplainContext<'a>>,
107{
108 let context = ExplainContext {
109 config,
110 features,
111 humanizer,
112 cardinality_stats,
113 used_indexes: Default::default(),
114 finishing: Default::default(),
115 duration: Default::default(),
116 target_cluster,
117 optimizer_notices: Default::default(),
118 };
119
120 Ok(Explainable::new(&mut plan).explain(&format, &context)?)
121}