11use fsst:: Symbol ;
2- use vortex_array:: array:: ConstantArray ;
3- use vortex_array:: compute:: { compare, CompareFn , Operator } ;
4- use vortex_array:: { Array , IntoArrayVariant } ;
2+ use vortex_array:: array:: { BoolArray , BooleanBuffer , ConstantArray } ;
3+ use vortex_array:: compute:: { compare, compare_lengths_to_empty, CompareFn , Operator } ;
4+ use vortex_array:: variants:: PrimitiveArrayTrait ;
5+ use vortex_array:: { Array , IntoArray , IntoArrayVariant , IntoCanonical } ;
56use vortex_buffer:: ByteBuffer ;
6- use vortex_dtype:: DType ;
7- use vortex_error:: { VortexExpect , VortexResult } ;
7+ use vortex_dtype:: { match_each_native_ptype , DType } ;
8+ use vortex_error:: { vortex_bail , VortexExpect , VortexResult } ;
89
910use crate :: { FSSTArray , FSSTEncoding } ;
1011
@@ -15,26 +16,61 @@ impl CompareFn<FSSTArray> for FSSTEncoding {
1516 rhs : & Array ,
1617 operator : Operator ,
1718 ) -> VortexResult < Option < Array > > {
18- match ( rhs. as_constant ( ) , operator) {
19- ( Some ( constant) , Operator :: Eq | Operator :: NotEq ) => compare_fsst_constant (
20- lhs,
21- & ConstantArray :: new ( constant, lhs. len ( ) ) ,
22- operator == Operator :: Eq ,
23- )
24- . map ( Some ) ,
19+ match rhs. as_constant ( ) {
20+ Some ( constant) => {
21+ compare_fsst_constant ( lhs, & ConstantArray :: new ( constant, lhs. len ( ) ) , operator)
22+ }
2523 // Otherwise, fall back to the default comparison behavior.
2624 _ => Ok ( None ) ,
2725 }
2826 }
2927}
3028
31- /// Specialized compare function implementation used when performing equals or not equals against
32- /// a constant.
29+ /// Specialized compare function implementation used when performing against a constant
3330fn compare_fsst_constant (
3431 left : & FSSTArray ,
3532 right : & ConstantArray ,
36- equal : bool ,
37- ) -> VortexResult < Array > {
33+ operator : Operator ,
34+ ) -> VortexResult < Option < Array > > {
35+ let rhs_scalar = right. scalar ( ) ;
36+ let is_rhs_empty = match rhs_scalar. dtype ( ) {
37+ DType :: Binary ( _) => rhs_scalar
38+ . as_binary ( )
39+ . is_empty ( )
40+ . vortex_expect ( "RHS should not be null" ) ,
41+ DType :: Utf8 ( _) => rhs_scalar
42+ . as_utf8 ( )
43+ . is_empty ( )
44+ . vortex_expect ( "RHS should not be null" ) ,
45+ _ => vortex_bail ! ( "VarBinArray can only have type of Binary or Utf8" ) ,
46+ } ;
47+ if is_rhs_empty {
48+ let buffer = match operator {
49+ // Every possible value is gte ""
50+ Operator :: Gte => BooleanBuffer :: new_set ( left. len ( ) ) ,
51+ // No value is lt ""
52+ Operator :: Lt => BooleanBuffer :: new_unset ( left. len ( ) ) ,
53+ _ => {
54+ let uncompressed_lengths = left
55+ . uncompressed_lengths ( )
56+ . into_canonical ( ) ?
57+ . into_primitive ( ) ?;
58+ match_each_native_ptype ! ( uncompressed_lengths. ptype( ) , |$P | {
59+ compare_lengths_to_empty( uncompressed_lengths. as_slice:: <$P >( ) . iter( ) . copied( ) , operator)
60+ } )
61+ }
62+ } ;
63+
64+ return Ok ( Some (
65+ BoolArray :: try_new ( buffer, left. validity ( ) ) ?. into_array ( ) ,
66+ ) ) ;
67+ }
68+
69+ // The following section only supports Eq/NotEq
70+ if !matches ! ( operator, Operator :: Eq | Operator :: NotEq ) {
71+ return Ok ( None ) ;
72+ }
73+
3874 let symbols = left. symbols ( ) . into_primitive ( ) ?;
3975 let symbols_u64 = symbols. as_slice :: < u64 > ( ) ;
4076
@@ -68,11 +104,7 @@ fn compare_fsst_constant(
68104 } ;
69105
70106 let rhs = ConstantArray :: new ( encoded_scalar, left. len ( ) ) ;
71- compare (
72- left. codes ( ) ,
73- rhs,
74- if equal { Operator :: Eq } else { Operator :: NotEq } ,
75- )
107+ compare ( left. codes ( ) , rhs, operator) . map ( Some )
76108}
77109
78110#[ cfg( test) ]
0 commit comments