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
12 changes: 6 additions & 6 deletions vortex-array/public-api.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1494,7 +1494,7 @@ pub fn vortex_array::arrays::Constant::child_name(array: vortex_array::ArrayView

pub fn vortex_array::arrays::Constant::deserialize(&self, dtype: &vortex_array::dtype::DType, len: usize, _metadata: &[u8], buffers: &[vortex_array::buffer::BufferHandle], _children: &dyn vortex_array::serde::ArrayChildren, session: &vortex_session::VortexSession) -> vortex_error::VortexResult<vortex_array::ArrayParts<Self>>

pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, _ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>
pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>

pub fn vortex_array::arrays::Constant::execute_parent(array: vortex_array::ArrayView<'_, Self>, parent: &vortex_array::ArrayRef, child_idx: usize, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<core::option::Option<vortex_array::ArrayRef>>

Expand Down Expand Up @@ -5312,7 +5312,7 @@ pub fn vortex_array::arrays::Constant::child_name(array: vortex_array::ArrayView

pub fn vortex_array::arrays::Constant::deserialize(&self, dtype: &vortex_array::dtype::DType, len: usize, _metadata: &[u8], buffers: &[vortex_array::buffer::BufferHandle], _children: &dyn vortex_array::serde::ArrayChildren, session: &vortex_session::VortexSession) -> vortex_error::VortexResult<vortex_array::ArrayParts<Self>>

pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, _ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>
pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>

pub fn vortex_array::arrays::Constant::execute_parent(array: vortex_array::ArrayView<'_, Self>, parent: &vortex_array::ArrayRef, child_idx: usize, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<core::option::Option<vortex_array::ArrayRef>>

Expand Down Expand Up @@ -19404,7 +19404,7 @@ pub fn vortex_array::arrays::Constant::child_name(array: vortex_array::ArrayView

pub fn vortex_array::arrays::Constant::deserialize(&self, dtype: &vortex_array::dtype::DType, len: usize, _metadata: &[u8], buffers: &[vortex_array::buffer::BufferHandle], _children: &dyn vortex_array::serde::ArrayChildren, session: &vortex_session::VortexSession) -> vortex_error::VortexResult<vortex_array::ArrayParts<Self>>

pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, _ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>
pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>

pub fn vortex_array::arrays::Constant::execute_parent(array: vortex_array::ArrayView<'_, Self>, parent: &vortex_array::ArrayRef, child_idx: usize, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<core::option::Option<vortex_array::ArrayRef>>

Expand Down Expand Up @@ -20376,7 +20376,7 @@ pub fn vortex_array::arrays::Constant::child_name(array: vortex_array::ArrayView

pub fn vortex_array::arrays::Constant::deserialize(&self, dtype: &vortex_array::dtype::DType, len: usize, _metadata: &[u8], buffers: &[vortex_array::buffer::BufferHandle], _children: &dyn vortex_array::serde::ArrayChildren, session: &vortex_session::VortexSession) -> vortex_error::VortexResult<vortex_array::ArrayParts<Self>>

pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, _ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>
pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>

pub fn vortex_array::arrays::Constant::execute_parent(array: vortex_array::ArrayView<'_, Self>, parent: &vortex_array::ArrayRef, child_idx: usize, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<core::option::Option<vortex_array::ArrayRef>>

Expand Down Expand Up @@ -23070,7 +23070,7 @@ pub fn vortex_array::arrays::Constant::child_name(array: vortex_array::ArrayView

pub fn vortex_array::arrays::Constant::deserialize(&self, dtype: &vortex_array::dtype::DType, len: usize, _metadata: &[u8], buffers: &[vortex_array::buffer::BufferHandle], _children: &dyn vortex_array::serde::ArrayChildren, session: &vortex_session::VortexSession) -> vortex_error::VortexResult<vortex_array::ArrayParts<Self>>

pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, _ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>
pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>

pub fn vortex_array::arrays::Constant::execute_parent(array: vortex_array::ArrayView<'_, Self>, parent: &vortex_array::ArrayRef, child_idx: usize, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<core::option::Option<vortex_array::ArrayRef>>

Expand Down Expand Up @@ -24290,7 +24290,7 @@ pub fn vortex_array::arrays::Constant::child_name(array: vortex_array::ArrayView

pub fn vortex_array::arrays::Constant::deserialize(&self, dtype: &vortex_array::dtype::DType, len: usize, _metadata: &[u8], buffers: &[vortex_array::buffer::BufferHandle], _children: &dyn vortex_array::serde::ArrayChildren, session: &vortex_session::VortexSession) -> vortex_error::VortexResult<vortex_array::ArrayParts<Self>>

pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, _ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>
pub fn vortex_array::arrays::Constant::execute(array: vortex_array::Array<Self>, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<vortex_array::ExecutionResult>

pub fn vortex_array::arrays::Constant::execute_parent(array: vortex_array::ArrayView<'_, Self>, parent: &vortex_array::ArrayRef, child_idx: usize, ctx: &mut vortex_array::ExecutionCtx) -> vortex_error::VortexResult<core::option::Option<vortex_array::ArrayRef>>

Expand Down
17 changes: 15 additions & 2 deletions vortex-array/src/arrays/constant/vtable/canonical.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use vortex_error::VortexExpect;
use vortex_error::VortexResult;

use crate::Canonical;
use crate::ExecutionCtx;
use crate::IntoArray;
use crate::array::ArrayView;
use crate::arrays::BoolArray;
Expand All @@ -36,7 +37,10 @@ use crate::scalar::Scalar;
use crate::validity::Validity;

/// Shared implementation for both `canonicalize` and `execute` methods.
pub(crate) fn constant_canonicalize(array: ArrayView<'_, Constant>) -> VortexResult<Canonical> {
pub(crate) fn constant_canonicalize(
array: ArrayView<'_, Constant>,
ctx: &mut ExecutionCtx,
) -> VortexResult<Canonical> {
let scalar = array.scalar();

let validity = match array.dtype().nullability() {
Expand Down Expand Up @@ -163,7 +167,16 @@ pub(crate) fn constant_canonicalize(array: ArrayView<'_, Constant>) -> VortexRes
let s = scalar.as_extension();

let storage_scalar = s.to_storage_scalar();
let storage_self = ConstantArray::new(storage_scalar, array.len()).into_array();

// NB: We need to execute the constant array to be canonical because there is a
// reduction rule that turns `Extension(Constant(..))` into `Constant(Extension(..))`,
// and if we don't do this we create an infinite cycle.
// See `ExtensionConstantRule` for more details.
Comment on lines +171 to +174
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

should we just remove the reduction rule?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

It's kind of hard to say since if we don't remove that reduction rule, all of our optimizations that look for a ConstantArray child now don't work.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should keep the rule 100%. We must have a standard way to check is constant.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yea makes sense

let storage_self = ConstantArray::new(storage_scalar, array.len())
.into_array()
.execute::<Canonical>(ctx)?
.into_array();

Canonical::Extension(ExtensionArray::new(ext_dtype.clone(), storage_self))
}
DType::Variant(_) => {
Expand Down
47 changes: 19 additions & 28 deletions vortex-array/src/arrays/constant/vtable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,10 @@ impl VTable for Constant {
PARENT_RULES.evaluate(array, parent, child_idx)
}

fn execute(array: Array<Self>, _ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
fn execute(array: Array<Self>, ctx: &mut ExecutionCtx) -> VortexResult<ExecutionResult> {
Ok(ExecutionResult::done(constant_canonicalize(
array.as_view(),
ctx,
)?))
}

Expand Down Expand Up @@ -268,10 +269,11 @@ fn append_value_or_nulls<B: ArrayBuilder + 'static>(
#[cfg(test)]
mod tests {
use rstest::rstest;
use vortex_error::VortexResult;
use vortex_session::VortexSession;

use crate::ExecutionCtx;
use crate::IntoArray;
use crate::VortexSessionExecute;
use crate::arrays::ConstantArray;
use crate::arrays::constant::vtable::canonical::constant_canonicalize;
use crate::assert_arrays_eq;
Expand All @@ -282,42 +284,37 @@ mod tests {
use crate::dtype::StructFields;
use crate::scalar::Scalar;

fn ctx() -> ExecutionCtx {
ExecutionCtx::new(VortexSession::empty())
}

/// Appends `array` into a fresh builder and asserts the result matches `constant_canonicalize`.
fn assert_append_matches_canonical(array: ConstantArray) -> vortex_error::VortexResult<()> {
let expected = constant_canonicalize(array.as_view())?.into_array();
fn assert_append_matches_canonical(array: ConstantArray) -> VortexResult<()> {
let mut ctx = VortexSession::empty().create_execution_ctx();

let expected = constant_canonicalize(array.as_view(), &mut ctx)?.into_array();
let mut builder = builder_with_capacity(array.dtype(), array.len());
array
.into_array()
.append_to_builder(builder.as_mut(), &mut ctx())?;
.append_to_builder(builder.as_mut(), &mut ctx)?;
let result = builder.finish();
assert_arrays_eq!(&result, &expected);
Ok(())
}

#[test]
fn test_null_constant_append() -> vortex_error::VortexResult<()> {
fn test_null_constant_append() -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(Scalar::null(DType::Null), 5))
}

#[rstest]
#[case::bool_true(true, 5)]
#[case::bool_false(false, 3)]
fn test_bool_constant_append(
#[case] value: bool,
#[case] n: usize,
) -> vortex_error::VortexResult<()> {
fn test_bool_constant_append(#[case] value: bool, #[case] n: usize) -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(
Scalar::bool(value, Nullability::NonNullable),
n,
))
}

#[test]
fn test_bool_null_constant_append() -> vortex_error::VortexResult<()> {
fn test_bool_null_constant_append() -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(
Scalar::null(DType::Bool(Nullability::Nullable)),
4,
Expand All @@ -332,7 +329,7 @@ mod tests {
fn test_primitive_constant_append(
#[case] scalar: Scalar,
#[case] n: usize,
) -> vortex_error::VortexResult<()> {
) -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(scalar, n))
}

Expand All @@ -341,18 +338,15 @@ mod tests {
#[case::utf8_noninline("hello world!!", 5)] // >12 bytes: requires buffer block
#[case::utf8_empty("", 3)]
#[case::utf8_n_zero("hello world!!", 0)] // n=0 with non-inline: must not write orphaned bytes
fn test_utf8_constant_append(
#[case] value: &str,
#[case] n: usize,
) -> vortex_error::VortexResult<()> {
fn test_utf8_constant_append(#[case] value: &str, #[case] n: usize) -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(
Scalar::utf8(value, Nullability::NonNullable),
n,
))
}

#[test]
fn test_utf8_null_constant_append() -> vortex_error::VortexResult<()> {
fn test_utf8_null_constant_append() -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(
Scalar::null(DType::Utf8(Nullability::Nullable)),
4,
Expand All @@ -362,26 +356,23 @@ mod tests {
#[rstest]
#[case::binary_inline(vec![1u8, 2, 3], 5)] // ≤12 bytes: inlined
#[case::binary_noninline(vec![0u8; 13], 5)] // >12 bytes: buffer block
fn test_binary_constant_append(
#[case] value: Vec<u8>,
#[case] n: usize,
) -> vortex_error::VortexResult<()> {
fn test_binary_constant_append(#[case] value: Vec<u8>, #[case] n: usize) -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(
Scalar::binary(value, Nullability::NonNullable),
n,
))
}

#[test]
fn test_binary_null_constant_append() -> vortex_error::VortexResult<()> {
fn test_binary_null_constant_append() -> VortexResult<()> {
assert_append_matches_canonical(ConstantArray::new(
Scalar::null(DType::Binary(Nullability::Nullable)),
4,
))
}

#[test]
fn test_struct_constant_append() -> vortex_error::VortexResult<()> {
fn test_struct_constant_append() -> VortexResult<()> {
let fields = StructFields::new(
["x", "y"].into(),
vec![
Expand All @@ -400,7 +391,7 @@ mod tests {
}

#[test]
fn test_null_struct_constant_append() -> vortex_error::VortexResult<()> {
fn test_null_struct_constant_append() -> VortexResult<()> {
let fields = StructFields::new(
["x"].into(),
vec![DType::Primitive(PType::I32, Nullability::Nullable)],
Expand Down
2 changes: 0 additions & 2 deletions vortex-array/src/arrays/extension/vtable/canonical.rs

This file was deleted.

8 changes: 4 additions & 4 deletions vortex-array/src/arrays/extension/vtable/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors
mod canonical;
mod kernel;
mod operations;
mod validity;

use std::hash::Hasher;

Expand Down Expand Up @@ -36,6 +32,10 @@ use crate::buffer::BufferHandle;
use crate::dtype::DType;
use crate::serde::ArrayChildren;

mod kernel;
mod operations;
mod validity;

#[derive(Clone, Debug)]
pub struct Extension;

Expand Down
Loading