@@ -3,6 +3,7 @@ use std::fmt::Debug;
33use vortex_array:: arrays:: ConstantArray ;
44use vortex_array:: compute:: { CompareFn , Operator , compare} ;
55use vortex_array:: { Array , ArrayRef } ;
6+ use vortex_dtype:: NativePType ;
67use vortex_error:: { VortexResult , vortex_bail} ;
78use vortex_scalar:: { PrimitiveScalar , Scalar } ;
89
@@ -74,27 +75,50 @@ where
7475 // Since this value is not encodable it cannot be equal to any value in the encoded
7576 // array, hence != to all values in the encoded array.
7677 Operator :: NotEq => Ok ( Some ( ConstantArray :: new ( true , alp. len ( ) ) . into_array ( ) ) ) ,
77- Operator :: Gt | Operator :: Gte => Ok ( Some ( compare (
78- alp. encoded ( ) ,
79- & ConstantArray :: new ( F :: encode_above ( value, exponents) , alp. len ( ) ) ,
80- // Since the encoded value is unencodable gte is equivalent to gt.
81- // Consider a value v, between two encodable values v_l (just less) and
82- // v_a (just above), then for all encodable values (u), v > u <=> v_g >= u
83- Operator :: Gte ,
84- ) ?) ) ,
85- Operator :: Lt | Operator :: Lte => Ok ( Some ( compare (
86- alp. encoded ( ) ,
87- & ConstantArray :: new ( F :: encode_below ( value, exponents) , alp. len ( ) ) ,
88- // Since the encoded values unencodable lt is equivalent to lte.
89- // See Gt | Gte for further explanation.
90- Operator :: Lte ,
91- ) ?) ) ,
78+ Operator :: Gt | Operator :: Gte => {
79+ // Per IEEE 754 totalOrder semantics the ordering is -Nan < -Inf < Inf < Nan.
80+ // All values in the encoded array are definitely finite
81+ let is_not_finite = value. is_infinite ( ) || NativePType :: is_nan ( value) ;
82+ if is_not_finite {
83+ Ok ( Some (
84+ ConstantArray :: new ( value. is_sign_negative ( ) , alp. len ( ) ) . into_array ( ) ,
85+ ) )
86+ } else {
87+ Ok ( Some ( compare (
88+ alp. encoded ( ) ,
89+ & ConstantArray :: new ( F :: encode_above ( value, exponents) , alp. len ( ) ) ,
90+ // Since the encoded value is unencodable gte is equivalent to gt.
91+ // Consider a value v, between two encodable values v_l (just less) and
92+ // v_a (just above), then for all encodable values (u), v > u <=> v_g >= u
93+ Operator :: Gte ,
94+ ) ?) )
95+ }
96+ }
97+ Operator :: Lt | Operator :: Lte => {
98+ // Per IEEE 754 totalOrder semantics the ordering is -Nan < -Inf < Inf < Nan.
99+ // All values in the encoded array are definitely finite
100+ let is_not_finite = value. is_infinite ( ) || NativePType :: is_nan ( value) ;
101+ if is_not_finite {
102+ Ok ( Some (
103+ ConstantArray :: new ( value. is_sign_positive ( ) , alp. len ( ) ) . into_array ( ) ,
104+ ) )
105+ } else {
106+ Ok ( Some ( compare (
107+ alp. encoded ( ) ,
108+ & ConstantArray :: new ( F :: encode_below ( value, exponents) , alp. len ( ) ) ,
109+ // Since the encoded values unencodable lt is equivalent to lte.
110+ // See Gt | Gte for further explanation.
111+ Operator :: Lte ,
112+ ) ?) )
113+ }
114+ }
92115 } ,
93116 }
94117}
95118
96119#[ cfg( test) ]
97120mod tests {
121+ use rstest:: rstest;
98122 use vortex_array:: ToCanonical ;
99123 use vortex_array:: arrays:: { ConstantArray , PrimitiveArray } ;
100124 use vortex_array:: compute:: { Operator , compare} ;
@@ -274,7 +298,7 @@ mod tests {
274298
275299 #[ test]
276300 fn compare_to_null ( ) {
277- let array = PrimitiveArray :: from_iter ( [ 1.234f32 ; 1025 ] ) ;
301+ let array = PrimitiveArray :: from_iter ( [ 1.234f32 ; 10 ] ) ;
278302 let encoded = alp_encode ( & array) . unwrap ( ) ;
279303
280304 let other = ConstantArray :: new (
@@ -291,4 +315,32 @@ mod tests {
291315 assert ! ( !v) ;
292316 }
293317 }
318+
319+ #[ rstest]
320+ #[ case( f32 :: NAN , false ) ]
321+ #[ case( -1.0f32 / 0.0f32 , true ) ]
322+ #[ case( f32 :: INFINITY , false ) ]
323+ #[ case( f32 :: NEG_INFINITY , true ) ]
324+ fn compare_to_non_finite_gt ( #[ case] value : f32 , #[ case] result : bool ) {
325+ let array = PrimitiveArray :: from_iter ( [ 1.234f32 ; 10 ] ) ;
326+ let encoded = alp_encode ( & array) . unwrap ( ) ;
327+
328+ let gte = test_alp_compare ( & encoded, value, Operator :: Gt ) . unwrap ( ) ;
329+
330+ assert_eq ! ( gte, [ result; 10 ] ) ;
331+ }
332+
333+ #[ rstest]
334+ #[ case( f32 :: NAN , true ) ]
335+ #[ case( -1.0f32 / 0.0f32 , false ) ]
336+ #[ case( f32 :: INFINITY , true ) ]
337+ #[ case( f32 :: NEG_INFINITY , false ) ]
338+ fn compare_to_non_finite_lt ( #[ case] value : f32 , #[ case] result : bool ) {
339+ let array = PrimitiveArray :: from_iter ( [ 1.234f32 ; 10 ] ) ;
340+ let encoded = alp_encode ( & array) . unwrap ( ) ;
341+
342+ let lt = test_alp_compare ( & encoded, value, Operator :: Lt ) . unwrap ( ) ;
343+
344+ assert_eq ! ( lt, [ result; 10 ] ) ;
345+ }
294346}
0 commit comments