Skip to content

Commit 4e0c3c8

Browse files
committed
feat[vortex-array]: add an expr array
Signed-off-by: Joe Isaacs <[email protected]>
1 parent c13a536 commit 4e0c3c8

File tree

6 files changed

+18
-35
lines changed

6 files changed

+18
-35
lines changed

vortex-array/src/arrays/expr/array.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ pub struct ExprArray {
1717
}
1818

1919
impl ExprArray {
20+
/// Creates a new ExprArray with the dtype validated to match the expression's return type.
2021
pub fn try_new(child: ArrayRef, expr: Expression, dtype: DType) -> VortexResult<Self> {
2122
assert_eq!(dtype, expr.return_dtype(child.dtype())?);
2223
Ok(unsafe { Self::unchecked_new(child, expr, dtype) })
@@ -37,7 +38,8 @@ impl ExprArray {
3738
}
3839
}
3940

40-
pub fn new_with_root_dtype(child: ArrayRef, expr: Expression) -> VortexResult<Self> {
41+
/// Creates a new ExprArray with the dtype inferred from the expression and child.
42+
pub fn new_infer_dtype(child: ArrayRef, expr: Expression) -> VortexResult<Self> {
4143
let dtype = expr.return_dtype(child.dtype())?;
4244
Ok(unsafe { Self::unchecked_new(child, expr, dtype) })
4345
}

vortex-array/src/arrays/expr/vtable/array.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,16 @@ impl ArrayVTable<ExprVTable> for ExprVTable {
2727
fn array_hash<H: std::hash::Hasher>(array: &ExprArray, state: &mut H, precision: Precision) {
2828
array.child.array_hash(state, precision);
2929
array.dtype.hash(state);
30+
// TODO(joe): fixme
31+
array.expr.serialize_metadata().hash()
3032
// Note: Expression doesn't implement Hash, so we skip it
3133
// This is acceptable since expressions are typically transient
3234
}
3335

3436
fn array_eq(array: &ExprArray, other: &ExprArray, precision: Precision) -> bool {
35-
array.child.array_eq(&other.child, precision) && array.dtype == other.dtype
36-
// Note: We don't compare expressions here as they don't implement Eq
37-
// This is acceptable since ExprArray is typically transient
37+
array.child.array_eq(&other.child, precision)
38+
&& array.dtype == other.dtype
39+
// TODO(joe): fixme
40+
&& array.expr.serialize_metadata() == other.expr.serialize_metadata()
3841
}
3942
}

vortex-array/src/arrays/expr/vtable/canonical.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ use crate::vtable::CanonicalVTable;
99

1010
impl CanonicalVTable<ExprVTable> for ExprVTable {
1111
fn canonicalize(array: &ExprArray) -> Canonical {
12-
// Evaluate the expression on the child array and canonicalize the result
1312
array
1413
.expr
1514
.evaluate(&array.child)
@@ -45,19 +44,9 @@ mod tests {
4544
let array = expr_array.into_array();
4645

4746
// Test canonicalize - should evaluate the expression
48-
let canonical = array.to_canonical();
47+
let canonical = array.to_canonical().into_array();
4948

50-
// The result should be a primitive array with value 15 repeated for each element
51-
let canonical_array = canonical.as_ref();
52-
assert_eq!(canonical_array.len(), 3);
53-
54-
println!("a {}", array.display_tree());
55-
56-
// Extract the primitive array from the Canonical enum
57-
if let crate::Canonical::Primitive(primitive) = canonical {
58-
assert_eq!(primitive.buffer::<i32>().as_slice(), &[15i32, 15, 15]);
59-
} else {
60-
panic!("Expected Canonical::Primitive variant");
61-
}
49+
let expect = (0..3).map(|_| 15i32).collect::<PrimitiveArray>();
50+
assert_eq!(expect, canonical);
6251
}
6352
}

vortex-array/src/arrays/expr/vtable/operator.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@ use crate::expr::transform::ExprOptimizer;
1212
use crate::vtable::OperatorVTable;
1313

1414
impl OperatorVTable<ExprVTable> for ExprVTable {
15-
fn bind(
16-
array: &ExprArray,
17-
selection: Option<&ArrayRef>,
18-
ctx: &mut dyn BindCtx,
19-
) -> VortexResult<BatchKernelRef> {
20-
// Canonicalize the ExprArray and bind the result
21-
// This evaluates the expression and returns the result
22-
let canonical = array.to_canonical();
23-
ctx.bind(&ArrayRef::from(canonical), selection)
24-
}
25-
2615
fn reduce(array: &ExprArray) -> VortexResult<Option<ArrayRef>> {
2716
// Get the default expression session
2817
let session = ExprSession::default();
@@ -66,7 +55,7 @@ mod tests {
6655

6756
let expr = get_item("a", pack([("a", root())], Nullability::NonNullable));
6857

69-
let expr_array = ExprArray::new_with_root_dtype(array.clone().into_array(), expr.clone())?;
58+
let expr_array = ExprArray::new_infer_dtype(array.clone().into_array(), expr.clone())?;
7059

7160
// Call reduce - it should optimize pack(a: $).a to just $
7261
let reduced = expr_array.reduce()?.vortex_expect("reduce failed");

vortex-array/src/arrays/struct_/vtable/operator.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ mod tests {
238238

239239
let expr = gt(get_item("a", root()), lit(5));
240240
let expr_array =
241-
ExprArray::new_with_root_dtype(struct_array.clone().into_array(), expr.clone())?;
241+
ExprArray::new_infer_dtype(struct_array.clone().into_array(), expr.clone())?;
242242

243243
let actual = expr_array.to_canonical().into_array();
244244
let expected = (0..5)
@@ -270,7 +270,7 @@ mod tests {
270270
gt(get_item("a", root()), lit(5)),
271271
lt(get_item("a", root()), lit(10)),
272272
);
273-
let expr_array = ExprArray::new_with_root_dtype(struct_array.clone().into_array(), expr)?;
273+
let expr_array = ExprArray::new_infer_dtype(struct_array.clone().into_array(), expr)?;
274274

275275
let actual = expr_array.to_canonical().into_array();
276276
let expected = (0..5)
@@ -304,7 +304,7 @@ mod tests {
304304
and(gt(col("a"), lit(5)), lt(col("b"), lit(4))),
305305
gt(col("a"), lit(6)),
306306
);
307-
let expr_array = ExprArray::new_with_root_dtype(struct_array.clone().into_array(), expr)?;
307+
let expr_array = ExprArray::new_infer_dtype(struct_array.clone().into_array(), expr)?;
308308
let parent: ArrayRef = expr_array.into_array();
309309
let result = struct_array
310310
.reduce_parent(&parent, 0)?
@@ -383,7 +383,7 @@ mod tests {
383383

384384
let expr = eq(lit(1), lit(0));
385385
let expr_array =
386-
ExprArray::new_with_root_dtype(struct_array.clone().into_array(), expr.clone())?;
386+
ExprArray::new_infer_dtype(struct_array.clone().into_array(), expr.clone())?;
387387

388388
let actual = expr_array.to_canonical().into_array();
389389
let expected = (0..5).map(|_| false).collect::<BoolArray>().into_array();

vortex-array/src/arrays/struct_/vtable/reduce.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ pub(crate) fn apply_partitioned_expr(
152152
)?
153153
.into_array();
154154

155-
Ok(ExprArray::new_with_root_dtype(child, partitioned.root.clone())?.into_array())
155+
Ok(ExprArray::new_infer_dtype(child, partitioned.root.clone())?.into_array())
156156
}
157157
}
158158
}

0 commit comments

Comments
 (0)