mz_expr/scalar/func/impls/
uint16.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Use of this software is governed by the Business Source License
4// included in the LICENSE file.
5//
6// As of the Change Date specified in that file, in accordance with
7// the Business Source License, use of this software will be governed
8// by the Apache License, Version 2.0.
9
10use std::fmt;
11
12use mz_lowertest::MzReflect;
13use mz_repr::adt::numeric::{self, Numeric, NumericMaxScale};
14use mz_repr::{ColumnType, ScalarType, strconv};
15use serde::{Deserialize, Serialize};
16
17use crate::EvalError;
18use crate::scalar::func::EagerUnaryFunc;
19
20sqlfunc!(
21    #[sqlname = "~"]
22    #[preserves_uniqueness = true]
23    #[inverse = to_unary!(super::BitNotUint16)]
24    fn bit_not_uint16(a: u16) -> u16 {
25        !a
26    }
27);
28
29sqlfunc!(
30    #[sqlname = "uint2_to_real"]
31    #[preserves_uniqueness = true]
32    #[inverse = to_unary!(super::CastFloat32ToUint16)]
33    #[is_monotone = true]
34    fn cast_uint16_to_float32(a: u16) -> f32 {
35        f32::from(a)
36    }
37);
38
39sqlfunc!(
40    #[sqlname = "uint2_to_double"]
41    #[preserves_uniqueness = true]
42    #[inverse = to_unary!(super::CastFloat64ToUint16)]
43    #[is_monotone = true]
44    fn cast_uint16_to_float64(a: u16) -> f64 {
45        f64::from(a)
46    }
47);
48
49sqlfunc!(
50    #[sqlname = "uint2_to_uint4"]
51    #[preserves_uniqueness = true]
52    #[inverse = to_unary!(super::CastUint32ToUint16)]
53    #[is_monotone = true]
54    fn cast_uint16_to_uint32(a: u16) -> u32 {
55        u32::from(a)
56    }
57);
58
59sqlfunc!(
60    #[sqlname = "uint2_to_uint8"]
61    #[preserves_uniqueness = true]
62    #[inverse = to_unary!(super::CastUint64ToUint16)]
63    #[is_monotone = true]
64    fn cast_uint16_to_uint64(a: u16) -> u64 {
65        u64::from(a)
66    }
67);
68
69sqlfunc!(
70    #[sqlname = "uint2_to_smallint"]
71    #[preserves_uniqueness = true]
72    #[inverse = to_unary!(super::CastInt16ToUint16)]
73    #[is_monotone = true]
74    fn cast_uint16_to_int16(a: u16) -> Result<i16, EvalError> {
75        i16::try_from(a).or_else(|_| Err(EvalError::Int16OutOfRange(a.to_string().into())))
76    }
77);
78
79sqlfunc!(
80    #[sqlname = "uint2_to_integer"]
81    #[preserves_uniqueness = true]
82    #[inverse = to_unary!(super::CastInt32ToUint16)]
83    #[is_monotone = true]
84    fn cast_uint16_to_int32(a: u16) -> i32 {
85        i32::from(a)
86    }
87);
88sqlfunc!(
89    #[sqlname = "uint2_to_bigint"]
90    #[preserves_uniqueness = true]
91    #[inverse = to_unary!(super::CastInt64ToUint16)]
92    #[is_monotone = true]
93    fn cast_uint16_to_int64(a: u16) -> i64 {
94        i64::from(a)
95    }
96);
97
98sqlfunc!(
99    #[sqlname = "uint2_to_text"]
100    #[preserves_uniqueness = true]
101    #[inverse = to_unary!(super::CastStringToUint16)]
102    fn cast_uint16_to_string(a: u16) -> String {
103        let mut buf = String::new();
104        strconv::format_uint16(&mut buf, a);
105        buf
106    }
107);
108
109#[derive(Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect)]
110pub struct CastUint16ToNumeric(pub Option<NumericMaxScale>);
111
112impl<'a> EagerUnaryFunc<'a> for CastUint16ToNumeric {
113    type Input = u16;
114    type Output = Result<Numeric, EvalError>;
115
116    fn call(&self, a: u16) -> Result<Numeric, EvalError> {
117        let mut a = Numeric::from(i32::from(a));
118        if let Some(scale) = self.0 {
119            if numeric::rescale(&mut a, scale.into_u8()).is_err() {
120                return Err(EvalError::NumericFieldOverflow);
121            }
122        }
123        Ok(a)
124    }
125
126    fn output_type(&self, input: ColumnType) -> ColumnType {
127        ScalarType::Numeric { max_scale: self.0 }.nullable(input.nullable)
128    }
129
130    fn could_error(&self) -> bool {
131        self.0.is_some()
132    }
133
134    fn inverse(&self) -> Option<crate::UnaryFunc> {
135        to_unary!(super::CastNumericToUint16)
136    }
137
138    fn is_monotone(&self) -> bool {
139        true
140    }
141}
142
143impl fmt::Display for CastUint16ToNumeric {
144    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145        f.write_str("uint2_to_numeric")
146    }
147}