mz_transform/fusion/map.rs
1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10//! Fuses a sequence of `Map` operators in to one `Map` operator.
11//!
12//! This transform introduces the complexity that max expressions can
13//! refer to the results of prior map expressions. This is an important
14//! detail that is often overlooked and leads to bugs. However, it is
15//! important to coalesce these operators so that we can more easily
16//! move them around other operators together.
17//!
18//! Also removes empty `Map` operators.
19
20use std::mem;
21
22use mz_expr::MirRelationExpr;
23
24use crate::TransformCtx;
25
26/// Fuses a sequence of `Map` operators in to one `Map` operator.
27#[derive(Debug)]
28pub struct Map;
29
30impl crate::Transform for Map {
31 fn name(&self) -> &'static str {
32 "MapFusion"
33 }
34
35 #[mz_ore::instrument(
36 target = "optimizer",
37 level = "debug",
38 fields(path.segment = "map_fusion")
39 )]
40 fn actually_perform_transform(
41 &self,
42 relation: &mut MirRelationExpr,
43 _: &mut TransformCtx,
44 ) -> Result<(), crate::TransformError> {
45 relation.visit_pre_mut(Self::action);
46 mz_repr::explain::trace_plan(&*relation);
47 Ok(())
48 }
49}
50
51impl Map {
52 /// Fuses a sequence of `Map` operators into one `Map` operator.
53 /// Remove the map operator if it is empty.
54 pub fn action(relation: &mut MirRelationExpr) {
55 if let MirRelationExpr::Map { input, scalars } = relation {
56 while let MirRelationExpr::Map {
57 input: inner_input,
58 scalars: inner_scalars,
59 } = &mut **input
60 {
61 inner_scalars.append(scalars);
62 mem::swap(scalars, inner_scalars);
63 **input = inner_input.take_dangerous();
64 }
65
66 if scalars.is_empty() {
67 *relation = input.take_dangerous();
68 }
69 }
70 }
71}