Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 24 additions & 6 deletions encodings/datetime-parts/src/compute/is_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -14,13 +15,30 @@ impl IsConstantKernel for DateTimePartsVTable {
fn is_constant(
&self,
array: &DateTimePartsArray,
_opts: &IsConstantOpts,
opts: &IsConstantOpts,
) -> VortexResult<Option<bool>> {
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))
}
}

Expand Down
3 changes: 2 additions & 1 deletion encodings/fastlanes/src/bitpacking/compute/between.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,7 +23,7 @@ impl BetweenKernel for BitPackedVTable {
upper: &dyn Array,
options: &BetweenOptions,
) -> VortexResult<Option<ArrayRef>> {
if !lower.is_constant() || !upper.is_constant() {
if !lower.is::<ConstantVTable>() || !upper.is::<ConstantVTable>() {
return Ok(None);
};

Expand Down
5 changes: 3 additions & 2 deletions encodings/fastlanes/src/for/array/for_compress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ fn compress_primitive<T: NativePType + WrappingSub + PrimInt>(
#[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;
Expand Down Expand Up @@ -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));
Comment on lines +101 to +102
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't do the same thing?

}

#[test]
Expand Down
13 changes: 12 additions & 1 deletion encodings/runend/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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]
Expand Down
25 changes: 1 addition & 24 deletions vortex-array/src/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -368,28 +365,8 @@ impl dyn Array + '_ {
self.as_opt::<V>().is_some()
}

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()
}

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<Scalar> {
self.is_constant().then(|| self.scalar_at(0))
self.as_opt::<ConstantVTable>().map(|a| a.scalar().clone())
}

/// Total size of the array in bytes, including all children and buffers.
Expand Down
3 changes: 2 additions & 1 deletion vortex-array/src/arrays/bool/compute/is_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ mod tests {
use rstest::rstest;

use super::*;
use crate::compute::is_constant;

#[rstest]
#[case(vec![true], true)]
Expand All @@ -40,6 +41,6 @@ mod tests {
}, false)]
fn test_is_constant(#[case] input: Vec<bool>, #[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));
}
}
9 changes: 3 additions & 6 deletions vortex-array/src/arrays/constant/compute/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -26,17 +25,15 @@ impl BooleanKernel for ConstantVTable {
) -> VortexResult<Option<ArrayRef>> {
// 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::<ConstantVTable>() 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();
Expand Down
3 changes: 2 additions & 1 deletion vortex-array/src/arrays/constant/vtable/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<ConstantVTable> for ConstantVTable {
Expand All @@ -15,7 +16,7 @@ impl EncodeVTable<ConstantVTable> for ConstantVTable {
_like: Option<&ConstantArray>,
) -> VortexResult<Option<ConstantArray>> {
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 {
Expand Down
20 changes: 0 additions & 20 deletions vortex-array/src/arrays/dict/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-FileCopyrightText: Copyright the Vortex contributors

use vortex_buffer::buffer;
use vortex_scalar::Scalar;

use super::DictArray;
use crate::Array;
Expand All @@ -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(
Expand Down
9 changes: 7 additions & 2 deletions vortex-array/src/arrays/list/compute/is_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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));
}
}
Expand Down Expand Up @@ -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]
Expand Down
3 changes: 2 additions & 1 deletion vortex-array/src/arrays/listview/compute/is_constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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));
}

Expand Down
5 changes: 3 additions & 2 deletions vortex-array/src/arrow/datum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<Self> {
if array.is_constant() {
if array.is::<ConstantVTable>() {
Ok(Self {
array: array.slice(0..1).into_arrow_preferred()?,
is_scalar: true,
Expand All @@ -51,7 +52,7 @@ impl Datum {
array: &dyn Array,
target_datatype: &DataType,
) -> VortexResult<Self> {
if array.is_constant() {
if array.is::<ConstantVTable>() {
Ok(Self {
array: array.slice(0..1).into_arrow(target_datatype)?,
is_scalar: true,
Expand Down
5 changes: 3 additions & 2 deletions vortex-array/src/compute/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -126,10 +127,10 @@ impl ComputeFnVTable for Boolean {
) -> VortexResult<Output> {
let BooleanArgs { lhs, rhs, operator } = BooleanArgs::try_from(args)?;

let rhs_is_constant = rhs.is_constant();
let rhs_is_constant = rhs.is::<ConstantVTable>();

// If LHS is constant, then we make sure it's on the RHS.
if lhs.is_constant() && !rhs_is_constant {
if lhs.is::<ConstantVTable>() && !rhs_is_constant {
return Ok(boolean(rhs, lhs, operator)?.into());
}

Expand Down
5 changes: 3 additions & 2 deletions vortex-array/src/compute/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -174,10 +175,10 @@ impl ComputeFnVTable for Compare {
.into());
}

let right_is_constant = rhs.is_constant();
let right_is_constant = rhs.is::<ConstantVTable>();

// 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::<ConstantVTable>() && !right_is_constant {
return Ok(compare(rhs, lhs, operator.swap())?.into());
}

Expand Down
Loading
Loading