risingwave_common/types/
scalar_impl.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::hash::Hasher;
16
17use super::*;
18use crate::{dispatch_scalar_ref_variants, dispatch_scalar_variants, for_all_native_types};
19
20/// `ScalarPartialOrd` allows comparison between `Scalar` and `ScalarRef`.
21///
22/// TODO: see if it is possible to implement this trait directly on `ScalarRef`.
23pub trait ScalarPartialOrd: Scalar {
24    fn scalar_cmp(&self, other: Self::ScalarRefType<'_>) -> Option<std::cmp::Ordering>;
25}
26
27/// Implement `Scalar` and `ScalarRef` for native type.
28/// For `PrimitiveArrayItemType`, clone is trivial, so `T` is both `Scalar` and `ScalarRef`.
29macro_rules! impl_all_native_scalar {
30    ($({ $scalar_type:ty, $_variant_name:ident, $_read_fn:ident } ),*) => {
31        $(
32            impl Scalar for $scalar_type {
33                type ScalarRefType<'a> = Self;
34
35                fn as_scalar_ref(&self) -> Self {
36                    *self
37                }
38            }
39
40            impl<'scalar> ScalarRef<'scalar> for $scalar_type {
41                type ScalarType = Self;
42
43                fn to_owned_scalar(&self) -> Self {
44                    *self
45                }
46
47                fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
48                    self.hash(state)
49                }
50            }
51        )*
52    };
53}
54
55for_all_native_types! { impl_all_native_scalar }
56
57/// Implement `Scalar` for `Box<str>`.
58/// `Box<str>` could be converted to `&str`.
59impl Scalar for Box<str> {
60    type ScalarRefType<'a> = &'a str;
61
62    fn as_scalar_ref(&self) -> &str {
63        self.as_ref()
64    }
65}
66
67/// Implement `Scalar` for `Bytes`.
68impl Scalar for Box<[u8]> {
69    type ScalarRefType<'a> = &'a [u8];
70
71    fn as_scalar_ref(&self) -> &[u8] {
72        self
73    }
74}
75
76/// Implement `Scalar` for `StructValue`.
77impl Scalar for StructValue {
78    type ScalarRefType<'a> = StructRef<'a>;
79
80    fn as_scalar_ref(&self) -> StructRef<'_> {
81        StructRef::ValueRef { val: self }
82    }
83}
84
85/// Implement `Scalar` for `ListValue`.
86impl Scalar for ListValue {
87    type ScalarRefType<'a> = ListRef<'a>;
88
89    fn as_scalar_ref(&self) -> ListRef<'_> {
90        self.into()
91    }
92}
93
94/// Implement `ScalarRef` for `Box<str>`.
95/// `Box<str>` could be converted to `&str`.
96impl<'a> ScalarRef<'a> for &'a str {
97    type ScalarType = Box<str>;
98
99    fn to_owned_scalar(&self) -> Box<str> {
100        (*self).into()
101    }
102
103    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
104        self.hash(state)
105    }
106}
107
108impl<'a> ScalarRef<'a> for &'a [u8] {
109    type ScalarType = Box<[u8]>;
110
111    fn to_owned_scalar(&self) -> Box<[u8]> {
112        self.to_vec().into()
113    }
114
115    fn hash_scalar<H: Hasher>(&self, state: &mut H) {
116        self.hash(state)
117    }
118}
119
120impl ScalarPartialOrd for Box<str> {
121    fn scalar_cmp(&self, other: &str) -> Option<std::cmp::Ordering> {
122        self.as_ref().partial_cmp(other)
123    }
124}
125
126impl<T: PrimitiveArrayItemType + Scalar> ScalarPartialOrd for T {
127    fn scalar_cmp(&self, other: Self) -> Option<std::cmp::Ordering> {
128        self.partial_cmp(&other)
129    }
130}
131
132impl ScalarPartialOrd for bool {
133    fn scalar_cmp(&self, other: Self) -> Option<std::cmp::Ordering> {
134        self.partial_cmp(&other)
135    }
136}
137
138/// Implement `Scalar` for `bool`.
139impl Scalar for bool {
140    type ScalarRefType<'a> = bool;
141
142    fn as_scalar_ref(&self) -> bool {
143        *self
144    }
145}
146
147/// Implement `ScalarRef` for `bool`.
148impl ScalarRef<'_> for bool {
149    type ScalarType = bool;
150
151    fn to_owned_scalar(&self) -> bool {
152        *self
153    }
154
155    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
156        self.hash(state)
157    }
158}
159
160/// Implement `Scalar` for `Decimal`.
161impl Scalar for Decimal {
162    type ScalarRefType<'a> = Decimal;
163
164    fn as_scalar_ref(&self) -> Decimal {
165        *self
166    }
167}
168
169/// Implement `ScalarRef` for `Decimal`.
170impl ScalarRef<'_> for Decimal {
171    type ScalarType = Decimal;
172
173    fn to_owned_scalar(&self) -> Decimal {
174        *self
175    }
176
177    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
178        self.normalize().hash(state)
179    }
180}
181
182/// Implement `Scalar` for `Interval`.
183impl Scalar for Interval {
184    type ScalarRefType<'a> = Interval;
185
186    fn as_scalar_ref(&self) -> Interval {
187        *self
188    }
189}
190
191/// Implement `ScalarRef` for `Interval`.
192impl ScalarRef<'_> for Interval {
193    type ScalarType = Interval;
194
195    fn to_owned_scalar(&self) -> Interval {
196        *self
197    }
198
199    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
200        self.hash(state)
201    }
202}
203
204/// Implement `Scalar` for `Date`.
205impl Scalar for Date {
206    type ScalarRefType<'a> = Date;
207
208    fn as_scalar_ref(&self) -> Date {
209        *self
210    }
211}
212
213/// Implement `ScalarRef` for `Date`.
214impl ScalarRef<'_> for Date {
215    type ScalarType = Date;
216
217    fn to_owned_scalar(&self) -> Date {
218        *self
219    }
220
221    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
222        self.hash(state)
223    }
224}
225
226/// Implement `Scalar` for `Timestamp`.
227impl Scalar for Timestamp {
228    type ScalarRefType<'a> = Timestamp;
229
230    fn as_scalar_ref(&self) -> Timestamp {
231        *self
232    }
233}
234
235/// Implement `ScalarRef` for `Timestamp`.
236impl ScalarRef<'_> for Timestamp {
237    type ScalarType = Timestamp;
238
239    fn to_owned_scalar(&self) -> Timestamp {
240        *self
241    }
242
243    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
244        self.hash(state)
245    }
246}
247
248/// Implement `Scalar` for `Time`.
249impl Scalar for Time {
250    type ScalarRefType<'a> = Time;
251
252    fn as_scalar_ref(&self) -> Time {
253        *self
254    }
255}
256
257/// Implement `ScalarRef` for `Time`.
258impl ScalarRef<'_> for Time {
259    type ScalarType = Time;
260
261    fn to_owned_scalar(&self) -> Time {
262        *self
263    }
264
265    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
266        self.hash(state)
267    }
268}
269
270/// Implement `Scalar` for `Timestamptz`.
271impl Scalar for Timestamptz {
272    type ScalarRefType<'a> = Timestamptz;
273
274    fn as_scalar_ref(&self) -> Timestamptz {
275        *self
276    }
277}
278
279/// Implement `ScalarRef` for `Timestamptz`.
280impl ScalarRef<'_> for Timestamptz {
281    type ScalarType = Timestamptz;
282
283    fn to_owned_scalar(&self) -> Timestamptz {
284        *self
285    }
286
287    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
288        self.hash(state)
289    }
290}
291
292/// Implement `Scalar` for `StructValue`.
293impl<'a> ScalarRef<'a> for StructRef<'a> {
294    type ScalarType = StructValue;
295
296    fn to_owned_scalar(&self) -> StructValue {
297        let fields = self.iter_fields_ref().map(|f| f.to_owned_datum()).collect();
298        StructValue::new(fields)
299    }
300
301    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
302        self.hash_scalar_inner(state)
303    }
304}
305
306/// Implement `Scalar` for `ListValue`.
307impl<'a> ScalarRef<'a> for ListRef<'a> {
308    type ScalarType = ListValue;
309
310    fn to_owned_scalar(&self) -> ListValue {
311        (*self).into()
312    }
313
314    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
315        self.hash_scalar_inner(state)
316    }
317}
318
319impl ScalarImpl {
320    pub fn get_ident(&self) -> &'static str {
321        dispatch_scalar_variants!(self, [I = VARIANT_NAME], { I })
322    }
323}
324
325impl ScalarRefImpl<'_> {
326    pub fn get_ident(&self) -> &'static str {
327        dispatch_scalar_ref_variants!(self, [I = VARIANT_NAME], { I })
328    }
329}