mz_expr/scalar/func/impls/
uint64.rs1use 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 = super::BitNotUint64
21)]
22fn bit_not_uint64(a: u64) -> u64 {
23 !a
24}
25
26#[sqlfunc(
27 sqlname = "uint8_to_real",
28 preserves_uniqueness = false,
29 inverse = super::CastFloat32ToUint64,
30 is_monotone = true
31)]
32fn cast_uint64_to_float32(a: u64) -> f32 {
33 #[allow(clippy::as_conversions)]
35 {
36 a as f32
37 }
38}
39
40#[sqlfunc(
41 sqlname = "uint8_to_double",
42 preserves_uniqueness = false,
43 inverse = super::CastFloat64ToUint64,
44 is_monotone = true
45)]
46fn cast_uint64_to_float64(a: u64) -> f64 {
47 #[allow(clippy::as_conversions)]
49 {
50 a as f64
51 }
52}
53
54#[sqlfunc(
55 sqlname = "uint8_to_uint2",
56 preserves_uniqueness = true,
57 inverse = super::CastUint16ToUint64,
58 is_monotone = true
59)]
60fn cast_uint64_to_uint16(a: u64) -> Result<u16, EvalError> {
61 u16::try_from(a).or_else(|_| Err(EvalError::UInt16OutOfRange(a.to_string().into())))
62}
63
64#[sqlfunc(
65 sqlname = "uint8_to_uint4",
66 preserves_uniqueness = true,
67 inverse = super::CastUint32ToUint64,
68 is_monotone = true
69)]
70fn cast_uint64_to_uint32(a: u64) -> Result<u32, EvalError> {
71 u32::try_from(a).or_else(|_| Err(EvalError::UInt32OutOfRange(a.to_string().into())))
72}
73
74#[sqlfunc(
75 sqlname = "uint8_to_smallint",
76 preserves_uniqueness = true,
77 inverse = super::CastInt16ToUint64,
78 is_monotone = true
79)]
80fn cast_uint64_to_int16(a: u64) -> Result<i16, EvalError> {
81 i16::try_from(a).or_else(|_| Err(EvalError::Int16OutOfRange(a.to_string().into())))
82}
83
84#[sqlfunc(
85 sqlname = "uint8_to_integer",
86 preserves_uniqueness = true,
87 inverse = super::CastInt32ToUint64,
88 is_monotone = true
89)]
90fn cast_uint64_to_int32(a: u64) -> Result<i32, EvalError> {
91 i32::try_from(a).or_else(|_| Err(EvalError::Int32OutOfRange(a.to_string().into())))
92}
93
94#[sqlfunc(
95 sqlname = "uint8_to_bigint",
96 preserves_uniqueness = true,
97 inverse = super::CastInt64ToUint64,
98 is_monotone = true
99)]
100fn cast_uint64_to_int64(a: u64) -> Result<i64, EvalError> {
101 i64::try_from(a).or_else(|_| Err(EvalError::Int64OutOfRange(a.to_string().into())))
102}
103
104#[sqlfunc(
105 sqlname = "uint8_to_text",
106 preserves_uniqueness = true,
107 inverse = super::CastStringToUint64
108)]
109fn cast_uint64_to_string(a: u64) -> String {
110 let mut buf = String::new();
111 strconv::format_uint64(&mut buf, a);
112 buf
113}
114
115#[derive(
116 Ord,
117 PartialOrd,
118 Clone,
119 Debug,
120 Eq,
121 PartialEq,
122 Serialize,
123 Deserialize,
124 Hash
125)]
126pub struct CastUint64ToNumeric(pub Option<NumericMaxScale>);
127
128#[sqlfunc(
129 CastUint64ToNumeric,
130 sqlname = "uint8_to_numeric",
131 could_error = self.0.is_some(),
132 inverse = super::CastNumericToUint64,
133 is_monotone = true,
134 output_type_expr = SqlScalarType::Numeric { max_scale: self.0 }
135 .nullable(input_type.nullable)
136)]
137fn cast_uint64_to_numeric(&self, a: u64) -> Result<Numeric, EvalError> {
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}