mz_transform/cse/
relation_cse.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//! Identifies common relation subexpressions and places them behind `Let` bindings.
11//!
12//! All structurally equivalent expressions, defined recursively as having structurally
13//! equivalent inputs, and identical parameters, will be placed behind `Let` bindings.
14//! The resulting expressions likely have an excess of `Let` expressions, and therefore
15//! we automatically run the `NormalizeLets` transformation to remove those that are not necessary.
16
17use mz_expr::MirRelationExpr;
18
19use crate::TransformCtx;
20use crate::normalize_lets::NormalizeLets;
21
22use super::anf::ANF;
23
24/// Identifies common relation subexpressions and places them behind `Let` bindings.
25#[derive(Debug)]
26pub struct RelationCSE {
27    anf: ANF,
28    normalize_lets: NormalizeLets,
29}
30
31impl RelationCSE {
32    /// Constructs a new [`RelationCSE`] instance.
33    ///
34    /// Also communicates its argument to let normalization.
35    pub fn new(inline_mfp: bool) -> RelationCSE {
36        RelationCSE {
37            anf: ANF::default(),
38            normalize_lets: NormalizeLets::new(inline_mfp),
39        }
40    }
41}
42
43impl crate::Transform for RelationCSE {
44    fn name(&self) -> &'static str {
45        "RelationCSE"
46    }
47
48    #[mz_ore::instrument(
49        target = "optimizer",
50        level = "debug",
51        fields(path.segment = "relation_cse")
52    )]
53    fn actually_perform_transform(
54        &self,
55        rel: &mut MirRelationExpr,
56        ctx: &mut TransformCtx,
57    ) -> Result<(), crate::TransformError> {
58        // Run ANF.
59        self.anf.transform_without_trace(rel)?;
60
61        // Run NormalizeLets.
62        self.normalize_lets.action(rel, ctx.features)?;
63
64        // Record the result and return.
65        mz_repr::explain::trace_plan(&*rel);
66        Ok(())
67    }
68}