graphrecords_query/operations/numeric/
negate.rs1use super::{numeric_bare, numeric_indexed};
2use crate::{
3 Bare, BareValueDomain, Explain, IndexDomain, Indexed, Labeled, Operand, QueryResult,
4 capabilities::ValueNegate,
5 element::Preserving,
6 execution::EvaluationCache,
7 operations::{Apply, ElementKernel, ElementPipeline, Operation, OperationContext, Prepare},
8 optimizer::{Estimate, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs, Stats},
9 registry::operation_manifest,
10 traits::Negate,
11};
12use graphrecords_core::GraphRecord;
13
14#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
15#[operation(scope = Element)]
16#[explain(label = "Negate")]
17#[plan(optimizer_hints(allows_limit_pushdown, empty = if_any))]
18pub struct NegateOperation;
19
20impl Prepare for NegateOperation {
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<I, V> ElementKernel<Indexed<I, V>> for NegateOperation
33where
34 I: IndexDomain,
35 V: ValueNegate,
36{
37 type Emission = Preserving;
38 type OutShape = Indexed<I, V>;
39
40 fn pipeline<'a>(
41 _graphrecord: &'a GraphRecord,
42 _prepared: Self::Prepared<'a>,
43 ) -> QueryResult<ElementPipeline<'a, Indexed<I, V>, Self>> {
44 Ok(numeric_indexed::<I, V, _>(Self::LABEL, V::negate))
45 }
46
47 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
48 input.with_unknown_distinct()
49 }
50}
51
52impl<V> ElementKernel<Bare<V>> for NegateOperation
53where
54 V: ValueNegate + BareValueDomain,
55{
56 type Emission = Preserving;
57 type OutShape = Bare<V>;
58
59 fn pipeline<'a>(
60 _graphrecord: &'a GraphRecord,
61 _prepared: Self::Prepared<'a>,
62 ) -> QueryResult<ElementPipeline<'a, Bare<V>, Self>> {
63 Ok(numeric_bare::<V, _>(Self::LABEL, V::negate))
64 }
65
66 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
67 input.with_unknown_distinct()
68 }
69}
70
71impl<O: Apply<NegateOperation>> Negate for O {
72 type ReturnOperand = O::Output;
73
74 fn neg(&self) -> Self::ReturnOperand {
75 Self::ReturnOperand::new(OperationContext::new(self.clone(), NegateOperation))
76 }
77}
78
79operation_manifest! {
80 NegateOperation {
81 method: Negate::neg;
82 scope: element;
83
84 kernel {
85 parameters: <I: IndexDomain, V: ValueNegate>;
86 input: Indexed<I, V>;
87 output: Indexed<I, V>;
88 emission: Preserving;
89 }
90
91 kernel {
92 parameters: <V: ValueNegate + BareValueDomain>;
93 input: Bare<V>;
94 output: Bare<V>;
95 emission: Preserving;
96 }
97 }
98}