Skip to content

Commit 68c86c5

Browse files
committed
bringback
1 parent ab76d1a commit 68c86c5

File tree

1 file changed

+47
-5
lines changed

1 file changed

+47
-5
lines changed

vortex-array/src/arrays/chunked/canonical.rs

+47-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
1-
use vortex_error::VortexResult;
1+
use vortex_dtype::{DType, StructDType};
2+
use vortex_error::{VortexExpect, VortexResult};
23

34
use super::ChunkedArray;
5+
use crate::arrays::StructArray;
46
use crate::builders::{ArrayBuilder, builder_with_capacity};
5-
use crate::{Array as _, ArrayCanonicalImpl, Canonical};
7+
use crate::validity::Validity;
8+
use crate::{Array as _, ArrayCanonicalImpl, ArrayRef, Canonical};
69

710
impl ArrayCanonicalImpl for ChunkedArray {
811
fn _to_canonical(&self) -> VortexResult<Canonical> {
9-
let mut builder = builder_with_capacity(self.dtype(), self.len());
10-
self.append_to_builder(builder.as_mut())?;
11-
builder.finish().to_canonical()
12+
match self.dtype() {
13+
DType::Struct(struct_dtype, _) => {
14+
let struct_array = swizzle_struct_chunks(
15+
self.chunks(),
16+
Validity::copy_from_array(self)?,
17+
struct_dtype,
18+
)?;
19+
Ok(Canonical::Struct(struct_array))
20+
}
21+
_ => {
22+
let mut builder = builder_with_capacity(self.dtype(), self.len());
23+
self.append_to_builder(builder.as_mut())?;
24+
builder.finish().to_canonical()
25+
}
26+
}
1227
}
1328

1429
fn _append_to_builder(&self, builder: &mut dyn ArrayBuilder) -> VortexResult<()> {
@@ -19,6 +34,33 @@ impl ArrayCanonicalImpl for ChunkedArray {
1934
}
2035
}
2136

37+
/// Swizzle the pointers within a ChunkedArray of StructArrays to instead be a single
38+
/// StructArray, where the Array for each Field is a ChunkedArray.
39+
fn swizzle_struct_chunks(
40+
chunks: &[ArrayRef],
41+
validity: Validity,
42+
struct_dtype: &StructDType,
43+
) -> VortexResult<StructArray> {
44+
let len = chunks.iter().map(|chunk| chunk.len()).sum();
45+
let mut field_arrays = Vec::new();
46+
47+
for (field_idx, field_dtype) in struct_dtype.fields().enumerate() {
48+
let field_chunks = chunks
49+
.iter()
50+
.map(|c| {
51+
c.as_struct_typed()
52+
.vortex_expect("Chunk was not a StructArray")
53+
.maybe_null_field_by_idx(field_idx)
54+
.vortex_expect("Invalid chunked array")
55+
})
56+
.collect::<Vec<_>>();
57+
let field_array = ChunkedArray::try_new(field_chunks, field_dtype.clone())?;
58+
field_arrays.push(field_array.into_array());
59+
}
60+
61+
StructArray::try_new(struct_dtype.names().clone(), field_arrays, len, validity)
62+
}
63+
2264
#[cfg(test)]
2365
mod tests {
2466
use std::sync::Arc;

0 commit comments

Comments
 (0)