mz_compute_types/
explain.rs1pub(crate) mod text;
13
14use std::collections::BTreeMap;
15
16use mz_expr::explain::{ExplainContext, ExplainMultiPlan, ExplainSource, enforce_linear_chains};
17use mz_expr::{MirRelationExpr, OptimizedMirRelationExpr};
18use mz_repr::GlobalId;
19use mz_repr::explain::{AnnotatedPlan, Explain, ExplainError, UnsupportedFormat};
20
21use crate::dataflows::DataflowDescription;
22use crate::plan::Plan;
23
24impl<'a> Explain<'a> for DataflowDescription<Plan> {
25 type Context = ExplainContext<'a>;
26
27 type Text = ExplainMultiPlan<'a, Plan>;
28
29 type Json = ExplainMultiPlan<'a, Plan>;
30
31 type Dot = UnsupportedFormat;
32
33 fn explain_text(&'a mut self, context: &'a Self::Context) -> Result<Self::Text, ExplainError> {
34 self.as_explain_multi_plan(context)
35 }
36
37 fn explain_json(&'a mut self, context: &'a Self::Context) -> Result<Self::Text, ExplainError> {
38 self.as_explain_multi_plan(context)
39 }
40}
41
42impl<'a> DataflowDescription<Plan> {
43 fn as_explain_multi_plan(
44 &'a mut self,
45 context: &'a ExplainContext<'a>,
46 ) -> Result<ExplainMultiPlan<'a, Plan>, ExplainError> {
47 let export_ids = export_ids_for(self);
48 let plans = self
49 .objects_to_build
50 .iter_mut()
51 .rev()
52 .map(|build_desc| {
53 let public_id = export_ids
54 .get(&build_desc.id)
55 .unwrap_or(&build_desc.id)
56 .clone();
57 let id = context
58 .humanizer
59 .humanize_id(public_id)
60 .unwrap_or_else(|| public_id.to_string());
61 let plan = AnnotatedPlan {
62 plan: &build_desc.plan,
63 annotations: BTreeMap::default(),
64 };
65 (id, plan)
66 })
67 .collect::<Vec<_>>();
68
69 let sources = self
70 .source_imports
71 .iter_mut()
72 .map(|(id, (source_desc, _, _upper))| {
73 let op = source_desc.arguments.operators.as_ref();
74 ExplainSource::new(*id, op, context.config.filter_pushdown)
75 })
76 .collect::<Vec<_>>();
77
78 Ok(ExplainMultiPlan {
79 context,
80 sources,
81 plans,
82 })
83 }
84}
85
86impl<'a> Explain<'a> for DataflowDescription<OptimizedMirRelationExpr> {
87 type Context = ExplainContext<'a>;
88
89 type Text = ExplainMultiPlan<'a, MirRelationExpr>;
90
91 type Json = ExplainMultiPlan<'a, MirRelationExpr>;
92
93 type Dot = UnsupportedFormat;
94
95 fn explain_text(&'a mut self, context: &'a Self::Context) -> Result<Self::Text, ExplainError> {
96 self.as_explain_multi_plan(context)
97 }
98
99 fn explain_json(&'a mut self, context: &'a Self::Context) -> Result<Self::Text, ExplainError> {
100 self.as_explain_multi_plan(context)
101 }
102}
103
104impl<'a> DataflowDescription<OptimizedMirRelationExpr> {
105 fn as_explain_multi_plan(
106 &'a mut self,
107 context: &'a ExplainContext<'a>,
108 ) -> Result<ExplainMultiPlan<'a, MirRelationExpr>, ExplainError> {
109 let export_ids = export_ids_for(self);
110 let plans = self
111 .objects_to_build
112 .iter_mut()
113 .rev()
114 .map(|build_desc| {
115 if context.config.linear_chains {
118 enforce_linear_chains(build_desc.plan.as_inner_mut())?;
119 };
120
121 let id = export_ids
122 .get(&build_desc.id)
123 .unwrap_or(&build_desc.id)
124 .clone();
125 let id = context
126 .humanizer
127 .humanize_id(id)
128 .unwrap_or_else(|| id.to_string());
129 let plan = AnnotatedPlan {
130 plan: build_desc.plan.as_inner(),
131 annotations: BTreeMap::default(),
132 };
133 Ok((id, plan))
134 })
135 .collect::<Result<Vec<_>, ExplainError>>()?;
136
137 let sources = self
138 .source_imports
139 .iter_mut()
140 .map(|(id, (source_desc, _, _upper))| {
141 let op = source_desc.arguments.operators.as_ref();
142 ExplainSource::new(*id, op, context.config.filter_pushdown)
143 })
144 .collect::<Vec<_>>();
145
146 Ok(ExplainMultiPlan {
147 context,
148 sources,
149 plans,
150 })
151 }
152}
153
154pub fn export_ids_for<P, S, T>(dd: &DataflowDescription<P, S, T>) -> BTreeMap<GlobalId, GlobalId> {
156 let mut map = BTreeMap::<GlobalId, GlobalId>::default();
157
158 if dd.sink_exports.len() == 1 && dd.objects_to_build.len() == 1 && dd.index_exports.is_empty() {
170 for (public_id, export) in dd.sink_exports.iter() {
171 map.insert(export.from, *public_id);
172 }
173 }
174
175 map
194}