use crate::{
db::{
DbSession, MissingRowPolicy, QueryError,
executor::{EntityAuthority, pipeline::execute_initial_grouped_rows_for_canister},
query::intent::StructuralQuery,
session::sql::{
SqlCacheAttribution, SqlCompiledCommandCacheKey, SqlStatementResult,
projection::{SqlProjectionPayload, grouped_sql_statement_result_from_page},
},
sql::lowering::{LoweredSelectShape, bind_lowered_sql_select_query_structural},
},
traits::CanisterKind,
};
impl<C: CanisterKind> DbSession<C> {
pub(in crate::db::session::sql) fn structural_query_from_lowered_select(
select: LoweredSelectShape,
authority: EntityAuthority,
) -> Result<crate::db::query::intent::StructuralQuery, QueryError> {
bind_lowered_sql_select_query_structural(
authority.model(),
select,
MissingRowPolicy::Ignore,
)
.map_err(QueryError::from_sql_lowering_error)
}
#[inline(never)]
pub(in crate::db::session::sql::execute) fn execute_lowered_sql_projection_core(
&self,
select: LoweredSelectShape,
authority: EntityAuthority,
) -> Result<SqlProjectionPayload, QueryError> {
let query = Self::structural_query_from_lowered_select(select, authority)?;
self.execute_structural_sql_projection_without_sql_cache(query, authority)
.map(|(payload, _)| payload)
}
pub(in crate::db::session::sql::execute) fn execute_grouped_sql_statement_from_entry_with<T>(
&self,
entry: crate::db::session::sql::SqlSelectPlanCacheEntry,
authority: EntityAuthority,
execute_grouped: impl FnOnce(
&Self,
EntityAuthority,
crate::db::query::plan::AccessPlannedQuery,
)
-> Result<(crate::db::executor::GroupedCursorPage, T), QueryError>,
) -> Result<(SqlStatementResult, T), QueryError> {
let (prepared_plan, columns, fixed_scales) = entry.into_parts();
let plan = prepared_plan.logical_plan().clone();
let (page, extra) = execute_grouped(self, authority, plan)?;
Ok((
grouped_sql_statement_result_from_page(columns, fixed_scales, page)?,
extra,
))
}
#[inline(never)]
pub(in crate::db::session::sql::execute) fn execute_structural_sql_grouped_statement_select_core(
&self,
structural: StructuralQuery,
authority: EntityAuthority,
compiled_cache_key: &SqlCompiledCommandCacheKey,
) -> Result<(SqlStatementResult, SqlCacheAttribution), QueryError> {
let (entry, cache_attribution) =
self.planned_sql_select_with_visibility(&structural, authority, compiled_cache_key)?;
let (statement_result, ()) = self.execute_grouped_sql_statement_from_entry_with(
entry,
authority,
|session, authority, plan| {
execute_initial_grouped_rows_for_canister(
&session.db,
session.debug,
authority,
plan,
)
.map_err(QueryError::execute)
.map(|page| (page, ()))
},
)?;
Ok((statement_result, cache_attribution))
}
}