Skip to main content

graphrecords_query/operations/comparison/
less_than.rs

1use 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}