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 data::DataKey,
53 plan::AccessPlannedQuery,
54 query::{
55 fluent::{delete::FluentDeleteQuery, load::FluentLoadQuery},
56 intent::{PlannedQuery, Query, QueryError},
57 predicate::PredicateFieldSlots,
58 },
59 },
60 error::{ErrorClass, ErrorOrigin, InternalError},
61 traits::EntityKind,
62};
63use thiserror::Error as ThisError;
64
65pub(super) fn compile_predicate_slots<E: EntityKind>(
66 plan: &AccessPlannedQuery<E::Key>,
67) -> Option<PredicateFieldSlots> {
68 plan.predicate
69 .as_ref()
70 .map(PredicateFieldSlots::resolve::<E>)
71}
72
73impl<E: EntityKind> From<PlannedQuery<E>> for ExecutablePlan<E> {
74 fn from(value: PlannedQuery<E>) -> Self {
75 Self::new(value.into_inner())
76 }
77}
78
79impl<E: EntityKind> Query<E> {
80 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
82 self.planned().map(ExecutablePlan::from)
83 }
84}
85
86impl<E: EntityKind> FluentLoadQuery<'_, E> {
87 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
89 self.planned().map(ExecutablePlan::from)
90 }
91}
92
93impl<E: EntityKind> FluentDeleteQuery<'_, E> {
94 pub fn plan(&self) -> Result<ExecutablePlan<E>, QueryError> {
96 self.planned().map(ExecutablePlan::from)
97 }
98}
99
100#[derive(Debug, ThisError)]
105pub(crate) enum ExecutorError {
106 #[error("corruption detected ({origin}): {message}")]
107 Corruption {
108 origin: ErrorOrigin,
109 message: String,
110 },
111
112 #[error("data key exists: {0}")]
113 KeyExists(DataKey),
114}
115
116impl ExecutorError {
117 pub(crate) const fn class(&self) -> ErrorClass {
118 match self {
119 Self::KeyExists(_) => ErrorClass::Conflict,
120 Self::Corruption { .. } => ErrorClass::Corruption,
121 }
122 }
123
124 pub(crate) const fn origin(&self) -> ErrorOrigin {
125 match self {
126 Self::KeyExists(_) => ErrorOrigin::Store,
127 Self::Corruption { origin, .. } => *origin,
128 }
129 }
130
131 pub(crate) fn corruption(origin: ErrorOrigin, message: impl Into<String>) -> Self {
132 Self::Corruption {
133 origin,
134 message: message.into(),
135 }
136 }
137
138 pub(crate) fn store_corruption(message: impl Into<String>) -> Self {
140 Self::corruption(ErrorOrigin::Store, message)
141 }
142
143 pub(crate) fn serialize_corruption(message: impl Into<String>) -> Self {
145 Self::corruption(ErrorOrigin::Serialize, message)
146 }
147
148 pub(crate) fn store_corruption_from(source: impl std::fmt::Display) -> Self {
150 Self::store_corruption(source.to_string())
151 }
152}
153
154impl From<ExecutorError> for InternalError {
155 fn from(err: ExecutorError) -> Self {
156 Self::classified(err.class(), err.origin(), err.to_string())
157 }
158}