diff --git a/arrow-json/src/reader/list_array.rs b/arrow-json/src/reader/list_array.rs index d363b6be978..32e57bb52fa 100644 --- a/arrow-json/src/reader/list_array.rs +++ b/arrow-json/src/reader/list_array.rs @@ -17,10 +17,10 @@ use crate::reader::tape::{Tape, TapeElement}; use crate::reader::{ArrayDecoder, DecoderContext}; -use arrow_array::OffsetSizeTrait; use arrow_array::builder::{BooleanBufferBuilder, BufferBuilder}; -use arrow_buffer::buffer::NullBuffer; -use arrow_data::{ArrayData, ArrayDataBuilder}; +use arrow_array::{Array, GenericListArray, OffsetSizeTrait, make_array}; +use arrow_buffer::{OffsetBuffer, ScalarBuffer, buffer::NullBuffer}; +use arrow_data::ArrayData; use arrow_schema::{ArrowError, DataType}; use std::marker::PhantomData; @@ -91,17 +91,17 @@ impl ArrayDecoder for ListArrayDecoder { offsets.append(offset) } - let child_data = self.decoder.decode(tape, &child_pos)?; + let field = match &self.data_type { + DataType::List(f) | DataType::LargeList(f) => f.clone(), + _ => unreachable!(), + }; + // SAFETY: offsets are built monotonically starting from 0 + let offsets = + unsafe { OffsetBuffer::::new_unchecked(ScalarBuffer::from(offsets.finish())) }; + let values = make_array(self.decoder.decode(tape, &child_pos)?); let nulls = nulls.as_mut().map(|x| NullBuffer::new(x.finish())); - let data = ArrayDataBuilder::new(self.data_type.clone()) - .len(pos.len()) - .nulls(nulls) - .add_buffer(offsets.finish()) - .child_data(vec![child_data]); - - // Safety - // Validated lengths above - Ok(unsafe { data.build_unchecked() }) + let array = GenericListArray::::try_new(field, offsets, values, nulls)?; + Ok(array.into_data()) } }