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 `ScalarRef` for `Box<str>`.
86/// `Box<str>` could be converted to `&str`.
87impl<'a> ScalarRef<'a> for &'a str {
88    type ScalarType = Box<str>;
89
90    fn to_owned_scalar(&self) -> Box<str> {
91        (*self).into()
92    }
93
94    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
95        self.hash(state)
96    }
97}
98
99impl<'a> ScalarRef<'a> for &'a [u8] {
100    type ScalarType = Box<[u8]>;
101
102    fn to_owned_scalar(&self) -> Box<[u8]> {
103        self.to_vec().into()
104    }
105
106    fn hash_scalar<H: Hasher>(&self, state: &mut H) {
107        self.hash(state)
108    }
109}
110
111impl ScalarPartialOrd for Box<str> {
112    fn scalar_cmp(&self, other: &str) -> Option<std::cmp::Ordering> {
113        self.as_ref().partial_cmp(other)
114    }
115}
116
117impl<T: PrimitiveArrayItemType + Scalar> ScalarPartialOrd for T {
118    fn scalar_cmp(&self, other: Self) -> Option<std::cmp::Ordering> {
119        self.partial_cmp(&other)
120    }
121}
122
123impl ScalarPartialOrd for bool {
124    fn scalar_cmp(&self, other: Self) -> Option<std::cmp::Ordering> {
125        self.partial_cmp(&other)
126    }
127}
128
129/// Implement `Scalar` for `bool`.
130impl Scalar for bool {
131    type ScalarRefType<'a> = bool;
132
133    fn as_scalar_ref(&self) -> bool {
134        *self
135    }
136}
137
138/// Implement `ScalarRef` for `bool`.
139impl ScalarRef<'_> for bool {
140    type ScalarType = bool;
141
142    fn to_owned_scalar(&self) -> bool {
143        *self
144    }
145
146    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
147        self.hash(state)
148    }
149}
150
151/// Implement `Scalar` for `Decimal`.
152impl Scalar for Decimal {
153    type ScalarRefType<'a> = Decimal;
154
155    fn as_scalar_ref(&self) -> Decimal {
156        *self
157    }
158}
159
160/// Implement `ScalarRef` for `Decimal`.
161impl ScalarRef<'_> for Decimal {
162    type ScalarType = Decimal;
163
164    fn to_owned_scalar(&self) -> Decimal {
165        *self
166    }
167
168    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
169        self.normalize().hash(state)
170    }
171}
172
173/// Implement `Scalar` for `Interval`.
174impl Scalar for Interval {
175    type ScalarRefType<'a> = Interval;
176
177    fn as_scalar_ref(&self) -> Interval {
178        *self
179    }
180}
181
182/// Implement `ScalarRef` for `Interval`.
183impl ScalarRef<'_> for Interval {
184    type ScalarType = Interval;
185
186    fn to_owned_scalar(&self) -> Interval {
187        *self
188    }
189
190    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
191        self.hash(state)
192    }
193}
194
195/// Implement `Scalar` for `Date`.
196impl Scalar for Date {
197    type ScalarRefType<'a> = Date;
198
199    fn as_scalar_ref(&self) -> Date {
200        *self
201    }
202}
203
204/// Implement `ScalarRef` for `Date`.
205impl ScalarRef<'_> for Date {
206    type ScalarType = Date;
207
208    fn to_owned_scalar(&self) -> Date {
209        *self
210    }
211
212    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
213        self.hash(state)
214    }
215}
216
217/// Implement `Scalar` for `Timestamp`.
218impl Scalar for Timestamp {
219    type ScalarRefType<'a> = Timestamp;
220
221    fn as_scalar_ref(&self) -> Timestamp {
222        *self
223    }
224}
225
226/// Implement `ScalarRef` for `Timestamp`.
227impl ScalarRef<'_> for Timestamp {
228    type ScalarType = Timestamp;
229
230    fn to_owned_scalar(&self) -> Timestamp {
231        *self
232    }
233
234    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
235        self.hash(state)
236    }
237}
238
239/// Implement `Scalar` for `Time`.
240impl Scalar for Time {
241    type ScalarRefType<'a> = Time;
242
243    fn as_scalar_ref(&self) -> Time {
244        *self
245    }
246}
247
248/// Implement `ScalarRef` for `Time`.
249impl ScalarRef<'_> for Time {
250    type ScalarType = Time;
251
252    fn to_owned_scalar(&self) -> Time {
253        *self
254    }
255
256    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
257        self.hash(state)
258    }
259}
260
261/// Implement `Scalar` for `Timestamptz`.
262impl Scalar for Timestamptz {
263    type ScalarRefType<'a> = Timestamptz;
264
265    fn as_scalar_ref(&self) -> Timestamptz {
266        *self
267    }
268}
269
270/// Implement `ScalarRef` for `Timestamptz`.
271impl ScalarRef<'_> for Timestamptz {
272    type ScalarType = Timestamptz;
273
274    fn to_owned_scalar(&self) -> Timestamptz {
275        *self
276    }
277
278    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
279        self.hash(state)
280    }
281}
282
283/// Implement `Scalar` for `StructValue`.
284impl<'a> ScalarRef<'a> for StructRef<'a> {
285    type ScalarType = StructValue;
286
287    fn to_owned_scalar(&self) -> StructValue {
288        let fields = self.iter_fields_ref().map(|f| f.to_owned_datum()).collect();
289        StructValue::new(fields)
290    }
291
292    fn hash_scalar<H: std::hash::Hasher>(&self, state: &mut H) {
293        self.hash_scalar_inner(state)
294    }
295}
296
297impl ScalarImpl {
298    pub fn get_ident(&self) -> &'static str {
299        dispatch_scalar_variants!(self, [I = VARIANT_NAME], { I })
300    }
301}
302
303impl ScalarRefImpl<'_> {
304    pub fn get_ident(&self) -> &'static str {
305        dispatch_scalar_ref_variants!(self, [I = VARIANT_NAME], { I })
306    }
307}