use crate::{
db::{
direction::Direction,
executor::{
AccessStreamBindings, ExecutableAccess, ExecutionOptimization, LoweredIndexPrefixSpec,
pipeline::contracts::FastPathKeyResult,
scan::fast_stream::execute_structural_fast_stream_request,
stream::access::TraversalRuntime,
},
index::predicate::IndexPredicateExecution,
query::plan::AccessPlannedQuery,
},
error::InternalError,
};
pub(in crate::db::executor) fn execute_secondary_index_fast_stream_route(
runtime: &TraversalRuntime,
plan: &AccessPlannedQuery,
index_prefix_spec: Option<&LoweredIndexPrefixSpec>,
stream_direction: Direction,
probe_fetch_hint: Option<usize>,
index_predicate_execution: Option<IndexPredicateExecution<'_>>,
) -> Result<Option<FastPathKeyResult>, InternalError> {
let access_strategy = plan.access.resolve_strategy();
let Some(executable_path) = access_strategy.as_path() else {
return Ok(None);
};
let path_capabilities = executable_path.capabilities();
let Some(index) = path_capabilities.index_prefix_model() else {
return Ok(None);
};
let Some(index_prefix_spec) = index_prefix_spec else {
return Err(InternalError::secondary_index_prefix_spec_required());
};
debug_assert_eq!(
index_prefix_spec.index(),
&index,
"secondary fast-path spec/index alignment must be validated by resolver",
);
let access = ExecutableAccess::new(
&plan.access,
AccessStreamBindings::with_index_prefix(index_prefix_spec, stream_direction),
probe_fetch_hint,
index_predicate_execution,
);
let fast = execute_structural_fast_stream_request(
runtime,
access,
ExecutionOptimization::SecondaryOrderPushdown,
)?;
if let Some(fetch) = probe_fetch_hint {
debug_assert!(
fast.rows_scanned <= fetch,
"secondary fast-path rows_scanned must not exceed bounded fetch",
);
}
Ok(Some(fast))
}