Skip to content

Commit

Permalink
Fixes rescale internal allowing zeros to scale greater than the maxim…
Browse files Browse the repository at this point in the history
…um possible precision (#566)
  • Loading branch information
paupino committed Jan 13, 2023
1 parent 2da7a0d commit bc8b53a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 15 deletions.
43 changes: 28 additions & 15 deletions src/ops/array.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::constants::{POWERS_10, U32_MASK};
use crate::constants::{MAX_PRECISION_U32, POWERS_10, U32_MASK};

/// Rescales the given decimal to new scale.
/// e.g. with 1.23 and new scale 3 rescale the value to 1.230
Expand All @@ -10,7 +10,7 @@ pub(crate) fn rescale_internal(value: &mut [u32; 3], value_scale: &mut u32, new_
}

if is_all_zero(value) {
*value_scale = new_scale;
*value_scale = new_scale.min(MAX_PRECISION_U32);
return;
}

Expand Down Expand Up @@ -299,29 +299,42 @@ mod test {
}

let tests = &[
("1", 0, "1"),
("1", 1, "1.0"),
("1", 5, "1.00000"),
("1", 10, "1.0000000000"),
("1", 20, "1.00000000000000000000"),
("0.6386554621848739495798319328", 27, "0.638655462184873949579831933"),
("1", 0, "1", 0),
("1", 1, "1.0", 1),
("1", 5, "1.00000", 5),
("1", 10, "1.0000000000", 10),
("1", 20, "1.00000000000000000000", 20),
(
"0.6386554621848739495798319328",
27,
"0.638655462184873949579831933",
27,
),
(
"843.65000000", // Scale 8
25, // 25
"843.6500000000000000000000000", // 25
"843.65000000", // Scale 8
25,
"843.6500000000000000000000000",
25,
),
(
"843.65000000", // Scale 8
30, // 30
"843.6500000000000000000000000000", // 28
"843.65000000", // Scale 8
30,
"843.6500000000000000000000000",
25, // Only fits 25
),
("0", 130, "0.000000000000000000000000000000", 28),
];

for &(value_raw, new_scale, expected_value) in tests {
for &(value_raw, new_scale, expected_value, expected_scale) in tests {
let (expected_value, _) = extract(expected_value);
let (mut value, mut value_scale) = extract(value_raw);
rescale_internal(&mut value, &mut value_scale, new_scale);
assert_eq!(value, expected_value);
assert_eq!(
value_scale, expected_scale,
"value: {}, requested scale: {}",
value_raw, new_scale
);
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/postgres/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,20 @@ mod test {
assert_eq!(None, result);
}

#[test]
fn read_very_small_numeric_type() {
let mut client = match Client::connect(&get_postgres_url(), NoTls) {
Ok(x) => x,
Err(err) => panic!("{:#?}", err),
};
let result: Decimal = match client.query("SELECT 1e-130::NUMERIC(130, 0)", &[]) {
Ok(x) => x.iter().next().unwrap().get(0),
Err(err) => panic!("error - {:#?}", err),
};
// We compare this to zero since it is so small that it is effectively zero
assert_eq!(Decimal::ZERO, result);
}

#[test]
fn read_numeric_type() {
let mut client = match Client::connect(&get_postgres_url(), NoTls) {
Expand Down

0 comments on commit bc8b53a

Please sign in to comment.