Skip to content

Commit b158bfe

Browse files
committed
Add canonical Map arrays and builder
Signed-off-by: Adam Gutglick <adam@spiraldb.com>
1 parent a54e5f6 commit b158bfe

42 files changed

Lines changed: 1074 additions & 32 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎fuzz/src/array/fill_null.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ pub fn fill_null_canonical_array(
4747
}
4848
Canonical::Struct(_)
4949
| Canonical::List(_)
50+
| Canonical::Map(_)
5051
| Canonical::FixedSizeList(_)
5152
| Canonical::Extension(_) => canonical.into_array().fill_null(fill_value.clone())?,
5253
Canonical::Union(_) => {

‎fuzz/src/array/mask.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ pub fn mask_canonical_array(
153153
Canonical::Union(_) => {
154154
todo!("TODO(connor)[Union]: support Union arrays in the mask fuzzer")
155155
}
156+
Canonical::Map(_) => unreachable!("Map arrays are not fuzzed"),
156157
Canonical::Variant(_) => unreachable!("Variant arrays are not fuzzed"),
157158
})
158159
}

‎fuzz/src/array/scalar_at.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub fn scalar_at_canonical_array(
107107
Canonical::Union(_) => {
108108
todo!("TODO(connor)[Union]: support Union arrays in the scalar_at fuzzer")
109109
}
110+
Canonical::Map(_) => unreachable!("Map arrays are not fuzzed"),
110111
Canonical::Variant(_) => unreachable!("Variant arrays are not fuzzed"),
111112
})
112113
}

