mz_expr/scalar/func/impls/
uint64.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!(super::BitNotUint64)
25)]
26fn bit_not_uint64(a: u64) -> u64 {
27 !a
28}
29
30#[sqlfunc(
31 sqlname = "uint8_to_real",
32 preserves_uniqueness = false,
33 inverse = to_unary!(super::CastFloat32ToUint64),
34 is_monotone = true
35)]
36fn cast_uint64_to_float32(a: u64) -> f32 {
37 #[allow(clippy::as_conversions)]
39 {
40 a as f32
41 }
42}
43
44#[sqlfunc(
45 sqlname = "uint8_to_double",
46 preserves_uniqueness = false,
47 inverse = to_unary!(super::CastFloat64ToUint64),
48 is_monotone = true
49)]
50fn cast_uint64_to_float64(a: u64) -> f64 {
51 #[allow(clippy::as_conversions)]
53 {
54 a as f64
55 }
56}
57
58#[sqlfunc(
59 sqlname = "uint8_to_uint2",
60 preserves_uniqueness = true,
61 inverse = to_unary!(super::CastUint16ToUint64),
62 is_monotone = true
63)]
64fn cast_uint64_to_uint16(a: u64) -> Result<u16, EvalError> {
65 u16::try_from(a).or_else(|_| Err(EvalError::UInt16OutOfRange(a.to_string().into())))
66}
67
68#[sqlfunc(
69 sqlname = "uint8_to_uint4",
70 preserves_uniqueness = true,
71 inverse = to_unary!(super::CastUint32ToUint64),
72 is_monotone = true
73)]
74fn cast_uint64_to_uint32(a: u64) -> Result<u32, EvalError> {
75 u32::try_from(a).or_else(|_| Err(EvalError::UInt32OutOfRange(a.to_string().into())))
76}
77
78#[sqlfunc(
79 sqlname = "uint8_to_smallint",
80 preserves_uniqueness = true,
81 inverse = to_unary!(super::CastInt16ToUint64),
82 is_monotone = true
83)]
84fn cast_uint64_to_int16(a: u64) -> Result<i16, EvalError> {
85 i16::try_from(a).or_else(|_| Err(EvalError::Int16OutOfRange(a.to_string().into())))
86}
87
88#[sqlfunc(
89 sqlname = "uint8_to_integer",
90 preserves_uniqueness = true,
91 inverse = to_unary!(super::CastInt32ToUint64),
92 is_monotone = true
93)]
94fn cast_uint64_to_int32(a: u64) -> Result<i32, EvalError> {
95 i32::try_from(a).or_else(|_| Err(EvalError::Int32OutOfRange(a.to_string().into())))
96}
97
98#[sqlfunc(
99 sqlname = "uint8_to_bigint",
100 preserves_uniqueness = true,
101 inverse = to_unary!(super::CastInt64ToUint64),
102 is_monotone = true
103)]
104fn cast_uint64_to_int64(a: u64) -> Result<i64, EvalError> {
105 i64::try_from(a).or_else(|_| Err(EvalError::Int64OutOfRange(a.to_string().into())))
106}
107
108#[sqlfunc(
109 sqlname = "uint8_to_text",
110 preserves_uniqueness = true,
111 inverse = to_unary!(super::CastStringToUint64)
112)]
113fn cast_uint64_to_string(a: u64) -> String {
114 let mut buf = String::new();
115 strconv::format_uint64(&mut buf, a);
116 buf
117}
118
119#[derive(
120 Ord,
121 PartialOrd,
122 Clone,
123 Debug,
124 Eq,
125 PartialEq,
126 Serialize,
127 Deserialize,
128 Hash,
129 MzReflect
130)]
131pub struct CastUint64ToNumeric(pub Option<NumericMaxScale>);
132
133impl EagerUnaryFunc for CastUint64ToNumeric {
134 type Input<'a> = u64;
135 type Output<'a> = Result<Numeric, EvalError>;
136
137 fn call<'a>(&self, a: Self::Input<'a>) -> Self::Output<'a> {
138 let mut a = Numeric::from(a);
139 if let Some(scale) = self.0 {
140 if numeric::rescale(&mut a, scale.into_u8()).is_err() {
141 return Err(EvalError::NumericFieldOverflow);
142 }
143 }
144 Ok(a)
146 }
147
148 fn output_type(&self, input: SqlColumnType) -> SqlColumnType {
149 SqlScalarType::Numeric { max_scale: self.0 }.nullable(input.nullable)
150 }
151
152 fn could_error(&self) -> bool {
153 self.0.is_some()
154 }
155
156 fn inverse(&self) -> Option<crate::UnaryFunc> {
157 to_unary!(super::CastNumericToUint64)
158 }
159
160 fn is_monotone(&self) -> bool {
161 true
162 }
163}
164
165impl fmt::Display for CastUint64ToNumeric {
166 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
167 f.write_str("uint8_to_numeric")
168 }
169}