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}