use crate::{
db::{
DbSession, MissingRowPolicy, QueryError,
executor::{
EntityAuthority, SharedPreparedExecutionPlan,
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_prepared_plan_with<
T,
>(
&self,
prepared_plan: SharedPreparedExecutionPlan,
projection: crate::db::session::sql::SqlProjectionContract,
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 (columns, fixed_scales) = projection.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 (prepared_plan, projection, cache_attribution) = self
.sql_select_prepared_plan_with_compiled_cache(
structural,
authority,
compiled_cache_key.schema_fingerprint(),
)?;
let (statement_result, ()) = self.execute_grouped_sql_statement_from_prepared_plan_with(
prepared_plan,
projection,
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))
}
}