Skip to main content

icydb_core/db/query/
expr.rs

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