Skip to main content

icydb_core/db/query/
expr.rs

1//! Module: query::expr
2//! Responsibility: schema-agnostic filter/sort expression wrappers and lowering.
3//! Does not own: planner route selection or executor evaluation.
4//! Boundary: intent boundary lowers these to validated predicate/order forms.
5
6use crate::db::query::plan::{OrderDirection, PlanError, validate::validate_order};
7use crate::db::{
8    predicate::{
9        Predicate, SchemaInfo, ValidateError, normalize, normalize_enum_literals,
10        reject_unsupported_query_features, validate,
11    },
12    query::plan::OrderSpec,
13};
14use thiserror::Error as ThisError;
15
16///
17/// FilterExpr
18/// Schema-agnostic filter expression for dynamic query input.
19/// Lowered into a validated predicate at the intent boundary.
20///
21
22#[derive(Clone, Debug)]
23pub struct FilterExpr(pub Predicate);
24
25impl FilterExpr {
26    /// Lower the filter expression into a validated predicate for the provided schema.
27    pub(crate) fn lower_with(&self, schema: &SchemaInfo) -> Result<Predicate, ValidateError> {
28        // Phase 1: normalize enum literals using schema enum metadata.
29        let normalized_enum_literals = normalize_enum_literals(schema, &self.0)?;
30
31        // Phase 2: reject unsupported query features and validate against schema.
32        reject_unsupported_query_features(&normalized_enum_literals)?;
33        validate(schema, &normalized_enum_literals)?;
34
35        // Phase 3: normalize structural predicate shape for deterministic planning.
36        Ok(normalize(&normalized_enum_literals))
37    }
38}
39
40///
41/// SortExpr
42/// Schema-agnostic sort expression for dynamic query input.
43/// Lowered into a validated order spec at the intent boundary.
44///
45
46#[derive(Clone, Debug)]
47pub struct SortExpr {
48    pub fields: Vec<(String, OrderDirection)>,
49}
50
51impl SortExpr {
52    /// Lower the sort expression into a validated order spec for the provided schema.
53    pub(crate) fn lower_with(&self, schema: &SchemaInfo) -> Result<OrderSpec, SortLowerError> {
54        let spec = OrderSpec {
55            fields: self.fields.clone(),
56        };
57
58        validate_order(schema, &spec)?;
59
60        Ok(spec)
61    }
62}
63
64///
65/// SortLowerError
66/// Errors returned when lowering sort expressions into order specs.
67///
68
69#[derive(Debug, ThisError)]
70pub(crate) enum SortLowerError {
71    #[error("{0}")]
72    Validate(#[from] ValidateError),
73
74    #[error("{0}")]
75    Plan(Box<PlanError>),
76}
77
78impl From<PlanError> for SortLowerError {
79    fn from(err: PlanError) -> Self {
80        Self::Plan(Box::new(err))
81    }
82}