Skip to main content

vortex_array/expr/analysis/
strict.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use super::BooleanLabels;
5use super::labeling::label_tree;
6use crate::expr::Expression;
7
8/// Label each expression with whether its entire subtree is strict.
9///
10/// A subtree is strict only when the node's scalar function and every child subtree are strict.
11/// See [`crate::scalar_fn::ScalarFnVTable::is_strict`] for the scalar-function contract.
12pub fn label_strict(expr: &Expression) -> BooleanLabels<'_> {
13    label_tree(
14        expr,
15        |expr| expr.signature().is_strict(),
16        |acc, &child| acc & child,
17    )
18}
19
20#[cfg(test)]
21mod tests {
22    use super::*;
23    use crate::expr::col;
24    use crate::expr::eq;
25    use crate::expr::is_null;
26    use crate::expr::lit;
27
28    #[test]
29    fn test_non_strict_with_is_null() {
30        let expr = is_null(col("col1"));
31        let labels = label_strict(&expr);
32
33        assert_eq!(labels.get(&expr), Some(&false));
34    }
35
36    #[test]
37    fn test_strict_expression() {
38        let expr = eq(lit(4), lit(5));
39        let labels = label_strict(&expr);
40
41        assert_eq!(labels.get(&expr), Some(&true));
42    }
43
44    #[test]
45    fn test_non_strict_child_makes_parent_subtree_non_strict() {
46        let left = eq(lit(4), lit(5));
47        let right = is_null(col("col2"));
48        let expr = eq(left.clone(), right.clone());
49
50        let labels = label_strict(&expr);
51
52        assert_eq!(labels.get(&left), Some(&true));
53        assert_eq!(labels.get(&right), Some(&false));
54        assert_eq!(labels.get(&expr), Some(&false));
55    }
56}