Fixed an overflow with a negative scale

This commit is contained in:
Julius de Bruijn 2020-07-04 13:02:16 +02:00 committed by Austin Bonander
parent 245d53e484
commit f246d41aed
3 changed files with 12 additions and 7 deletions

View file

@ -69,9 +69,16 @@ impl TryFrom<PgNumeric> for Decimal {
let bigint = BigInt::from_radix_be(sign, &cents, 100)
.ok_or("PgNumeric contained an out-of-range digit")?;
match bigint.to_i128() {
Some(num) => Ok(Decimal::from_i128_with_scale(num, scale as u32)),
None => Err("Decimal's integer part out of range.".into()),
match (bigint.to_i128(), scale) {
// A negative scale, meaning we have nothing on the right and must
// add zeroes to the left.
(Some(num), scale) if scale < 0 => Ok(Decimal::from_i128_with_scale(
num * 10i128.pow(scale.abs() as u32),
0,
)),
// A positive scale, so we have decimals on the right.
(Some(num), _) => Ok(Decimal::from_i128_with_scale(num, scale as u32)),
(None, _) => Err("Decimal's integer part out of range.".into()),
}
}
}

View file

@ -203,8 +203,7 @@ test_type!(bigdecimal<sqlx::types::BigDecimal>(
test_type!(decimal<sqlx::types::Decimal>(MySql,
"CAST(0 as DECIMAL(0, 0))" == sqlx::types::Decimal::from_str("0").unwrap(),
"CAST(1 AS DECIMAL(1, 0))" == sqlx::types::Decimal::from_str("1").unwrap(),
// bug in rust_decimal: https://github.com/paupino/rust-decimal/issues/251
//"CAST(10000 AS DECIMAL(5, 0))" == sqlx::types::Decimal::from_str("10000").unwrap(),
"CAST(10000 AS DECIMAL(5, 0))" == sqlx::types::Decimal::from_str("10000").unwrap(),
"CAST(0.1 AS DECIMAL(2, 1))" == sqlx::types::Decimal::from_str("0.1").unwrap(),
"CAST(0.01234 AS DECIMAL(6, 5))" == sqlx::types::Decimal::from_str("0.01234").unwrap(),
"CAST(12.34 AS DECIMAL(4, 2))" == sqlx::types::Decimal::from_str("12.34").unwrap(),

View file

@ -343,8 +343,7 @@ test_type!(bigdecimal<sqlx::types::BigDecimal>(Postgres,
test_type!(decimal<sqlx::types::Decimal>(Postgres,
"0::numeric" == sqlx::types::Decimal::from_str("0").unwrap(),
"1::numeric" == sqlx::types::Decimal::from_str("1").unwrap(),
// bug in rust_decimal: https://github.com/paupino/rust-decimal/issues/251
//"10000::numeric" == sqlx::types::Decimal::from_str("10000").unwrap(),
"10000::numeric" == sqlx::types::Decimal::from_str("10000").unwrap(),
"0.1::numeric" == sqlx::types::Decimal::from_str("0.1").unwrap(),
"0.01234::numeric" == sqlx::types::Decimal::from_str("0.01234").unwrap(),
"12.34::numeric" == sqlx::types::Decimal::from_str("12.34").unwrap(),