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