Skip to main content

mz_expr/scalar/
columns.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//! Generic interface for scalar expressions that hold columns.
11
12use std::collections::{BTreeMap, BTreeSet};
13
14pub trait Columns: Sized {
15    /// Construct a column reference expression.
16    fn column(c: usize) -> Self;
17
18    /// True when the outermost structure is a column.
19    fn is_column(&self) -> bool;
20
21    /// If self is a column, return the column index, otherwise `None`.
22    fn as_column(&self) -> Option<usize>;
23
24    /// If self is a column, return a mutable reference to the column index.
25    fn as_column_mut(&mut self) -> Option<&mut usize>;
26
27    /// The support of the given set, i.e., the columns that are actually used.
28    ///
29    /// You can use `BTreeSet::last()` to extract the maximum column.
30    fn support(&self) -> BTreeSet<usize> {
31        let mut support = BTreeSet::new();
32        self.support_into(&mut support);
33        support
34    }
35
36    /// Adds the support of the given set, i.e., the columns that are actually used,
37    /// to the given set.
38    fn support_into(&self, support: &mut BTreeSet<usize>);
39
40    /// Rewrites column indices with their value in `permutation`.
41    ///
42    /// This method is applicable even when `permutation` is not a
43    /// strict permutation, and it only needs to have entries for
44    /// each column referenced in `self`.
45    fn permute(&mut self, permutation: &[usize]) {
46        self.visit_columns(|c| *c = permutation[*c]);
47    }
48
49    /// Rewrites column indices with their value in `permutation`.
50    ///
51    /// This method is applicable even when `permutation` is not a
52    /// strict permutation, and it only needs to have entries for
53    /// each column referenced in `self`.
54    fn permute_map(&mut self, permutation: &BTreeMap<usize, usize>) {
55        self.visit_columns(|c| *c = permutation[c]);
56    }
57
58    /// Visits each column reference and applies `action` to the column.
59    ///
60    /// Useful for remapping columns, or for collecting expression support.
61    fn visit_columns<F>(&mut self, action: F)
62    where
63        F: FnMut(&mut usize);
64}