use crate::{
db::{
cursor::{GroupedPlannedCursor, PlannedCursor},
executor::planning::continuation::scalar::ScalarContinuationContext,
executor::{PreparedLoadPlan, pipeline::orchestrator::LoadSurfaceMode},
query::plan::ExecutionOrdering,
},
error::InternalError,
};
pub(in crate::db::executor) struct LoadCursorResolver;
impl LoadCursorResolver {
pub(in crate::db::executor) fn resolve_load_cursor_context(
plan: &PreparedLoadPlan,
cursor: LoadCursorInput,
execution_mode: LoadSurfaceMode,
) -> Result<PreparedLoadCursor, InternalError> {
let ordering = plan.execution_ordering()?;
execution_mode
.validate_grouped_ordering(matches!(ordering, ExecutionOrdering::Grouped(_)))?;
let cursor = match (execution_mode.is_scalar_page(), cursor) {
(true, LoadCursorInput::Scalar(cursor)) => {
let cursor = plan.revalidate_cursor(*cursor)?;
let continuation_signature = plan.continuation_signature_for_runtime()?;
PreparedLoadCursor::Scalar(Box::new(ScalarContinuationContext::for_runtime(
cursor,
continuation_signature,
)))
}
(false, LoadCursorInput::Grouped(cursor)) => {
PreparedLoadCursor::Grouped(plan.revalidate_grouped_cursor(cursor)?)
}
(true, LoadCursorInput::Grouped(_)) | (false, LoadCursorInput::Scalar(_)) => {
return Err(execution_mode.cursor_input_invariant_error());
}
};
Ok(cursor)
}
}
pub(in crate::db::executor) enum LoadCursorInput {
Scalar(Box<PlannedCursor>),
Grouped(GroupedPlannedCursor),
}
impl LoadCursorInput {
#[must_use]
pub(in crate::db::executor) fn scalar(cursor: impl Into<PlannedCursor>) -> Self {
Self::Scalar(Box::new(cursor.into()))
}
#[must_use]
pub(in crate::db::executor) fn grouped(cursor: impl Into<GroupedPlannedCursor>) -> Self {
Self::Grouped(cursor.into())
}
}
pub(in crate::db::executor) enum PreparedLoadCursor {
Scalar(Box<ScalarContinuationContext>),
Grouped(GroupedPlannedCursor),
}