icydb_core/db/query/trace.rs
1//! Module: query::trace
2//! Responsibility: lightweight, deterministic trace projections for planned queries.
3//! Does not own: query semantics, plan hashing primitives, or executor routing policy.
4//! Boundary: read-only diagnostics surface assembled at query/session boundaries.
5
6use crate::db::query::explain::ExplainPlan;
7
8///
9/// TraceExecutionFamily
10///
11/// TraceExecutionFamily is the query-facing execution-family label derived at
12/// the session boundary after executor route selection.
13/// It keeps high-level trace shape visible without making query diagnostics
14/// depend on executor-owned route types.
15///
16#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum TraceExecutionFamily {
18 PrimaryKey,
19 Ordered,
20 Grouped,
21}
22
23///
24/// TraceReuseArtifactClass
25///
26/// Trace-surface label for the planner-owned artifact class reused for this
27/// query identity.
28/// `0.109.0` ships one explicit reuse class: the shared prepared query plan.
29///
30#[derive(Clone, Copy, Debug, Eq, PartialEq)]
31pub enum TraceReuseArtifactClass {
32 SharedPreparedQueryPlan,
33}
34
35///
36/// TraceReuseEvent
37///
38/// Trace-surface semantic reuse result for one query planning attempt.
39/// This keeps the shipped `0.109.0` reuse boundary explicit: one artifact
40/// class and one exact-match hit or miss outcome.
41///
42#[derive(Clone, Copy, Debug, Eq, PartialEq)]
43pub struct TraceReuseEvent {
44 pub(in crate::db) artifact_class: TraceReuseArtifactClass,
45 pub(in crate::db) hit: bool,
46}
47
48impl TraceReuseEvent {
49 /// Construct one reuse-hit event for the shipped artifact class.
50 #[must_use]
51 pub const fn hit(artifact_class: TraceReuseArtifactClass) -> Self {
52 Self {
53 artifact_class,
54 hit: true,
55 }
56 }
57
58 /// Construct one reuse-miss event for the shipped artifact class.
59 #[must_use]
60 pub const fn miss(artifact_class: TraceReuseArtifactClass) -> Self {
61 Self {
62 artifact_class,
63 hit: false,
64 }
65 }
66
67 /// Return the shipped artifact class this event describes.
68 #[must_use]
69 pub const fn artifact_class(self) -> TraceReuseArtifactClass {
70 self.artifact_class
71 }
72
73 /// Return true when this event represents a semantic-reuse hit.
74 #[must_use]
75 pub const fn is_hit(self) -> bool {
76 self.hit
77 }
78}
79
80///
81/// QueryTracePlan
82///
83/// Lightweight trace payload for one planned query.
84/// Includes plan hash, selected access strategy summary, reuse attribution,
85/// and logical explain output.
86///
87#[derive(Clone, Debug, Eq, PartialEq)]
88pub struct QueryTracePlan {
89 pub(in crate::db) plan_hash: String,
90 pub(in crate::db) access_strategy: String,
91 pub(in crate::db) execution_family: Option<TraceExecutionFamily>,
92 pub(in crate::db) reuse: TraceReuseEvent,
93 pub(in crate::db) explain: ExplainPlan,
94}
95
96impl QueryTracePlan {
97 /// Construct one query trace payload.
98 #[must_use]
99 pub const fn new(
100 plan_hash: String,
101 access_strategy: String,
102 execution_family: Option<TraceExecutionFamily>,
103 reuse: TraceReuseEvent,
104 explain: ExplainPlan,
105 ) -> Self {
106 Self {
107 plan_hash,
108 access_strategy,
109 execution_family,
110 reuse,
111 explain,
112 }
113 }
114
115 /// Borrow the canonical explain fingerprint hash.
116 #[must_use]
117 pub const fn plan_hash(&self) -> &str {
118 self.plan_hash.as_str()
119 }
120
121 /// Borrow the rendered access strategy summary.
122 #[must_use]
123 pub const fn access_strategy(&self) -> &str {
124 self.access_strategy.as_str()
125 }
126
127 /// Return the selected execution family classification.
128 #[must_use]
129 pub const fn execution_family(&self) -> Option<TraceExecutionFamily> {
130 self.execution_family
131 }
132
133 /// Return semantic-reuse attribution for this trace build.
134 #[must_use]
135 pub const fn reuse(&self) -> TraceReuseEvent {
136 self.reuse
137 }
138
139 /// Borrow planner explain output carried in this trace payload.
140 #[must_use]
141 pub const fn explain(&self) -> &ExplainPlan {
142 &self.explain
143 }
144}