MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / enforce_linear_chains

Function enforce_linear_chains

src/expr/src/explain.rs:223–279  ·  view source on GitHub ↗

Normalize the way inputs of multi-input variants are rendered. After the transform is applied, non-trival inputs `$input` of variants with more than one input are wrapped in a `let $x = $input in $x` blocks. If these blocks are subsequently pulled up by `NormalizeLets`, the rendered version of the resulting tree will only have linear chains.

(expr: &mut MirRelationExpr)

Source from the content-addressed store, hash-verified

221/// If these blocks are subsequently pulled up by `NormalizeLets`,
222/// the rendered version of the resulting tree will only have linear chains.
223pub fn enforce_linear_chains(expr: &mut MirRelationExpr) -> Result<(), ExplainError> {
224 use MirRelationExpr::{Constant, Get, Join, Union};
225
226 if expr.is_recursive() {
227 // `linear_chains` is not implemented for WMR, see
228 // https://github.com/MaterializeInc/database-issues/issues/5631
229 return Err(LinearChainsPlusRecursive);
230 }
231
232 // helper struct: a generator of fresh local ids
233 let mut id_gen = id_gen(expr).peekable();
234
235 let mut wrap_in_let = |input: &mut MirRelationExpr| {
236 match input {
237 Constant { .. } | Get { .. } => (),
238 input => {
239 // generate fresh local id
240 // let id = id_cnt
241 // .next()
242 // .map(|id| LocalId::new(1000_u64 + u64::cast_from(id_map.len()) + id))
243 // .unwrap();
244 let id = id_gen.next().unwrap();
245 let value = input.take_safely(None);
246 // generate a `let $fresh_id = $body in $fresh_id` to replace this input
247 let mut binding = MirRelationExpr::Let {
248 id,
249 value: Box::new(value),
250 body: Box::new(Get {
251 id: Id::Local(id.clone()),
252 typ: input.typ(),
253 access_strategy: AccessStrategy::UnknownOrLocal,
254 }),
255 };
256 // swap the current body with the replacement
257 std::mem::swap(input, &mut binding);
258 }
259 }
260 };
261
262 expr.try_visit_mut_post(&mut |expr: &mut MirRelationExpr| {
263 match expr {
264 Join { inputs, .. } => {
265 for input in inputs {
266 wrap_in_let(input);
267 }
268 }
269 Union { base, inputs } => {
270 wrap_in_let(base);
271 for input in inputs {
272 wrap_in_let(input);
273 }
274 }
275 _ => (),
276 }
277 Ok(())
278 })
279}
280

Callers 6

as_explain_multi_planMethod · 0.85
as_explain_multi_planMethod · 0.85
handle_explainFunction · 0.85

Calls 8

unwrapMethod · 0.80
take_safelyMethod · 0.80
try_visit_mut_postMethod · 0.80
id_genFunction · 0.70
is_recursiveMethod · 0.45
nextMethod · 0.45
cloneMethod · 0.45
typMethod · 0.45

Tested by 2

handle_explainFunction · 0.68