mz_expr/scalar/func/impls/
int16.rs1use std::fmt;
11
12use mz_expr_derive::sqlfunc;
13use mz_lowertest::MzReflect;
14use mz_repr::adt::numeric::{self, Numeric, NumericMaxScale};
15use mz_repr::{SqlColumnType, SqlScalarType, strconv};
16use serde::{Deserialize, Serialize};
17
18use crate::EvalError;
19use crate::scalar::func::EagerUnaryFunc;
20
21#[sqlfunc(
22 sqlname = "-",
23 preserves_uniqueness = true,
24 inverse = to_unary!(NegInt16),
25 is_monotone = true
26)]
27fn neg_int16(a: i16) -> Result<i16, EvalError> {
28 a.checked_neg()
29 .ok_or_else(|| EvalError::Int16OutOfRange(a.to_string().into()))
30}
31
32#[sqlfunc(
33 sqlname = "~",
34 preserves_uniqueness = true,
35 inverse = to_unary!(BitNotInt16)
36)]
37fn bit_not_int16(a: i16) -> i16 {
38 !a
39}
40
41#[sqlfunc(sqlname = "abs")]
42fn abs_int16(a: i16) -> Result<i16, EvalError> {
43 a.checked_abs()
44 .ok_or_else(|| EvalError::Int16OutOfRange(a.to_string().into()))
45}
46
47#[sqlfunc(
48 sqlname = "smallint_to_real",
49 preserves_uniqueness = true,
50 inverse = to_unary!(super::CastFloat32ToInt16),
51 is_monotone = true
52)]
53fn cast_int16_to_float32(a: i16) -> f32 {
54 f32::from(a)
55}
56
57#[sqlfunc(
58 sqlname = "smallint_to_double",
59 preserves_uniqueness = true,
60 inverse = to_unary!(super::CastFloat64ToInt16),
61 is_monotone = true
62)]
63fn cast_int16_to_float64(a: i16) -> f64 {
64 f64::from(a)
65}
66
67#[sqlfunc(
68 sqlname = "smallint_to_integer",
69 preserves_uniqueness = true,
70 inverse = to_unary!(super::CastInt32ToInt16),
71 is_monotone = true
72)]
73fn cast_int16_to_int32(a: i16) -> i32 {
74 i32::from(a)
75}
76
77#[sqlfunc(
78 sqlname = "smallint_to_bigint",
79 preserves_uniqueness = true,
80 inverse = to_unary!(super::CastInt64ToInt16),
81 is_monotone = true
82)]
83fn cast_int16_to_int64(a: i16) -> i64 {
84 i64::from(a)
85}
86
87#[sqlfunc(
88 sqlname = "smallint_to_text",
89 preserves_uniqueness = true,
90 inverse = to_unary!(super::CastStringToInt16)
91)]
92fn 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#[sqlfunc(
99 sqlname = "smallint_to_uint2",
100 preserves_uniqueness = true,
101 inverse = to_unary!(super::CastUint16ToInt16),
102 is_monotone = true
103)]
104fn 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#[sqlfunc(
109 sqlname = "smallint_to_uint4",
110 preserves_uniqueness = true,
111 inverse = to_unary!(super::CastUint32ToInt16),
112 is_monotone = true
113)]
114fn 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#[sqlfunc(
119 sqlname = "smallint_to_uint8",
120 preserves_uniqueness = true,
121 inverse = to_unary!(super::CastUint64ToInt16),
122 is_monotone = true
123)]
124fn 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#[derive(
129 Ord,
130 PartialOrd,
131 Clone,
132 Debug,
133 Eq,
134 PartialEq,
135 Serialize,
136 Deserialize,
137 Hash,
138 MzReflect
139)]
140pub struct CastInt16ToNumeric(pub Option<NumericMaxScale>);
141
142impl EagerUnaryFunc for CastInt16ToNumeric {
143 type Input<'a> = i16;
144 type Output<'a> = Result<Numeric, EvalError>;
145
146 fn call<'a>(&self, a: Self::Input<'a>) -> Self::Output<'a> {
147 let mut a = Numeric::from(i32::from(a));
148 if let Some(scale) = self.0 {
149 if numeric::rescale(&mut a, scale.into_u8()).is_err() {
150 return Err(EvalError::NumericFieldOverflow);
151 }
152 }
153 Ok(a)
154 }
155
156 fn output_type(&self, input: SqlColumnType) -> SqlColumnType {
157 SqlScalarType::Numeric { max_scale: self.0 }.nullable(input.nullable)
158 }
159
160 fn could_error(&self) -> bool {
161 self.0.is_some()
162 }
163
164 fn inverse(&self) -> Option<crate::UnaryFunc> {
165 to_unary!(super::CastNumericToInt16)
166 }
167
168 fn is_monotone(&self) -> bool {
169 true
170 }
171}
172
173impl fmt::Display for CastInt16ToNumeric {
174 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
175 f.write_str("smallint_to_numeric")
176 }
177}