Skip to content

Commit 2c730c4

Browse files
authored
Drop direct arrow-select dependency (#10826)
This is still transitively picked up through arrow_cast and parquet variant but the logic is simpler without it
1 parent 0db53f9 commit 2c730c4

4 files changed

Lines changed: 47 additions & 24 deletions

File tree

‎Cargo.lock‎

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎vortex-arrow/Cargo.toml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ arrow-buffer = { workspace = true }
2424
arrow-cast = { workspace = true }
2525
arrow-data = { workspace = true }
2626
arrow-schema = { workspace = true, features = ["canonical_extension_types"] }
27-
arrow-select = { workspace = true }
2827
itertools = { workspace = true }
2928
num-traits = { workspace = true }
3029
simdutf8 = { workspace = true }

‎vortex-arrow/src/executor/list.rs‎

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,10 @@ use arrow_schema::FieldRef;
1111
use vortex_array::ArrayRef;
1212
use vortex_array::Canonical;
1313
use vortex_array::ExecutionCtx;
14-
use vortex_array::arrays::Chunked;
1514
use vortex_array::arrays::List;
1615
use vortex_array::arrays::ListArray;
1716
use vortex_array::arrays::ListView;
1817
use vortex_array::arrays::ListViewArray;
19-
use vortex_array::arrays::chunked::ChunkedArrayExt;
2018
use vortex_array::arrays::list::ListArraySlotsExt;
2119
use vortex_array::arrays::listview::ListViewArraySlotsExt;
2220
use vortex_array::arrays::listview::ListViewDataParts;
@@ -41,7 +39,7 @@ impl Matcher for ArrowListExportable {
4139
type Match<'a> = &'a ArrayRef;
4240

4341
fn try_match(array: &ArrayRef) -> Option<Self::Match<'_>> {
44-
(array.is::<List>() || array.is::<Chunked>() || array.is::<ListView>()).then_some(array)
42+
(array.is::<List>() || array.is::<ListView>()).then_some(array)
4543
}
4644
}
4745

@@ -66,23 +64,9 @@ pub(super) fn to_arrow_list<O: OffsetSizeTrait + NativePType>(
6664
return list_to_list::<O>(&list.into_owned(), elements_field, exporter, ctx);
6765
}
6866

69-
// Converting each chunk individually, then using the fast concat logic from arrow
70-
if let Some(chunked) = array.as_opt::<Chunked>() {
71-
let mut arrow_chunks: Vec<ArrowArrayRef> = Vec::with_capacity(chunked.nchunks());
72-
for chunk in chunked.chunks() {
73-
arrow_chunks.push(to_arrow_list::<O>(
74-
chunk.clone(),
75-
elements_field,
76-
exporter,
77-
ctx,
78-
)?);
79-
}
80-
81-
let refs = arrow_chunks.iter().map(|a| a.as_ref()).collect::<Vec<_>>();
82-
return Ok(arrow_select::concat::concat(&refs)?);
83-
}
84-
8567
// Otherwise the array is canonical: a ListViewArray, which we rebuild to ZCTL if needed.
68+
// Chunked lists canonicalize to a zero-copy ListView over chunked elements, so they take
69+
// this path without an intermediate Arrow concatenation.
8670
// Note: arrow_cast::cast supports ListView → List (apache/arrow-rs#8735), but it
8771
// unconditionally uses take. Our rebuild uses a heuristic that picks list-by-list
8872
// for large lists, which avoids materializing a large index buffer.
@@ -226,12 +210,14 @@ mod tests {
226210
use arrow_array::GenericListArray;
227211
use arrow_array::Int32Array;
228212
use arrow_array::Int64Array;
213+
use arrow_buffer::OffsetBuffer;
229214
use arrow_schema::DataType;
230215
use arrow_schema::Field;
231216
use vortex_array::Canonical;
232217
use vortex_array::IntoArray;
233218
use vortex_array::VortexSessionExecute;
234219
use vortex_array::arrays::BoolArray;
220+
use vortex_array::arrays::ChunkedArray;
235221
use vortex_array::arrays::PrimitiveArray;
236222
use vortex_array::arrays::SliceArray;
237223
use vortex_array::dtype::DType;
@@ -249,6 +235,39 @@ mod tests {
249235
/// A shared session for these list-executor tests, used to create execution contexts.
250236
static SESSION: LazyLock<VortexSession> = LazyLock::new(VortexSession::empty);
251237

238+
#[test]
239+
fn chunked_list_exports() -> VortexResult<()> {
240+
let mut ctx = SESSION.create_execution_ctx();
241+
let first = ListArray::try_new(
242+
buffer![1i32, 2, 3].into_array(),
243+
buffer![0i32, 2, 3].into_array(),
244+
Validity::NonNullable,
245+
&mut ctx,
246+
)?;
247+
let second = ListArray::try_new(
248+
buffer![4i32, 5].into_array(),
249+
buffer![0i32, 0, 2].into_array(),
250+
Validity::NonNullable,
251+
&mut ctx,
252+
)?;
253+
let dtype = first.dtype().clone();
254+
let chunked = ChunkedArray::try_new(vec![first.into_array(), second.into_array()], dtype)?;
255+
256+
let field = Field::new("item", DataType::Int32, false);
257+
let actual = chunked
258+
.into_array()
259+
.execute_arrow(Some(&DataType::List(field.clone().into())), &mut ctx)?;
260+
261+
let expected = GenericListArray::<i32>::try_new(
262+
field.into(),
263+
OffsetBuffer::new(vec![0, 2, 3, 3, 5].into()),
264+
Arc::new(Int32Array::from(vec![1, 2, 3, 4, 5])),
265+
None,
266+
)?;
267+
assert_eq!(&expected as &dyn Array, actual.as_ref());
268+
Ok(())
269+
}
270+
252271
#[test]
253272
fn test_to_arrow_list_i32() -> VortexResult<()> {
254273
let mut ctx = SESSION.create_execution_ctx();

‎vortex-arrow/src/scalar.rs‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use arrow_array::Scalar as ArrowScalar;
99
use arrow_array::*;
1010
use arrow_buffer::NullBuffer;
1111
use arrow_buffer::OffsetBuffer;
12+
use arrow_data::transform::MutableArrayData;
1213
use arrow_schema::Field;
1314
use arrow_schema::Fields;
1415
use vortex_array::dtype::DType;
@@ -235,11 +236,16 @@ fn concat_scalar_arrays(
235236
return Ok(new_empty_array(&to_data_type_naive(dtype)?));
236237
}
237238

238-
let arrays = scalars
239+
// Every scalar is a single-element array of the same Arrow type, so append them in order.
240+
let data = scalars
239241
.iter()
240-
.map(|scalar| scalar.get().0)
242+
.map(|scalar| scalar.get().0.to_data())
241243
.collect::<Vec<_>>();
242-
Ok(arrow_select::concat::concat(&arrays)?)
244+
let mut builder = MutableArrayData::new(data.iter().collect(), false, data.len());
245+
for index in 0..data.len() {
246+
builder.try_extend(index, 0, SCALAR_ARRAY_LEN)?;
247+
}
248+
Ok(make_array(builder.freeze()))
243249
}
244250

245251
/// Convert an [`ExtScalar`] to an Arrow [`Datum`].

0 commit comments

Comments
 (0)