@@ -15,6 +15,7 @@ use vortex_array::Precision;
1515use vortex_array:: ProstMetadata ;
1616use vortex_array:: SerializeMetadata ;
1717use vortex_array:: arrays:: PrimitiveVTable ;
18+ use vortex_array:: arrays:: VarBinViewArray ;
1819use vortex_array:: buffer:: BufferHandle ;
1920use vortex_array:: dtype:: DType ;
2021use vortex_array:: dtype:: Nullability ;
@@ -39,6 +40,7 @@ use vortex_session::VortexSession;
3940
4041use crate :: compress:: runend_decode_bools;
4142use crate :: compress:: runend_decode_primitive;
43+ use crate :: compress:: runend_decode_varbinview;
4244use crate :: compress:: runend_encode;
4345use crate :: kernel:: PARENT_KERNELS ;
4446use crate :: rules:: RULES ;
@@ -239,12 +241,6 @@ impl RunEndArray {
239241 "run ends must be unsigned integers, was {}" ,
240242 ends. dtype( ) ,
241243 ) ;
242- vortex_ensure ! (
243- values. dtype( ) . is_primitive( ) || values. dtype( ) . is_boolean( ) ,
244- "RunEnd array can only have Bool or Primitive values, {} given" ,
245- values. dtype( )
246- ) ;
247-
248244 vortex_ensure ! (
249245 ends. len( ) == values. len( ) ,
250246 "run ends len != run values len, {} != {}" ,
@@ -342,32 +338,7 @@ impl RunEndArray {
342338 ///
343339 /// # Validation
344340 ///
345- /// The `ends` must be non-nullable unsigned integers. The values may be `Bool` or `Primitive`
346- /// types.
347- ///
348- /// # Examples
349- ///
350- /// ```
351- /// # use vortex_array::arrays::{BoolArray, VarBinViewArray};
352- /// # use vortex_array::IntoArray;
353- /// # use vortex_buffer::buffer;
354- /// # use vortex_runend::RunEndArray;
355- ///
356- /// // Error to provide incorrectly-typed values!
357- /// let result = RunEndArray::try_new(
358- /// buffer![1u8, 2u8].into_array(),
359- /// VarBinViewArray::from_iter_str(["bad", "dtype"]).into_array(),
360- /// );
361- /// assert!(result.is_err());
362- ///
363- /// // This array is happy
364- /// let result = RunEndArray::try_new(
365- /// buffer![1u8, 2u8].into_array(),
366- /// BoolArray::from_iter([false, true]).into_array(),
367- /// );
368- ///
369- /// assert!(result.is_ok());
370- /// ```
341+ /// The `ends` must be non-nullable unsigned integers.
371342 pub fn try_new ( ends : ArrayRef , values : ArrayRef ) -> VortexResult < Self > {
372343 let length: usize = if ends. is_empty ( ) {
373344 0
@@ -510,6 +481,7 @@ pub(super) fn run_end_canonicalize(
510481 ctx : & mut ExecutionCtx ,
511482) -> VortexResult < ArrayRef > {
512483 let pends = array. ends ( ) . clone ( ) . execute_as ( "ends" , ctx) ?;
484+
513485 Ok ( match array. dtype ( ) {
514486 DType :: Bool ( _) => {
515487 let bools = array. values ( ) . clone ( ) . execute_as ( "values" , ctx) ?;
@@ -519,13 +491,22 @@ pub(super) fn run_end_canonicalize(
519491 let pvalues = array. values ( ) . clone ( ) . execute_as ( "values" , ctx) ?;
520492 runend_decode_primitive ( pends, pvalues, array. offset ( ) , array. len ( ) ) ?. into_array ( )
521493 }
522- _ => vortex_panic ! ( "Only Primitive and Bool values are supported" ) ,
494+ DType :: Utf8 ( _) | DType :: Binary ( _) => {
495+ let values = array
496+ . values ( )
497+ . clone ( )
498+ . execute_as :: < VarBinViewArray > ( "values" , ctx) ?;
499+ runend_decode_varbinview ( pends, values, array. offset ( ) , array. len ( ) ) ?. into_array ( )
500+ }
501+ _ => vortex_bail ! ( "Unsupported RunEnd value type: {}" , array. dtype( ) ) ,
523502 } )
524503}
525504
526505#[ cfg( test) ]
527506mod tests {
528507 use vortex_array:: IntoArray ;
508+ use vortex_array:: arrays:: DictArray ;
509+ use vortex_array:: arrays:: VarBinViewArray ;
529510 use vortex_array:: assert_arrays_eq;
530511 use vortex_array:: dtype:: DType ;
531512 use vortex_array:: dtype:: Nullability ;
@@ -552,4 +533,33 @@ mod tests {
552533 let expected = buffer ! [ 1 , 1 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 ] . into_array ( ) ;
553534 assert_arrays_eq ! ( arr. into_array( ) , expected) ;
554535 }
536+
537+ #[ test]
538+ fn test_runend_utf8 ( ) {
539+ let values = VarBinViewArray :: from_iter_str ( [ "a" , "b" , "c" ] ) . into_array ( ) ;
540+ let arr = RunEndArray :: new ( buffer ! [ 2u32 , 5 , 10 ] . into_array ( ) , values) ;
541+ assert_eq ! ( arr. len( ) , 10 ) ;
542+ assert_eq ! ( arr. dtype( ) , & DType :: Utf8 ( Nullability :: NonNullable ) ) ;
543+
544+ let expected =
545+ VarBinViewArray :: from_iter_str ( [ "a" , "a" , "b" , "b" , "b" , "c" , "c" , "c" , "c" , "c" ] )
546+ . into_array ( ) ;
547+ assert_arrays_eq ! ( arr. into_array( ) , expected) ;
548+ }
549+
550+ #[ test]
551+ fn test_runend_dict ( ) {
552+ let dict_values = VarBinViewArray :: from_iter_str ( [ "x" , "y" , "z" ] ) . into_array ( ) ;
553+ let dict_codes = buffer ! [ 0u32 , 1 , 2 ] . into_array ( ) ;
554+ let dict = DictArray :: try_new ( dict_codes, dict_values) . unwrap ( ) ;
555+
556+ let arr =
557+ RunEndArray :: try_new ( buffer ! [ 2u32 , 5 , 10 ] . into_array ( ) , dict. into_array ( ) ) . unwrap ( ) ;
558+ assert_eq ! ( arr. len( ) , 10 ) ;
559+
560+ let expected =
561+ VarBinViewArray :: from_iter_str ( [ "x" , "x" , "y" , "y" , "y" , "z" , "z" , "z" , "z" , "z" ] )
562+ . into_array ( ) ;
563+ assert_arrays_eq ! ( arr. into_array( ) , expected) ;
564+ }
555565}
0 commit comments