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