icydb_core/db/executor/
mod.rs1pub(super) mod aggregate;
2mod context;
3mod cursor;
4mod delete;
5mod executable_plan;
6mod execution_plan;
7mod kernel;
8pub(super) mod load;
9mod mutation;
10mod physical_path;
11mod plan_metrics;
12pub(super) mod route;
13mod stream;
14#[cfg(test)]
15mod tests;
16mod window;
17
18pub(in crate::db) use crate::db::lowering::{LoweredIndexPrefixSpec, LoweredIndexRangeSpec};
19pub(super) use context::*;
20pub(in crate::db) use cursor::{
21 PlannedCursor, decode_pk_cursor_boundary, decode_typed_primary_key_cursor_slot, prepare_cursor,
22 revalidate_cursor, validate_index_range_anchor,
23 validate_index_range_boundary_anchor_consistency,
24};
25pub(super) use delete::DeleteExecutor;
26pub(in crate::db) use executable_plan::ExecutablePlan;
27pub(in crate::db::executor) use execution_plan::ExecutionPlan;
28pub(in crate::db::executor) use kernel::{
29 ExecutionKernel, IndexPredicateCompileMode, PlanRow, PostAccessStats,
30};
31pub(super) use load::LoadExecutor;
32pub use load::{ExecutionAccessPathVariant, ExecutionOptimization, ExecutionTrace};
33pub(super) use mutation::save::SaveExecutor;
34pub(super) use stream::access::*;
35pub(super) use stream::key::{
36 BudgetedOrderedKeyStream, KeyOrderComparator, OrderedKeyStream, OrderedKeyStreamBox,
37 VecOrderedKeyStream,
38};
39pub(in crate::db) use window::compute_page_window;
40
41use crate::{
51 db::{
52 cursor::CursorPlanError,
53 data::DataKey,
54 plan::AccessPlannedQuery,
55 query::{
56 fluent::{delete::FluentDeleteQuery, load::FluentLoadQuery},
57 intent::{PlannedQuery, Query, QueryError},
58 plan::{OrderPlanError, PlanError},
59 predicate::PredicateFieldSlots,
60 predicate::ValidateError,
61 },
62 },
63 error::{ErrorClass, ErrorOrigin, InternalError},
64 traits::EntityKind,
65};
66use thiserror::Error as ThisError;
67
68pub(super) fn compile_predicate_slots<E: EntityKind>(
69 plan: &AccessPlannedQuery<E::Key>,
70) -> Option<PredicateFieldSlots> {
71 plan.predicate
72 .as_ref()
73 .map(PredicateFieldSlots::resolve::<E>)
74}
75
76impl<E: EntityKind> From<PlannedQuery<E>> for ExecutablePlan<E> {
77 fn from(value: PlannedQuery<E>) -> Self {
78 Self::new(value.into_inner())
79 }
80}
81
82impl<E: EntityKind> Query<E> {
83 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
85 self.planned().map(ExecutablePlan::from)
86 }
87}
88
89impl<E: EntityKind> FluentLoadQuery<'_, E> {
90 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
92 self.planned().map(ExecutablePlan::from)
93 }
94}
95
96impl<E: EntityKind> FluentDeleteQuery<'_, E> {
97 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
99 self.planned().map(ExecutablePlan::from)
100 }
101}
102
103#[derive(Debug, ThisError)]
111pub(crate) enum ExecutorPlanError {
112 #[error("{0}")]
113 Predicate(Box<ValidateError>),
114
115 #[error("{0}")]
116 Order(Box<OrderPlanError>),
117
118 #[error("{0}")]
119 Cursor(Box<CursorPlanError>),
120}
121
122impl ExecutorPlanError {
123 #[must_use]
125 pub(crate) fn into_plan_error(self) -> PlanError {
126 match self {
127 Self::Predicate(err) => PlanError::from(*err),
128 Self::Order(err) => PlanError::from(*err),
129 Self::Cursor(err) => PlanError::from(*err),
130 }
131 }
132}
133
134impl From<ValidateError> for ExecutorPlanError {
135 fn from(err: ValidateError) -> Self {
136 Self::Predicate(Box::new(err))
137 }
138}
139
140impl From<OrderPlanError> for ExecutorPlanError {
141 fn from(err: OrderPlanError) -> Self {
142 Self::Order(Box::new(err))
143 }
144}
145
146impl From<CursorPlanError> for ExecutorPlanError {
147 fn from(err: CursorPlanError) -> Self {
148 Self::Cursor(Box::new(err))
149 }
150}
151
152#[derive(Debug, ThisError)]
157pub(crate) enum ExecutorError {
158 #[error("corruption detected ({origin}): {message}")]
159 Corruption {
160 origin: ErrorOrigin,
161 message: String,
162 },
163
164 #[error("data key exists: {0}")]
165 KeyExists(DataKey),
166}
167
168impl ExecutorError {
169 pub(crate) const fn class(&self) -> ErrorClass {
170 match self {
171 Self::KeyExists(_) => ErrorClass::Conflict,
172 Self::Corruption { .. } => ErrorClass::Corruption,
173 }
174 }
175
176 pub(crate) const fn origin(&self) -> ErrorOrigin {
177 match self {
178 Self::KeyExists(_) => ErrorOrigin::Store,
179 Self::Corruption { origin, .. } => *origin,
180 }
181 }
182
183 pub(crate) fn corruption(origin: ErrorOrigin, message: impl Into<String>) -> Self {
184 Self::Corruption {
185 origin,
186 message: message.into(),
187 }
188 }
189
190 pub(crate) fn store_corruption(message: impl Into<String>) -> Self {
192 Self::corruption(ErrorOrigin::Store, message)
193 }
194
195 pub(crate) fn serialize_corruption(message: impl Into<String>) -> Self {
197 Self::corruption(ErrorOrigin::Serialize, message)
198 }
199
200 pub(crate) fn store_corruption_from(source: impl std::fmt::Display) -> Self {
202 Self::store_corruption(source.to_string())
203 }
204}
205
206impl From<ExecutorError> for InternalError {
207 fn from(err: ExecutorError) -> Self {
208 Self::classified(err.class(), err.origin(), err.to_string())
209 }
210}