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(Ord, PartialOrd, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Hash, MzReflect)]
120pub struct CastUint64ToNumeric(pub Option<NumericMaxScale>);
121
122impl<'a> EagerUnaryFunc<'a> for CastUint64ToNumeric {
123 type Input = u64;
124 type Output = Result<Numeric, EvalError>;
125
126 fn call(&self, a: u64) -> Result<Numeric, EvalError> {
127 let mut a = Numeric::from(a);
128 if let Some(scale) = self.0 {
129 if numeric::rescale(&mut a, scale.into_u8()).is_err() {
130 return Err(EvalError::NumericFieldOverflow);
131 }
132 }
133 Ok(a)
135 }
136
137 fn output_type(&self, input: SqlColumnType) -> SqlColumnType {
138 SqlScalarType::Numeric { max_scale: self.0 }.nullable(input.nullable)
139 }
140
141 fn could_error(&self) -> bool {
142 self.0.is_some()
143 }
144
145 fn inverse(&self) -> Option<crate::UnaryFunc> {
146 to_unary!(super::CastNumericToUint64)
147 }
148
149 fn is_monotone(&self) -> bool {
150 true
151 }
152}
153
154impl fmt::Display for CastUint64ToNumeric {
155 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 f.write_str("uint8_to_numeric")
157 }
158}