vortex_array/expr/exprs/
root.rs

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4use std::fmt::Formatter;
5
6use vortex_dtype::DType;
7use vortex_dtype::FieldPath;
8use vortex_error::VortexExpect;
9use vortex_error::VortexResult;
10use vortex_error::vortex_bail;
11use vortex_vector::Datum;
12
13use crate::ArrayRef;
14use crate::expr::Arity;
15use crate::expr::ChildName;
16use crate::expr::EmptyOptions;
17use crate::expr::ExecutionArgs;
18use crate::expr::ExprId;
19use crate::expr::StatsCatalog;
20use crate::expr::VTable;
21use crate::expr::VTableExt;
22use crate::expr::expression::Expression;
23use crate::expr::stats::Stat;
24
25/// An expression that returns the full scope of the expression evaluation.
26// TODO(ngates): rename to "Scope"
27pub struct Root;
28
29impl VTable for Root {
30    type Options = EmptyOptions;
31
32    fn id(&self) -> ExprId {
33        ExprId::from("vortex.root")
34    }
35
36    fn serialize(&self, _instance: &Self::Options) -> VortexResult<Option<Vec<u8>>> {
37        Ok(Some(vec![]))
38    }
39
40    fn deserialize(&self, _metadata: &[u8]) -> VortexResult<Self::Options> {
41        Ok(EmptyOptions)
42    }
43
44    fn arity(&self, _options: &Self::Options) -> Arity {
45        Arity::Exact(0)
46    }
47
48    fn child_name(&self, _instance: &Self::Options, child_idx: usize) -> ChildName {
49        unreachable!(
50            "Root expression does not have children, got index {}",
51            child_idx
52        )
53    }
54
55    fn fmt_sql(
56        &self,
57        _options: &Self::Options,
58        _expr: &Expression,
59        f: &mut Formatter<'_>,
60    ) -> std::fmt::Result {
61        write!(f, "$")
62    }
63
64    fn return_dtype(&self, _options: &Self::Options, _arg_dtypes: &[DType]) -> VortexResult<DType> {
65        vortex_bail!("Root expression does not support return_dtype")
66    }
67
68    fn evaluate(
69        &self,
70        _options: &Self::Options,
71        _expr: &Expression,
72        scope: &ArrayRef,
73    ) -> VortexResult<ArrayRef> {
74        Ok(scope.clone())
75    }
76
77    fn execute(&self, _data: &Self::Options, _args: ExecutionArgs) -> VortexResult<Datum> {
78        vortex_bail!("Root expression is not executable")
79    }
80
81    fn stat_expression(
82        &self,
83        _options: &Self::Options,
84        _expr: &Expression,
85        stat: Stat,
86        catalog: &dyn StatsCatalog,
87    ) -> Option<Expression> {
88        catalog.stats_ref(&FieldPath::root(), stat)
89    }
90
91    fn is_null_sensitive(&self, _options: &Self::Options) -> bool {
92        false
93    }
94
95    fn is_fallible(&self, _options: &Self::Options) -> bool {
96        false
97    }
98}
99
100/// Creates an expression that references the root scope.
101///
102/// Returns the entire input array as passed to the expression evaluator.
103/// This is commonly used as the starting point for field access and other operations.
104pub fn root() -> Expression {
105    Root.try_new_expr(EmptyOptions, vec![])
106        .vortex_expect("Failed to create Root expression")
107}
108
109/// Return whether the expression is a root expression.
110pub fn is_root(expr: &Expression) -> bool {
111    expr.is::<Root>()
112}