graphrecords_query/operations/numeric/
sign.rs1use super::{numeric_bare, numeric_indexed};
2use crate::{
3 Bare, BareValueDomain, Explain, IndexDomain, Indexed, Labeled, Operand, QueryResult,
4 capabilities::ValueSign,
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::Sign,
11};
12use graphrecords_core::GraphRecord;
13
14#[derive(Clone, Explain, Operation, OperationInputs, OptimizerHints, PlanIdentity, PlanInputs)]
15#[operation(scope = Element)]
16#[explain(label = "Sign")]
17#[plan(optimizer_hints(allows_limit_pushdown, empty = if_any))]
18pub struct SignOperation;
19
20impl Prepare for SignOperation {
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 SignOperation
33where
34 I: IndexDomain,
35 V: ValueSign,
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::sign))
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 SignOperation
53where
54 V: ValueSign + 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::sign))
64 }
65
66 fn estimate(&self, input: Estimate, _stats: &Stats) -> Estimate {
67 input.with_unknown_distinct()
68 }
69}
70
71impl<O: Apply<SignOperation>> Sign for O {
72 type ReturnOperand = O::Output;
73
74 fn sign(&self) -> Self::ReturnOperand {
75 Self::ReturnOperand::new(OperationContext::new(self.clone(), SignOperation))
76 }
77}
78
79operation_manifest! {
80 SignOperation {
81 method: Sign::sign;
82 scope: element;
83
84 kernel {
85 parameters: <I: IndexDomain, V: ValueSign>;
86 input: Indexed<I, V>;
87 output: Indexed<I, V>;
88 emission: Preserving;
89 }
90
91 kernel {
92 parameters: <V: ValueSign + BareValueDomain>;
93 input: Bare<V>;
94 output: Bare<V>;
95 emission: Preserving;
96 }
97 }
98}