graphrecords_query/operations/indexing/
resolve.rs1use crate::{
2 Bare, EntityDomain, EntityReference, Explain, Failure, IndexDomain, IndexValue, Indexed,
3 Labeled, Operand, QueryResult,
4 element::{Pipeline, Preserving},
5 execution::EvaluationCache,
6 operations::{Apply, ElementKernel, ElementPipeline, Operation, OperationContext, Prepare},
7 optimizer::{OperationInputs, OptimizerHints, PlanIdentity, PlanInputs},
8 registry::operation_manifest,
9 traits::Resolve,
10};
11use graphrecords_core::GraphRecord;
12
13#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
14#[operation(scope = Element)]
15#[explain(label = "Resolve")]
16#[plan(optimizer_hints(allows_limit_pushdown, empty = if_any))]
17pub struct ResolveOperation;
18
19impl Prepare for ResolveOperation {
20 type Prepared<'a> = ();
21
22 fn prepare<'a>(
23 &'a self,
24 _graphrecord: &'a GraphRecord,
25 _cache: &'a EvaluationCache<'a>,
26 ) -> QueryResult<Self::Prepared<'a>> {
27 Ok(())
28 }
29}
30
31impl<E: EntityDomain, I: IndexDomain> ElementKernel<Indexed<I, IndexValue<E>>>
32 for ResolveOperation
33{
34 type Emission = Preserving;
35 type OutShape = Indexed<I, EntityReference<E>>;
36
37 fn pipeline<'a>(
38 graphrecord: &'a GraphRecord,
39 _prepared: Self::Prepared<'a>,
40 ) -> QueryResult<ElementPipeline<'a, Indexed<I, IndexValue<E>>, Self>> {
41 Ok(Pipeline::keyed(move |index, value: QueryResult<_>| {
42 value.and_then(|identifier| {
43 E::resolve_index(graphrecord, &identifier)
44 .map_err(|error| Failure::new_at::<I, _>(Self::LABEL, error, &index))
45 })
46 }))
47 }
48}
49
50impl<E: EntityDomain> ElementKernel<Bare<IndexValue<E>>> for ResolveOperation {
51 type Emission = Preserving;
52 type OutShape = Bare<EntityReference<E>>;
53
54 fn pipeline<'a>(
55 graphrecord: &'a GraphRecord,
56 _prepared: Self::Prepared<'a>,
57 ) -> QueryResult<ElementPipeline<'a, Bare<IndexValue<E>>, Self>> {
58 Ok(Pipeline::new(move |value: QueryResult<_>| {
59 value.and_then(|identifier| {
60 E::resolve_index(graphrecord, &identifier)
61 .map_err(|error| Failure::new(Self::LABEL, error))
62 })
63 }))
64 }
65}
66
67impl<O: Apply<ResolveOperation>> Resolve for O {
68 type ReturnOperand = O::Output;
69
70 fn resolve(&self) -> Self::ReturnOperand {
71 Self::ReturnOperand::new(OperationContext::new(self.clone(), ResolveOperation))
72 }
73}
74
75operation_manifest! {
76 ResolveOperation {
77 method: Resolve::resolve;
78 scope: element;
79
80 kernel {
81 parameters: <E: EntityDomain, I: IndexDomain>;
82 input: Indexed<I, IndexValue<E>>;
83 output: Indexed<I, EntityReference<E>>;
84 emission: Preserving;
85 }
86
87 kernel {
88 parameters: <E: EntityDomain>;
89 input: Bare<IndexValue<E>>;
90 output: Bare<EntityReference<E>>;
91 emission: Preserving;
92 }
93 }
94}