Skip to main content

icydb_core/db/query/
expr.rs

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