Skip to main content

mz_expr/scalar/func/impls/
int16.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 mz_expr_derive::sqlfunc;
11use mz_repr::adt::numeric::{self, Numeric, NumericMaxScale};
12use mz_repr::{SqlScalarType, strconv};
13use serde::{Deserialize, Serialize};
14
15use crate::EvalError;
16
17#[sqlfunc(
18    sqlname = "-",
19    preserves_uniqueness = true,
20    inverse = NegInt16,
21    is_monotone = true
22)]
23fn neg_int16(a: i16) -> Result<i16, EvalError> {
24    a.checked_neg()
25        .ok_or_else(|| EvalError::Int16OutOfRange(a.to_string().into()))
26}
27
28#[sqlfunc(
29    sqlname = "~",
30    preserves_uniqueness = true,
31    inverse = BitNotInt16
32)]
33fn bit_not_int16(a: i16) -> i16 {
34    !a
35}
36
37#[sqlfunc(sqlname = "abs")]
38fn abs_int16(a: i16) -> Result<i16, EvalError> {
39    a.checked_abs()
40        .ok_or_else(|| EvalError::Int16OutOfRange(a.to_string().into()))
41}
42
43#[sqlfunc(
44    sqlname = "smallint_to_real",
45    preserves_uniqueness = true,
46    inverse = super::CastFloat32ToInt16,
47    is_monotone = true
48)]
49fn cast_int16_to_float32(a: i16) -> f32 {
50    f32::from(a)
51}
52
53#[sqlfunc(
54    sqlname = "smallint_to_double",
55    preserves_uniqueness = true,
56    inverse = super::CastFloat64ToInt16,
57    is_monotone = true
58)]
59fn cast_int16_to_float64(a: i16) -> f64 {
60    f64::from(a)
61}
62
63#[sqlfunc(
64    sqlname = "smallint_to_integer",
65    preserves_uniqueness = true,
66    inverse = super::CastInt32ToInt16,
67    is_monotone = true
68)]
69fn cast_int16_to_int32(a: i16) -> i32 {
70    i32::from(a)
71}
72
73#[sqlfunc(
74    sqlname = "smallint_to_bigint",
75    preserves_uniqueness = true,
76    inverse = super::CastInt64ToInt16,
77    is_monotone = true
78)]
79fn cast_int16_to_int64(a: i16) -> i64 {
80    i64::from(a)
81}
82
83#[sqlfunc(
84    sqlname = "smallint_to_text",
85    preserves_uniqueness = true,
86    inverse = super::CastStringToInt16
87)]
88fn cast_int16_to_string(a: i16) -> String {
89    let mut buf = String::new();
90    strconv::format_int16(&mut buf, a);
91    buf
92}
93
94#[sqlfunc(
95    sqlname = "smallint_to_uint2",
96    preserves_uniqueness = true,
97    inverse = super::CastUint16ToInt16,
98    is_monotone = true
99)]
100fn cast_int16_to_uint16(a: i16) -> Result<u16, EvalError> {
101    u16::try_from(a).or_else(|_| Err(EvalError::UInt16OutOfRange(a.to_string().into())))
102}
103
104#[sqlfunc(
105    sqlname = "smallint_to_uint4",
106    preserves_uniqueness = true,
107    inverse = super::CastUint32ToInt16,
108    is_monotone = true
109)]
110fn cast_int16_to_uint32(a: i16) -> Result<u32, EvalError> {
111    u32::try_from(a).or_else(|_| Err(EvalError::UInt32OutOfRange(a.to_string().into())))
112}
113
114#[sqlfunc(
115    sqlname = "smallint_to_uint8",
116    preserves_uniqueness = true,
117    inverse = super::CastUint64ToInt16,
118    is_monotone = true
119)]
120fn cast_int16_to_uint64(a: i16) -> Result<u64, EvalError> {
121    u64::try_from(a).or_else(|_| Err(EvalError::UInt64OutOfRange(a.to_string().into())))
122}
123
124#[derive(
125    Ord,
126    PartialOrd,
127    Clone,
128    Debug,
129    Eq,
130    PartialEq,
131    Serialize,
132    Deserialize,
133    Hash
134)]
135pub struct CastInt16ToNumeric(pub Option<NumericMaxScale>);
136
137#[sqlfunc(
138    CastInt16ToNumeric,
139    sqlname = "smallint_to_numeric",
140    could_error = self.0.is_some(),
141    inverse = super::CastNumericToInt16,
142    is_monotone = true,
143    output_type_expr = SqlScalarType::Numeric { max_scale: self.0 }
144        .nullable(input_type.nullable)
145)]
146fn cast_int16_to_numeric(&self, a: i16) -> Result<Numeric, EvalError> {
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}