Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions arrow-array/src/array/list_view_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,35 @@ impl<OffsetSize: OffsetSizeTrait> GenericListViewArray<OffsetSize> {
Self::try_new(field, offsets, sizes, values, nulls).unwrap()
}

/// Create a new [`GenericListViewArray`] from the provided parts without validation
///
/// See [`Self::try_new`] for the checked version of this function, and the
/// documentation of that function for the invariants that must be upheld.
///
/// # Safety
///
/// The parts must form a valid [`ListViewArray`] or [`LargeListViewArray`] according
/// to the Arrow spec.
pub unsafe fn new_unchecked(
field: FieldRef,
offsets: ScalarBuffer<OffsetSize>,
sizes: ScalarBuffer<OffsetSize>,
values: ArrayRef,
nulls: Option<NullBuffer>,
) -> Self {
if cfg!(feature = "force_validate") {
return Self::new(field, offsets, sizes, values, nulls);
}

Self {
data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
nulls,
values,
value_offsets: offsets,
value_sizes: sizes,
}
}

/// Create a new [`GenericListViewArray`] of length `len` where all values are null
pub fn new_null(field: FieldRef, len: usize) -> Self {
let values = new_empty_array(field.data_type());
Expand Down
28 changes: 11 additions & 17 deletions arrow-json/src/reader/list_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ use std::marker::PhantomData;
use std::sync::Arc;

use arrow_array::builder::BooleanBufferBuilder;
use arrow_array::{ArrayRef, GenericListArray, OffsetSizeTrait, make_array};
use arrow_array::{ArrayRef, GenericListArray, GenericListViewArray, OffsetSizeTrait};
use arrow_buffer::buffer::NullBuffer;
use arrow_buffer::{Buffer, OffsetBuffer, ScalarBuffer};
use arrow_data::ArrayDataBuilder;
use arrow_buffer::{OffsetBuffer, ScalarBuffer};
use arrow_schema::{ArrowError, DataType, FieldRef};

use crate::reader::tape::{Tape, TapeElement};
Expand Down Expand Up @@ -115,22 +114,17 @@ impl<O: OffsetSizeTrait, const IS_VIEW: bool> ArrayDecoder for ListLikeArrayDeco
sizes.push(offsets[i] - offsets[i - 1]);
}
offsets.pop();
let data_type = if O::IS_LARGE {
DataType::LargeListView(self.field.clone())
} else {
DataType::ListView(self.field.clone())
};
// SAFETY: offsets and sizes are constructed correctly from the tape
let array_data = unsafe {
ArrayDataBuilder::new(data_type)
.len(pos.len())
.nulls(nulls)
.child_data(vec![values.to_data()])
.add_buffer(Buffer::from_vec(offsets))
.add_buffer(Buffer::from_vec(sizes))
.build_unchecked()
let array = unsafe {
GenericListViewArray::<O>::new_unchecked(
self.field.clone(),
ScalarBuffer::from(offsets),
ScalarBuffer::from(sizes),
values,
nulls,
)
};
Ok(make_array(array_data))
Ok(Arc::new(array))
} else {
// SAFETY: offsets are built monotonically starting from 0
let offsets = unsafe { OffsetBuffer::<O>::new_unchecked(ScalarBuffer::from(offsets)) };
Expand Down
Loading