risingwave_expr_impl/scalar/
array_contain.rs1use std::collections::HashSet;
18
19use risingwave_common::types::ListRef;
20use risingwave_expr::function;
21
22fn array_contains_impl(left: ListRef<'_>, right: ListRef<'_>) -> bool {
93 let flatten = left.flatten();
94 let set: HashSet<_> = flatten.iter().collect();
95 right
96 .flatten()
97 .iter()
98 .all(|item| item.is_some_and(|v| set.contains(&Some(v))))
99}
100
101#[function("array_contains(anyarray, anyarray) -> boolean")]
102fn array_contains(left: ListRef<'_>, right: ListRef<'_>) -> bool {
103 array_contains_impl(left, right)
104}
105
106#[function("array_contained(anyarray, anyarray) -> boolean")]
107fn array_contained(left: ListRef<'_>, right: ListRef<'_>) -> bool {
108 array_contains_impl(right, left)
109}
110
111fn array_overlaps_impl(left: ListRef<'_>, right: ListRef<'_>) -> bool {
112 let flatten = left.flatten();
113 let set: HashSet<_> = flatten.iter().flatten().collect();
114 right
115 .flatten()
116 .iter()
117 .any(|item| item.is_some_and(|v| set.contains(&v)))
118}
119
120#[function("array_overlaps(anyarray, anyarray) -> boolean")]
121fn array_overlaps(left: ListRef<'_>, right: ListRef<'_>) -> bool {
122 array_overlaps_impl(left, right)
123}
124
125#[cfg(test)]
126mod tests {
127 use risingwave_common::types::{DataType, ListValue, Scalar, ScalarImpl};
128
129 use super::*;
130
131 #[test]
132 fn test_contains() {
133 assert!(array_contains_impl(
134 ListValue::from_iter([2, 3]).as_scalar_ref(),
135 ListValue::from_iter([2]).as_scalar_ref(),
136 ));
137 assert!(!array_contains_impl(
138 ListValue::from_iter([2, 3]).as_scalar_ref(),
139 ListValue::from_iter([5]).as_scalar_ref(),
140 ));
141 }
142
143 #[test]
144 fn test_overlaps() {
145 assert!(array_overlaps_impl(
146 ListValue::from_iter([2, 3]).as_scalar_ref(),
147 ListValue::from_iter([3, 5]).as_scalar_ref(),
148 ));
149 assert!(!array_overlaps_impl(
150 ListValue::from_iter([2, 3]).as_scalar_ref(),
151 ListValue::from_iter([4, 5]).as_scalar_ref(),
152 ));
153 assert!(!array_overlaps_impl(
154 ListValue::from_datum_iter(
155 &DataType::Int32,
156 [Some(ScalarImpl::Int32(1)), None::<ScalarImpl>],
157 )
158 .as_scalar_ref(),
159 ListValue::from_datum_iter(
160 &DataType::Int32,
161 [None::<ScalarImpl>, Some(ScalarImpl::Int32(2))],
162 )
163 .as_scalar_ref(),
164 ));
165 assert!(!array_overlaps_impl(
166 ListValue::from_datum_iter(&DataType::Int32, [None::<ScalarImpl>]).as_scalar_ref(),
167 ListValue::from_datum_iter(&DataType::Int32, [None::<ScalarImpl>]).as_scalar_ref(),
168 ));
169 }
170}