icydb_core/db/query/
diagnostics.rs1pub use crate::db::executor::trace::{QueryTraceEvent, TraceAccess, TraceExecutorKind, TracePhase};
11use crate::db::query::plan::{AccessPath, AccessPlan, ExplainPlan, PlanFingerprint};
12
13#[derive(Clone, Debug, Eq, PartialEq)]
20pub struct QueryDiagnostics {
21 pub explain: ExplainPlan,
22 pub fingerprint: PlanFingerprint,
23}
24
25impl From<ExplainPlan> for QueryDiagnostics {
26 fn from(explain: ExplainPlan) -> Self {
27 let fingerprint = explain.fingerprint();
28 Self {
29 explain,
30 fingerprint,
31 }
32 }
33}
34
35#[derive(Clone, Debug, Eq, PartialEq)]
42pub struct QueryExecutionDiagnostics {
43 pub fingerprint: PlanFingerprint,
44 pub events: Vec<QueryTraceEvent>,
45}
46
47pub type QueryTraceAccess = TraceAccess;
49
50pub type QueryTraceExecutorKind = TraceExecutorKind;
52
53pub type QueryTracePhase = TracePhase;
55
56pub(crate) fn trace_access_from_plan<K>(plan: &AccessPlan<K>) -> TraceAccess {
57 match plan {
58 AccessPlan::Path(path) => trace_access_from_path(path),
59 AccessPlan::Union(children) => {
60 TraceAccess::Union {
62 branches: u32::try_from(children.len()).unwrap_or(u32::MAX),
63 }
64 }
65 AccessPlan::Intersection(children) => {
66 TraceAccess::Intersection {
68 branches: u32::try_from(children.len()).unwrap_or(u32::MAX),
69 }
70 }
71 }
72}
73
74fn trace_access_from_path<K>(path: &AccessPath<K>) -> TraceAccess {
75 match path {
76 AccessPath::ByKey(_) => TraceAccess::ByKey,
77 AccessPath::ByKeys(keys) => {
78 TraceAccess::ByKeys {
80 count: u32::try_from(keys.len()).unwrap_or(u32::MAX),
81 }
82 }
83 AccessPath::KeyRange { .. } => TraceAccess::KeyRange,
84 AccessPath::IndexPrefix { index, values } => {
85 TraceAccess::IndexPrefix {
87 name: index.name,
88 prefix_len: u32::try_from(values.len()).unwrap_or(u32::MAX),
89 }
90 }
91 AccessPath::FullScan => TraceAccess::FullScan,
92 }
93}
94
95#[must_use]
96pub const fn start_event(
97 fingerprint: PlanFingerprint,
98 access: Option<TraceAccess>,
99 executor: TraceExecutorKind,
100) -> QueryTraceEvent {
101 QueryTraceEvent::Start {
102 fingerprint,
103 executor,
104 access,
105 }
106}
107
108#[must_use]
109pub const fn finish_event(
110 fingerprint: PlanFingerprint,
111 access: Option<TraceAccess>,
112 executor: TraceExecutorKind,
113 rows: u64,
114) -> QueryTraceEvent {
115 QueryTraceEvent::Finish {
116 fingerprint,
117 executor,
118 access,
119 rows,
120 }
121}