MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / to_sql

Method to_sql

src/pgrepr/src/value/numeric.rs:50–156  ·  view source on GitHub ↗
(
        &self,
        _: &Type,
        out: &mut BytesMut,
    )

Source from the content-addressed store, hash-verified

48
49impl ToSql for Numeric {
50 fn to_sql(
51 &self,
52 _: &Type,
53 out: &mut BytesMut,
54 ) -> Result<IsNull, Box<dyn Error + 'static + Send + Sync>> {
55 let mut d = self.0.0.clone();
56 let scale = u16::try_from(numeric::get_scale(&d))?;
57 let is_zero = d.is_zero();
58 let is_nan = d.is_nan();
59 let is_neg = d.is_negative() && !is_zero;
60 let is_infinite = d.is_infinite();
61
62 let mut cx = numeric::cx_datum();
63 // Need to extend exponents slightly because fractional components need
64 // to be aligned to base 10,000.
65 cx.set_max_exponent(cx.max_exponent() + isize::cast_from(i64::from(TO_FROM_SQL_BASE_POW)))
66 .unwrap();
67 cx.set_min_exponent(cx.min_exponent() - isize::cast_from(i64::from(TO_FROM_SQL_BASE_POW)))
68 .unwrap();
69 cx.abs(&mut d);
70
71 let mut digits = [0u16; UNITS_LEN];
72 let mut d_i = UNITS_LEN;
73
74 let (fract_units, leading_zero_units) = if d.exponent() < 0 {
75 let pos_exp = usize::try_from(-d.exponent()).expect("positive value < 40");
76 // You have leading zeroes in the case where:
77 // - The exponent's absolute value exceeds the number of digits
78 // - `d` only contains fractional zeroes
79 let leading_zero_units = if pos_exp >= usize::cast_from(d.digits()) {
80 // If the value is zero, one zero digit gets double counted
81 // (this is also why the above inequality is not strict)
82 let digits = if d.is_zero() {
83 0
84 } else {
85 usize::cast_from(d.digits())
86 };
87 // integer division with rounding up instead of down
88 (pos_exp - digits + usize::cast_from(TO_FROM_SQL_BASE_POW) - 1)
89 / usize::cast_from(TO_FROM_SQL_BASE_POW)
90 } else {
91 0
92 };
93
94 // Ensure most significant fractional digit in ten's place of base
95 // 10,000 value.
96 let s = pos_exp % usize::cast_from(TO_FROM_SQL_BASE_POW);
97 let unit_shift_exp = if s != 0 {
98 pos_exp + usize::cast_from(TO_FROM_SQL_BASE_POW) - s
99 } else {
100 pos_exp
101 };
102
103 // Convert d into a "canonical coefficient" with most significant
104 // fractional digit properly aligned.
105 cx.scaleb(&mut d, &AdtNumeric::from(unit_shift_exp));
106
107 (

Callers 2

innerFunction · 0.45

Calls 9

get_scaleFunction · 0.85
cx_datumFunction · 0.85
is_negativeMethod · 0.80
unwrapMethod · 0.80
expectMethod · 0.80
remMethod · 0.80
cloneMethod · 0.45
is_zeroMethod · 0.45
iterMethod · 0.45

Tested by 1