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