‎vortex-array/src/aggregate_fn/fns/is_constant/mod.rs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ impl AggregateFnVTable for IsConstant {
402402
Canonical::Struct(s) => check_struct_constant(s, ctx)?,
403403
Canonical::Extension(e) => check_extension_constant(e, ctx)?,
404404
Canonical::List(l) => check_listview_constant(l, ctx)?,
405+
Canonical::Map(_) => {
406+
vortex_bail!("Map arrays don't support IsConstant")
407+
}
405408
Canonical::FixedSizeList(f) => check_fixed_size_list_constant(f, ctx)?,
406409
Canonical::Null(_) => true,
407410
Canonical::Union(_) => {

‎vortex-array/src/aggregate_fn/fns/min_max/mod.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ impl AggregateFnVTable for MinMax {
422422
}
423423
Canonical::Struct(_)
424424
| Canonical::List(_)
425+
| Canonical::Map(_)
425426
| Canonical::FixedSizeList(_)
426427
| Canonical::Variant(_) => {
427428
vortex_bail!("Unsupported canonical type for min_max: {}", batch.dtype())

‎vortex-array/src/aggregate_fn/fns/uncompressed_size_in_bytes/mod.rs‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ use crate::aggregate_fn::EmptyOptions;
4545
use crate::array::ArrayView;
4646
use crate::arrays::Constant;
4747
use crate::arrays::ConstantArray;
48+
use crate::arrays::map::MapArrayExt;
4849
use crate::arrays::varbinview::BinaryView;
4950
use crate::dtype::DType;
5051
use crate::dtype::DecimalType;
@@ -199,6 +200,9 @@ pub(crate) fn canonical_uncompressed_size_in_bytes(
199200
Canonical::Decimal(array) => decimal_uncompressed_size_in_bytes(array, ctx),
200201
Canonical::VarBinView(array) => varbinview_uncompressed_size_in_bytes(array, ctx),
201202
Canonical::List(array) => list_view_uncompressed_size_in_bytes(array, ctx),
203+
Canonical::Map(array) => {
204+
list_view_uncompressed_size_in_bytes(&array.entries().into_owned(), ctx)
205+
}
202206
Canonical::FixedSizeList(array) => fixed_size_list_uncompressed_size_in_bytes(array, ctx),
203207
Canonical::Struct(array) => struct_uncompressed_size_in_bytes(array, ctx),
204208
Canonical::Union(array) => union_uncompressed_size_in_bytes(array, ctx),
@@ -232,13 +236,14 @@ pub(crate) fn constant_uncompressed_size_in_bytes(
232236
array.len(),
233237
array.scalar().as_binary().value().map(|value| value.len()),
234238
)?,
235-
DType::List(..) | DType::FixedSizeList(..) | DType::Struct(..) | DType::Extension(_) => {
239+
DType::List(..)
240+
| DType::Map(..)
241+
| DType::FixedSizeList(..)
242+
| DType::Struct(..)
243+
| DType::Extension(_) => {
236244
let canonical = array.array().clone().execute::<Canonical>(ctx)?;
237245
return canonical_uncompressed_size_in_bytes(&canonical, ctx);
238246
}
239-
DType::Map(..) => {
240-
vortex_bail!("UncompressedSizeInBytes is not supported for map arrays yet")
241-
}
242247
DType::Union(..) => {
243248
todo!(
244249
"TODO(connor)[Union]: support constant Union size accounting after constant Union \
@@ -297,7 +302,10 @@ fn supports_uncompressed_size_in_bytes(dtype: &DType) -> bool {
297302
DType::List(element_dtype, _) | DType::FixedSizeList(element_dtype, ..) => {
298303
supports_uncompressed_size_in_bytes(element_dtype)
299304
}
300-
DType::Map(..) => false,
305+
DType::Map(map_dtype, _) => {
306+
supports_uncompressed_size_in_bytes(&map_dtype.key_dtype())
307+
&& supports_uncompressed_size_in_bytes(&map_dtype.value_dtype())
308+
}
301309
DType::Struct(fields, _) => fields
302310
.fields()
303311
.all(|field| supports_uncompressed_size_in_bytes(&field)),

‎vortex-array/src/arrays/constant/vtable/canonical.rs‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::arrays::DecimalArray;
2020
use crate::arrays::ExtensionArray;
2121
use crate::arrays::FixedSizeListArray;
2222
use crate::arrays::ListViewArray;
23+
use crate::arrays::MapArray;
2324
use crate::arrays::NullArray;
2425
use crate::arrays::PrimitiveArray;
2526
use crate::arrays::StructArray;
@@ -126,7 +127,16 @@ pub(crate) fn constant_canonicalize(
126127
))
127128
}
128129
DType::List(..) => Canonical::List(constant_canonical_list_array(scalar, array.len())),
129-
DType::Map(..) => vortex_error::vortex_bail!("canonical map arrays are not yet supported"),
130+
DType::Map(map_dtype, nullability) => {
131+
let entries_scalar = Scalar::try_new(
132+
DType::List(Arc::new(map_dtype.entries_dtype()), *nullability),
133+
scalar.value().cloned(),
134+
)?;
135+
Canonical::Map(MapArray::try_new(
136+
map_dtype.clone(),
137+
constant_canonical_list_array(&entries_scalar, array.len()),
138+
)?)
139+
}
130140
DType::FixedSizeList(element_dtype, list_size, _) => {
131141
let value = scalar.as_list();
132142

‎vortex-array/src/arrays/dict/execute.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ pub(crate) fn take_canonical(
4949
Canonical::Decimal(a) => Canonical::Decimal(take_decimal(&a, codes, ctx)),
5050
Canonical::VarBinView(a) => Canonical::VarBinView(take_varbinview(&a, codes, ctx)),
5151
Canonical::List(a) => Canonical::List(take_listview(&a, codes, ctx)),
52+
Canonical::Map(_) => vortex_error::vortex_bail!("Map arrays don't support take"),
5253
Canonical::FixedSizeList(a) => {
5354
Canonical::FixedSizeList(take_fixed_size_list(&a, codes, ctx))
5455
}

‎vortex-array/src/arrays/filter/execute/mod.rs‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use std::sync::Arc;
99

1010
use vortex_error::VortexExpect;
1111
use vortex_error::VortexResult;
12+
use vortex_error::vortex_bail;
1213
use vortex_mask::Mask;
1314
use vortex_mask::MaskValues;
1415

@@ -87,14 +88,18 @@ pub(super) fn execute_filter_fast_paths(
8788
}
8889

8990
/// Filter a canonical array by a mask, returning a new canonical array.
90-
pub(super) fn execute_filter(canonical: Canonical, mask: &Arc<MaskValues>) -> Canonical {
91-
match canonical {
91+
pub(super) fn execute_filter(
92+
canonical: Canonical,
93+
mask: &Arc<MaskValues>,
94+
) -> VortexResult<Canonical> {
95+
Ok(match canonical {
9296
Canonical::Null(_) => Canonical::Null(NullArray::new(mask.true_count())),
9397
Canonical::Bool(a) => Canonical::Bool(bool::filter_bool(&a, mask)),
9498
Canonical::Primitive(a) => Canonical::Primitive(primitive::filter_primitive(&a, mask)),
9599
Canonical::Decimal(a) => Canonical::Decimal(decimal::filter_decimal(&a, mask)),
96100
Canonical::VarBinView(a) => Canonical::VarBinView(varbinview::filter_varbinview(&a, mask)),
97101
Canonical::List(a) => Canonical::List(listview::filter_listview(&a, mask)),
102+
Canonical::Map(_) => vortex_bail!("Map arrays don't support filter"),
98103
Canonical::FixedSizeList(a) => {
99104
Canonical::FixedSizeList(fixed_size_list::filter_fixed_size_list(&a, mask))
100105
}
@@ -123,5 +128,5 @@ pub(super) fn execute_filter(canonical: Canonical, mask: &Arc<MaskValues>) -> Ca
123128
.vortex_expect("filtered VariantArray children are row-aligned"),
124129
)
125130
}
126-
}
131+
})
127132
}

‎vortex-array/src/arrays/filter/vtable.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ impl VTable for Filter {
167167
// TODO(joe): fix the ownership of AnyCanonical
168168
let child = Canonical::from(array.child().as_::<AnyCanonical>());
169169
Ok(ExecutionResult::done(
170-
execute_filter(child, &mask_values).into_array(),
170+
execute_filter(child, &mask_values)?.into_array(),
171171
))
172172
}
173173

0 commit comments

Comments
 (0)