Skip to main content

icydb_core/db/query/
expr.rs

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