8
8
// by the Apache License, Version 2.0.
9
9
10
10
//! `EXPLAIN` support for MIR structures.
11
-
12
- use std:: collections:: BTreeMap ;
11
+ //!
12
+ //! The specialized [`Explain`] implementation for an [`MirRelationExpr`]
13
+ //! wrapped in an [`Explainable`] newtype struct allows us to interpret more
14
+ //! [`ExplainConfig`] options. This is the case because attribute derivation and
15
+ //! let normalization are defined in [`mz_transform`] and conssequently are not
16
+ //! available for the default [`Explain`] implementation for [`MirRelationExpr`]
17
+ //! in [`mz_expr`].
13
18
14
19
use mz_compute_client:: types:: dataflows:: DataflowDescription ;
15
- use mz_expr:: {
16
- explain_new:: { enforce_linear_chains, ExplainContext , ExplainMultiPlan , ExplainSinglePlan } ,
17
- visit:: Visit ,
18
- MirRelationExpr , OptimizedMirRelationExpr ,
19
- } ;
20
- use mz_ore:: { stack:: RecursionLimitError , str:: bracketed, str:: separated} ;
21
- use mz_repr:: explain_new:: {
22
- AnnotatedPlan , Attributes , Explain , ExplainConfig , ExplainError , UnsupportedFormat ,
23
- } ;
24
- use mz_transform:: attribute:: {
25
- Arity , DerivedAttributes , NonNegative , RelationType , SubtreeSize , UniqueKeys ,
20
+ use mz_expr:: explain:: {
21
+ enforce_linear_chains, ExplainContext , ExplainMultiPlan , ExplainSinglePlan ,
26
22
} ;
23
+ use mz_expr:: { MirRelationExpr , OptimizedMirRelationExpr } ;
24
+ use mz_repr:: explain:: { Explain , ExplainConfig , ExplainError , UnsupportedFormat } ;
25
+ use mz_transform:: attribute:: annotate_plan;
26
+ use mz_transform:: normalize_lets:: normalize_lets;
27
27
28
28
use super :: Explainable ;
29
29
@@ -68,12 +68,13 @@ impl<'a> Explainable<'a, MirRelationExpr> {
68
68
// normalize the representation of nested Let bindings
69
69
// and enforce sequential Let binding IDs
70
70
if !config. raw_plans {
71
- mz_transform:: normalize_lets:: normalize_lets ( self . 0 )
72
- . map_err ( |e| ExplainError :: UnknownError ( e. to_string ( ) ) ) ?;
71
+ normalize_lets ( self . 0 ) . map_err ( |e| ExplainError :: UnknownError ( e. to_string ( ) ) ) ?;
73
72
}
74
73
75
- let plan = try_from ( context, self . 0 ) ?;
76
- Ok ( ExplainSinglePlan { context, plan } )
74
+ Ok ( ExplainSinglePlan {
75
+ context,
76
+ plan : annotate_plan ( self . 0 , context) ?,
77
+ } )
77
78
}
78
79
}
79
80
@@ -115,25 +116,26 @@ impl<'a> Explainable<'a, DataflowDescription<OptimizedMirRelationExpr>> {
115
116
. iter_mut ( )
116
117
. rev ( )
117
118
. map ( |build_desc| {
119
+ let plan = build_desc. plan . as_inner_mut ( ) ;
120
+
118
121
// normalize the representation as linear chains
119
122
// (this implies !config.raw_plans by construction)
120
123
if config. linear_chains {
121
- enforce_linear_chains ( build_desc . plan . as_inner_mut ( ) ) ?;
124
+ enforce_linear_chains ( plan) ?;
122
125
} ;
123
126
// unless raw plans are explicitly requested
124
127
// normalize the representation of nested Let bindings
125
128
// and enforce sequential Let binding IDs
126
129
if !config. raw_plans {
127
- mz_transform:: normalize_lets:: normalize_lets ( build_desc. plan . as_inner_mut ( ) )
128
- . map_err ( |e| ExplainError :: UnknownError ( e. to_string ( ) ) ) ?;
130
+ normalize_lets ( plan) . map_err ( |e| ExplainError :: UnknownError ( e. to_string ( ) ) ) ?;
129
131
}
130
132
131
133
let id = context
132
134
. humanizer
133
135
. humanize_id ( build_desc. id )
134
136
. unwrap_or_else ( || build_desc. id . to_string ( ) ) ;
135
- let plan = try_from ( context , build_desc . plan . as_inner ( ) ) ? ;
136
- Ok ( ( id, plan) )
137
+
138
+ Ok ( ( id, annotate_plan ( plan, context ) ? ) )
137
139
} )
138
140
. collect :: < Result < Vec < _ > , ExplainError > > ( ) ?;
139
141
@@ -159,79 +161,3 @@ impl<'a> Explainable<'a, DataflowDescription<OptimizedMirRelationExpr>> {
159
161
} )
160
162
}
161
163
}
162
-
163
- fn try_from < ' a > (
164
- context : & ' a ExplainContext ,
165
- plan : & ' a MirRelationExpr ,
166
- ) -> Result < AnnotatedPlan < ' a , MirRelationExpr > , RecursionLimitError > {
167
- let mut annotations = BTreeMap :: < & MirRelationExpr , Attributes > :: default ( ) ;
168
- let config = context. config ;
169
-
170
- if config. requires_attributes ( ) {
171
- // get the annotation keys
172
- let subtree_refs = plan. post_order_vec ( ) ;
173
- // get the annotation values
174
- let mut explain_attrs = DerivedAttributes :: from ( config) ;
175
- plan. visit ( & mut explain_attrs) ?;
176
-
177
- if config. subtree_size {
178
- for ( expr, attr) in std:: iter:: zip (
179
- subtree_refs. iter ( ) ,
180
- explain_attrs. remove_results :: < SubtreeSize > ( ) . into_iter ( ) ,
181
- ) {
182
- let attrs = annotations. entry ( expr) . or_default ( ) ;
183
- attrs. subtree_size = Some ( attr) ;
184
- }
185
- }
186
- if config. non_negative {
187
- for ( expr, attr) in std:: iter:: zip (
188
- subtree_refs. iter ( ) ,
189
- explain_attrs. remove_results :: < NonNegative > ( ) . into_iter ( ) ,
190
- ) {
191
- let attrs = annotations. entry ( expr) . or_default ( ) ;
192
- attrs. non_negative = Some ( attr) ;
193
- }
194
- }
195
-
196
- if config. arity {
197
- for ( expr, attr) in std:: iter:: zip (
198
- subtree_refs. iter ( ) ,
199
- explain_attrs. remove_results :: < Arity > ( ) . into_iter ( ) ,
200
- ) {
201
- let attrs = annotations. entry ( expr) . or_default ( ) ;
202
- attrs. arity = Some ( attr) ;
203
- }
204
- }
205
-
206
- if config. types {
207
- for ( expr, types) in std:: iter:: zip (
208
- subtree_refs. iter ( ) ,
209
- explain_attrs. remove_results :: < RelationType > ( ) . into_iter ( ) ,
210
- ) {
211
- let humanized_columns = types
212
- . into_iter ( )
213
- . map ( |c| context. humanizer . humanize_column_type ( & c) )
214
- . collect :: < Vec < _ > > ( ) ;
215
- let attr = bracketed ( "(" , ")" , separated ( ", " , humanized_columns) ) . to_string ( ) ;
216
- let attrs = annotations. entry ( expr) . or_default ( ) ;
217
- attrs. types = Some ( attr) ;
218
- }
219
- }
220
-
221
- if config. keys {
222
- for ( expr, keys) in std:: iter:: zip (
223
- subtree_refs. iter ( ) ,
224
- explain_attrs. remove_results :: < UniqueKeys > ( ) . into_iter ( ) ,
225
- ) {
226
- let formatted_keys = keys
227
- . into_iter ( )
228
- . map ( |key_set| bracketed ( "[" , "]" , separated ( ", " , key_set) ) . to_string ( ) ) ;
229
- let attr = bracketed ( "(" , ")" , separated ( ", " , formatted_keys) ) . to_string ( ) ;
230
- let attrs = annotations. entry ( expr) . or_default ( ) ;
231
- attrs. keys = Some ( attr) ;
232
- }
233
- }
234
- }
235
-
236
- Ok ( AnnotatedPlan { plan, annotations } )
237
- }
0 commit comments