icydb_core/db/query/intent/
query.rs1use crate::{
2 db::{
3 predicate::{CompareOp, MissingRowPolicy, Predicate},
4 query::{
5 builder::aggregate::AggregateExpr,
6 explain::ExplainPlan,
7 expr::{FilterExpr, SortExpr},
8 intent::{
9 LoadSpec, QueryError, QueryMode, access_plan_to_entity_keys, model::QueryModel,
10 },
11 plan::AccessPlannedQuery,
12 },
13 },
14 traits::{EntityKind, SingletonEntity},
15 value::Value,
16};
17
18#[derive(Debug)]
30pub struct Query<E: EntityKind> {
31 intent: QueryModel<'static, E::Key>,
32}
33
34impl<E: EntityKind> Query<E> {
35 #[must_use]
39 pub const fn new(consistency: MissingRowPolicy) -> Self {
40 Self {
41 intent: QueryModel::new(E::MODEL, consistency),
42 }
43 }
44
45 #[must_use]
47 pub const fn mode(&self) -> QueryMode {
48 self.intent.mode()
49 }
50
51 #[must_use]
52 pub(crate) fn has_explicit_order(&self) -> bool {
53 self.intent.has_explicit_order()
54 }
55
56 #[must_use]
57 pub(crate) const fn has_grouping(&self) -> bool {
58 self.intent.has_grouping()
59 }
60
61 #[must_use]
62 pub(crate) const fn load_spec(&self) -> Option<LoadSpec> {
63 self.intent.load_spec()
64 }
65
66 #[must_use]
68 pub fn filter(mut self, predicate: Predicate) -> Self {
69 self.intent = self.intent.filter(predicate);
70 self
71 }
72
73 pub fn filter_expr(self, expr: FilterExpr) -> Result<Self, QueryError> {
75 let Self { intent } = self;
76 let intent = intent.filter_expr(expr)?;
77
78 Ok(Self { intent })
79 }
80
81 pub fn sort_expr(self, expr: SortExpr) -> Result<Self, QueryError> {
83 let Self { intent } = self;
84 let intent = intent.sort_expr(expr)?;
85
86 Ok(Self { intent })
87 }
88
89 #[must_use]
91 pub fn order_by(mut self, field: impl AsRef<str>) -> Self {
92 self.intent = self.intent.order_by(field);
93 self
94 }
95
96 #[must_use]
98 pub fn order_by_desc(mut self, field: impl AsRef<str>) -> Self {
99 self.intent = self.intent.order_by_desc(field);
100 self
101 }
102
103 #[must_use]
105 pub fn distinct(mut self) -> Self {
106 self.intent = self.intent.distinct();
107 self
108 }
109
110 pub fn group_by(self, field: impl AsRef<str>) -> Result<Self, QueryError> {
112 let Self { intent } = self;
113 let intent = intent.push_group_field(field.as_ref())?;
114
115 Ok(Self { intent })
116 }
117
118 #[must_use]
120 pub fn aggregate(mut self, aggregate: AggregateExpr) -> Self {
121 self.intent = self.intent.push_group_aggregate(aggregate);
122 self
123 }
124
125 #[must_use]
127 pub fn grouped_limits(mut self, max_groups: u64, max_group_bytes: u64) -> Self {
128 self.intent = self.intent.grouped_limits(max_groups, max_group_bytes);
129 self
130 }
131
132 pub fn having_group(
134 self,
135 field: impl AsRef<str>,
136 op: CompareOp,
137 value: Value,
138 ) -> Result<Self, QueryError> {
139 let field = field.as_ref().to_owned();
140 let Self { intent } = self;
141 let intent = intent.push_having_group_clause(&field, op, value)?;
142
143 Ok(Self { intent })
144 }
145
146 pub fn having_aggregate(
148 self,
149 aggregate_index: usize,
150 op: CompareOp,
151 value: Value,
152 ) -> Result<Self, QueryError> {
153 let Self { intent } = self;
154 let intent = intent.push_having_aggregate_clause(aggregate_index, op, value)?;
155
156 Ok(Self { intent })
157 }
158
159 pub(crate) fn by_id(self, id: E::Key) -> Self {
161 let Self { intent } = self;
162 Self {
163 intent: intent.by_id(id),
164 }
165 }
166
167 pub(crate) fn by_ids<I>(self, ids: I) -> Self
169 where
170 I: IntoIterator<Item = E::Key>,
171 {
172 let Self { intent } = self;
173 Self {
174 intent: intent.by_ids(ids),
175 }
176 }
177
178 #[must_use]
180 pub fn delete(mut self) -> Self {
181 self.intent = self.intent.delete();
182 self
183 }
184
185 #[must_use]
192 pub fn limit(mut self, limit: u32) -> Self {
193 self.intent = self.intent.limit(limit);
194 self
195 }
196
197 #[must_use]
203 pub fn offset(mut self, offset: u32) -> Self {
204 self.intent = self.intent.offset(offset);
205 self
206 }
207
208 pub fn explain(&self) -> Result<ExplainPlan, QueryError> {
210 let plan = self.planned()?;
211
212 Ok(plan.explain())
213 }
214
215 pub fn planned(&self) -> Result<PlannedQuery<E>, QueryError> {
217 let plan = self.build_plan()?;
218 let _projection = plan.projection_spec(E::MODEL);
219
220 Ok(PlannedQuery::new(plan))
221 }
222
223 pub fn plan(&self) -> Result<CompiledQuery<E>, QueryError> {
227 let plan = self.build_plan()?;
228 let _projection = plan.projection_spec(E::MODEL);
229
230 Ok(CompiledQuery::new(plan))
231 }
232
233 fn build_plan(&self) -> Result<AccessPlannedQuery<E::Key>, QueryError> {
235 let plan_value = self.intent.build_plan_model()?;
236 let (logical, access) = plan_value.into_parts();
237 let access = access_plan_to_entity_keys::<E>(E::MODEL, access)?;
238 let plan = AccessPlannedQuery::from_parts(logical, access);
239
240 Ok(plan)
241 }
242}
243
244impl<E> Query<E>
245where
246 E: EntityKind + SingletonEntity,
247 E::Key: Default,
248{
249 pub(crate) fn only(self) -> Self {
251 let Self { intent } = self;
252
253 Self {
254 intent: intent.only(E::Key::default()),
255 }
256 }
257}
258
259#[derive(Debug)]
267pub struct PlannedQuery<E: EntityKind> {
268 plan: AccessPlannedQuery<E::Key>,
269}
270
271impl<E: EntityKind> PlannedQuery<E> {
272 #[must_use]
273 pub(in crate::db) const fn new(plan: AccessPlannedQuery<E::Key>) -> Self {
274 Self { plan }
275 }
276
277 #[must_use]
278 pub fn explain(&self) -> ExplainPlan {
279 self.plan.explain_with_model(E::MODEL)
280 }
281}
282
283#[derive(Clone, Debug)]
292pub struct CompiledQuery<E: EntityKind> {
293 plan: AccessPlannedQuery<E::Key>,
294}
295
296impl<E: EntityKind> CompiledQuery<E> {
297 #[must_use]
298 pub(in crate::db) const fn new(plan: AccessPlannedQuery<E::Key>) -> Self {
299 Self { plan }
300 }
301
302 #[must_use]
303 pub fn explain(&self) -> ExplainPlan {
304 self.plan.explain_with_model(E::MODEL)
305 }
306
307 #[must_use]
309 #[cfg(test)]
310 pub(crate) fn projection_spec(&self) -> crate::db::query::plan::expr::ProjectionSpec {
311 self.plan.projection_spec(E::MODEL)
312 }
313
314 #[must_use]
315 pub(in crate::db) fn into_inner(self) -> AccessPlannedQuery<E::Key> {
316 self.plan
317 }
318}