Skip to main content

icydb_core/db/query/fingerprint/
fingerprint.rs

1//! Module: query::fingerprint::fingerprint
2//! Responsibility: deterministic plan fingerprint derivation from planner contracts.
3//! Does not own: explain projection assembly or execution-plan compilation.
4//! Boundary: stable plan identity hash surface for diagnostics/caching.
5
6use crate::db::{
7    codec::hex::encode_hex_lower,
8    query::{
9        explain::ExplainPlan,
10        fingerprint::{finalize_sha256_digest, hash_sections, new_plan_fingerprint_hasher},
11    },
12};
13
14///
15/// PlanFingerprint
16///
17/// Stable, deterministic fingerprint for logical plans.
18///
19
20#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
21pub struct PlanFingerprint([u8; 32]);
22
23impl PlanFingerprint {
24    #[must_use]
25    pub fn as_hex(&self) -> String {
26        encode_hex_lower(&self.0)
27    }
28}
29
30impl std::fmt::Display for PlanFingerprint {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        f.write_str(&self.as_hex())
33    }
34}
35
36impl ExplainPlan {
37    /// Compute a stable fingerprint for this explain plan.
38    #[must_use]
39    pub fn fingerprint(&self) -> PlanFingerprint {
40        // Phase 1: hash canonical explain fields under the current fingerprint profile.
41        let mut hasher = new_plan_fingerprint_hasher();
42        hash_sections::hash_explain_plan_profile(
43            &mut hasher,
44            self,
45            hash_sections::ExplainHashProfile::Fingerprint,
46        );
47
48        // Phase 2: finalize into the fixed-width fingerprint payload.
49        PlanFingerprint(finalize_sha256_digest(hasher))
50    }
51}