mz_expr/scalar/func/impls/
int16.rs
1use 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!(NegInt16)]
24 #[is_monotone = true]
25 fn neg_int16(a: i16) -> Result<i16, EvalError> {
26 a.checked_neg()
27 .ok_or_else(|| EvalError::Int16OutOfRange(a.to_string().into()))
28 }
29);
30
31sqlfunc!(
32 #[sqlname = "~"]
33 #[preserves_uniqueness = true]
34 #[inverse = to_unary!(BitNotInt16)]
35 fn bit_not_int16(a: i16) -> i16 {
36 !a
37 }
38);
39
40sqlfunc!(
41 #[sqlname = "abs"]
42 fn abs_int16(a: i16) -> Result<i16, EvalError> {
43 a.checked_abs()
44 .ok_or_else(|| EvalError::Int16OutOfRange(a.to_string().into()))
45 }
46);
47
48sqlfunc!(
49 #[sqlname = "smallint_to_real"]
50 #[preserves_uniqueness = true]
51 #[inverse = to_unary!(super::CastFloat32ToInt16)]
52 #[is_monotone = true]
53 fn cast_int16_to_float32(a: i16) -> f32 {
54 f32::from(a)
55 }
56);
57
58sqlfunc!(
59 #[sqlname = "smallint_to_double"]
60 #[preserves_uniqueness = true]
61 #[inverse = to_unary!(super::CastFloat64ToInt16)]
62 #[is_monotone = true]
63 fn cast_int16_to_float64(a: i16) -> f64 {
64 f64::from(a)
65 }
66);
67
68sqlfunc!(
69 #[sqlname = "smallint_to_integer"]
70 #[preserves_uniqueness = true]
71 #[inverse = to_unary!(super::CastInt32ToInt16)]
72 #[is_monotone = true]
73 fn cast_int16_to_int32(a: i16) -> i32 {
74 i32::from(a)
75 }
76);
77
78sqlfunc!(
79 #[sqlname = "smallint_to_bigint"]
80 #[preserves_uniqueness = true]
81 #[inverse = to_unary!(super::CastInt64ToInt16)]
82 #[is_monotone = true]
83 fn cast_int16_to_int64(a: i16) -> i64 {
84 i64::from(a)
85 }
86);
87
88sqlfunc!(
89 #[sqlname = "smallint_to_text"]
90 #[preserves_uniqueness = true]
91 #[inverse = to_unary!(super::CastStringToInt16)]
92 fn cast_int16_to_string(a: i16) -> String {
93 let mut buf = String::new();
94 strconv::format_int16(&mut buf, a);
95 buf
96 }
97);
98
99sqlfunc!(
100 #[sqlname = "smallint_to_uint2"]
101 #[preserves_uniqueness = true]
102 #[inverse = to_unary!(super::CastUint16ToInt16)]
103 #[is_monotone = true]
104 fn cast_int16_to_uint16(a: i16) -> Result<u16, EvalError> {
105 u16::try_from(a).or_else(|_| Err(EvalError::UInt16OutOfRange(a.to_string().into())))
106 }
107);
108
109sqlfunc!(
110 #[sqlname = "smallint_to_uint4"]
111 #[preserves_uniqueness = true]
112 #[inverse = to_unary!(super::CastUint32ToInt16)]
113 #[is_monotone = true]
114 fn cast_int16_to_uint32(a: i16) -> Result<u32, EvalError> {
115 u32::try_from(a).or_else(|_| Err(EvalError::UInt32OutOfRange(a.to_string().into())))
116 }
117);
118
119sqlfunc!(
120 #[sqlname = "smallint_to_uint8"]
121 #[preserves_uniqueness = true]
122 #[inverse = to_unary!(super::CastUint64ToInt16)]
123 #[is_monotone = true]
124 fn cast_int16_to_uint64(a: i16) -> Result<u64, EvalError> {
125 u64::try_from(a).or_else(|_| Err(EvalError::UInt64OutOfRange(a.to_string().into())))
126 }
127);
128
129#[derive(Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect)]
130pub struct CastInt16ToNumeric(pub Option<NumericMaxScale>);
131
132impl<'a> EagerUnaryFunc<'a> for CastInt16ToNumeric {
133 type Input = i16;
134 type Output = Result<Numeric, EvalError>;
135
136 fn call(&self, a: i16) -> Result<Numeric, EvalError> {
137 let mut a = Numeric::from(i32::from(a));
138 if let Some(scale) = self.0 {
139 if numeric::rescale(&mut a, scale.into_u8()).is_err() {
140 return Err(EvalError::NumericFieldOverflow);
141 }
142 }
143 Ok(a)
144 }
145
146 fn output_type(&self, input: ColumnType) -> ColumnType {
147 ScalarType::Numeric { max_scale: self.0 }.nullable(input.nullable)
148 }
149
150 fn could_error(&self) -> bool {
151 self.0.is_some()
152 }
153
154 fn inverse(&self) -> Option<crate::UnaryFunc> {
155 to_unary!(super::CastNumericToInt16)
156 }
157
158 fn is_monotone(&self) -> bool {
159 true
160 }
161}
162
163impl fmt::Display for CastInt16ToNumeric {
164 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
165 f.write_str("smallint_to_numeric")
166 }
167}