File tree Expand file tree Collapse file tree
vortex-tensor/src/scalar_fns Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ use std::sync::Arc;
77use std:: sync:: LazyLock ;
88
99use vortex_error:: VortexExpect ;
10+ use vortex_error:: VortexResult ;
1011use vortex_error:: vortex_panic;
1112use vortex_utils:: iter:: ReduceBalancedIterExt ;
1213
@@ -434,6 +435,22 @@ where
434435 iter. into_iter ( ) . reduce_balanced ( and)
435436}
436437
438+ /// The validity of a scalar function whose result is null exactly when any operand is null: the
439+ /// conjunction of its children's validities.
440+ ///
441+ /// This is the `ScalarFnVTable::validity` for kernels that propagate nulls and never produce a
442+ /// null from non-null inputs (comparisons, arithmetic, most geo and tensor ops). Returning it lets
443+ /// the planner derive the output's null mask without executing the kernel. Yields `None` when the
444+ /// expression has no children.
445+ pub fn null_propagating_validity ( expression : & Expression ) -> VortexResult < Option < Expression > > {
446+ let child_validities = expression
447+ . children ( )
448+ . iter ( )
449+ . map ( Expression :: validity)
450+ . collect :: < VortexResult < Vec < _ > > > ( ) ?;
451+ Ok ( and_collect ( child_validities) )
452+ }
453+
437454/// Create a new [`Binary`] using the [`Add`](Operator::Add) operator.
438455///
439456/// ## Example usage
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ use vortex_array::arrays::ScalarFnArray;
1010use vortex_array:: dtype:: DType ;
1111use vortex_array:: dtype:: Nullability ;
1212use vortex_array:: expr:: Expression ;
13+ use vortex_array:: expr:: null_propagating_validity;
1314use vortex_array:: scalar_fn:: Arity ;
1415use vortex_array:: scalar_fn:: ChildName ;
1516use vortex_array:: scalar_fn:: EmptyOptions ;
@@ -22,7 +23,6 @@ use vortex_session::VortexSession;
2223use vortex_session:: registry:: CachedId ;
2324
2425use crate :: extension:: validate_geometry_operands;
25- use crate :: scalar_fn:: null_propagate:: binary_result_validity;
2626use crate :: scalar_fn:: null_propagate:: execute_null_propagating;
2727
2828/// OGC `ST_Contains` between two native geometry operands, each a column or a constant
@@ -93,7 +93,7 @@ impl ScalarFnVTable for GeoContains {
9393 _: & Self :: Options ,
9494 expression : & Expression ,
9595 ) -> VortexResult < Option < Expression > > {
96- binary_result_validity ( expression)
96+ null_propagating_validity ( expression)
9797 }
9898
9999 fn is_null_sensitive ( & self , _: & Self :: Options ) -> bool {
Original file line number Diff line number Diff line change @@ -12,6 +12,7 @@ use vortex_array::dtype::DType;
1212use vortex_array:: dtype:: Nullability ;
1313use vortex_array:: dtype:: PType ;
1414use vortex_array:: expr:: Expression ;
15+ use vortex_array:: expr:: null_propagating_validity;
1516use vortex_array:: scalar_fn:: Arity ;
1617use vortex_array:: scalar_fn:: ChildName ;
1718use vortex_array:: scalar_fn:: EmptyOptions ;
@@ -24,7 +25,6 @@ use vortex_session::VortexSession;
2425use vortex_session:: registry:: CachedId ;
2526
2627use crate :: extension:: validate_geometry_operands;
27- use crate :: scalar_fn:: null_propagate:: binary_result_validity;
2828use crate :: scalar_fn:: null_propagate:: execute_null_propagating;
2929
3030/// Planar (Euclidean) `ST_Distance` (no geodesic correction) between two native geometry
@@ -93,7 +93,7 @@ impl ScalarFnVTable for GeoDistance {
9393 _: & Self :: Options ,
9494 expression : & Expression ,
9595 ) -> VortexResult < Option < Expression > > {
96- binary_result_validity ( expression)
96+ null_propagating_validity ( expression)
9797 }
9898
9999 fn is_null_sensitive ( & self , _: & Self :: Options ) -> bool {
Original file line number Diff line number Diff line change @@ -10,6 +10,7 @@ use vortex_array::arrays::ScalarFnArray;
1010use vortex_array:: dtype:: DType ;
1111use vortex_array:: dtype:: Nullability ;
1212use vortex_array:: expr:: Expression ;
13+ use vortex_array:: expr:: null_propagating_validity;
1314use vortex_array:: scalar_fn:: Arity ;
1415use vortex_array:: scalar_fn:: ChildName ;
1516use vortex_array:: scalar_fn:: EmptyOptions ;
@@ -22,7 +23,6 @@ use vortex_session::VortexSession;
2223use vortex_session:: registry:: CachedId ;
2324
2425use crate :: extension:: validate_geometry_operands;
25- use crate :: scalar_fn:: null_propagate:: binary_result_validity;
2626use crate :: scalar_fn:: null_propagate:: execute_null_propagating;
2727
2828/// OGC `ST_Intersects` (not disjoint; boundary contact counts) between two native geometry
@@ -91,7 +91,7 @@ impl ScalarFnVTable for GeoIntersects {
9191 _: & Self :: Options ,
9292 expression : & Expression ,
9393 ) -> VortexResult < Option < Expression > > {
94- binary_result_validity ( expression)
94+ null_propagating_validity ( expression)
9595 }
9696
9797 fn is_null_sensitive ( & self , _: & Self :: Options ) -> bool {
Original file line number Diff line number Diff line change @@ -19,8 +19,6 @@ use vortex_array::arrays::PrimitiveArray;
1919use vortex_array:: dtype:: DType ;
2020use vortex_array:: dtype:: Nullability ;
2121use vortex_array:: dtype:: PType ;
22- use vortex_array:: expr:: Expression ;
23- use vortex_array:: expr:: and;
2422use vortex_array:: scalar:: Scalar ;
2523use vortex_array:: validity:: Validity ;
2624use vortex_buffer:: BitBuffer ;
@@ -132,16 +130,6 @@ fn all_null_array<T: GeoOutput>(len: usize) -> ArrayRef {
132130 ConstantArray :: new ( Scalar :: null ( T :: null_dtype ( ) ) , len) . into_array ( )
133131}
134132
135- /// The validity expression for a binary geo kernel: the result is null iff either operand is
136- /// null. Returning this lets the planner derive the output's null mask symbolically (mask
137- /// pushdown) instead of executing the whole kernel.
138- pub ( crate ) fn binary_result_validity ( expression : & Expression ) -> VortexResult < Option < Expression > > {
139- Ok ( Some ( and (
140- expression. child ( 0 ) . validity ( ) ?,
141- expression. child ( 1 ) . validity ( ) ?,
142- ) ) )
143- }
144-
145133/// Run a binary geo kernel over operands `a` and `b`, each a column or a constant literal.
146134///
147135/// The output is null wherever either operand is null, and its type is nullable if either operand
Original file line number Diff line number Diff line change @@ -15,7 +15,7 @@ use vortex_array::arrays::scalar_fn::plugin::ScalarFnArrayVTable;
1515use vortex_array:: dtype:: DType ;
1616use vortex_array:: dtype:: Nullability ;
1717use vortex_array:: expr:: Expression ;
18- use vortex_array:: expr:: and ;
18+ use vortex_array:: expr:: null_propagating_validity ;
1919use vortex_array:: match_each_float_ptype;
2020use vortex_array:: scalar_fn:: Arity ;
2121use vortex_array:: scalar_fn:: ChildName ;
@@ -180,10 +180,7 @@ impl ScalarFnVTable for CosineSimilarity {
180180 expression : & Expression ,
181181 ) -> VortexResult < Option < Expression > > {
182182 // The result is null if either input tensor is null.
183- let lhs_validity = expression. child ( 0 ) . validity ( ) ?;
184- let rhs_validity = expression. child ( 1 ) . validity ( ) ?;
185-
186- Ok ( Some ( and ( lhs_validity, rhs_validity) ) )
183+ null_propagating_validity ( expression)
187184 }
188185
189186 fn is_null_sensitive ( & self , _options : & Self :: Options ) -> bool {
Original file line number Diff line number Diff line change @@ -18,7 +18,7 @@ use vortex_array::dtype::DType;
1818use vortex_array:: dtype:: NativePType ;
1919use vortex_array:: dtype:: Nullability ;
2020use vortex_array:: expr:: Expression ;
21- use vortex_array:: expr:: and ;
21+ use vortex_array:: expr:: null_propagating_validity ;
2222use vortex_array:: match_each_float_ptype;
2323use vortex_array:: scalar_fn:: Arity ;
2424use vortex_array:: scalar_fn:: ChildName ;
@@ -164,10 +164,7 @@ impl ScalarFnVTable for InnerProduct {
164164 expression : & Expression ,
165165 ) -> VortexResult < Option < Expression > > {
166166 // The result is null if either input tensor is null.
167- let lhs_validity = expression. child ( 0 ) . validity ( ) ?;
168- let rhs_validity = expression. child ( 1 ) . validity ( ) ?;
169-
170- Ok ( Some ( and ( lhs_validity, rhs_validity) ) )
167+ null_propagating_validity ( expression)
171168 }
172169
173170 fn is_null_sensitive ( & self , _options : & Self :: Options ) -> bool {
Original file line number Diff line number Diff line change @@ -31,7 +31,7 @@ use vortex_array::dtype::NativePType;
3131use vortex_array:: dtype:: Nullability ;
3232use vortex_array:: dtype:: proto:: dtype as pb;
3333use vortex_array:: expr:: Expression ;
34- use vortex_array:: expr:: and ;
34+ use vortex_array:: expr:: null_propagating_validity ;
3535use vortex_array:: match_each_float_ptype;
3636use vortex_array:: scalar:: Scalar ;
3737use vortex_array:: scalar:: ScalarValue ;
@@ -256,10 +256,7 @@ impl ScalarFnVTable for L2Denorm {
256256 _options : & Self :: Options ,
257257 expression : & Expression ,
258258 ) -> VortexResult < Option < Expression > > {
259- let normalized_validity = expression. child ( 0 ) . validity ( ) ?;
260- let norms_validity = expression. child ( 1 ) . validity ( ) ?;
261-
262- Ok ( Some ( and ( normalized_validity, norms_validity) ) )
259+ null_propagating_validity ( expression)
263260 }
264261
265262 fn is_null_sensitive ( & self , _options : & Self :: Options ) -> bool {
Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ use vortex_array::dtype::NativePType;
2525use vortex_array:: dtype:: Nullability ;
2626use vortex_array:: dtype:: proto:: dtype as pb;
2727use vortex_array:: expr:: Expression ;
28+ use vortex_array:: expr:: null_propagating_validity;
2829use vortex_array:: match_each_float_ptype;
2930use vortex_array:: scalar:: Scalar ;
3031use vortex_array:: scalar_fn:: Arity ;
@@ -184,7 +185,7 @@ impl ScalarFnVTable for L2Norm {
184185 expression : & Expression ,
185186 ) -> VortexResult < Option < Expression > > {
186187 // The result is null if the input tensor is null.
187- Ok ( Some ( expression. child ( 0 ) . validity ( ) ? ) )
188+ null_propagating_validity ( expression)
188189 }
189190
190191 fn is_null_sensitive ( & self , _options : & Self :: Options ) -> bool {
You can’t perform that action at this time.
0 commit comments