Skip to content

Commit c2ccf29

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

File tree

29 files changed

+889
-783
lines changed

29 files changed

+889
-783
lines changed

vortex-array/src/expr/bound.rs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3+
4+
use std::any::Any;
5+
use std::fmt::Debug;
6+
use std::fmt::Display;
7+
use std::fmt::Formatter;
8+
use std::hash::Hash;
9+
use std::hash::Hasher;
10+
11+
use vortex_dtype::DType;
12+
use vortex_error::VortexResult;
13+
use vortex_utils::debug_with::DebugWith;
14+
15+
use crate::expr::options::ExpressionOptions;
16+
use crate::expr::signature::ExpressionSignature;
17+
use crate::expr::ExprId;
18+
use crate::expr::ExprVTable;
19+
use crate::expr::VTable;
20+
21+
/// An instance of an expression bound to some invocation options.
22+
pub struct BoundExpression {
23+
vtable: ExprVTable,
24+
options: Box<dyn Any + Send + Sync>,
25+
}
26+
27+
impl BoundExpression {
28+
/// Create a new bound expression from raw vtable and options.
29+
///
30+
/// # Safety
31+
///
32+
/// The caller must ensure that the provided options are compatible with the provided vtable.
33+
pub(super) unsafe fn new_unchecked(
34+
vtable: ExprVTable,
35+
options: Box<dyn Any + Send + Sync>,
36+
) -> Self {
37+
Self { vtable, options }
38+
}
39+
40+
/// Create a new bound expression from a vtable.
41+
pub fn new<V: VTable>(vtable: V, options: V::Options) -> Self {
42+
let vtable = ExprVTable::new::<V>(vtable);
43+
let options = Box::new(options);
44+
Self { vtable, options }
45+
}
46+
47+
/// Create a new expression from a static vtable.
48+
pub fn new_static<V: VTable>(vtable: &'static V, options: V::Options) -> Self {
49+
let vtable = ExprVTable::new_static::<V>(vtable);
50+
let options = Box::new(options);
51+
Self { vtable, options }
52+
}
53+
54+
/// The vtable for this expression.
55+
pub fn vtable(&self) -> &ExprVTable {
56+
&self.vtable
57+
}
58+
59+
/// Returns the ID of this expression.
60+
pub fn id(&self) -> ExprId {
61+
self.vtable.id()
62+
}
63+
64+
/// The type-erased options for this expression.
65+
pub fn options(&self) -> ExpressionOptions<'_> {
66+
ExpressionOptions {
67+
vtable: &self.vtable,
68+
options: self.options.as_ref(),
69+
}
70+
}
71+
72+
/// Signature information for this expression.
73+
pub fn signature(&self) -> ExpressionSignature<'_> {
74+
ExpressionSignature {
75+
vtable: &self.vtable,
76+
options: self.options.as_ref(),
77+
}
78+
}
79+
80+
/// Compute the return [`DType`] of this expression given the input argument types.
81+
pub fn return_dtype(&self, arg_types: &[DType]) -> VortexResult<DType> {
82+
self.vtable
83+
.as_dyn()
84+
.return_dtype(self.options.as_ref(), arg_types)
85+
}
86+
}
87+
88+
impl Clone for BoundExpression {
89+
fn clone(&self) -> Self {
90+
BoundExpression {
91+
vtable: self.vtable.clone(),
92+
options: self.vtable.as_dyn().options_clone(self.options.as_ref()),
93+
}
94+
}
95+
}
96+
97+
impl Debug for BoundExpression {
98+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
99+
f.debug_struct("BoundExpression")
100+
.field("vtable", &self.vtable)
101+
.field(
102+
"options",
103+
&DebugWith(|fmt| {
104+
self.vtable
105+
.as_dyn()
106+
.options_debug(self.options.as_ref(), fmt)
107+
}),
108+
)
109+
.finish()
110+
}
111+
}
112+
113+
impl Display for BoundExpression {
114+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
115+
write!(f, "{}(", self.vtable.id())?;
116+
self.vtable
117+
.as_dyn()
118+
.options_display(self.options.as_ref(), f)?;
119+
write!(f, ")")
120+
}
121+
}
122+
123+
impl PartialEq for BoundExpression {
124+
fn eq(&self, other: &Self) -> bool {
125+
self.vtable == other.vtable
126+
&& self
127+
.vtable
128+
.as_dyn()
129+
.options_eq(self.options.as_ref(), other.options.as_ref())
130+
}
131+
}
132+
impl Eq for BoundExpression {}
133+
134+
impl Hash for BoundExpression {
135+
fn hash<H: Hasher>(&self, state: &mut H) {
136+
self.vtable.hash(state);
137+
self.vtable
138+
.as_dyn()
139+
.options_hash(self.options.as_ref(), state);
140+
}
141+
}

vortex-array/src/expr/display.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ impl Display for DisplayTreeExpr<'_> {
1717
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
1818
pub use termtree::Tree;
1919
fn make_tree(expr: &Expression) -> Result<Tree<String>, std::fmt::Error> {
20-
let node_name = format!("{}", ExpressionDebug(expr));
20+
let node_name = format!("{}", expr);
2121

2222
// Get child names for display purposes
23-
let child_names = (0..expr.children().len()).map(|i| expr.child_name(i));
23+
let child_names = (0..expr.children().len()).map(|i| expr.signature().child_name(i));
2424
let children = expr.children();
2525

2626
let child_trees: Result<Vec<Tree<String>>, _> = children
@@ -40,18 +40,6 @@ impl Display for DisplayTreeExpr<'_> {
4040
}
4141
}
4242

43-
struct ExpressionDebug<'a>(&'a Expression);
44-
impl Display for ExpressionDebug<'_> {
45-
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46-
// Special-case when expression has no data to avoid trailing space.
47-
if self.0.data().is::<()>() {
48-
return write!(f, "{}", self.0.id().as_ref());
49-
}
50-
write!(f, "{} ", self.0.id().as_ref())?;
51-
self.0.vtable().as_dyn().fmt_data(self.0.data().as_ref(), f)
52-
}
53-
}
54-
5543
#[cfg(test)]
5644
mod tests {
5745
use vortex_dtype::DType;

0 commit comments

Comments
 (0)