icydb_core/db/query/plan/
executable.rs1use crate::{
2 db::query::plan::{ExplainPlan, LogicalPlan, PlanFingerprint},
3 error::{ErrorClass, ErrorOrigin, InternalError},
4 traits::EntityKind,
5};
6use std::marker::PhantomData;
7
8pub struct ExecutablePlan<E: EntityKind> {
15 plan: LogicalPlan,
16 _marker: PhantomData<E>,
17}
18
19impl<E: EntityKind> ExecutablePlan<E> {
20 pub(crate) const fn new(plan: LogicalPlan) -> Self {
21 Self {
22 plan,
23 _marker: PhantomData,
24 }
25 }
26
27 #[must_use]
29 pub fn explain(&self) -> ExplainPlan {
30 self.plan.explain()
31 }
32
33 #[must_use]
35 pub fn fingerprint(&self) -> PlanFingerprint {
36 self.plan.fingerprint()
37 }
38
39 pub(crate) const fn access(&self) -> &crate::db::query::plan::AccessPlan {
40 &self.plan.access
41 }
42
43 pub(crate) fn into_inner(self) -> LogicalPlan {
44 self.plan
45 }
46
47 #[must_use]
49 pub fn erase(self) -> ExecutablePlanErased {
50 ExecutablePlanErased {
51 plan: self.plan,
52 entity_path: E::PATH,
53 }
54 }
55}
56
57#[doc(hidden)]
59pub struct ExecutablePlanErased {
60 plan: LogicalPlan,
61 entity_path: &'static str,
62}
63
64impl ExecutablePlanErased {
65 #[doc(hidden)]
66 pub fn into_typed<E: EntityKind>(self) -> Result<ExecutablePlan<E>, InternalError> {
67 if self.entity_path != E::PATH {
68 return Err(InternalError::new(
69 ErrorClass::Unsupported,
70 ErrorOrigin::Query,
71 format!(
72 "plan entity mismatch: expected {}, found {}",
73 E::PATH,
74 self.entity_path
75 ),
76 ));
77 }
78
79 Ok(ExecutablePlan::new(self.plan))
80 }
81}