use vortex_error::VortexExpect;
use crate::dtype::FieldName;
use crate::dtype::StructFields;
use crate::expr::BoundExpression;
use crate::expr::Expression;
use crate::expr::analysis::AnnotationFn;
use crate::scalar_fn::fns::get_item::GetItem;
use crate::scalar_fn::fns::root::Root;
use crate::scalar_fn::fns::select::Select;
pub fn make_free_field_annotator(
scope: &StructFields,
) -> impl AnnotationFn<Expression, Annotation = FieldName> {
move |expr: &Expression| {
if let Some(selection) = expr.as_opt::<Select>() {
if expr.child(0).is::<Root>() {
return selection
.normalize_to_included_fields(scope.names())
.vortex_expect("Select fields must be valid for scope")
.into_iter()
.collect();
}
} else if let Some(field_name) = expr.as_opt::<GetItem>() {
if expr.child(0).is::<Root>() {
return vec![field_name.clone()];
}
} else if expr.is::<Root>() {
return scope.names().iter().cloned().collect();
}
vec![]
}
}
pub fn make_bound_free_field_annotator(
scope: &StructFields,
) -> impl AnnotationFn<BoundExpression, Annotation = FieldName> {
move |expr: &BoundExpression| {
let Some(scalar_fn) = expr.as_scalar() else {
return scope.names().iter().cloned().collect();
};
if let Some(selection) = scalar_fn.as_opt::<Select>() {
if expr.children()[0].is_root() {
return selection
.normalize_to_included_fields(scope.names())
.vortex_expect("Select fields must be valid for scope")
.into_iter()
.collect();
}
} else if let Some(field_name) = scalar_fn.as_opt::<GetItem>()
&& expr.children()[0].is_root()
{
return vec![field_name.clone()];
}
vec![]
}
}