vortex_array/arrays/map/compute/
cast.rs1use std::sync::Arc;
5
6use vortex_error::VortexResult;
7use vortex_error::vortex_bail;
8
9use crate::ArrayRef;
10use crate::array::ArrayView;
11use crate::arrays::ListView;
12use crate::arrays::map::Map;
13use crate::arrays::map::MapArrayExt;
14use crate::arrays::map::MapArraySlotsExt;
15use crate::arrays::map::compute::rebuild_map_from_array;
16use crate::dtype::DType;
17use crate::dtype::MapDType;
18use crate::executor::ExecutionCtx;
19use crate::scalar_fn::fns::cast::CastKernel;
20use crate::scalar_fn::fns::cast::CastReduce;
21
22fn prepare_map_cast_target(
23 array: ArrayView<'_, Map>,
24 dtype: &DType,
25) -> VortexResult<Option<(MapDType, DType)>> {
26 let Some(target_map_dtype) = dtype.as_map_opt() else {
27 return Ok(None);
28 };
29
30 if target_map_dtype.keys_sorted() && !array.keys_sorted() {
31 vortex_bail!(
32 "Cannot cast {} to {dtype}: source does not assert sorted map keys",
33 array.dtype()
34 );
35 }
36
37 let target_entries_dtype = DType::List(
38 Arc::new(target_map_dtype.entries_dtype()),
39 dtype.nullability(),
40 );
41 Ok(Some((target_map_dtype.clone(), target_entries_dtype)))
42}
43
44impl CastReduce for Map {
45 fn cast(array: ArrayView<'_, Self>, dtype: &DType) -> VortexResult<Option<ArrayRef>> {
46 let Some((target_map_dtype, target_entries_dtype)) = prepare_map_cast_target(array, dtype)?
47 else {
48 return Ok(None);
49 };
50
51 let Some(entries) = <ListView as CastReduce>::cast(
52 array.entries().as_::<ListView>(),
53 &target_entries_dtype,
54 )?
55 else {
56 return Ok(None);
57 };
58
59 rebuild_map_from_array(target_map_dtype, entries).map(Some)
60 }
61}
62
63impl CastKernel for Map {
64 fn cast(
65 array: ArrayView<'_, Self>,
66 dtype: &DType,
67 ctx: &mut ExecutionCtx,
68 ) -> VortexResult<Option<ArrayRef>> {
69 let Some((target_map_dtype, target_entries_dtype)) = prepare_map_cast_target(array, dtype)?
70 else {
71 return Ok(None);
72 };
73
74 let Some(entries) = <ListView as CastKernel>::cast(
75 array.entries().as_::<ListView>(),
76 &target_entries_dtype,
77 ctx,
78 )?
79 else {
80 return Ok(None);
81 };
82
83 rebuild_map_from_array(target_map_dtype, entries).map(Some)
84 }
85}