vortex_array/expr/analysis/
infallible.rs1use crate::expr::Expression;
5use crate::expr::analysis::BooleanLabels;
6use crate::expr::label_tree;
7
8pub fn label_infallible(expr: &Expression) -> BooleanLabels<'_> {
14 label_tree(
15 expr,
16 |expr| match expr {
17 Expression::Scalar { scalar_fn, .. } => scalar_fn.signature().is_infallible(),
18 Expression::Root => true,
20 },
21 |acc, &child| acc & child,
22 )
23}
24
25#[cfg(test)]
26mod tests {
27 use super::*;
28 use crate::expr::checked_add;
29 use crate::expr::col;
30 use crate::expr::eq;
31 use crate::expr::is_null;
32 use crate::expr::lit;
33 use crate::expr::merge_opts;
34 use crate::expr::not;
35 use crate::scalar_fn::fns::merge::DuplicateHandling;
36
37 #[test]
38 fn not_is_infallible() {
39 let expr = not(col("x"));
40 let labels = label_infallible(&expr);
41 assert_eq!(labels.get(&expr), Some(&true));
42 }
43
44 #[test]
45 fn checked_add_defaults_to_fallible() {
46 let expr = checked_add(col("a"), col("b"));
47 let labels = label_infallible(&expr);
48 assert_eq!(labels.get(&expr), Some(&false));
49 }
50
51 #[test]
52 fn eq_is_infallible() {
53 let expr = eq(col("a"), lit(5));
54 let labels = label_infallible(&expr);
55 assert_eq!(labels.get(&expr), Some(&true));
56 }
57
58 #[test]
59 fn merge_with_error_handling_is_fallible() {
60 let expr = merge_opts([col("a"), col("b")], DuplicateHandling::Error);
61 let labels = label_infallible(&expr);
62 assert_eq!(labels.get(&expr), Some(&false));
63 }
64
65 #[test]
66 fn merge_with_rightmost_handling_is_infallible() {
67 let expr = merge_opts([col("a"), col("b")], DuplicateHandling::RightMost);
68 let labels = label_infallible(&expr);
69 assert_eq!(labels.get(&expr), Some(&true));
70 }
71
72 #[test]
73 fn nested_with_fallible_child() {
74 let child = checked_add(col("a"), col("b"));
75 let expr = not(child.clone());
76 let labels = label_infallible(&expr);
77 assert_eq!(labels.get(&child), Some(&false));
78 assert_eq!(labels.get(&expr), Some(&false));
79 }
80
81 #[test]
82 fn nested_without_fallible_child() {
83 let child = is_null(col("x"));
84 let expr = not(child.clone());
85 let labels = label_infallible(&expr);
86 assert_eq!(labels.get(&child), Some(&true));
87 assert_eq!(labels.get(&expr), Some(&true));
88 }
89}