use crate::{
db::{
access::AccessPlan,
predicate::{Predicate, normalize, normalize_enum_literals},
query::plan::{OrderSpec, PlannerError, canonicalize_order_spec, plan_access_with_order},
schema::{SchemaInfo, ValidateError, reject_unsupported_query_features},
},
model::{entity::EntityModel, index::IndexModel},
value::Value,
};
#[derive(Debug)]
pub(in crate::db::query) struct AccessPlanningInputs<'a> {
predicate: Option<&'a Predicate>,
order: Option<&'a OrderSpec>,
key_access_override: Option<AccessPlan<Value>>,
}
impl<'a> AccessPlanningInputs<'a> {
#[must_use]
pub(in crate::db::query) const fn new(
predicate: Option<&'a Predicate>,
order: Option<&'a OrderSpec>,
key_access_override: Option<AccessPlan<Value>>,
) -> Self {
Self {
predicate,
order,
key_access_override,
}
}
#[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
}
#[must_use]
pub(in crate::db::query) fn into_key_access_override(self) -> Option<AccessPlan<Value>> {
self.key_access_override
}
}
pub(in crate::db::query) fn normalize_query_predicate(
schema_info: &SchemaInfo,
predicate: Option<&Predicate>,
) -> Result<Option<Predicate>, ValidateError> {
predicate
.map(|predicate| {
reject_unsupported_query_features(predicate).map_err(ValidateError::from)?;
let predicate = normalize_enum_literals(schema_info, predicate)?;
Ok::<Predicate, ValidateError>(normalize(&predicate))
})
.transpose()
}
pub(in crate::db::query) fn plan_query_access(
model: &EntityModel,
visible_indexes: &[&'static IndexModel],
schema_info: &SchemaInfo,
normalized_predicate: Option<&Predicate>,
order: Option<&OrderSpec>,
key_access_override: Option<AccessPlan<Value>>,
) -> Result<AccessPlan<Value>, PlannerError> {
if let Some(plan) = key_access_override {
Ok(plan)
} else {
let canonical_order = canonicalize_order_spec(model, order.cloned());
plan_access_with_order(
model,
visible_indexes,
schema_info,
normalized_predicate,
canonical_order.as_ref(),
)
}
}