Skip to content

Commit 175883d

Browse files
authored
TryFromArrayRef support handling cast failures (#2740)
1 parent 1116bbf commit 175883d

File tree

4 files changed

+26
-23
lines changed

4 files changed

+26
-23
lines changed

vortex-array/src/array/convert.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use arrow_array::Array;
21
use vortex_error::VortexResult;
32

43
use crate::ArrayRef;
@@ -13,12 +12,7 @@ pub trait TryIntoArray {
1312
fn try_into_array(self) -> VortexResult<ArrayRef>;
1413
}
1514

16-
/// Trait for converting a type from a Vortex [`ArrayRef`], returning an error if the conversion fails.
17-
pub trait TryFromArray: Sized {
18-
fn try_from_array(array: &dyn Array) -> VortexResult<Self>;
19-
}
20-
2115
/// Trait for converting a type from a Vortex [`ArrayRef`], returning an error if the conversion fails.
2216
pub trait TryFromArrayRef: Sized {
23-
fn try_from_array(array: ArrayRef) -> VortexResult<Self>;
17+
fn try_from_array(array: ArrayRef) -> Result<Self, ArrayRef>;
2418
}

vortex-array/src/array/mod.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod validity;
77
mod variants;
88
mod visitor;
99

10-
use std::any::{Any, type_name};
10+
use std::any::Any;
1111
use std::fmt::{Debug, Display, Formatter};
1212
use std::sync::Arc;
1313

@@ -20,7 +20,7 @@ pub use validity::*;
2020
pub use variants::*;
2121
pub use visitor::*;
2222
use vortex_dtype::DType;
23-
use vortex_error::{VortexExpect, VortexResult, vortex_err};
23+
use vortex_error::{VortexExpect, VortexResult};
2424
use vortex_mask::Mask;
2525

2626
use crate::arrays::{
@@ -228,22 +228,22 @@ impl ToOwned for dyn Array {
228228
}
229229

230230
impl<A: Array + Clone + 'static> TryFromArrayRef for A {
231-
fn try_from_array(array: ArrayRef) -> VortexResult<Self> {
232-
Ok(Arc::unwrap_or_clone(
233-
array
234-
.as_any_arc()
235-
.downcast::<A>()
236-
.map_err(|_| vortex_err!("Cannot downcast to {}", type_name::<A>()))?,
237-
))
231+
fn try_from_array(array: ArrayRef) -> Result<Self, ArrayRef> {
232+
let fallback = array.clone();
233+
if let Ok(array) = array.as_any_arc().downcast::<A>() {
234+
// manually drop the fallback value so `Arc::unwrap_or_clone` doesn't always have to clone
235+
drop(fallback);
236+
Ok(Arc::unwrap_or_clone(array))
237+
} else {
238+
Err(fallback)
239+
}
238240
}
239241
}
240242

241243
impl<A: Array + Clone + 'static> TryFromArrayRef for Arc<A> {
242-
fn try_from_array(array: ArrayRef) -> VortexResult<Self> {
243-
array
244-
.as_any_arc()
245-
.downcast::<A>()
246-
.map_err(|_| vortex_err!("Cannot downcast to {}", type_name::<A>()))
244+
fn try_from_array(array: ArrayRef) -> Result<Self, ArrayRef> {
245+
let fallback = array.clone();
246+
array.as_any_arc().downcast::<A>().map_err(|_| fallback)
247247
}
248248
}
249249

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use arrow_schema::DataType;
22
use vortex_dtype::DType;
3-
use vortex_error::VortexResult;
3+
use vortex_error::{VortexResult, vortex_err};
44

55
use crate::arrays::VarBinViewArray;
66
use crate::arrays::varbin::VarBinArray;
@@ -21,6 +21,7 @@ impl ArrayCanonicalImpl for VarBinArray {
2121
};
2222
VarBinViewArray::try_from_array(ArrayRef::from_arrow(array, nullable))
2323
.map(Canonical::VarBinView)
24+
.map_err(|_| vortex_err!("Array wasn't a VarBinViewArray"))
2425
}
2526
}
2627

vortex-array/src/arrays/varbinview/mod.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ use arrow_buffer::ScalarBuffer;
1111
use static_assertions::{assert_eq_align, assert_eq_size};
1212
use vortex_buffer::{Alignment, Buffer, ByteBuffer};
1313
use vortex_dtype::DType;
14-
use vortex_error::{VortexExpect, VortexResult, VortexUnwrap, vortex_bail, vortex_panic};
14+
use vortex_error::{
15+
VortexExpect, VortexResult, VortexUnwrap, vortex_bail, vortex_err, vortex_panic,
16+
};
1517
use vortex_mask::Mask;
1618

1719
use crate::array::{ArrayCanonicalImpl, ArrayValidityImpl};
@@ -397,6 +399,7 @@ impl VarBinViewArray {
397399
&string_view_array,
398400
nullability.into(),
399401
))
402+
.map_err(|_| vortex_err!("Array was not a VarBinViewArray"))
400403
.vortex_expect("StringViewArray to VarBinViewArray downcast")
401404
}
402405
DType::Binary(nullability) => {
@@ -408,6 +411,7 @@ impl VarBinViewArray {
408411
&binary_view_array,
409412
nullability.into(),
410413
))
414+
.map_err(|_| vortex_err!("Array was not a VarBinViewArray"))
411415
.vortex_expect("BinaryViewArray to VarBinViewArray downcast")
412416
}
413417
other => vortex_panic!("VarBinViewArray must be Utf8 or Binary, was {other}"),
@@ -422,6 +426,7 @@ impl VarBinViewArray {
422426
}
423427
let array = ArrayRef::from_arrow(&builder.finish(), false);
424428
VarBinViewArray::try_from_array(array)
429+
.map_err(|_| vortex_err!("Array was not a VarBinViewArray"))
425430
.vortex_expect("VarBinViewArray from StringViewBuilder")
426431
}
427432

@@ -434,6 +439,7 @@ impl VarBinViewArray {
434439

435440
let array = ArrayRef::from_arrow(&builder.finish(), true);
436441
VarBinViewArray::try_from_array(array)
442+
.map_err(|_| vortex_err!("Array was not a VarBinViewArray"))
437443
.vortex_expect("VarBinViewArray from StringViewBuilder")
438444
}
439445

@@ -445,6 +451,7 @@ impl VarBinViewArray {
445451
}
446452
let array = ArrayRef::from_arrow(&builder.finish(), false);
447453
VarBinViewArray::try_from_array(array)
454+
.map_err(|_| vortex_err!("Array was not a VarBinViewArray"))
448455
.vortex_expect("VarBinViewArray from StringViewBuilder")
449456
}
450457

@@ -456,6 +463,7 @@ impl VarBinViewArray {
456463
builder.extend(iter);
457464
let array = ArrayRef::from_arrow(&builder.finish(), true);
458465
VarBinViewArray::try_from_array(array)
466+
.map_err(|_| vortex_err!("Array was not a VarBinViewArray"))
459467
.vortex_expect("VarBinViewArray from StringViewBuilder")
460468
}
461469
}

0 commit comments

Comments
 (0)