Skip to main content

icydb_core/db/query/
expr.rs

1use crate::db::query::{
2    enum_filter::normalize_enum_literals,
3    plan::{OrderDirection, OrderSpec, PlanError, validate::validate_order},
4    predicate::{self, Predicate, SchemaInfo, ValidateError, normalize},
5};
6use thiserror::Error as ThisError;
7
8///
9/// FilterExpr
10/// Schema-agnostic filter expression for dynamic query input.
11/// Lowered into a validated predicate at the intent boundary.
12///
13
14#[derive(Clone, Debug)]
15pub struct FilterExpr(pub Predicate);
16
17impl FilterExpr {
18    /// Lower the filter expression into a validated predicate for the provided schema.
19    pub(crate) fn lower_with(&self, schema: &SchemaInfo) -> Result<Predicate, ValidateError> {
20        let normalized_enum_literals = normalize_enum_literals(schema, &self.0)?;
21        predicate::validate::reject_unsupported_query_features(&normalized_enum_literals)?;
22        predicate::validate(schema, &normalized_enum_literals)?;
23
24        Ok(normalize(&normalized_enum_literals))
25    }
26}
27
28///
29/// SortExpr
30/// Schema-agnostic sort expression for dynamic query input.
31/// Lowered into a validated order spec at the intent boundary.
32///
33
34#[derive(Clone, Debug)]
35pub struct SortExpr {
36    pub fields: Vec<(String, OrderDirection)>,
37}
38
39impl SortExpr {
40    /// Lower the sort expression into a validated order spec for the provided schema.
41    pub(crate) fn lower_with(&self, schema: &SchemaInfo) -> Result<OrderSpec, SortLowerError> {
42        let spec = OrderSpec {
43            fields: self.fields.clone(),
44        };
45
46        validate_order(schema, &spec)?;
47
48        Ok(spec)
49    }
50}
51
52///
53/// SortLowerError
54/// Errors returned when lowering sort expressions into order specs.
55///
56
57#[derive(Debug, ThisError)]
58pub(crate) enum SortLowerError {
59    #[error("{0}")]
60    Validate(#[from] ValidateError),
61
62    #[error("{0}")]
63    Plan(Box<PlanError>),
64}
65
66impl From<PlanError> for SortLowerError {
67    fn from(err: PlanError) -> Self {
68        Self::Plan(Box::new(err))
69    }
70}