mz_expr/scalar/func/impls/
int64.rs1use mz_expr_derive::sqlfunc;
11use mz_repr::adt::numeric::{self, Numeric, NumericMaxScale};
12use mz_repr::adt::system::Oid;
13use mz_repr::{SqlScalarType, strconv};
14use serde::{Deserialize, Serialize};
15
16use crate::EvalError;
17
18#[sqlfunc(
19 sqlname = "-",
20 preserves_uniqueness = true,
21 inverse = NegInt64,
22 is_monotone = true
23)]
24fn neg_int64(a: i64) -> Result<i64, EvalError> {
25 a.checked_neg()
26 .ok_or_else(|| EvalError::Int64OutOfRange(a.to_string().into()))
27}
28
29#[sqlfunc(
30 sqlname = "~",
31 preserves_uniqueness = true,
32 inverse = BitNotInt64
33)]
34fn bit_not_int64(a: i64) -> i64 {
35 !a
36}
37
38#[sqlfunc(sqlname = "abs")]
39fn abs_int64(a: i64) -> Result<i64, EvalError> {
40 a.checked_abs()
41 .ok_or_else(|| EvalError::Int64OutOfRange(a.to_string().into()))
42}
43
44#[sqlfunc(
45 sqlname = "bigint_to_boolean",
46 preserves_uniqueness = false,
47 inverse = super::CastBoolToInt64
48)]
49fn cast_int64_to_bool(a: i64) -> bool {
50 a != 0
51}
52
53#[sqlfunc(
54 sqlname = "bigint_to_smallint",
55 preserves_uniqueness = true,
56 inverse = super::CastInt16ToInt64,
57 is_monotone = true
58)]
59fn cast_int64_to_int16(a: i64) -> Result<i16, EvalError> {
60 i16::try_from(a).or_else(|_| Err(EvalError::Int16OutOfRange(a.to_string().into())))
61}
62
63#[sqlfunc(
64 sqlname = "bigint_to_integer",
65 preserves_uniqueness = true,
66 inverse = super::CastInt32ToInt64,
67 is_monotone = true
68)]
69fn cast_int64_to_int32(a: i64) -> Result<i32, EvalError> {
70 i32::try_from(a).or_else(|_| Err(EvalError::Int32OutOfRange(a.to_string().into())))
71}
72
73#[sqlfunc(
74 sqlname = "bigint_to_oid",
75 preserves_uniqueness = true,
76 inverse = super::CastOidToInt64
77)]
78fn cast_int64_to_oid(a: i64) -> Result<Oid, EvalError> {
79 u32::try_from(a)
82 .map(Oid)
83 .or_else(|_| Err(EvalError::OidOutOfRange(a.to_string().into())))
84}
85
86#[sqlfunc(
87 sqlname = "bigint_to_uint2",
88 preserves_uniqueness = true,
89 inverse = super::CastUint16ToInt64,
90 is_monotone = true
91)]
92fn cast_int64_to_uint16(a: i64) -> Result<u16, EvalError> {
93 u16::try_from(a).or_else(|_| Err(EvalError::UInt16OutOfRange(a.to_string().into())))
94}
95
96#[sqlfunc(
97 sqlname = "bigint_to_uint4",
98 preserves_uniqueness = true,
99 inverse = super::CastUint32ToInt64,
100 is_monotone = true
101)]
102fn cast_int64_to_uint32(a: i64) -> Result<u32, EvalError> {
103 u32::try_from(a).or_else(|_| Err(EvalError::UInt32OutOfRange(a.to_string().into())))
104}
105
106#[sqlfunc(
107 sqlname = "bigint_to_uint8",
108 preserves_uniqueness = true,
109 inverse = super::CastUint64ToInt64,
110 is_monotone = true
111)]
112fn cast_int64_to_uint64(a: i64) -> Result<u64, EvalError> {
113 u64::try_from(a).or_else(|_| Err(EvalError::UInt64OutOfRange(a.to_string().into())))
114}
115
116#[derive(
117 Ord,
118 PartialOrd,
119 Clone,
120 Debug,
121 Eq,
122 PartialEq,
123 Serialize,
124 Deserialize,
125 Hash
126)]
127pub struct CastInt64ToNumeric(pub Option<NumericMaxScale>);
128
129#[sqlfunc(
130 CastInt64ToNumeric,
131 sqlname = "bigint_to_numeric",
132 could_error = self.0.is_some(),
133 inverse = super::CastNumericToInt64,
134 is_monotone = true,
135 output_type_expr = SqlScalarType::Numeric { max_scale: self.0 }
136 .nullable(input_type.nullable)
137)]
138fn cast_int64_to_numeric(&self, a: i64) -> Result<Numeric, EvalError> {
139 let mut a = Numeric::from(a);
140 if let Some(scale) = self.0 {
141 if numeric::rescale(&mut a, scale.into_u8()).is_err() {
142 return Err(EvalError::NumericFieldOverflow);
143 }
144 }
145 Ok(a)
147}
148
149#[sqlfunc(
150 sqlname = "bigint_to_real",
151 preserves_uniqueness = false,
152 inverse = super::CastFloat32ToInt64,
153 is_monotone = true
154)]
155#[allow(clippy::as_conversions)]
157fn cast_int64_to_float32(a: i64) -> f32 {
158 a as f32
159}
160
161#[sqlfunc(
162 sqlname = "bigint_to_double",
163 preserves_uniqueness = false, inverse = super::CastFloat64ToInt64,
165 is_monotone = true
166)]
167#[allow(clippy::as_conversions)]
169fn cast_int64_to_float64(a: i64) -> f64 {
170 a as f64
171}
172
173#[sqlfunc(
174 sqlname = "bigint_to_text",
175 preserves_uniqueness = true,
176 inverse = super::CastStringToInt64
177)]
178fn cast_int64_to_string(a: i64) -> String {
179 let mut buf = String::new();
180 strconv::format_int64(&mut buf, a);
181 buf
182}