graphrecords_query/operations/comparison/
less_than.rs1use super::{ordering_bare, ordering_indexed};
2use crate::{
3 Bare, BareValueDomain, Explain, IndexDomain, Indexed, Labeled, Mask, Operand, QueryResult,
4 capabilities::ValueOrdering,
5 execution::EvaluationCache,
6 operations::{
7 Apply, ArgumentSource, ElementKernel, ElementPipeline, Keyed, Operation, OperationContext,
8 Prepare, Unaligned,
9 },
10 optimizer::{Estimate, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs, Stats},
11 registry::{describe::ArgumentRetention, operation_manifest},
12 traits::LessThan,
13};
14use graphrecords_core::GraphRecord;
15use std::{
16 cmp::Ordering,
17 fmt::{Debug, Display},
18};
19
20#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
21#[operation(scope = Element)]
22#[explain(label = "LessThan")]
23#[plan(optimizer_hints(empty = if_all))]
24pub struct LessThanOperation<A> {
25 #[argument]
26 argument: A,
27}
28
29impl<A: Prepare> Prepare for LessThanOperation<A> {
30 type Prepared<'a>
31 = A::Prepared<'a>
32 where
33 Self: 'a;
34
35 fn prepare<'a>(
36 &'a self,
37 graphrecord: &'a GraphRecord,
38 cache: &'a EvaluationCache<'a>,
39 ) -> QueryResult<Self::Prepared<'a>> {
40 self.argument.prepare(graphrecord, cache)
41 }
42}
43
44impl<I, V, A> ElementKernel<Indexed<I, V>> for LessThanOperation<A>
45where
46 I: IndexDomain,
47 V: ValueOrdering,
48 A: ArgumentSource<Keyed<I>, V>,
49 V::Owned: Debug + Display + Send + Sync,
50{
51 type Emission = A::Retention;
52 type OutShape = Indexed<I, Mask>;
53
54 fn pipeline<'a>(
55 _graphrecord: &'a GraphRecord,
56 prepared: Self::Prepared<'a>,
57 ) -> QueryResult<ElementPipeline<'a, Indexed<I, V>, Self>> {
58 Ok(ordering_indexed::<_, V, A>(
59 prepared,
60 Self::LABEL,
61 V::ordering,
62 Ordering::is_lt,
63 ))
64 }
65
66 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
67 Estimate {
68 selectivity: None,
69 ..input.with_unknown_distinct()
70 }
71 }
72}
73
74impl<V, A> ElementKernel<Bare<V>> for LessThanOperation<A>
75where
76 V: ValueOrdering + BareValueDomain,
77 A: ArgumentSource<Unaligned, V>,
78 V::Owned: Debug + Display + Send + Sync,
79{
80 type Emission = A::Retention;
81 type OutShape = Bare<Mask>;
82
83 fn pipeline<'a>(
84 _graphrecord: &'a GraphRecord,
85 prepared: Self::Prepared<'a>,
86 ) -> QueryResult<ElementPipeline<'a, Bare<V>, Self>> {
87 Ok(ordering_bare::<V, A>(
88 prepared,
89 Self::LABEL,
90 V::ordering,
91 Ordering::is_lt,
92 ))
93 }
94
95 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
96 Estimate {
97 selectivity: None,
98 ..input.with_unknown_distinct()
99 }
100 }
101}
102
103impl<O, A> LessThan<A> for O
104where
105 LessThanOperation<A>: Operation,
106 O: Apply<LessThanOperation<A>>,
107{
108 type ReturnOperand = O::Output;
109
110 fn less_than(&self, argument: A) -> Self::ReturnOperand {
111 Self::ReturnOperand::new(OperationContext::new(
112 self.clone(),
113 LessThanOperation { argument },
114 ))
115 }
116}
117
118operation_manifest! {
119 LessThanOperation<A> {
120 method: LessThan<A>::less_than;
121 scope: element;
122
123 kernel {
124 parameters: <I: IndexDomain, V: ValueOrdering>;
125 argument: A: ArgumentSource<Keyed<I>, V>;
126 input: Indexed<I, V>;
127 output: Indexed<I, Mask>;
128 emission: ArgumentRetention;
129 where V::Owned: Debug + Display + Send + Sync;
130 }
131
132 kernel {
133 parameters: <V: ValueOrdering + BareValueDomain>;
134 argument: A: ArgumentSource<Unaligned, V>;
135 input: Bare<V>;
136 output: Bare<Mask>;
137 emission: ArgumentRetention;
138 where V::Owned: Debug + Display + Send + Sync;
139 }
140 }
141}