Skip to main content

icydb_core/db/query/
expr.rs

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