use crate::{
db::{
QueryError,
access::AccessPlan,
predicate::{Predicate, normalize, normalize_enum_literals},
query::plan::{
OrderSpec, PlannedAccessSelection, VisibleIndexes,
canonicalize_order_spec_for_grouping,
plan_access_selection_with_order_and_semantic_indexes,
},
query::preparation::PreparationWork,
schema::SchemaInfo,
},
value::Value,
};
#[derive(Debug)]
pub(in crate::db::query) struct AccessPlanningInputs<'a> {
predicate: Option<&'a Predicate>,
order: Option<&'a OrderSpec>,
}
impl<'a> AccessPlanningInputs<'a> {
#[must_use]
pub(in crate::db::query) const fn new(
predicate: Option<&'a Predicate>,
order: Option<&'a OrderSpec>,
) -> Self {
Self { predicate, order }
}
#[must_use]
pub(in crate::db::query) const fn predicate(&self) -> Option<&'a Predicate> {
self.predicate
}
#[must_use]
pub(in crate::db::query) const fn order(&self) -> Option<&'a OrderSpec> {
self.order
}
}
pub(in crate::db::query) fn normalize_query_predicate(
schema_info: &SchemaInfo,
predicate: Option<&Predicate>,
work: &PreparationWork<'_>,
) -> Result<Option<Predicate>, QueryError> {
predicate
.map(|predicate| {
let predicate = normalize_enum_literals(schema_info, predicate, work)?;
Ok::<Predicate, QueryError>(normalize(predicate))
})
.transpose()
}
pub(in crate::db::query) fn plan_query_access_with_accepted_schema(
visible_indexes: &VisibleIndexes,
schema_info: &SchemaInfo,
normalized_predicate: Option<&Predicate>,
order: Option<&OrderSpec>,
grouped: bool,
key_access_override: Option<AccessPlan<Value>>,
work: &PreparationWork<'_>,
) -> Result<PlannedAccessSelection, QueryError> {
if let Some(plan) = key_access_override {
return Ok(PlannedAccessSelection::new(
plan,
Some(crate::db::query::plan::PlannedNonIndexAccessReason::IntentKeyAccessOverride),
));
}
let canonical_order = canonicalize_order_spec_for_grouping(
schema_info.primary_key_names(),
order.map(|order| work.copy_order_spec(order)).transpose()?,
grouped,
work,
)?;
plan_access_selection_with_order_and_semantic_indexes(
visible_indexes.accepted_semantic_index_contracts(),
schema_info,
normalized_predicate,
canonical_order.as_ref(),
grouped,
work,
)
.map_err(QueryError::from)
}