Skip to content

Commit 3b662b4

Browse files
committed
Support GenericListViewArray::new_unchecked and refactor ListView json decoder
1 parent ca331b5 commit 3b662b4

2 files changed

Lines changed: 39 additions & 17 deletions

File tree

arrow-array/src/array/list_view_array.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,34 @@ impl<OffsetSize: OffsetSizeTrait> GenericListViewArray<OffsetSize> {
223223
Self::try_new(field, offsets, sizes, values, nulls).unwrap()
224224
}
225225

226+
/// Create a new [`GenericListViewArray`] from the provided parts without validation
227+
///
228+
/// See [`Self::try_new`] for the checked version of this function, and the
229+
/// documentation of that function for the invariants that must be upheld.
230+
///
231+
/// # Safety
232+
///
233+
/// Safe if [`Self::new`] would not panic with the given arguments
234+
pub unsafe fn new_unchecked(
235+
field: FieldRef,
236+
offsets: ScalarBuffer<OffsetSize>,
237+
sizes: ScalarBuffer<OffsetSize>,
238+
values: ArrayRef,
239+
nulls: Option<NullBuffer>,
240+
) -> Self {
241+
if cfg!(feature = "force_validate") {
242+
return Self::new(field, offsets, sizes, values, nulls);
243+
}
244+
245+
Self {
246+
data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
247+
nulls,
248+
values,
249+
value_offsets: offsets,
250+
value_sizes: sizes,
251+
}
252+
}
253+
226254
/// Create a new [`GenericListViewArray`] of length `len` where all values are null
227255
pub fn new_null(field: FieldRef, len: usize) -> Self {
228256
let values = new_empty_array(field.data_type());

arrow-json/src/reader/list_array.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ use std::marker::PhantomData;
1919
use std::sync::Arc;
2020

2121
use arrow_array::builder::BooleanBufferBuilder;
22-
use arrow_array::{ArrayRef, GenericListArray, OffsetSizeTrait, make_array};
22+
use arrow_array::{ArrayRef, GenericListArray, GenericListViewArray, OffsetSizeTrait};
2323
use arrow_buffer::buffer::NullBuffer;
24-
use arrow_buffer::{Buffer, OffsetBuffer, ScalarBuffer};
25-
use arrow_data::ArrayDataBuilder;
24+
use arrow_buffer::{OffsetBuffer, ScalarBuffer};
2625
use arrow_schema::{ArrowError, DataType, FieldRef};
2726

2827
use crate::reader::tape::{Tape, TapeElement};
@@ -109,22 +108,17 @@ impl<O: OffsetSizeTrait, const IS_VIEW: bool> ArrayDecoder for ListLikeArrayDeco
109108
sizes.push(offsets[i] - offsets[i - 1]);
110109
}
111110
offsets.pop();
112-
let data_type = if O::IS_LARGE {
113-
DataType::LargeListView(self.field.clone())
114-
} else {
115-
DataType::ListView(self.field.clone())
116-
};
117111
// SAFETY: offsets and sizes are constructed correctly from the tape
118-
let array_data = unsafe {
119-
ArrayDataBuilder::new(data_type)
120-
.len(pos.len())
121-
.nulls(nulls)
122-
.child_data(vec![values.to_data()])
123-
.add_buffer(Buffer::from_vec(offsets))
124-
.add_buffer(Buffer::from_vec(sizes))
125-
.build_unchecked()
112+
let array = unsafe {
113+
GenericListViewArray::<O>::new_unchecked(
114+
self.field.clone(),
115+
ScalarBuffer::from(offsets),
116+
ScalarBuffer::from(sizes),
117+
values,
118+
nulls,
119+
)
126120
};
127-
Ok(make_array(array_data))
121+
Ok(Arc::new(array))
128122
} else {
129123
// SAFETY: offsets are built monotonically starting from 0
130124
let offsets = unsafe { OffsetBuffer::<O>::new_unchecked(ScalarBuffer::from(offsets)) };

0 commit comments

Comments
 (0)