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
3 changes: 2 additions & 1 deletion vortex-array/src/arrays/scalar_fn/vtable/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use crate::dtype::DType;
use crate::executor::ExecutionCtx;
use crate::executor::ExecutionResult;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::matcher::Matcher;
use crate::scalar_fn;
use crate::scalar_fn::Arity;
Expand Down Expand Up @@ -309,7 +310,7 @@ impl scalar_fn::ScalarFnVTable for ArrayExpr {
fn fmt_sql(
&self,
options: &Self::Options,
_expr: &Expression,
_expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
write!(f, "{}", options.0.encoding_id())
Expand Down
8 changes: 6 additions & 2 deletions vortex-array/src/expr/bound_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,10 @@ impl BoundExpression {

impl Display for BoundExpression {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.unbind(), f)
match self.kind() {
BoundKind::Scalar { scalar_fn, .. } => scalar_fn.fmt_sql(self, f),
BoundKind::Root => f.write_str("$"),
}
}
}

Expand Down Expand Up @@ -333,9 +336,10 @@ mod tests {
}

#[test]
fn bound_tree_display_matches_unbound() -> VortexResult<()> {
fn bound_display_matches_unbound() -> VortexResult<()> {
for expr in [root(), col("a"), eq(col("a"), lit(1_i32)), lit(true)] {
let bound = expr.bind_scope(&scope())?;
assert_eq!(bound.to_string(), expr.to_string());
assert_eq!(
bound.display_tree().to_string(),
expr.display_tree().to_string()
Expand Down
32 changes: 32 additions & 0 deletions vortex-array/src/expr/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,38 @@ pub enum DisplayFormat {
Tree,
}

/// Read-only expression-tree interface used by scalar functions for SQL-style formatting.
///
/// Both [`Expression`] and [`BoundExpression`] implement this interface, allowing scalar
/// functions to format either representation without converting between them.
pub trait ExprDisplay: Display {
/// Return the child at `index`.
fn display_child(&self, index: usize) -> &dyn ExprDisplay;

/// Return the number of children in this node.
fn display_children_count(&self) -> usize;
}

impl ExprDisplay for Expression {
fn display_child(&self, index: usize) -> &dyn ExprDisplay {
Expression::child(self, index)
}

fn display_children_count(&self) -> usize {
self.children().len()
}
}

impl ExprDisplay for BoundExpression {
fn display_child(&self, index: usize) -> &dyn ExprDisplay {
&self.children()[index]
}

fn display_children_count(&self) -> usize {
self.children().len()
}
}

trait DisplayTreeNode: Sized {
fn tree_children(&self) -> &[Self];

Expand Down
9 changes: 7 additions & 2 deletions vortex-array/src/scalar_fn/erased.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::ArrayRef;
use crate::ExecutionCtx;
use crate::dtype::DType;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::scalar_fn::EmptyOptions;
use crate::scalar_fn::ExecutionArgs;
use crate::scalar_fn::ReduceCtx;
Expand Down Expand Up @@ -160,8 +161,12 @@ impl ScalarFnRef {
// Expression-taking methods — used by expr/ module via pub(crate)
// ------------------------------------------------------------------

/// Format this expression in SQL-style format.
pub(crate) fn fmt_sql(&self, expr: &Expression, f: &mut Formatter<'_>) -> std::fmt::Result {
/// Format an expression tree in SQL-style format.
pub(crate) fn fmt_sql(
&self,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
self.0.fmt_sql(expr, f)
}

Expand Down
9 changes: 5 additions & 4 deletions vortex-array/src/scalar_fn/fns/between/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use crate::arrays::Primitive;
use crate::builtins::ArrayBuiltins;
use crate::dtype::DType;
use crate::dtype::DType::Bool;
use crate::expr::display::ExprDisplay;
use crate::expr::expression::Expression;
use crate::scalar::Scalar;
use crate::scalar_fn::Arity;
Expand Down Expand Up @@ -224,7 +225,7 @@ impl ScalarFnVTable for Between {
fn fmt_sql(
&self,
options: &Self::Options,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
let lower_op = if options.lower_strict.is_strict() {
Expand All @@ -240,11 +241,11 @@ impl ScalarFnVTable for Between {
write!(
f,
"({} {} {} {} {})",
expr.child(1),
expr.display_child(1),
lower_op,
expr.child(0),
expr.display_child(0),
upper_op,
expr.child(2)
expr.display_child(2)
)
}

Expand Down
8 changes: 5 additions & 3 deletions vortex-array/src/scalar_fn/fns/binary/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors

use std::fmt::Display;
use std::fmt::Formatter;

#[expect(deprecated)]
Expand All @@ -19,6 +20,7 @@ use crate::ExecutionCtx;
use crate::dtype::DType;
use crate::dtype::Nullability;
use crate::expr::and;
use crate::expr::display::ExprDisplay;
use crate::expr::expression::Expression;
use crate::expr::lit;
use crate::scalar_fn::Arity;
Expand Down Expand Up @@ -89,13 +91,13 @@ impl ScalarFnVTable for Binary {
fn fmt_sql(
&self,
operator: &Operator,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
write!(f, "(")?;
expr.child(0).fmt_sql(f)?;
Display::fmt(expr.display_child(0), f)?;
write!(f, " {} ", operator)?;
expr.child(1).fmt_sql(f)?;
Display::fmt(expr.display_child(1), f)?;
write!(f, ")")
}

Expand Down
9 changes: 5 additions & 4 deletions vortex-array/src/scalar_fn/fns/case_when.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::builders::builder_with_capacity;
use crate::builtins::ArrayBuiltins;
use crate::dtype::DType;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::scalar::Scalar;
use crate::scalar_fn::Arity;
use crate::scalar_fn::ChildName;
Expand Down Expand Up @@ -136,21 +137,21 @@ impl ScalarFnVTable for CaseWhen {
fn fmt_sql(
&self,
options: &Self::Options,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> fmt::Result {
write!(f, "CASE")?;
for i in 0..options.num_when_then_pairs as usize {
write!(
f,
" WHEN {} THEN {}",
expr.child(i * 2),
expr.child(i * 2 + 1)
expr.display_child(i * 2),
expr.display_child(i * 2 + 1)
)?;
}
if options.has_else {
let else_idx = options.num_when_then_pairs as usize * 2;
write!(f, " ELSE {}", expr.child(else_idx))?;
write!(f, " ELSE {}", expr.display_child(else_idx))?;
}
write!(f, " END")
}
Expand Down
11 changes: 9 additions & 2 deletions vortex-array/src/scalar_fn/fns/cast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

mod kernel;

use std::fmt::Display;
use std::fmt::Formatter;

pub use kernel::*;
Expand Down Expand Up @@ -33,6 +34,7 @@ use crate::arrays::VarBinView;
use crate::arrays::struct_::compute::cast::struct_cast;
use crate::builtins::ArrayBuiltins;
use crate::dtype::DType;
use crate::expr::display::ExprDisplay;
use crate::expr::expression::Expression;
use crate::expr::lit;
use crate::scalar_fn::Arity;
Expand Down Expand Up @@ -91,9 +93,14 @@ impl ScalarFnVTable for Cast {
}
}

fn fmt_sql(&self, dtype: &DType, expr: &Expression, f: &mut Formatter<'_>) -> std::fmt::Result {
fn fmt_sql(
&self,
dtype: &DType,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
write!(f, "cast(")?;
expr.children()[0].fmt_sql(f)?;
Display::fmt(expr.display_child(0), f)?;
write!(f, " as {}", dtype)?;
write!(f, ")")
}
Expand Down
5 changes: 3 additions & 2 deletions vortex-array/src/scalar_fn/fns/dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::IntoArray;
use crate::arrays::ConstantArray;
use crate::dtype::DType;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::expr::traversal::NodeExt;
use crate::expr::traversal::NodeVisitor;
use crate::expr::traversal::TraversalOrder;
Expand Down Expand Up @@ -64,10 +65,10 @@ impl ScalarFnVTable for DynamicComparison {
fn fmt_sql(
&self,
dynamic: &DynamicComparisonExpr,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
expr.child(0).fmt_sql(f)?;
Display::fmt(expr.display_child(0), f)?;
write!(f, " {} dynamic(", dynamic.operator)?;
match dynamic.scalar() {
None => write!(f, "scalar=<none>")?,
Expand Down
6 changes: 4 additions & 2 deletions vortex-array/src/scalar_fn/fns/get_item.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors

use std::fmt::Display;
use std::fmt::Formatter;

use prost::Message;
Expand All @@ -20,6 +21,7 @@ use crate::dtype::DType;
use crate::dtype::FieldName;
use crate::dtype::Nullability;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::expr::lit;
use crate::scalar_fn::Arity;
use crate::scalar_fn::ChildName;
Expand Down Expand Up @@ -78,10 +80,10 @@ impl ScalarFnVTable for GetItem {
fn fmt_sql(
&self,
field_name: &FieldName,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
expr.children()[0].fmt_sql(f)?;
Display::fmt(expr.display_child(0), f)?;
write!(f, ".{}", field_name)
}

Expand Down
7 changes: 4 additions & 3 deletions vortex-array/src/scalar_fn/fns/is_not_null.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: Copyright the Vortex contributors

use std::fmt::Display;
use std::fmt::Formatter;

use vortex_error::VortexResult;
Expand All @@ -13,7 +14,7 @@ use crate::IntoArray;
use crate::arrays::ConstantArray;
use crate::dtype::DType;
use crate::dtype::Nullability;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::scalar_fn::Arity;
use crate::scalar_fn::ChildName;
use crate::scalar_fn::EmptyOptions;
Expand Down Expand Up @@ -60,11 +61,11 @@ impl ScalarFnVTable for IsNotNull {
fn fmt_sql(
&self,
_options: &Self::Options,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
write!(f, "is_not_null(")?;
expr.child(0).fmt_sql(f)?;
Display::fmt(expr.display_child(0), f)?;
write!(f, ")")
}

Expand Down
7 changes: 4 additions & 3 deletions vortex-array/src/scalar_fn/fns/like/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ use crate::dtype::DType;
use crate::dtype::Nullability;
use crate::expr::Expression;
use crate::expr::and;
use crate::expr::display::ExprDisplay;
use crate::scalar::Scalar;
use crate::scalar_fn::Arity;
use crate::scalar_fn::ChildName;
Expand Down Expand Up @@ -107,10 +108,10 @@ impl ScalarFnVTable for Like {
fn fmt_sql(
&self,
options: &Self::Options,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
expr.child(0).fmt_sql(f)?;
Display::fmt(expr.display_child(0), f)?;
if options.negated {
write!(f, " not")?;
}
Expand All @@ -119,7 +120,7 @@ impl ScalarFnVTable for Like {
} else {
write!(f, " like ")?;
}
expr.child(1).fmt_sql(f)
Display::fmt(expr.display_child(1), f)
}

fn return_dtype(&self, _options: &Self::Options, arg_dtypes: &[DType]) -> VortexResult<DType> {
Expand Down
3 changes: 2 additions & 1 deletion vortex-array/src/scalar_fn/fns/literal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::IntoArray;
use crate::arrays::ConstantArray;
use crate::dtype::DType;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::scalar::Scalar;
use crate::scalar_fn::Arity;
use crate::scalar_fn::ChildName;
Expand Down Expand Up @@ -74,7 +75,7 @@ impl ScalarFnVTable for Literal {
fn fmt_sql(
&self,
scalar: &Scalar,
_expr: &Expression,
_expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
write!(f, "{}", scalar)
Expand Down
7 changes: 4 additions & 3 deletions vortex-array/src/scalar_fn/fns/pack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use crate::dtype::FieldNames;
use crate::dtype::Nullability;
use crate::dtype::StructFields;
use crate::expr::Expression;
use crate::expr::display::ExprDisplay;
use crate::expr::lit;
use crate::scalar_fn::Arity;
use crate::scalar_fn::ChildName;
Expand Down Expand Up @@ -105,13 +106,13 @@ impl ScalarFnVTable for Pack {
fn fmt_sql(
&self,
options: &Self::Options,
expr: &Expression,
expr: &dyn ExprDisplay,
f: &mut Formatter<'_>,
) -> std::fmt::Result {
write!(f, "pack(")?;
for (i, (name, child)) in options.names.iter().zip(expr.children().iter()).enumerate() {
for (i, name) in options.names.iter().enumerate() {
write!(f, "{}: ", name)?;
child.fmt_sql(f)?;
Display::fmt(expr.display_child(i), f)?;
if i + 1 < options.names.len() {
write!(f, ", ")?;
}
Expand Down
Loading
Loading