From 34eb7cb84c93543ca7da38c060cf276be7b848cb Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Fri, 16 Jan 2026 15:26:14 +0000 Subject: [PATCH 1/2] Only check for ConstantVTable Signed-off-by: Nicholas Gates --- vortex-array/src/array/mod.rs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/vortex-array/src/array/mod.rs b/vortex-array/src/array/mod.rs index 534429fdc05..1075a354ec5 100644 --- a/vortex-array/src/array/mod.rs +++ b/vortex-array/src/array/mod.rs @@ -369,16 +369,10 @@ impl dyn Array + '_ { } pub fn is_constant(&self) -> bool { - let opts = IsConstantOpts { - cost: Cost::Specialized, - }; - is_constant_opts(self, &opts) - .inspect_err(|e| tracing::warn!("Failed to compute IsConstant: {e}")) - .ok() - .flatten() - .unwrap_or_default() + self.is::() } + // TODO(ngates): we should deprecate this and have callers use the compute function directly. pub fn is_constant_opts(&self, cost: Cost) -> bool { let opts = IsConstantOpts { cost }; is_constant_opts(self, &opts) @@ -389,7 +383,7 @@ impl dyn Array + '_ { } pub fn as_constant(&self) -> Option { - self.is_constant().then(|| self.scalar_at(0)) + self.as_opt::().map(|a| a.scalar().clone()) } /// Total size of the array in bytes, including all children and buffers. From 5116d34e0695d058e980ab93d0188ec6738e7212 Mon Sep 17 00:00:00 2001 From: Nicholas Gates Date: Mon, 19 Jan 2026 15:15:11 +0000 Subject: [PATCH 2/2] Only check for ConstantVTable Signed-off-by: Nicholas Gates --- .../datetime-parts/src/compute/is_constant.rs | 30 +++++++++++++++---- .../src/bitpacking/compute/between.rs | 3 +- .../fastlanes/src/for/array/for_compress.rs | 5 ++-- encodings/runend/src/ops.rs | 13 +++++++- vortex-array/src/array/mod.rs | 17 ----------- .../src/arrays/bool/compute/is_constant.rs | 3 +- .../src/arrays/constant/compute/boolean.rs | 9 ++---- .../src/arrays/constant/vtable/encode.rs | 3 +- vortex-array/src/arrays/dict/tests.rs | 20 ------------- .../src/arrays/list/compute/is_constant.rs | 9 ++++-- .../arrays/listview/compute/is_constant.rs | 3 +- vortex-array/src/arrow/datum.rs | 5 ++-- vortex-array/src/compute/boolean.rs | 5 ++-- vortex-array/src/compute/compare.rs | 5 ++-- vortex-array/src/compute/is_constant.rs | 11 +++---- vortex-array/src/compute/list_contains.rs | 3 +- vortex-array/src/compute/take.rs | 3 +- vortex-btrblocks/src/lib.rs | 11 ++++++- vortex-btrblocks/src/string.rs | 6 ++-- 19 files changed, 89 insertions(+), 75 deletions(-) diff --git a/encodings/datetime-parts/src/compute/is_constant.rs b/encodings/datetime-parts/src/compute/is_constant.rs index d2788f5d5f0..f06583b4616 100644 --- a/encodings/datetime-parts/src/compute/is_constant.rs +++ b/encodings/datetime-parts/src/compute/is_constant.rs @@ -4,6 +4,7 @@ use vortex_array::compute::IsConstantKernel; use vortex_array::compute::IsConstantKernelAdapter; use vortex_array::compute::IsConstantOpts; +use vortex_array::compute::is_constant_opts; use vortex_array::register_kernel; use vortex_error::VortexResult; @@ -14,13 +15,30 @@ impl IsConstantKernel for DateTimePartsVTable { fn is_constant( &self, array: &DateTimePartsArray, - _opts: &IsConstantOpts, + opts: &IsConstantOpts, ) -> VortexResult> { - Ok(Some( - array.days().is_constant() - && array.seconds().is_constant() - && array.subseconds().is_constant(), - )) + let Some(days) = is_constant_opts(array.days().as_ref(), opts)? else { + return Ok(None); + }; + if !days { + return Ok(Some(false)); + } + + let Some(seconds) = is_constant_opts(array.seconds().as_ref(), opts)? else { + return Ok(None); + }; + if !seconds { + return Ok(Some(false)); + } + + let Some(subseconds) = is_constant_opts(array.subseconds().as_ref(), opts)? else { + return Ok(None); + }; + if !subseconds { + return Ok(Some(false)); + } + + Ok(Some(true)) } } diff --git a/encodings/fastlanes/src/bitpacking/compute/between.rs b/encodings/fastlanes/src/bitpacking/compute/between.rs index a231f55d8b6..6868dbfc4d0 100644 --- a/encodings/fastlanes/src/bitpacking/compute/between.rs +++ b/encodings/fastlanes/src/bitpacking/compute/between.rs @@ -4,6 +4,7 @@ use vortex_array::Array; use vortex_array::ArrayRef; use vortex_array::IntoArray; +use vortex_array::arrays::ConstantVTable; use vortex_array::compute::BetweenKernel; use vortex_array::compute::BetweenKernelAdapter; use vortex_array::compute::BetweenOptions; @@ -22,7 +23,7 @@ impl BetweenKernel for BitPackedVTable { upper: &dyn Array, options: &BetweenOptions, ) -> VortexResult> { - if !lower.is_constant() || !upper.is_constant() { + if !lower.is::() || !upper.is::() { return Ok(None); }; diff --git a/encodings/fastlanes/src/for/array/for_compress.rs b/encodings/fastlanes/src/for/array/for_compress.rs index 842ecc1cd4e..2f13ffd9ed9 100644 --- a/encodings/fastlanes/src/for/array/for_compress.rs +++ b/encodings/fastlanes/src/for/array/for_compress.rs @@ -45,6 +45,7 @@ fn compress_primitive( #[cfg(test)] mod test { use itertools::Itertools; + use vortex_array::Array; use vortex_array::ToCanonical; use vortex_array::assert_arrays_eq; use vortex_array::expr::stats::StatsProvider; @@ -97,8 +98,8 @@ mod test { assert!(compressed.reference_scalar().dtype().is_signed_int()); assert!(compressed.encoded().dtype().is_signed_int()); - let constant = compressed.encoded().as_constant().unwrap(); - assert_eq!(constant, Scalar::from(0i32)); + let encoded = compressed.encoded().scalar_at(0); + assert_eq!(encoded, Scalar::from(0i32)); } #[test] diff --git a/encodings/runend/src/ops.rs b/encodings/runend/src/ops.rs index 6a15906275c..aa0fc36ac1d 100644 --- a/encodings/runend/src/ops.rs +++ b/encodings/runend/src/ops.rs @@ -46,6 +46,8 @@ mod tests { use vortex_array::arrays::PrimitiveArray; use vortex_array::assert_arrays_eq; use vortex_array::compute::Cost; + use vortex_array::compute::IsConstantOpts; + use vortex_array::compute::is_constant_opts; use vortex_buffer::buffer; use vortex_dtype::DType; use vortex_dtype::Nullability; @@ -131,7 +133,16 @@ mod tests { let sliced_array = re_array.slice(2..5); - assert!(sliced_array.is_constant_opts(Cost::Canonicalize)) + assert!( + is_constant_opts( + &sliced_array, + &IsConstantOpts { + cost: Cost::Canonicalize + } + ) + .unwrap() + .unwrap_or_default() + ) } #[test] diff --git a/vortex-array/src/array/mod.rs b/vortex-array/src/array/mod.rs index 61230baaec9..9ffc50f1abb 100644 --- a/vortex-array/src/array/mod.rs +++ b/vortex-array/src/array/mod.rs @@ -45,11 +45,8 @@ use crate::arrays::VarBinVTable; use crate::arrays::VarBinViewVTable; use crate::builders::ArrayBuilder; use crate::compute::ComputeFn; -use crate::compute::Cost; use crate::compute::InvocationArgs; -use crate::compute::IsConstantOpts; use crate::compute::Output; -use crate::compute::is_constant_opts; use crate::expr::stats::Precision; use crate::expr::stats::Stat; use crate::expr::stats::StatsProviderExt; @@ -368,20 +365,6 @@ impl dyn Array + '_ { self.as_opt::().is_some() } - pub fn is_constant(&self) -> bool { - self.is::() - } - - // TODO(ngates): we should deprecate this and have callers use the compute function directly. - pub fn is_constant_opts(&self, cost: Cost) -> bool { - let opts = IsConstantOpts { cost }; - is_constant_opts(self, &opts) - .inspect_err(|e| tracing::warn!("Failed to compute IsConstant: {e}")) - .ok() - .flatten() - .unwrap_or_default() - } - pub fn as_constant(&self) -> Option { self.as_opt::().map(|a| a.scalar().clone()) } diff --git a/vortex-array/src/arrays/bool/compute/is_constant.rs b/vortex-array/src/arrays/bool/compute/is_constant.rs index 0a74c597821..7398bf42cac 100644 --- a/vortex-array/src/arrays/bool/compute/is_constant.rs +++ b/vortex-array/src/arrays/bool/compute/is_constant.rs @@ -29,6 +29,7 @@ mod tests { use rstest::rstest; use super::*; + use crate::compute::is_constant; #[rstest] #[case(vec![true], true)] @@ -40,6 +41,6 @@ mod tests { }, false)] fn test_is_constant(#[case] input: Vec, #[case] expected: bool) { let array = BoolArray::from_iter(input); - assert_eq!(array.is_constant(), expected); + assert_eq!(is_constant(array.as_ref()).unwrap(), Some(expected)); } } diff --git a/vortex-array/src/arrays/constant/compute/boolean.rs b/vortex-array/src/arrays/constant/compute/boolean.rs index de72cc6022b..2c1978ac478 100644 --- a/vortex-array/src/arrays/constant/compute/boolean.rs +++ b/vortex-array/src/arrays/constant/compute/boolean.rs @@ -3,7 +3,6 @@ use vortex_dtype::DType; use vortex_error::VortexResult; -use vortex_error::vortex_bail; use vortex_error::vortex_err; use vortex_scalar::Scalar; @@ -26,17 +25,15 @@ impl BooleanKernel for ConstantVTable { ) -> VortexResult> { // We only implement this for constant <-> constant arrays, otherwise we allow fall back // to the Arrow implementation. - if !rhs.is_constant() { + let Some(rhs) = rhs.as_opt::() else { return Ok(None); - } + }; let length = lhs.len(); let nullable = lhs.dtype().is_nullable() || rhs.dtype().is_nullable(); let lhs = lhs.scalar().as_bool().value(); - let Some(rhs) = rhs.as_constant() else { - vortex_bail!("Binary boolean operation requires both sides to be constant"); - }; let rhs = rhs + .scalar() .as_bool_opt() .ok_or_else(|| vortex_err!("expected rhs to be boolean"))? .value(); diff --git a/vortex-array/src/arrays/constant/vtable/encode.rs b/vortex-array/src/arrays/constant/vtable/encode.rs index abb4bd7425f..278273daf2c 100644 --- a/vortex-array/src/arrays/constant/vtable/encode.rs +++ b/vortex-array/src/arrays/constant/vtable/encode.rs @@ -6,6 +6,7 @@ use vortex_error::VortexResult; use crate::Canonical; use crate::arrays::ConstantArray; use crate::arrays::ConstantVTable; +use crate::compute::is_constant; use crate::vtable::EncodeVTable; impl EncodeVTable for ConstantVTable { @@ -15,7 +16,7 @@ impl EncodeVTable for ConstantVTable { _like: Option<&ConstantArray>, ) -> VortexResult> { let canonical = canonical.as_ref(); - if canonical.is_constant() { + if is_constant(canonical)?.unwrap_or_default() { let scalar = canonical.scalar_at(0); Ok(Some(ConstantArray::new(scalar, canonical.len()))) } else { diff --git a/vortex-array/src/arrays/dict/tests.rs b/vortex-array/src/arrays/dict/tests.rs index f5270dc9d00..b5fae87ae35 100644 --- a/vortex-array/src/arrays/dict/tests.rs +++ b/vortex-array/src/arrays/dict/tests.rs @@ -2,7 +2,6 @@ // SPDX-FileCopyrightText: Copyright the Vortex contributors use vortex_buffer::buffer; -use vortex_scalar::Scalar; use super::DictArray; use crate::Array; @@ -14,25 +13,6 @@ use crate::arrays::VarBinArray; use crate::assert_arrays_eq; use crate::validity::Validity; -#[test] -fn test_slice_into_const_dict() { - let dict = DictArray::try_new( - PrimitiveArray::from_option_iter(vec![Some(0u32), None, Some(1)]).to_array(), - PrimitiveArray::from_option_iter(vec![Some(0i32), Some(1), Some(2)]).to_array(), - ) - .unwrap(); - - assert_eq!( - Some(Scalar::new(dict.dtype().clone(), 0i32.into())), - dict.slice(0..1).as_constant() - ); - - assert_eq!( - Some(Scalar::null(dict.dtype().clone())), - dict.slice(1..2).as_constant() - ); -} - #[test] fn test_scalar_at_null_code() { let dict = DictArray::try_new( diff --git a/vortex-array/src/arrays/list/compute/is_constant.rs b/vortex-array/src/arrays/list/compute/is_constant.rs index 6c4f395cbb0..643daffa1fb 100644 --- a/vortex-array/src/arrays/list/compute/is_constant.rs +++ b/vortex-array/src/arrays/list/compute/is_constant.rs @@ -9,6 +9,7 @@ use crate::arrays::ListVTable; use crate::compute::IsConstantKernel; use crate::compute::IsConstantKernelAdapter; use crate::compute::IsConstantOpts; +use crate::compute::is_constant; use crate::compute::numeric; use crate::register_kernel; @@ -47,7 +48,7 @@ impl IsConstantKernel for ListVTable { .slice(SMALL_ARRAY_THRESHOLD + 1..array.len() + 1); let list_lengths = numeric(&end_offsets, &start_offsets, NumericOperator::Sub)?; - if !list_lengths.is_constant() { + if !is_constant(&list_lengths)?.unwrap_or_default() { return Ok(Some(false)); } } @@ -107,7 +108,11 @@ mod tests { .unwrap() .unwrap() ); - assert!(struct_of_lists.is_constant()); + assert!( + is_constant(struct_of_lists.as_ref()) + .unwrap() + .unwrap_or_default() + ); } #[rstest] diff --git a/vortex-array/src/arrays/listview/compute/is_constant.rs b/vortex-array/src/arrays/listview/compute/is_constant.rs index 8671877ac0e..c77c350c98a 100644 --- a/vortex-array/src/arrays/listview/compute/is_constant.rs +++ b/vortex-array/src/arrays/listview/compute/is_constant.rs @@ -8,6 +8,7 @@ use crate::arrays::ListViewVTable; use crate::compute::IsConstantKernel; use crate::compute::IsConstantKernelAdapter; use crate::compute::IsConstantOpts; +use crate::compute::is_constant_opts; use crate::register_kernel; impl IsConstantKernel for ListViewVTable { @@ -21,7 +22,7 @@ impl IsConstantKernel for ListViewVTable { // - All elements are valid (no nulls) // First check if all list sizes are constant. - if !array.sizes().is_constant_opts(opts.cost) { + if !is_constant_opts(array.sizes().as_ref(), opts)?.unwrap_or_default() { return Ok(Some(false)); } diff --git a/vortex-array/src/arrow/datum.rs b/vortex-array/src/arrow/datum.rs index 66f9b8e43d2..80fcb3c3ab3 100644 --- a/vortex-array/src/arrow/datum.rs +++ b/vortex-array/src/arrow/datum.rs @@ -12,6 +12,7 @@ use crate::Array; use crate::ArrayRef; use crate::IntoArray; use crate::arrays::ConstantArray; +use crate::arrays::ConstantVTable; use crate::arrow::FromArrowArray; use crate::arrow::IntoArrowArray; @@ -25,7 +26,7 @@ pub struct Datum { impl Datum { /// Create a new [`Datum`] from an [`ArrayRef`], which can then be passed to Arrow compute. pub fn try_new(array: &dyn Array) -> VortexResult { - if array.is_constant() { + if array.is::() { Ok(Self { array: array.slice(0..1).into_arrow_preferred()?, is_scalar: true, @@ -51,7 +52,7 @@ impl Datum { array: &dyn Array, target_datatype: &DataType, ) -> VortexResult { - if array.is_constant() { + if array.is::() { Ok(Self { array: array.slice(0..1).into_arrow(target_datatype)?, is_scalar: true, diff --git a/vortex-array/src/compute/boolean.rs b/vortex-array/src/compute/boolean.rs index aac1b1c620c..353f8afc2dc 100644 --- a/vortex-array/src/compute/boolean.rs +++ b/vortex-array/src/compute/boolean.rs @@ -16,6 +16,7 @@ use vortex_error::vortex_err; use crate::Array; use crate::ArrayRef; +use crate::arrays::ConstantVTable; use crate::arrow::FromArrowArray; use crate::arrow::IntoArrowArray; use crate::compute::ComputeFn; @@ -126,10 +127,10 @@ impl ComputeFnVTable for Boolean { ) -> VortexResult { let BooleanArgs { lhs, rhs, operator } = BooleanArgs::try_from(args)?; - let rhs_is_constant = rhs.is_constant(); + let rhs_is_constant = rhs.is::(); // If LHS is constant, then we make sure it's on the RHS. - if lhs.is_constant() && !rhs_is_constant { + if lhs.is::() && !rhs_is_constant { return Ok(boolean(rhs, lhs, operator)?.into()); } diff --git a/vortex-array/src/compute/compare.rs b/vortex-array/src/compute/compare.rs index eac6f3d057c..bd0301745e4 100644 --- a/vortex-array/src/compute/compare.rs +++ b/vortex-array/src/compute/compare.rs @@ -30,6 +30,7 @@ use crate::ArrayRef; use crate::Canonical; use crate::IntoArray; use crate::arrays::ConstantArray; +use crate::arrays::ConstantVTable; use crate::arrow::Datum; use crate::arrow::IntoArrowArray; use crate::arrow::from_arrow_array_with_len; @@ -174,10 +175,10 @@ impl ComputeFnVTable for Compare { .into()); } - let right_is_constant = rhs.is_constant(); + let right_is_constant = rhs.is::(); // Always try to put constants on the right-hand side so encodings can optimise themselves. - if lhs.is_constant() && !right_is_constant { + if lhs.is::() && !right_is_constant { return Ok(compare(rhs, lhs, operator.swap())?.into()); } diff --git a/vortex-array/src/compute/is_constant.rs b/vortex-array/src/compute/is_constant.rs index 32f67be343b..ac73a1ea0a4 100644 --- a/vortex-array/src/compute/is_constant.rs +++ b/vortex-array/src/compute/is_constant.rs @@ -307,6 +307,7 @@ mod tests { use crate::IntoArray as _; use crate::arrays::PrimitiveArray; + use crate::compute::is_constant; use crate::expr::stats::Stat; #[test] @@ -315,16 +316,16 @@ mod tests { arr.statistics() .compute_all(&[Stat::Min, Stat::Max]) .unwrap(); - assert!(!arr.is_constant()); + assert!(!is_constant(&arr).unwrap().unwrap_or_default()); let arr = buffer![0, 0].into_array(); arr.statistics() .compute_all(&[Stat::Min, Stat::Max]) .unwrap(); - assert!(arr.is_constant()); + assert!(is_constant(&arr).unwrap().unwrap_or_default()); let arr = PrimitiveArray::from_option_iter([Some(0), Some(0)]); - assert!(arr.is_constant()); + assert!(is_constant(arr.as_ref()).unwrap().unwrap_or_default()); } #[test] @@ -333,13 +334,13 @@ mod tests { arr.statistics() .compute_all(&[Stat::Min, Stat::Max]) .unwrap(); - assert!(!arr.is_constant()); + assert!(!is_constant(arr.as_ref()).unwrap().unwrap_or_default()); let arr = PrimitiveArray::from_option_iter([Some(f32::NEG_INFINITY), Some(f32::NEG_INFINITY)]); arr.statistics() .compute_all(&[Stat::Min, Stat::Max]) .unwrap(); - assert!(arr.is_constant()); + assert!(is_constant(arr.as_ref()).unwrap().unwrap_or_default()); } } diff --git a/vortex-array/src/compute/list_contains.rs b/vortex-array/src/compute/list_contains.rs index 95c01bddc76..e2141835dae 100644 --- a/vortex-array/src/compute/list_contains.rs +++ b/vortex-array/src/compute/list_contains.rs @@ -28,6 +28,7 @@ use crate::IntoArray; use crate::ToCanonical; use crate::arrays::BoolArray; use crate::arrays::ConstantArray; +use crate::arrays::ConstantVTable; use crate::arrays::ListViewArray; use crate::arrays::PrimitiveArray; use crate::compute::BinaryArgs; @@ -255,7 +256,7 @@ fn list_contains_scalar( nullability: Nullability, ) -> VortexResult { // If the list array is constant, we perform a single comparison. - if array.len() > 1 && array.is_constant() { + if array.len() > 1 && array.is::() { let contains = list_contains_scalar(&array.slice(0..1), value, nullability)?; return Ok(ConstantArray::new(contains.scalar_at(0), array.len()).into_array()); } diff --git a/vortex-array/src/compute/take.rs b/vortex-array/src/compute/take.rs index 3005be8080e..42388cf17b2 100644 --- a/vortex-array/src/compute/take.rs +++ b/vortex-array/src/compute/take.rs @@ -16,6 +16,7 @@ use crate::ArrayRef; use crate::Canonical; use crate::IntoArray; use crate::arrays::ConstantArray; +use crate::arrays::ConstantVTable; use crate::compute::ComputeFn; use crate::compute::ComputeFnVTable; use crate::compute::InvocationArgs; @@ -93,7 +94,7 @@ impl ComputeFnVTable for Take { // We know that constant array don't need stats propagation, so we can avoid the overhead of // computing derived stats and merging them in. - if !taken_array.is_constant() { + if !taken_array.is::() { propagate_take_stats(array, &taken_array, indices)?; } diff --git a/vortex-btrblocks/src/lib.rs b/vortex-btrblocks/src/lib.rs index 4de200fea10..4f66e5fbad6 100644 --- a/vortex-btrblocks/src/lib.rs +++ b/vortex-btrblocks/src/lib.rs @@ -46,6 +46,8 @@ use vortex_array::arrays::StructArray; use vortex_array::arrays::TemporalArray; use vortex_array::arrays::list_from_list_view; use vortex_array::compute::Cost; +use vortex_array::compute::IsConstantOpts; +use vortex_array::compute::is_constant_opts; use vortex_array::vtable::VTable; use vortex_array::vtable::ValidityHelper; use vortex_dtype::DType; @@ -483,7 +485,14 @@ impl BtrBlocksCompressor { if let Ok(temporal_array) = TemporalArray::try_from(ext_array.to_array()) && let TemporalMetadata::Timestamp(..) = temporal_array.temporal_metadata() { - if temporal_array.as_ref().is_constant_opts(Cost::Canonicalize) { + if is_constant_opts( + temporal_array.as_ref(), + &IsConstantOpts { + cost: Cost::Canonicalize, + }, + )? + .unwrap_or_default() + { return Ok(ConstantArray::new( temporal_array.as_ref().scalar_at(0), ext_array.len(), diff --git a/vortex-btrblocks/src/string.rs b/vortex-btrblocks/src/string.rs index ddcfe4c0322..8f1d765056a 100644 --- a/vortex-btrblocks/src/string.rs +++ b/vortex-btrblocks/src/string.rs @@ -11,6 +11,7 @@ use vortex_array::arrays::VarBinArray; use vortex_array::arrays::VarBinViewArray; use vortex_array::arrays::VarBinViewVTable; use vortex_array::builders::dict::dict_encode; +use vortex_array::compute::is_constant; use vortex_array::vtable::ValidityHelper; use vortex_error::VortexExpect; use vortex_error::VortexResult; @@ -330,7 +331,8 @@ impl Scheme for ConstantScheme { return Ok(0.0); } - if stats.estimated_distinct_count > 1 || !stats.src.is_constant() { + if stats.estimated_distinct_count > 1 || !is_constant(stats.src.as_ref())?.unwrap_or(false) + { return Ok(0.0); } @@ -440,7 +442,6 @@ impl Scheme for NullDominated { #[cfg(test)] mod tests { - use vortex_array::arrays::VarBinViewArray; use vortex_array::builders::ArrayBuilder; use vortex_array::builders::VarBinViewBuilder; @@ -487,7 +488,6 @@ mod tests { /// Tests to verify that each string compression scheme produces the expected encoding. #[cfg(test)] mod scheme_selection_tests { - use vortex_array::arrays::ConstantVTable; use vortex_array::arrays::DictVTable; use vortex_array::arrays::VarBinViewArray;