11use vortex_error:: { VortexExpect , VortexResult } ;
22
3+ use crate :: Array ;
34use crate :: arrays:: { ChunkedArray , ChunkedEncoding } ;
45use crate :: compute:: { IsConstantFn , IsConstantOpts , is_constant_opts, scalar_at} ;
56
@@ -9,7 +10,7 @@ impl IsConstantFn<&ChunkedArray> for ChunkedEncoding {
910 array : & ChunkedArray ,
1011 opts : & IsConstantOpts ,
1112 ) -> VortexResult < Option < bool > > {
12- let mut chunks = array. chunks ( ) . iter ( ) ;
13+ let mut chunks = array. chunks ( ) . iter ( ) . skip_while ( |c| c . is_empty ( ) ) ;
1314
1415 let first_chunk = chunks. next ( ) . vortex_expect ( "Must have at least one value" ) ;
1516
@@ -20,6 +21,10 @@ impl IsConstantFn<&ChunkedArray> for ChunkedEncoding {
2021 let first_value = scalar_at ( first_chunk, 0 ) ?. into_nullable ( ) ;
2122
2223 for chunk in chunks {
24+ if chunk. is_empty ( ) {
25+ continue ;
26+ }
27+
2328 if !is_constant_opts ( chunk, opts) ? {
2429 return Ok ( Some ( false ) ) ;
2530 }
@@ -32,3 +37,30 @@ impl IsConstantFn<&ChunkedArray> for ChunkedEncoding {
3237 Ok ( Some ( true ) )
3338 }
3439}
40+
41+ #[ cfg( test) ]
42+ mod tests {
43+ use vortex_buffer:: { Buffer , buffer} ;
44+ use vortex_dtype:: { DType , Nullability , PType } ;
45+
46+ use crate :: arrays:: ChunkedArray ;
47+ use crate :: { Array , IntoArray } ;
48+
49+ #[ test]
50+ fn empty_chunk_is_constant ( ) {
51+ let chunked = ChunkedArray :: try_new (
52+ vec ! [
53+ Buffer :: <u8 >:: empty( ) . into_array( ) ,
54+ Buffer :: <u8 >:: empty( ) . into_array( ) ,
55+ buffer![ 255u8 , 255 ] . into_array( ) ,
56+ Buffer :: <u8 >:: empty( ) . into_array( ) ,
57+ buffer![ 255u8 , 255 ] . into_array( ) ,
58+ ] ,
59+ DType :: Primitive ( PType :: U8 , Nullability :: NonNullable ) ,
60+ )
61+ . unwrap ( )
62+ . into_array ( ) ;
63+
64+ assert ! ( chunked. statistics( ) . compute_is_constant( ) . unwrap( ) ) ;
65+ }
66+ }
0 commit comments