use crate::db::{session::sql::CompiledSqlCommand, sql::parser::SqlParsePhaseAttribution};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
pub(in crate::db) struct SqlCompilePhaseAttribution {
pub cache_key: u64,
pub cache_lookup: u64,
pub parse: u64,
pub parse_tokenize: u64,
pub parse_select: u64,
pub parse_expr: u64,
pub parse_predicate: u64,
pub aggregate_lane_check: u64,
pub prepare: u64,
pub lower: u64,
pub bind: u64,
pub cache_insert: u64,
}
#[derive(Debug)]
pub(in crate::db) struct SqlCompileArtifacts {
pub command: CompiledSqlCommand,
pub shape: SqlQueryShape,
pub aggregate_lane_check: u64,
pub prepare: u64,
pub lower: u64,
pub bind: u64,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(in crate::db) struct SqlQueryShape {
pub is_aggregate: bool,
pub returns_rows: bool,
pub is_mutation: bool,
}
impl SqlQueryShape {
#[must_use]
pub(in crate::db::session::sql) const fn read_rows(is_aggregate: bool) -> Self {
Self {
is_aggregate,
returns_rows: true,
is_mutation: false,
}
}
#[must_use]
pub(in crate::db::session::sql) const fn metadata() -> Self {
Self {
is_aggregate: false,
returns_rows: false,
is_mutation: false,
}
}
#[must_use]
pub(in crate::db::session::sql) const fn mutation(returns_rows: bool) -> Self {
Self {
is_aggregate: false,
returns_rows,
is_mutation: true,
}
}
}
#[derive(Clone, Copy, Debug, Default)]
pub(in crate::db::session::sql) struct SqlCompileAttributionBuilder {
phase: SqlCompilePhaseAttribution,
}
impl SqlCompileAttributionBuilder {
pub(in crate::db::session::sql) const fn record_cache_key(&mut self, local_instructions: u64) {
self.phase.cache_key = local_instructions;
}
pub(in crate::db::session::sql) const fn record_cache_lookup(
&mut self,
local_instructions: u64,
) {
self.phase.cache_lookup = local_instructions;
}
pub(in crate::db::session::sql) const fn record_parse(
&mut self,
local_instructions: u64,
attribution: SqlParsePhaseAttribution,
) {
let statement_shell = local_instructions
.saturating_sub(attribution.tokenize)
.saturating_sub(attribution.expr)
.saturating_sub(attribution.predicate);
self.phase.parse = local_instructions;
self.phase.parse_tokenize = attribution.tokenize;
self.phase.parse_select = statement_shell;
self.phase.parse_expr = attribution.expr;
self.phase.parse_predicate = attribution.predicate;
}
pub(in crate::db::session::sql) const fn record_core_compile(
&mut self,
attribution: SqlCompilePhaseAttribution,
) {
self.phase.aggregate_lane_check = attribution.aggregate_lane_check;
self.phase.prepare = attribution.prepare;
self.phase.lower = attribution.lower;
self.phase.bind = attribution.bind;
}
pub(in crate::db::session::sql) const fn record_cache_insert(
&mut self,
local_instructions: u64,
) {
self.phase.cache_insert = local_instructions;
}
#[must_use]
pub(in crate::db::session::sql) const fn finish(self) -> SqlCompilePhaseAttribution {
self.phase
}
}
impl SqlCompileArtifacts {
pub(in crate::db::session::sql) fn new(
command: CompiledSqlCommand,
shape: SqlQueryShape,
aggregate_lane_check: u64,
prepare: u64,
lower: u64,
bind: u64,
) -> Self {
debug_assert_eq!(
shape.is_aggregate,
matches!(command, CompiledSqlCommand::GlobalAggregate { .. }),
"compile aggregate shape must match the compiled command variant"
);
debug_assert_eq!(
shape.is_mutation,
matches!(
command,
CompiledSqlCommand::Delete { .. }
| CompiledSqlCommand::Insert(_)
| CompiledSqlCommand::Update(_)
),
"compile mutation shape must match the compiled command variant"
);
debug_assert_eq!(
shape.returns_rows,
Self::command_returns_rows(&command),
"compile row-returning shape must match the compiled command variant"
);
Self {
command,
shape,
aggregate_lane_check,
prepare,
lower,
bind,
}
}
const fn command_returns_rows(command: &CompiledSqlCommand) -> bool {
match command {
CompiledSqlCommand::Select { .. } | CompiledSqlCommand::GlobalAggregate { .. } => true,
CompiledSqlCommand::Delete { returning, .. } => returning.is_some(),
CompiledSqlCommand::Insert(statement) => statement.returning.is_some(),
CompiledSqlCommand::Update(statement) => statement.returning.is_some(),
CompiledSqlCommand::Explain(_)
| CompiledSqlCommand::DescribeEntity
| CompiledSqlCommand::ShowIndexesEntity
| CompiledSqlCommand::ShowColumnsEntity
| CompiledSqlCommand::ShowEntities => false,
}
}
#[must_use]
pub(in crate::db::session::sql) const fn phase_attribution(
&self,
) -> SqlCompilePhaseAttribution {
SqlCompilePhaseAttribution {
cache_key: 0,
cache_lookup: 0,
parse: 0,
parse_tokenize: 0,
parse_select: 0,
parse_expr: 0,
parse_predicate: 0,
aggregate_lane_check: self.aggregate_lane_check,
prepare: self.prepare,
lower: self.lower,
bind: self.bind,
cache_insert: 0,
}
}
}