icydb_core/db/query/
expr.rs1use crate::db::{
7 predicate::{Predicate, normalize, normalize_enum_literals},
8 query::{
9 builder::FieldRef,
10 builder::{
11 AggregateExpr, NumericProjectionExpr, RoundProjectionExpr, TextProjectionExpr,
12 ValueProjectionExpr, scalar_projection::render_scalar_projection_expr_sql_label,
13 },
14 plan::{
15 OrderDirection, OrderTerm as PlannedOrderTerm,
16 expr::{Expr, FieldId},
17 },
18 },
19 schema::{SchemaInfo, ValidateError, reject_unsupported_query_features, validate},
20};
21
22#[derive(Clone, Debug)]
29pub struct FilterExpr(pub Predicate);
30
31impl FilterExpr {
32 pub(crate) fn lower_with(&self, schema: &SchemaInfo) -> Result<Predicate, ValidateError> {
34 let normalized_enum_literals = normalize_enum_literals(schema, &self.0)?;
36
37 reject_unsupported_query_features(&normalized_enum_literals)?;
39 validate(schema, &normalized_enum_literals)?;
40
41 Ok(normalize(&normalized_enum_literals))
43 }
44}
45
46#[derive(Clone, Debug, Eq, PartialEq)]
55pub struct OrderExpr {
56 label: String,
57 expr: Expr,
58}
59
60impl OrderExpr {
61 #[must_use]
63 pub fn field(field: impl Into<String>) -> Self {
64 let field = field.into();
65
66 Self {
67 label: field.clone(),
68 expr: Expr::Field(FieldId::new(field)),
69 }
70 }
71
72 const fn new(label: String, expr: Expr) -> Self {
75 Self { label, expr }
76 }
77
78 pub(in crate::db) fn lower(&self, direction: OrderDirection) -> PlannedOrderTerm {
81 PlannedOrderTerm::new(self.label.clone(), self.expr.clone(), direction)
82 }
83}
84
85impl From<&str> for OrderExpr {
86 fn from(value: &str) -> Self {
87 Self::field(value)
88 }
89}
90
91impl From<String> for OrderExpr {
92 fn from(value: String) -> Self {
93 Self::field(value)
94 }
95}
96
97impl From<FieldRef> for OrderExpr {
98 fn from(value: FieldRef) -> Self {
99 Self::field(value.as_str())
100 }
101}
102
103impl From<TextProjectionExpr> for OrderExpr {
104 fn from(value: TextProjectionExpr) -> Self {
105 Self::new(value.sql_label(), value.expr().clone())
106 }
107}
108
109impl From<NumericProjectionExpr> for OrderExpr {
110 fn from(value: NumericProjectionExpr) -> Self {
111 Self::new(value.sql_label(), value.expr().clone())
112 }
113}
114
115impl From<RoundProjectionExpr> for OrderExpr {
116 fn from(value: RoundProjectionExpr) -> Self {
117 Self::new(value.sql_label(), value.expr().clone())
118 }
119}
120
121impl From<AggregateExpr> for OrderExpr {
122 fn from(value: AggregateExpr) -> Self {
123 let expr = Expr::Aggregate(value);
124
125 Self::new(render_scalar_projection_expr_sql_label(&expr), expr)
126 }
127}
128
129#[derive(Clone, Debug, Eq, PartialEq)]
138pub struct OrderTerm {
139 expr: OrderExpr,
140 direction: OrderDirection,
141}
142
143impl OrderTerm {
144 #[must_use]
146 pub fn asc(expr: impl Into<OrderExpr>) -> Self {
147 Self {
148 expr: expr.into(),
149 direction: OrderDirection::Asc,
150 }
151 }
152
153 #[must_use]
155 pub fn desc(expr: impl Into<OrderExpr>) -> Self {
156 Self {
157 expr: expr.into(),
158 direction: OrderDirection::Desc,
159 }
160 }
161
162 pub(in crate::db) fn lower(&self) -> PlannedOrderTerm {
165 self.expr.lower(self.direction)
166 }
167}
168
169#[must_use]
171pub fn field(field: impl Into<String>) -> OrderExpr {
172 OrderExpr::field(field)
173}
174
175#[must_use]
177pub fn asc(expr: impl Into<OrderExpr>) -> OrderTerm {
178 OrderTerm::asc(expr)
179}
180
181#[must_use]
183pub fn desc(expr: impl Into<OrderExpr>) -> OrderTerm {
184 OrderTerm::desc(expr)
185}