@@ -205,13 +205,13 @@ fn write_optional_index<W: Write + ?Sized>(
205205}
206206
207207#[ derive( Debug , Clone ) ]
208- enum NullState {
208+ enum NullState < ' a > {
209209 NonNullable ,
210210 NullableNoNulls {
211211 union_value_byte : u8 ,
212212 } ,
213213 Nullable {
214- nulls : NullBuffer ,
214+ nulls : & ' a NullBuffer ,
215215 null_order : Nullability ,
216216 } ,
217217}
@@ -221,7 +221,7 @@ enum NullState {
221221/// - Carries the per-site nullability **state** as a single enum that enforces invariants
222222pub ( crate ) struct FieldEncoder < ' a > {
223223 encoder : Encoder < ' a > ,
224- null_state : NullState ,
224+ null_state : NullState < ' a > ,
225225}
226226
227227impl < ' a > FieldEncoder < ' a > {
@@ -617,16 +617,15 @@ impl<'a> FieldEncoder<'a> {
617617 // Compute the effective null state from writer-declared nullability and data nulls.
618618 let null_state = match nullability {
619619 None => NullState :: NonNullable ,
620- Some ( order) => {
621- if let Some ( nulls) = array. nulls ( ) . cloned ( ) {
622- NullState :: Nullable {
623- nulls,
624- null_order : order,
625- }
620+ Some ( null_order) => {
621+ if array. null_count ( ) > 0
622+ && let Some ( nulls) = array. nulls ( )
623+ {
624+ NullState :: Nullable { nulls, null_order }
626625 } else {
627626 // Nullable site with no null buffer for this view
628627 NullState :: NullableNoNulls {
629- union_value_byte : union_value_branch_byte ( order , false ) ,
628+ union_value_byte : union_value_branch_byte ( null_order , false ) ,
630629 }
631630 }
632631 }
@@ -3025,4 +3024,26 @@ mod tests {
30253024 expected. extend ( avro_long_bytes ( 30 ) ) ;
30263025 assert_bytes_eq ( & got, & expected) ;
30273026 }
3027+
3028+ #[ test]
3029+ fn nullable_state_with_null_buffer_and_zero_nulls ( ) {
3030+ let values = vec ! [ 1i32 , 2 , 3 ] ;
3031+ let arr = Int32Array :: from_iter_values_with_nulls (
3032+ values. into_iter ( ) ,
3033+ Some ( NullBuffer :: new_valid ( 3 ) ) ,
3034+ ) ;
3035+ assert_eq ! ( arr. null_count( ) , 0 ) ;
3036+ assert ! ( arr. nulls( ) . is_some( ) ) ;
3037+ let plan = FieldPlan :: Scalar ;
3038+ let enc = FieldEncoder :: make_encoder ( & arr, & plan, Some ( Nullability :: NullFirst ) ) . unwrap ( ) ;
3039+ match enc. null_state {
3040+ NullState :: NullableNoNulls { union_value_byte } => {
3041+ assert_eq ! (
3042+ union_value_byte,
3043+ union_value_branch_byte( Nullability :: NullFirst , false )
3044+ ) ;
3045+ }
3046+ other => panic ! ( "expected NullableNoNulls, got {other:?}" ) ,
3047+ }
3048+ }
30283049}
0 commit comments