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