#[cfg(feature = "diagnostics")]
use crate::db::{
DirectDataRowAttribution, GroupedExecutionAttribution, KernelRowAttribution,
ScalarAggregateAttribution,
executor::{
GroupedCountAttribution as ExecutorGroupedCountAttribution,
ScalarAggregateTerminalAttribution,
},
session::sql::{
cache::SqlCacheAttribution, compile::SqlCompilePhaseAttribution,
projection::SqlProjectionMaterializationMetrics,
},
};
#[cfg(feature = "diagnostics")]
use candid::CandidType;
#[cfg(feature = "diagnostics")]
use serde::Deserialize;
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlCompileAttribution {
pub cache_key_local_instructions: u64,
pub cache_lookup_local_instructions: u64,
pub parse_local_instructions: u64,
pub parse_tokenize_local_instructions: u64,
pub parse_select_local_instructions: u64,
pub parse_expr_local_instructions: u64,
pub parse_predicate_local_instructions: u64,
pub aggregate_lane_check_local_instructions: u64,
pub prepare_local_instructions: u64,
pub lower_local_instructions: u64,
pub bind_local_instructions: u64,
pub cache_insert_local_instructions: u64,
}
#[cfg(feature = "diagnostics")]
impl SqlCompileAttribution {
pub(in crate::db::session::sql) const fn from_phase(phase: SqlCompilePhaseAttribution) -> Self {
Self {
cache_key_local_instructions: phase.cache_key,
cache_lookup_local_instructions: phase.cache_lookup,
parse_local_instructions: phase.parse,
parse_tokenize_local_instructions: phase.parse_tokenize,
parse_select_local_instructions: phase.parse_select,
parse_expr_local_instructions: phase.parse_expr,
parse_predicate_local_instructions: phase.parse_predicate,
aggregate_lane_check_local_instructions: phase.aggregate_lane_check,
prepare_local_instructions: phase.prepare,
lower_local_instructions: phase.lower,
bind_local_instructions: phase.bind,
cache_insert_local_instructions: phase.cache_insert,
}
}
}
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlExecutionAttribution {
pub planner_local_instructions: u64,
pub planner_schema_info_local_instructions: u64,
pub planner_prepare_local_instructions: u64,
pub planner_cache_key_local_instructions: u64,
pub planner_cache_lookup_local_instructions: u64,
pub planner_plan_build_local_instructions: u64,
pub planner_cache_insert_local_instructions: u64,
pub store_local_instructions: u64,
pub executor_invocation_local_instructions: u64,
pub executor_local_instructions: u64,
pub response_finalization_local_instructions: u64,
}
#[cfg(feature = "diagnostics")]
impl SqlExecutionAttribution {
pub(in crate::db::session::sql) const fn from_phase(
phase: &SqlExecutePhaseAttribution,
) -> Self {
Self {
planner_local_instructions: phase.planner_local_instructions,
planner_schema_info_local_instructions: phase.planner_schema_info_local_instructions,
planner_prepare_local_instructions: phase.planner_prepare_local_instructions,
planner_cache_key_local_instructions: phase.planner_cache_key_local_instructions,
planner_cache_lookup_local_instructions: phase.planner_cache_lookup_local_instructions,
planner_plan_build_local_instructions: phase.planner_plan_build_local_instructions,
planner_cache_insert_local_instructions: phase.planner_cache_insert_local_instructions,
store_local_instructions: phase.store_local_instructions,
executor_invocation_local_instructions: phase.executor_invocation_local_instructions,
executor_local_instructions: phase.executor_local_instructions,
response_finalization_local_instructions: phase
.response_finalization_local_instructions,
}
}
}
#[cfg(feature = "diagnostics")]
pub type SqlScalarAggregateAttribution = ScalarAggregateAttribution;
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlPureCoveringAttribution {
pub decode_local_instructions: u64,
pub row_assembly_local_instructions: u64,
}
#[cfg(feature = "diagnostics")]
impl SqlPureCoveringAttribution {
pub(in crate::db::session::sql) const fn from_local_instructions(
decode_local_instructions: u64,
row_assembly_local_instructions: u64,
) -> Option<Self> {
if decode_local_instructions == 0 && row_assembly_local_instructions == 0 {
return None;
}
Some(Self {
decode_local_instructions,
row_assembly_local_instructions,
})
}
}
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlHybridCoveringAttribution {
pub path_hits: u64,
pub index_field_accesses: u64,
pub row_field_accesses: u64,
}
#[cfg(feature = "diagnostics")]
impl SqlHybridCoveringAttribution {
pub(in crate::db::session::sql) const fn from_projection_metrics(
metrics: SqlProjectionMaterializationMetrics,
) -> Option<Self> {
if metrics.has_hybrid_covering_work() {
Some(Self {
path_hits: metrics.hybrid_covering_path_hits,
index_field_accesses: metrics.hybrid_covering_index_field_accesses,
row_field_accesses: metrics.hybrid_covering_row_field_accesses,
})
} else {
None
}
}
}
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlOutputBlobAttribution {
pub projected_values: u64,
pub projected_bytes: u64,
pub rendered_hex_bytes: u64,
}
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Copy, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlQueryCacheAttribution {
pub sql_compiled_command_hits: u64,
pub sql_compiled_command_misses: u64,
pub shared_query_plan_hits: u64,
pub shared_query_plan_misses: u64,
}
#[cfg(feature = "diagnostics")]
impl SqlQueryCacheAttribution {
pub(in crate::db::session::sql) const fn from_phases(
compile: SqlCacheAttribution,
execute: SqlCacheAttribution,
) -> Self {
let merged = compile.merge(execute);
Self {
sql_compiled_command_hits: merged.sql_compiled_command_cache_hits,
sql_compiled_command_misses: merged.sql_compiled_command_cache_misses,
shared_query_plan_hits: merged.shared_query_plan_cache_hits,
shared_query_plan_misses: merged.shared_query_plan_cache_misses,
}
}
}
#[cfg(feature = "diagnostics")]
#[derive(CandidType, Clone, Debug, Default, Deserialize, Eq, PartialEq)]
pub struct SqlQueryExecutionAttribution {
pub compile_local_instructions: u64,
pub compile: SqlCompileAttribution,
pub plan_lookup_local_instructions: u64,
pub execution: SqlExecutionAttribution,
pub direct_data_row: Option<DirectDataRowAttribution>,
pub kernel_row: Option<KernelRowAttribution>,
pub grouped: Option<GroupedExecutionAttribution>,
pub scalar_aggregate: Option<SqlScalarAggregateAttribution>,
pub pure_covering: Option<SqlPureCoveringAttribution>,
pub hybrid_covering: Option<SqlHybridCoveringAttribution>,
pub output_blob: SqlOutputBlobAttribution,
pub store_get_calls: u64,
pub index_store_get_calls: u64,
pub index_store_range_scan_calls: u64,
pub index_store_entry_reads: u64,
pub response_decode_local_instructions: u64,
pub execute_local_instructions: u64,
pub total_local_instructions: u64,
pub cache: SqlQueryCacheAttribution,
}
#[cfg(feature = "diagnostics")]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(in crate::db) struct SqlExecutePhaseAttribution {
pub planner_local_instructions: u64,
pub planner_schema_info_local_instructions: u64,
pub planner_prepare_local_instructions: u64,
pub planner_cache_key_local_instructions: u64,
pub planner_cache_lookup_local_instructions: u64,
pub planner_plan_build_local_instructions: u64,
pub planner_cache_insert_local_instructions: u64,
pub store_local_instructions: u64,
pub executor_invocation_local_instructions: u64,
pub executor_local_instructions: u64,
pub response_finalization_local_instructions: u64,
pub grouped_stream_local_instructions: u64,
pub grouped_fold_local_instructions: u64,
pub grouped_finalize_local_instructions: u64,
pub grouped_count: ExecutorGroupedCountAttribution,
pub scalar_aggregate_terminal: ScalarAggregateTerminalAttribution,
pub direct_data_row: Option<DirectDataRowAttribution>,
pub kernel_row: Option<KernelRowAttribution>,
}
#[cfg(feature = "diagnostics")]
impl SqlExecutePhaseAttribution {
#[must_use]
pub(in crate::db) const fn from_execute_total_and_store_total(
execute_local_instructions: u64,
store_local_instructions: u64,
) -> Self {
Self {
planner_local_instructions: 0,
planner_schema_info_local_instructions: 0,
planner_prepare_local_instructions: 0,
planner_cache_key_local_instructions: 0,
planner_cache_lookup_local_instructions: 0,
planner_plan_build_local_instructions: 0,
planner_cache_insert_local_instructions: 0,
store_local_instructions,
executor_invocation_local_instructions: execute_local_instructions,
executor_local_instructions: execute_local_instructions
.saturating_sub(store_local_instructions),
response_finalization_local_instructions: 0,
grouped_stream_local_instructions: 0,
grouped_fold_local_instructions: 0,
grouped_finalize_local_instructions: 0,
grouped_count: ExecutorGroupedCountAttribution::none(),
scalar_aggregate_terminal: ScalarAggregateTerminalAttribution::none(),
direct_data_row: None,
kernel_row: None,
}
}
}