graphrecords_query/operations/grouping/
inspection.rs1use crate::{
2 Arity, Bare, Definite, ElementShape, EvaluateOperand, Explain, IndexDomain, Indexed, Labeled,
3 Multiple, Operand, QueryResult, Single, Unordered,
4 execution::EvaluationCache,
5 index::GroupKey,
6 operands::{FailuresOperand, OperandHandle, Partition},
7 operations::{Apply, BucketFailureArity, GroupKernel, Operation, OperationContext, Prepare},
8 optimizer::{OperationInputs, OptimizerHints, PlanIdentity, PlanInputs},
9 registry::operation_manifest,
10 traits::{BucketErrors, KeyErrors},
11};
12use graphrecords_core::GraphRecord;
13
14#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
15#[operation(scope = Group)]
16#[explain(label = "BucketErrors")]
17#[plan(optimizer_hints(empty = if_any))]
18pub struct BucketErrorsOperation;
19
20impl Prepare for BucketErrorsOperation {
21 type Prepared<'a> = ();
22
23 fn prepare<'a>(
24 &'a self,
25 _graphrecord: &'a GraphRecord,
26 _cache: &'a EvaluationCache<'a>,
27 ) -> QueryResult<Self::Prepared<'a>> {
28 Ok(())
29 }
30}
31
32impl<M: IndexDomain, K: GroupKey, S: ElementShape, C: BucketFailureArity<S>>
33 GroupKernel<M, K, OperandHandle<S, C>> for BucketErrorsOperation
34{
35 type Output = FailuresOperand<K, Unordered>;
36
37 fn execute<'a>(
38 graphrecord: &'a GraphRecord,
39 partition: Partition<'a, M, K, OperandHandle<S, C>>,
40 _prepared: Self::Prepared<'a>,
41 ) -> QueryResult<<Self::Output as EvaluateOperand>::ReturnValue<'a>> {
42 let elements: Vec<_> = partition
43 .buckets()
44 .filter_map(|bucket| {
45 C::bucket_failure(bucket.payload()).map(|failure| {
46 let index = K::resolve_key(Self::LABEL, graphrecord, bucket.key())?;
47
48 Ok((index, Ok(failure.clone())))
49 })
50 })
51 .collect::<QueryResult<_>>()?;
52
53 Ok(Box::new(elements.into_iter()))
54 }
55}
56
57impl<O: Apply<BucketErrorsOperation>> BucketErrors for O {
58 type ReturnOperand = O::Output;
59
60 fn bucket_errors(&self) -> Self::ReturnOperand {
61 Self::ReturnOperand::new(OperationContext::new(self.clone(), BucketErrorsOperation))
62 }
63}
64
65pub(super) mod bucket_errors {
66 use super::{
67 Bare, BucketErrors, BucketErrorsOperation, Definite, FailuresOperand, Indexed, Multiple,
68 OperandHandle, Single, Unordered, operation_manifest,
69 };
70
71 operation_manifest! {
72 BucketErrorsOperation {
73 method: BucketErrors::bucket_errors;
74 scope: group;
75
76 kernel {
77 group: <M: IndexDomain, K: GroupKey>;
78 parameters: <I: IndexDomain, V: ValueDomain, O: OrderState>;
79 input: OperandHandle<Indexed<I, V>, Multiple<O>>;
80 output: FailuresOperand<K, Unordered>;
81 }
82 kernel {
83 group: <M: IndexDomain, K: GroupKey>;
84 parameters: <I: IndexDomain, V: ValueDomain>;
85 input: OperandHandle<Indexed<I, V>, Single>;
86 output: FailuresOperand<K, Unordered>;
87 }
88 kernel {
89 group: <M: IndexDomain, K: GroupKey>;
90 parameters: <I: IndexDomain, V: ValueDomain>;
91 input: OperandHandle<Indexed<I, V>, Definite>;
92 output: FailuresOperand<K, Unordered>;
93 }
94 kernel {
95 group: <M: IndexDomain, K: GroupKey>;
96 parameters: <V: BareValueDomain, O: OrderState>;
97 input: OperandHandle<Bare<V>, Multiple<O>>;
98 output: FailuresOperand<K, Unordered>;
99 }
100 kernel {
101 group: <M: IndexDomain, K: GroupKey>;
102 parameters: <V: BareValueDomain>;
103 input: OperandHandle<Bare<V>, Single>;
104 output: FailuresOperand<K, Unordered>;
105 }
106 kernel {
107 group: <M: IndexDomain, K: GroupKey>;
108 parameters: <V: BareValueDomain>;
109 input: OperandHandle<Bare<V>, Definite>;
110 output: FailuresOperand<K, Unordered>;
111 }
112 }
113 }
114}
115
116#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
117#[operation(scope = Group)]
118#[explain(label = "KeyErrors")]
119#[plan(optimizer_hints(empty = if_any))]
120pub struct KeyErrorsOperation;
121
122impl Prepare for KeyErrorsOperation {
123 type Prepared<'a> = ();
124
125 fn prepare<'a>(
126 &'a self,
127 _graphrecord: &'a GraphRecord,
128 _cache: &'a EvaluationCache<'a>,
129 ) -> QueryResult<Self::Prepared<'a>> {
130 Ok(())
131 }
132}
133
134impl<M: IndexDomain, K: GroupKey, S: ElementShape, C: Arity> GroupKernel<M, K, OperandHandle<S, C>>
135 for KeyErrorsOperation
136{
137 type Output = FailuresOperand<M, Unordered>;
138
139 fn execute<'a>(
140 _graphrecord: &'a GraphRecord,
141 partition: Partition<'a, M, K, OperandHandle<S, C>>,
142 _prepared: Self::Prepared<'a>,
143 ) -> QueryResult<<Self::Output as EvaluateOperand>::ReturnValue<'a>> {
144 let key_failures = partition.into_parts().1;
145
146 Ok(Box::new(
147 key_failures
148 .into_iter()
149 .map(|(member, failure)| (member, Ok(*failure))),
150 ))
151 }
152}
153
154impl<O: Apply<KeyErrorsOperation>> KeyErrors for O {
155 type ReturnOperand = O::Output;
156
157 fn key_errors(&self) -> Self::ReturnOperand {
158 Self::ReturnOperand::new(OperationContext::new(self.clone(), KeyErrorsOperation))
159 }
160}
161
162pub(super) mod key_errors {
163 use super::{
164 FailuresOperand, KeyErrors, KeyErrorsOperation, OperandHandle, Unordered,
165 operation_manifest,
166 };
167
168 operation_manifest! {
169 KeyErrorsOperation {
170 method: KeyErrors::key_errors;
171 scope: group;
172
173 kernel {
174 group: <M: IndexDomain, K: GroupKey>;
175 parameters: <S: ElementShape, C: Arity>;
176 input: OperandHandle<S, C>;
177 output: FailuresOperand<M, Unordered>;
178 }
179 }
180 }
181}