Skip to content

Commit cedbb4b

Browse files
committed
Expressions
Signed-off-by: Nicholas Gates <[email protected]>
1 parent c2ccf29 commit cedbb4b

File tree

26 files changed

+511
-568
lines changed

26 files changed

+511
-568
lines changed

vortex-array/src/compute/between.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// SPDX-FileCopyrightText: Copyright the Vortex contributors
33

44
use std::any::Any;
5+
use std::fmt::Display;
6+
use std::fmt::Formatter;
57
use std::sync::LazyLock;
68

79
use arcref::ArcRef;
@@ -253,6 +255,22 @@ pub struct BetweenOptions {
253255
pub upper_strict: StrictComparison,
254256
}
255257

258+
impl Display for BetweenOptions {
259+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
260+
let lower_op = if self.lower_strict.is_strict() {
261+
"<"
262+
} else {
263+
"<="
264+
};
265+
let upper_op = if self.upper_strict.is_strict() {
266+
"<"
267+
} else {
268+
"<="
269+
};
270+
write!(f, "lower_strict: {}, upper_strict: {}", lower_op, upper_op)
271+
}
272+
}
273+
256274
impl Options for BetweenOptions {
257275
fn as_any(&self) -> &dyn Any {
258276
self

vortex-array/src/expr/bound.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use vortex_dtype::DType;
1212
use vortex_error::VortexResult;
1313
use vortex_utils::debug_with::DebugWith;
1414

15-
use crate::expr::options::ExpressionOptions;
16-
use crate::expr::signature::ExpressionSignature;
1715
use crate::expr::ExprId;
1816
use crate::expr::ExprVTable;
1917
use crate::expr::VTable;
18+
use crate::expr::options::ExpressionOptions;
19+
use crate::expr::signature::ExpressionSignature;
2020

2121
/// An instance of an expression bound to some invocation options.
2222
pub struct BoundExpression {

vortex-array/src/expr/expression.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ use std::sync::Arc;
1111

1212
use itertools::Itertools;
1313
use vortex_dtype::DType;
14-
use vortex_error::vortex_ensure;
1514
use vortex_error::VortexResult;
15+
use vortex_error::vortex_ensure;
1616

17+
use crate::ArrayRef;
18+
use crate::expr::StatsCatalog;
19+
use crate::expr::VTable;
1720
use crate::expr::bound::BoundExpression;
1821
use crate::expr::display::DisplayTreeExpr;
1922
use crate::expr::stats::Stat;
20-
use crate::expr::StatsCatalog;
21-
use crate::expr::VTable;
22-
use crate::ArrayRef;
2323

2424
/// A node in a Vortex expression tree.
2525
///
@@ -142,13 +142,11 @@ impl Expression {
142142
}
143143

144144
/// Returns an expression representing the zoned maximum statistic, if available.
145-
#[deprecated(note = "Use `stat_expression` instead")]
146145
pub fn stat_min(&self, catalog: &dyn StatsCatalog) -> Option<Expression> {
147146
self.stat_expression(Stat::Min, catalog)
148147
}
149148

150149
/// Returns an expression representing the zoned maximum statistic, if available.
151-
#[deprecated(note = "Use `stat_expression` instead")]
152150
pub fn stat_max(&self, catalog: &dyn StatsCatalog) -> Option<Expression> {
153151
self.stat_expression(Stat::Max, catalog)
154152
}

vortex-array/src/expr/exprs/between.rs

Lines changed: 52 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,25 @@ use std::fmt::Formatter;
66
use prost::Message;
77
use vortex_dtype::DType;
88
use vortex_dtype::DType::Bool;
9-
use vortex_error::vortex_bail;
109
use vortex_error::VortexExpect;
1110
use vortex_error::VortexResult;
11+
use vortex_error::vortex_bail;
1212
use vortex_proto::expr as pb;
13+
use vortex_vector::Datum;
1314

14-
use crate::compute::between as between_compute;
15+
use crate::ArrayRef;
1516
use crate::compute::BetweenOptions;
16-
use crate::expr::expression::Expression;
17-
use crate::expr::exprs::binary::Binary;
18-
use crate::expr::exprs::operators::Operator;
17+
use crate::compute::between as between_compute;
1918
use crate::expr::Arity;
2019
use crate::expr::ChildName;
20+
use crate::expr::ExecutionArgs;
2121
use crate::expr::ExprId;
2222
use crate::expr::StatsCatalog;
2323
use crate::expr::VTable;
2424
use crate::expr::VTableExt;
25-
use crate::ArrayRef;
25+
use crate::expr::expression::Expression;
26+
use crate::expr::exprs::binary::Binary;
27+
use crate::expr::exprs::operators::Operator;
2628

2729
/// An optimized scalar expression to compute whether values fall between two bounds.
2830
///
@@ -54,9 +56,9 @@ impl VTable for Between {
5456
))
5557
}
5658

57-
fn deserialize(&self, metadata: &[u8]) -> VortexResult<Option<Self::Options>> {
59+
fn deserialize(&self, metadata: &[u8]) -> VortexResult<Self::Options> {
5860
let opts = pb::BetweenOpts::decode(metadata)?;
59-
Ok(Some(BetweenOptions {
61+
Ok(BetweenOptions {
6062
lower_strict: if opts.lower_strict {
6163
crate::compute::StrictComparison::Strict
6264
} else {
@@ -67,17 +69,11 @@ impl VTable for Between {
6769
} else {
6870
crate::compute::StrictComparison::NonStrict
6971
},
70-
}))
72+
})
7173
}
7274

73-
fn validate(&self, expr: &ExpressionView<Self>) -> VortexResult<()> {
74-
if expr.children().len() != 3 {
75-
vortex_bail!(
76-
"Between expression requires exactly 3 children, got {}",
77-
expr.children().len()
78-
);
79-
}
80-
Ok(())
75+
fn arity(&self, _options: &Self::Options) -> Arity {
76+
Arity::Exact(3)
8177
}
8278

8379
fn child_name(&self, _instance: &Self::Options, child_idx: usize) -> ChildName {
@@ -89,8 +85,12 @@ impl VTable for Between {
8985
}
9086
}
9187

92-
fn fmt_sql(&self, expr: &ExpressionView<Self>, f: &mut Formatter<'_>) -> std::fmt::Result {
93-
let options = expr.data();
88+
fn fmt_sql(
89+
&self,
90+
options: &Self::Options,
91+
expr: &Expression,
92+
f: &mut Formatter<'_>,
93+
) -> std::fmt::Result {
9494
let lower_op = if options.lower_strict.is_strict() {
9595
"<"
9696
} else {
@@ -104,18 +104,18 @@ impl VTable for Between {
104104
write!(
105105
f,
106106
"({} {} {} {} {})",
107-
expr.lower(),
107+
expr.child(1),
108108
lower_op,
109-
expr.child(),
109+
expr.child(0),
110110
upper_op,
111-
expr.upper()
111+
expr.child(2)
112112
)
113113
}
114114

115-
fn return_dtype(&self, expr: &ExpressionView<Self>, scope: &DType) -> VortexResult<DType> {
116-
let arr_dt = expr.child().return_dtype(scope)?;
117-
let lower_dt = expr.lower().return_dtype(scope)?;
118-
let upper_dt = expr.upper().return_dtype(scope)?;
115+
fn return_dtype(&self, options: &Self::Options, arg_dtypes: &[DType]) -> VortexResult<DType> {
116+
let arr_dt = &arg_dtypes[0];
117+
let lower_dt = &arg_dtypes[1];
118+
let upper_dt = &arg_dtypes[2];
119119

120120
if !arr_dt.eq_ignore_nullability(&lower_dt) {
121121
vortex_bail!(
@@ -137,56 +137,45 @@ impl VTable for Between {
137137
))
138138
}
139139

140-
fn evaluate(&self, expr: &ExpressionView<Self>, scope: &ArrayRef) -> VortexResult<ArrayRef> {
141-
let arr = expr.child().evaluate(scope)?;
142-
let lower = expr.lower().evaluate(scope)?;
143-
let upper = expr.upper().evaluate(scope)?;
144-
between_compute(&arr, &lower, &upper, expr.data())
140+
fn evaluate(
141+
&self,
142+
options: &Self::Options,
143+
expr: &Expression,
144+
scope: &ArrayRef,
145+
) -> VortexResult<ArrayRef> {
146+
let arr = expr.child(0).evaluate(scope)?;
147+
let lower = expr.child(1).evaluate(scope)?;
148+
let upper = expr.child(2).evaluate(scope)?;
149+
between_compute(&arr, &lower, &upper, options)
150+
}
151+
152+
fn execute(&self, data: &Self::Options, args: ExecutionArgs) -> VortexResult<Datum> {
153+
todo!()
145154
}
146155

147156
fn stat_falsification(
148157
&self,
149-
_options: &Self::Options,
158+
options: &Self::Options,
150159
expr: &Expression,
151160
catalog: &dyn StatsCatalog,
152161
) -> Option<Expression> {
153-
expr.to_binary_expr().stat_falsification(catalog)
154-
}
155-
156-
fn is_null_sensitive(&self, _instance: &Self::Options) -> bool {
157-
false
158-
}
159-
160-
fn arity(&self, _options: &Self::Options) -> Arity {
161-
Arity::Exact(3)
162-
}
163-
}
164-
165-
impl ExpressionView<'_, Between> {
166-
pub fn child(&self) -> &Expression {
167-
&self.children()[0]
168-
}
169-
170-
pub fn lower(&self) -> &Expression {
171-
&self.children()[1]
172-
}
173-
174-
pub fn upper(&self) -> &Expression {
175-
&self.children()[2]
176-
}
177-
178-
pub fn to_binary_expr(&self) -> Expression {
179-
let options = self.data();
180-
let arr = self.children()[0].clone();
181-
let lower = self.children()[1].clone();
182-
let upper = self.children()[2].clone();
162+
let arr = expr.child(0).clone();
163+
let lower = expr.child(1).clone();
164+
let upper = expr.child(2).clone();
183165

184166
let lhs = Binary.new_expr(
185167
options.lower_strict.to_operator().into(),
186168
[lower, arr.clone()],
187169
);
188170
let rhs = Binary.new_expr(options.upper_strict.to_operator().into(), [arr, upper]);
189-
Binary.new_expr(Operator::And, [lhs, rhs])
171+
172+
Binary
173+
.new_expr(Operator::And, [lhs, rhs])
174+
.stat_falsification(catalog)
175+
}
176+
177+
fn is_null_sensitive(&self, _instance: &Self::Options) -> bool {
178+
false
190179
}
191180
}
192181

0 commit comments

Comments
 (0)