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