From 64d8cda686e796f4348be5ac566bebe99b8b3848 Mon Sep 17 00:00:00 2001 From: Weijun-H Date: Fri, 18 Apr 2025 17:48:07 +0800 Subject: [PATCH] fix: Encoded an array of type Struct([]) --- arrow-row/src/lib.rs | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/arrow-row/src/lib.rs b/arrow-row/src/lib.rs index 3316a1778844..a36d5ff13a06 100644 --- a/arrow-row/src/lib.rs +++ b/arrow-row/src/lib.rs @@ -1236,9 +1236,14 @@ fn row_lengths(cols: &[ArrayRef], encoders: &[Encoder]) -> Vec { Encoder::Struct(rows, null) => { let array = as_struct_array(array); lengths.iter_mut().enumerate().for_each(|(idx, length)| { - match array.is_valid(idx) { - true => *length += 1 + rows.row(idx).as_ref().len(), - false => *length += 1 + null.data.len(), + if array.is_valid(idx) { + // Only calculate row length if there are rows + if rows.num_rows() > 0 { + *length += rows.row(idx).as_ref().len(); + } + *length += 1; + } else { + *length += 1 + null.data.len(); } }); } @@ -1330,9 +1335,18 @@ fn encode_column( .skip(1) .enumerate() .for_each(|(idx, offset)| { - let (row, sentinel) = match array.is_valid(idx) { - true => (rows.row(idx), 0x01), - false => (*null, null_sentinel), + let (row, sentinel) = if array.is_valid(idx) { + let row = if rows.num_rows() == 0 { + Row { + data: &[], + config: &rows.config, + } + } else { + rows.row(idx) + }; + (row, 0x01) + } else { + (*null, null_sentinel) }; let end_offset = *offset + 1 + row.as_ref().len(); data[*offset] = sentinel; @@ -2539,4 +2553,17 @@ mod tests { let rows = converter.convert_columns(&[Arc::new(a) as _]).unwrap(); assert_eq!(rows.row(0).cmp(&rows.row(1)), Ordering::Less); } + + #[test] + fn test_empty_struct() { + let s = Arc::new(StructArray::new_empty_fields(5, None)) as ArrayRef; + + let sort_fields = vec![SortField::new(s.data_type().clone())]; + let converter = RowConverter::new(sort_fields).unwrap(); + let r = converter.convert_columns(&[Arc::clone(&s)]).unwrap(); + + let back = converter.convert_rows(&r).unwrap(); + assert_eq!(back.len(), 1); + assert_eq!(&back[0], &s); + } }