Skip to main content

hawdb_executor/
retrieval_report.rs

1// Copyright 2026 Nowledge
2// Licensed under the Apache License, Version 2.0.
3
4//! Provider-attested coverage and actual grouped selection work.
5
6use hawdb_plan_cypher::PhysicalOperatorId;
7
8/// Optional native source evidence. A generation is diagnostic identity, not
9/// permission to combine this source with a different canonical snapshot.
10#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
11pub struct TextSeedSourceReport {
12    pub generation: Option<u64>,
13    pub source_commit_epoch: Option<u64>,
14    pub corpus_documents: Option<usize>,
15    pub matching_documents: Option<usize>,
16    pub postings_visited: Option<u64>,
17    pub bytes_read: Option<u64>,
18    pub document_bytes_read: Option<u64>,
19}
20
21#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
22pub struct TextSeedExecutionReport {
23    pub operator_id: Option<PhysicalOperatorId>,
24    pub complete_requested: bool,
25    pub executed: bool,
26    pub source_exhausted: bool,
27    pub candidate_limit: usize,
28    /// The provider's result before canonical filtering or a downstream LIMIT.
29    pub candidate_count: usize,
30    pub retained_result_bytes: usize,
31    pub source: Option<TextSeedSourceReport>,
32}
33
34impl TextSeedExecutionReport {
35    pub fn status(&self) -> &'static str {
36        if !self.executed {
37            "skipped"
38        } else if !self.complete_requested {
39            "window"
40        } else if self.source_exhausted {
41            "complete"
42        } else {
43            "incomplete"
44        }
45    }
46}
47
48#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
49pub struct GroupedEvidenceExecutionReport {
50    pub operator_id: Option<PhysicalOperatorId>,
51    pub executed: bool,
52    /// Exhaustion of the aggregate's declared input, including semantic LIMITs.
53    pub input_exhausted: bool,
54    pub input_rows: usize,
55    /// Repeated empty or single scalar-column keys reused without an owned copy.
56    pub borrowed_group_key_rows: usize,
57    pub groups_considered: usize,
58    pub retained_evidence: usize,
59    pub output_groups: usize,
60    pub peak_state_bytes: usize,
61    pub spilled_bytes: u64,
62}
63
64#[cfg(test)]
65mod tests {
66    use super::*;
67    use crate::observer::{grouped_evidence_report_value, text_seed_execution_report_value};
68    use hawdb_core::Value;
69
70    #[test]
71    fn coverage_status_and_value_encoding_preserve_unknown_source_evidence() {
72        let mut report = TextSeedExecutionReport {
73            complete_requested: true,
74            operator_id: Some(PhysicalOperatorId::from_ordinal(4)),
75            ..Default::default()
76        };
77        assert_eq!(report.status(), "skipped");
78        report.executed = true;
79        assert_eq!(report.status(), "incomplete");
80        report.source_exhausted = true;
81        assert_eq!(report.status(), "complete");
82        report.source = Some(TextSeedSourceReport {
83            generation: Some(19),
84            postings_visited: Some(32),
85            ..Default::default()
86        });
87        let Value::Map(encoded) = text_seed_execution_report_value(&report) else {
88            panic!()
89        };
90        assert_eq!(encoded["operator_id"], Value::Int(4));
91        assert_eq!(encoded["status"], Value::String("complete".into()));
92        let Value::Map(source) = &encoded["source"] else {
93            panic!()
94        };
95        assert_eq!(source["generation"], Value::Int(19));
96        assert_eq!(source["source_commit_epoch"], Value::Null);
97        assert_eq!(source["bytes_read"], Value::Null);
98        report.complete_requested = false;
99        assert_eq!(report.status(), "window");
100        let Value::Map(grouped) =
101            grouped_evidence_report_value(&GroupedEvidenceExecutionReport::default())
102        else {
103            panic!()
104        };
105        assert_eq!(grouped["executed"], Value::Bool(false));
106        assert_eq!(grouped["input_exhausted"], Value::Bool(false));
107    }
108}