Skip to main content

icydb_core/db/executor/
executable_plan.rs

1//! Module: db::executor::executable_plan
2//! Responsibility: bind validated access-planned queries to executor-ready contracts.
3//! Does not own: logical plan semantics or route policy decisions.
4//! Boundary: shared plan container for load/delete/aggregate runtime entrypoints.
5
6#[cfg(test)]
7use crate::db::executor::planning::route::LoadTerminalFastPathContract;
8use crate::{
9    db::{
10        access::AccessPlan,
11        cursor::{ContinuationSignature, CursorPlanError, GroupedPlannedCursor, PlannedCursor},
12        executor::{
13            EntityAuthority, ExecutionPreparation, ExecutorPlanError, GroupedPaginationWindow,
14            LoweredIndexPrefixSpec, LoweredIndexRangeSpec,
15            explain::assemble_load_execution_node_descriptor, lower_index_prefix_specs,
16            lower_index_range_specs, planning::preparation::slot_map_for_model_plan,
17            traversal::row_read_consistency_for_plan,
18        },
19        predicate::MissingRowPolicy,
20        query::explain::ExplainExecutionNodeDescriptor,
21        query::plan::{
22            AccessPlannedQuery, ContinuationContract, ExecutionOrdering, GroupSpec, OrderSpec,
23            QueryMode, constant_covering_projection_value_from_access,
24            covering_index_projection_context,
25        },
26    },
27    error::InternalError,
28    traits::{EntityKind, EntityValue},
29};
30use std::marker::PhantomData;
31#[cfg(test)]
32use std::ops::Bound;
33///
34/// ExecutionStrategy
35///
36/// Executor-facing execution shape contract derived from planner ordering.
37/// Session and runtime entrypoints consume this strategy and must not
38/// re-derive grouped/scalar routing shape from boolean flags.
39///
40#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41pub enum ExecutionStrategy {
42    PrimaryKey,
43    Ordered,
44    Grouped,
45}
46
47///
48/// BytesByProjectionMode
49///
50/// Canonical `bytes_by(field)` projection mode classification used by execution
51/// and explain surfaces.
52///
53
54#[derive(Clone, Copy, Debug, Eq, PartialEq)]
55pub(in crate::db) enum BytesByProjectionMode {
56    Materialized,
57    CoveringIndex,
58    CoveringConstant,
59}
60
61/// Classify canonical `bytes_by(field)` execution mode from one neutral access context.
62#[must_use]
63pub(in crate::db::executor) fn classify_bytes_by_projection_mode(
64    access: &AccessPlan<crate::value::Value>,
65    order_spec: Option<&OrderSpec>,
66    consistency: MissingRowPolicy,
67    has_predicate: bool,
68    target_field: &str,
69    primary_key_name: &'static str,
70) -> BytesByProjectionMode {
71    if !matches!(consistency, MissingRowPolicy::Ignore) {
72        return BytesByProjectionMode::Materialized;
73    }
74
75    if constant_covering_projection_value_from_access(access, target_field).is_some() {
76        return BytesByProjectionMode::CoveringConstant;
77    }
78
79    if has_predicate {
80        return BytesByProjectionMode::Materialized;
81    }
82
83    if covering_index_projection_context(access, order_spec, target_field, primary_key_name)
84        .is_some()
85    {
86        return BytesByProjectionMode::CoveringIndex;
87    }
88
89    BytesByProjectionMode::Materialized
90}
91
92/// ExecutablePlanCore
93///
94/// Generic-free executable-plan payload shared by typed `ExecutablePlan<E>`
95/// wrappers. This keeps cursor, ordering, and lowered structural plan state
96/// monomorphic while typed access and model-driven behavior remain at the
97/// outer executor boundary.
98///
99
100#[derive(Debug)]
101struct ExecutablePlanCore {
102    plan: AccessPlannedQuery,
103    continuation: Option<ContinuationContract>,
104    index_prefix_specs: Vec<LoweredIndexPrefixSpec>,
105    index_prefix_spec_invalid: bool,
106    index_range_specs: Vec<LoweredIndexRangeSpec>,
107    index_range_spec_invalid: bool,
108}
109
110impl ExecutablePlanCore {
111    #[must_use]
112    const fn new(
113        plan: AccessPlannedQuery,
114        continuation: Option<ContinuationContract>,
115        index_prefix_specs: Vec<LoweredIndexPrefixSpec>,
116        index_prefix_spec_invalid: bool,
117        index_range_specs: Vec<LoweredIndexRangeSpec>,
118        index_range_spec_invalid: bool,
119    ) -> Self {
120        Self {
121            plan,
122            continuation,
123            index_prefix_specs,
124            index_prefix_spec_invalid,
125            index_range_specs,
126            index_range_spec_invalid,
127        }
128    }
129
130    #[must_use]
131    const fn plan(&self) -> &AccessPlannedQuery {
132        &self.plan
133    }
134
135    #[must_use]
136    const fn mode(&self) -> QueryMode {
137        self.plan.scalar_plan().mode
138    }
139
140    #[must_use]
141    const fn is_grouped(&self) -> bool {
142        match self.continuation {
143            Some(ref contract) => contract.is_grouped(),
144            None => false,
145        }
146    }
147
148    fn execution_ordering(&self) -> Result<ExecutionOrdering, InternalError> {
149        let contract = self.continuation_contract()?;
150        Ok(contract.order_contract().ordering().clone())
151    }
152
153    fn execution_strategy(&self) -> Result<ExecutionStrategy, InternalError> {
154        let ordering = self.execution_ordering()?;
155
156        Ok(match ordering {
157            ExecutionOrdering::PrimaryKey => ExecutionStrategy::PrimaryKey,
158            ExecutionOrdering::Explicit(_) => ExecutionStrategy::Ordered,
159            ExecutionOrdering::Grouped(_) => ExecutionStrategy::Grouped,
160        })
161    }
162
163    #[must_use]
164    const fn consistency(&self) -> MissingRowPolicy {
165        row_read_consistency_for_plan(&self.plan)
166    }
167
168    #[must_use]
169    const fn order_spec(&self) -> Option<&OrderSpec> {
170        self.plan.scalar_plan().order.as_ref()
171    }
172
173    #[must_use]
174    fn has_predicate(&self) -> bool {
175        self.plan.has_residual_predicate()
176    }
177
178    fn index_prefix_specs(&self) -> Result<&[LoweredIndexPrefixSpec], InternalError> {
179        if self.index_prefix_spec_invalid {
180            return Err(
181                ExecutorPlanError::lowered_index_prefix_spec_invalid().into_internal_error()
182            );
183        }
184
185        Ok(self.index_prefix_specs.as_slice())
186    }
187
188    fn index_range_specs(&self) -> Result<&[LoweredIndexRangeSpec], InternalError> {
189        if self.index_range_spec_invalid {
190            return Err(ExecutorPlanError::lowered_index_range_spec_invalid().into_internal_error());
191        }
192
193        Ok(self.index_range_specs.as_slice())
194    }
195
196    #[must_use]
197    fn into_inner(self) -> AccessPlannedQuery {
198        self.plan
199    }
200
201    fn prepare_cursor(
202        &self,
203        authority: EntityAuthority,
204        cursor: Option<&[u8]>,
205    ) -> Result<PlannedCursor, ExecutorPlanError> {
206        let Some(contract) = self.continuation.as_ref() else {
207            return Err(ExecutorPlanError::continuation_cursor_requires_load_plan());
208        };
209
210        authority
211            .prepare_scalar_cursor(contract, cursor)
212            .map_err(ExecutorPlanError::from)
213    }
214
215    fn revalidate_cursor(
216        &self,
217        authority: EntityAuthority,
218        cursor: PlannedCursor,
219    ) -> Result<PlannedCursor, InternalError> {
220        let Some(contract) = self.continuation.as_ref() else {
221            return Err(
222                ExecutorPlanError::continuation_cursor_requires_load_plan().into_internal_error()
223            );
224        };
225
226        authority
227            .revalidate_scalar_cursor(contract, cursor)
228            .map_err(CursorPlanError::into_internal_error)
229    }
230
231    fn revalidate_grouped_cursor(
232        &self,
233        cursor: GroupedPlannedCursor,
234    ) -> Result<GroupedPlannedCursor, InternalError> {
235        let Some(contract) = self.continuation.as_ref() else {
236            return Err(
237                ExecutorPlanError::grouped_cursor_revalidation_requires_grouped_plan()
238                    .into_internal_error(),
239            );
240        };
241
242        contract
243            .revalidate_grouped_cursor(cursor)
244            .map_err(CursorPlanError::into_internal_error)
245    }
246
247    fn continuation_signature_for_runtime(&self) -> Result<ContinuationSignature, InternalError> {
248        let contract = self.continuation_contract()?;
249        Ok(contract.continuation_signature())
250    }
251
252    fn grouped_cursor_boundary_arity(&self) -> Result<usize, InternalError> {
253        let contract = self.continuation_contract()?;
254        if !contract.is_grouped() {
255            return Err(
256                ExecutorPlanError::grouped_cursor_boundary_arity_requires_grouped_plan()
257                    .into_internal_error(),
258            );
259        }
260
261        Ok(contract.boundary_arity())
262    }
263
264    fn grouped_pagination_window(
265        &self,
266        cursor: &GroupedPlannedCursor,
267    ) -> Result<GroupedPaginationWindow, InternalError> {
268        let contract = self.continuation_contract()?;
269        let window = contract
270            .grouped_paging_window(cursor)
271            .map_err(CursorPlanError::into_internal_error)?;
272        let (
273            limit,
274            initial_offset_for_page,
275            selection_bound,
276            resume_initial_offset,
277            resume_boundary,
278        ) = window.into_parts();
279
280        Ok(GroupedPaginationWindow::new(
281            limit,
282            initial_offset_for_page,
283            selection_bound,
284            resume_initial_offset,
285            resume_boundary,
286        ))
287    }
288
289    // Borrow immutable continuation contract for load-mode plans.
290    fn continuation_contract(&self) -> Result<&ContinuationContract, InternalError> {
291        self.continuation.as_ref().ok_or_else(|| {
292            ExecutorPlanError::continuation_contract_requires_load_plan().into_internal_error()
293        })
294    }
295}
296
297// Build one canonical lowered executable-plan core from resolved authority
298// plus one logical plan, regardless of whether the caller started from a typed
299// `ExecutablePlan<E>` shell or a structural follow-on rewrite.
300fn build_executable_plan_core(
301    authority: EntityAuthority,
302    mut plan: AccessPlannedQuery,
303) -> ExecutablePlanCore {
304    authority.finalize_static_planning_shape(&mut plan);
305
306    // Phase 0: derive immutable continuation contract once from planner semantics.
307    let continuation = plan.continuation_contract(authority.entity_path());
308
309    // Phase 1: lower index-prefix specs once and retain invariant state.
310    let (index_prefix_specs, index_prefix_spec_invalid) =
311        match lower_index_prefix_specs(authority.entity_tag(), &plan.access) {
312            Ok(specs) => (specs, false),
313            Err(_) => (Vec::new(), true),
314        };
315
316    // Phase 2: lower index-range specs once and retain invariant state.
317    let (index_range_specs, index_range_spec_invalid) =
318        match lower_index_range_specs(authority.entity_tag(), &plan.access) {
319            Ok(specs) => (specs, false),
320            Err(_) => (Vec::new(), true),
321        };
322
323    ExecutablePlanCore::new(
324        plan,
325        continuation,
326        index_prefix_specs,
327        index_prefix_spec_invalid,
328        index_range_specs,
329        index_range_spec_invalid,
330    )
331}
332
333///
334/// ExecutablePlan
335///
336/// Executor-ready plan bound to a specific entity type.
337///
338
339#[derive(Debug)]
340pub(in crate::db) struct ExecutablePlan<E: EntityKind> {
341    core: ExecutablePlanCore,
342    marker: PhantomData<fn() -> E>,
343}
344
345///
346/// PreparedLoadPlan
347///
348/// Generic-free load-plan boundary consumed by continuation resolution and
349/// load pipeline preparation after the typed `ExecutablePlan<E>` shell is no
350/// longer needed.
351///
352
353#[derive(Debug)]
354pub(in crate::db::executor) struct PreparedLoadPlan {
355    authority: EntityAuthority,
356    core: ExecutablePlanCore,
357}
358
359impl PreparedLoadPlan {
360    #[must_use]
361    pub(in crate::db::executor) fn from_plan(
362        authority: EntityAuthority,
363        plan: AccessPlannedQuery,
364    ) -> Self {
365        Self {
366            authority,
367            core: build_executable_plan_core(authority, plan),
368        }
369    }
370
371    #[must_use]
372    pub(in crate::db::executor) const fn authority(&self) -> EntityAuthority {
373        self.authority
374    }
375
376    #[must_use]
377    pub(in crate::db::executor) const fn mode(&self) -> QueryMode {
378        self.core.mode()
379    }
380
381    #[must_use]
382    pub(in crate::db::executor) const fn logical_plan(&self) -> &AccessPlannedQuery {
383        self.core.plan()
384    }
385
386    pub(in crate::db::executor) fn execution_ordering(
387        &self,
388    ) -> Result<ExecutionOrdering, InternalError> {
389        self.core.execution_ordering()
390    }
391
392    pub(in crate::db::executor) fn revalidate_cursor(
393        &self,
394        cursor: PlannedCursor,
395    ) -> Result<PlannedCursor, InternalError> {
396        self.core.revalidate_cursor(self.authority, cursor)
397    }
398
399    pub(in crate::db::executor) fn revalidate_grouped_cursor(
400        &self,
401        cursor: GroupedPlannedCursor,
402    ) -> Result<GroupedPlannedCursor, InternalError> {
403        self.core.revalidate_grouped_cursor(cursor)
404    }
405
406    pub(in crate::db::executor) fn continuation_signature_for_runtime(
407        &self,
408    ) -> Result<ContinuationSignature, InternalError> {
409        self.core.continuation_signature_for_runtime()
410    }
411
412    pub(in crate::db::executor) fn grouped_cursor_boundary_arity(
413        &self,
414    ) -> Result<usize, InternalError> {
415        self.core.grouped_cursor_boundary_arity()
416    }
417
418    pub(in crate::db::executor) fn grouped_pagination_window(
419        &self,
420        cursor: &GroupedPlannedCursor,
421    ) -> Result<GroupedPaginationWindow, InternalError> {
422        self.core.grouped_pagination_window(cursor)
423    }
424
425    pub(in crate::db::executor) fn index_prefix_specs(
426        &self,
427    ) -> Result<&[LoweredIndexPrefixSpec], InternalError> {
428        self.core.index_prefix_specs()
429    }
430
431    pub(in crate::db::executor) fn index_range_specs(
432        &self,
433    ) -> Result<&[LoweredIndexRangeSpec], InternalError> {
434        self.core.index_range_specs()
435    }
436
437    #[must_use]
438    pub(in crate::db::executor) fn into_plan(self) -> AccessPlannedQuery {
439        self.core.into_inner()
440    }
441}
442
443///
444/// PreparedAggregatePlan
445///
446/// Generic-free aggregate-plan boundary consumed by aggregate terminal and
447/// runtime preparation after the typed `ExecutablePlan<E>` shell is no longer
448/// needed.
449///
450
451#[derive(Debug)]
452pub(in crate::db::executor) struct PreparedAggregatePlan {
453    authority: EntityAuthority,
454    core: ExecutablePlanCore,
455}
456
457impl PreparedAggregatePlan {
458    #[must_use]
459    pub(in crate::db::executor) fn execution_preparation(&self) -> ExecutionPreparation {
460        ExecutionPreparation::from_plan(self.core.plan(), slot_map_for_model_plan(self.core.plan()))
461    }
462
463    pub(in crate::db::executor) fn into_streaming_parts(
464        self,
465    ) -> Result<
466        (
467            EntityAuthority,
468            AccessPlannedQuery,
469            Vec<LoweredIndexPrefixSpec>,
470            Vec<LoweredIndexRangeSpec>,
471        ),
472        InternalError,
473    > {
474        let Self { authority, core } = self;
475        if core.index_prefix_spec_invalid {
476            return Err(
477                ExecutorPlanError::lowered_index_prefix_spec_invalid().into_internal_error()
478            );
479        }
480        if core.index_range_spec_invalid {
481            return Err(ExecutorPlanError::lowered_index_range_spec_invalid().into_internal_error());
482        }
483
484        Ok((
485            authority,
486            core.plan,
487            core.index_prefix_specs,
488            core.index_range_specs,
489        ))
490    }
491
492    /// Re-shape one prepared aggregate plan into one grouped prepared load plan
493    /// without reconstructing a typed `ExecutablePlan<E>` shell.
494    #[must_use]
495    pub(in crate::db::executor) fn into_grouped_load_plan(
496        self,
497        group: GroupSpec,
498    ) -> PreparedLoadPlan {
499        PreparedLoadPlan::from_plan(self.authority, self.core.into_inner().into_grouped(group))
500    }
501}
502
503impl<E: EntityKind> ExecutablePlan<E> {
504    pub(in crate::db) fn new(plan: AccessPlannedQuery) -> Self {
505        Self::build(plan)
506    }
507
508    fn build(mut plan: AccessPlannedQuery) -> Self {
509        let authority = EntityAuthority::for_type::<E>();
510        authority.finalize_static_planning_shape(&mut plan);
511        authority.finalize_planner_route_profile(&mut plan);
512
513        Self {
514            core: build_executable_plan_core(authority, plan),
515            marker: PhantomData,
516        }
517    }
518
519    /// Explain scalar load execution shape as one canonical execution-node descriptor tree.
520    pub(in crate::db) fn explain_load_execution_node_descriptor(
521        &self,
522    ) -> Result<ExplainExecutionNodeDescriptor, InternalError>
523    where
524        E: EntityValue,
525    {
526        if !self.mode().is_load() {
527            return Err(
528                ExecutorPlanError::load_execution_descriptor_requires_load_plan()
529                    .into_internal_error(),
530            );
531        }
532
533        let authority = EntityAuthority::for_type::<E>();
534
535        assemble_load_execution_node_descriptor(
536            authority.fields(),
537            authority.primary_key_name(),
538            self.core.plan(),
539        )
540    }
541
542    /// Validate and decode a continuation cursor into executor-ready cursor state.
543    pub(in crate::db) fn prepare_cursor(
544        &self,
545        cursor: Option<&[u8]>,
546    ) -> Result<PlannedCursor, ExecutorPlanError> {
547        self.core
548            .prepare_cursor(EntityAuthority::for_type::<E>(), cursor)
549    }
550
551    /// Return the plan mode (load vs delete).
552    #[must_use]
553    pub(in crate::db) const fn mode(&self) -> QueryMode {
554        self.core.mode()
555    }
556
557    /// Return whether this executable plan carries grouped logical shape.
558    #[must_use]
559    pub(in crate::db) const fn is_grouped(&self) -> bool {
560        self.core.is_grouped()
561    }
562
563    /// Return planner-projected execution strategy for entrypoint dispatch.
564    pub(in crate::db) fn execution_strategy(&self) -> Result<ExecutionStrategy, InternalError> {
565        self.core.execution_strategy()
566    }
567
568    /// Borrow the structural logical plan for executor-owned tests.
569    #[must_use]
570    #[cfg(test)]
571    pub(in crate::db) const fn logical_plan(&self) -> &AccessPlannedQuery {
572        self.core.plan()
573    }
574
575    /// Expose planner-projected execution ordering for executor/lowering tests.
576    #[cfg(test)]
577    pub(in crate::db) fn execution_ordering(&self) -> Result<ExecutionOrdering, InternalError> {
578        self.core.execution_ordering()
579    }
580
581    pub(in crate::db) const fn access(
582        &self,
583    ) -> &crate::db::access::AccessPlan<crate::value::Value> {
584        &self.core.plan().access
585    }
586
587    /// Borrow scalar row-consistency policy for runtime row reads.
588    #[must_use]
589    pub(in crate::db) const fn consistency(&self) -> MissingRowPolicy {
590        self.core.consistency()
591    }
592
593    /// Classify canonical `bytes_by(field)` execution mode for this plan/field.
594    #[must_use]
595    pub(in crate::db) fn bytes_by_projection_mode(
596        &self,
597        target_field: &str,
598    ) -> BytesByProjectionMode {
599        let authority = EntityAuthority::for_type::<E>();
600
601        classify_bytes_by_projection_mode(
602            self.access(),
603            self.order_spec(),
604            self.consistency(),
605            self.has_predicate(),
606            target_field,
607            authority.primary_key_name(),
608        )
609    }
610
611    /// Return a stable explain/diagnostic label for one bytes-by mode.
612    #[must_use]
613    pub(in crate::db) const fn bytes_by_projection_mode_label(
614        mode: BytesByProjectionMode,
615    ) -> &'static str {
616        match mode {
617            BytesByProjectionMode::Materialized => "field_materialized",
618            BytesByProjectionMode::CoveringIndex => "field_covering_index",
619            BytesByProjectionMode::CoveringConstant => "field_covering_constant",
620        }
621    }
622
623    /// Borrow scalar ORDER BY contract for this executable plan, if any.
624    #[must_use]
625    pub(in crate::db::executor) const fn order_spec(&self) -> Option<&OrderSpec> {
626        self.core.order_spec()
627    }
628
629    /// Return whether this executable plan has a residual predicate.
630    #[must_use]
631    pub(in crate::db::executor) fn has_predicate(&self) -> bool {
632        self.core.has_predicate()
633    }
634
635    pub(in crate::db) fn index_prefix_specs(
636        &self,
637    ) -> Result<&[LoweredIndexPrefixSpec], InternalError> {
638        self.core.index_prefix_specs()
639    }
640
641    pub(in crate::db) fn index_range_specs(
642        &self,
643    ) -> Result<&[LoweredIndexRangeSpec], InternalError> {
644        self.core.index_range_specs()
645    }
646
647    /// Render one canonical executor snapshot for test-only planner/executor
648    /// contract checks.
649    #[cfg(test)]
650    pub(in crate::db) fn render_snapshot_canonical(&self) -> Result<String, InternalError>
651    where
652        E: EntityValue,
653    {
654        // Phase 1: project all executor-owned summary fields from the logical plan.
655        let plan = self.core.plan();
656        let authority = EntityAuthority::for_type::<E>();
657        let projection_spec = plan.frozen_projection_spec();
658        let projection_selection = if plan.grouped_plan().is_some()
659            || projection_spec.len() != authority.row_layout().field_count()
660        {
661            "Declared"
662        } else {
663            "All"
664        };
665        let projection_coverage_flag = plan.grouped_plan().is_some();
666        let continuation_signature = self.core.continuation_signature_for_runtime()?;
667        let ordering_direction = self
668            .core
669            .continuation_contract()?
670            .order_contract()
671            .direction();
672        let load_terminal_fast_path =
673            crate::db::executor::planning::route::derive_load_terminal_fast_path_contract_for_plan(
674                authority, plan,
675            );
676
677        // Phase 2: lower index-bound summaries into stable compact text.
678        let index_prefix_specs = render_index_prefix_specs(self.core.index_prefix_specs()?);
679        let index_range_specs = render_index_range_specs(self.core.index_range_specs()?);
680        let explain_plan = plan.explain_with_model(E::MODEL);
681
682        // Phase 3: join the canonical snapshot payload in one stable line order.
683        Ok([
684            "snapshot_version=1".to_string(),
685            format!("plan_hash={}", plan.fingerprint()),
686            format!("mode={:?}", self.core.mode()),
687            format!("is_grouped={}", self.core.is_grouped()),
688            format!("execution_strategy={:?}", self.core.execution_strategy()?),
689            format!(
690                "load_terminal_fast_path={}",
691                render_load_terminal_fast_path_label(load_terminal_fast_path.as_ref())
692            ),
693            format!("ordering_direction={ordering_direction:?}"),
694            format!(
695                "distinct_execution_strategy={:?}",
696                plan.distinct_execution_strategy()
697            ),
698            format!("projection_selection={projection_selection}"),
699            format!("projection_spec={projection_spec:?}"),
700            format!("order_spec={:?}", plan.scalar_plan().order),
701            format!("page_spec={:?}", plan.scalar_plan().page),
702            format!("projection_coverage_flag={projection_coverage_flag}"),
703            format!("continuation_signature={continuation_signature}"),
704            format!("index_prefix_specs={index_prefix_specs}"),
705            format!("index_range_specs={index_range_specs}"),
706            format!("explain_plan={explain_plan:?}"),
707        ]
708        .join("\n"))
709    }
710
711    /// Split the executable plan into its canonical structural logical plan.
712    ///
713    /// Aggregate/scalar prepared boundaries should prefer this helper when they
714    /// no longer need the typed `ExecutablePlan<E>` shell after entering
715    /// structural execution preparation.
716    pub(in crate::db) fn into_plan(self) -> AccessPlannedQuery {
717        self.core.into_inner()
718    }
719
720    /// Validate and decode grouped continuation cursor state for grouped plans.
721    #[cfg(test)]
722    pub(in crate::db) fn prepare_grouped_cursor(
723        &self,
724        cursor: Option<&[u8]>,
725    ) -> Result<GroupedPlannedCursor, ExecutorPlanError> {
726        let Some(contract) = self.core.continuation.as_ref() else {
727            return Err(ExecutorPlanError::grouped_cursor_preparation_requires_grouped_plan());
728        };
729
730        contract
731            .prepare_grouped_cursor(EntityAuthority::for_type::<E>().entity_path(), cursor)
732            .map_err(ExecutorPlanError::from)
733    }
734
735    /// Validate one already-decoded grouped continuation token for grouped plans.
736    pub(in crate::db) fn prepare_grouped_cursor_token(
737        &self,
738        cursor: Option<crate::db::cursor::GroupedContinuationToken>,
739    ) -> Result<GroupedPlannedCursor, ExecutorPlanError> {
740        let Some(contract) = self.core.continuation.as_ref() else {
741            return Err(ExecutorPlanError::grouped_cursor_preparation_requires_grouped_plan());
742        };
743
744        contract
745            .prepare_grouped_cursor_token(EntityAuthority::for_type::<E>().entity_path(), cursor)
746            .map_err(ExecutorPlanError::from)
747    }
748
749    /// Consume one typed load executable plan into one generic-free boundary
750    /// payload for continuation and load-pipeline preparation.
751    #[must_use]
752    pub(in crate::db::executor) fn into_prepared_load_plan(self) -> PreparedLoadPlan {
753        PreparedLoadPlan {
754            authority: EntityAuthority::for_type::<E>(),
755            core: self.core,
756        }
757    }
758
759    /// Consume one typed aggregate executable plan into one generic-free
760    /// boundary payload for aggregate terminal and runtime preparation.
761    #[must_use]
762    pub(in crate::db::executor) fn into_prepared_aggregate_plan(self) -> PreparedAggregatePlan {
763        PreparedAggregatePlan {
764            authority: EntityAuthority::for_type::<E>(),
765            core: self.core,
766        }
767    }
768}
769
770#[cfg(test)]
771const fn render_load_terminal_fast_path_label(
772    contract: Option<&LoadTerminalFastPathContract>,
773) -> &'static str {
774    match contract {
775        Some(LoadTerminalFastPathContract::CoveringRead(_)) => "CoveringRead",
776        None => "Materialized",
777    }
778}
779
780#[cfg(test)]
781fn render_index_prefix_specs(specs: &[LoweredIndexPrefixSpec]) -> String {
782    let rendered = specs
783        .iter()
784        .map(|spec| {
785            format!(
786                "{{index:{},bound_type:equality,lower:{},upper:{}}}",
787                spec.index().name(),
788                render_lowered_bound(spec.lower()),
789                render_lowered_bound(spec.upper()),
790            )
791        })
792        .collect::<Vec<_>>();
793
794    format!("[{}]", rendered.join(","))
795}
796
797#[cfg(test)]
798fn render_index_range_specs(specs: &[LoweredIndexRangeSpec]) -> String {
799    let rendered = specs
800        .iter()
801        .map(|spec| {
802            format!(
803                "{{index:{},lower:{},upper:{}}}",
804                spec.index().name(),
805                render_lowered_bound(spec.lower()),
806                render_lowered_bound(spec.upper()),
807            )
808        })
809        .collect::<Vec<_>>();
810
811    format!("[{}]", rendered.join(","))
812}
813
814#[cfg(test)]
815fn render_lowered_bound(bound: &Bound<crate::db::access::LoweredKey>) -> String {
816    match bound {
817        Bound::Included(key) => format!("included({})", render_lowered_key_summary(key)),
818        Bound::Excluded(key) => format!("excluded({})", render_lowered_key_summary(key)),
819        Bound::Unbounded => "unbounded".to_string(),
820    }
821}
822
823#[cfg(test)]
824fn render_lowered_key_summary(key: &crate::db::access::LoweredKey) -> String {
825    let bytes = key.as_bytes();
826    let head_len = bytes.len().min(8);
827    let tail_len = bytes.len().min(8);
828    let head = crate::db::codec::cursor::encode_cursor(&bytes[..head_len]);
829    let tail = crate::db::codec::cursor::encode_cursor(&bytes[bytes.len() - tail_len..]);
830
831    format!("len:{}:head:{head}:tail:{tail}", bytes.len())
832}