Skip to content

Commit

Permalink
Further improved decimal to floating point conversion in Microsoft SQ…
Browse files Browse the repository at this point in the history
…L Server
  • Loading branch information
lovasoa committed Aug 13, 2024
1 parent dced7b4 commit d3faa99
Show file tree
Hide file tree
Showing 10 changed files with 63 additions and 44 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.6.25

- Further improved decimal to floating point conversion in Microsoft SQL Server

## 0.6.24

- Improved decimal to floating point conversion in Postgres and Microsoft SQL Server
Expand Down
59 changes: 30 additions & 29 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ members = [

[package]
name = "sqlx-oldapi"
version = "0.6.24"
version = "0.6.25"
license = "MIT OR Apache-2.0"
readme = "README.md"
repository = "https://github.com/lovasoa/sqlx"
Expand Down Expand Up @@ -125,8 +125,8 @@ bstr = ["sqlx-core/bstr"]
git2 = ["sqlx-core/git2"]

[dependencies]
sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.24", path = "sqlx-core", default-features = false }
sqlx-macros = { package = "sqlx-macros-oldapi", version = "0.6.24", path = "sqlx-macros", default-features = false, optional = true }
sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.25", path = "sqlx-core", default-features = false }
sqlx-macros = { package = "sqlx-macros-oldapi", version = "0.6.25", path = "sqlx-macros", default-features = false, optional = true }

[dev-dependencies]
anyhow = "1.0.52"
Expand Down
2 changes: 1 addition & 1 deletion examples/postgres/axum-social-with-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ edition = "2021"
[dependencies]
# Primary crates
axum = { version = "0.5.13", features = ["macros"] }
sqlx = { package = "sqlx-oldapi", version = "0.6.24", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }
sqlx = { package = "sqlx-oldapi", version = "0.6.25", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }
tokio = { version = "1.20.1", features = ["rt-multi-thread", "macros"] }

# Important secondary crates
Expand Down
2 changes: 1 addition & 1 deletion sqlx-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sqlx-cli"
version = "0.6.24"
version = "0.6.25"
description = "Command-line utility for SQLx, the Rust SQL toolkit."
edition = "2021"
readme = "README.md"
Expand Down
4 changes: 2 additions & 2 deletions sqlx-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sqlx-core-oldapi"
version = "0.6.24"
version = "0.6.25"
repository = "https://github.com/lovasoa/sqlx"
description = "Core of SQLx, the rust SQL toolkit. Not intended to be used directly."
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -101,7 +101,7 @@ offline = ["serde", "either/serde"]
paste = "1.0.6"
ahash = "0.8.3"
atoi = "2.0.0"
sqlx-rt = { path = "../sqlx-rt", version = "0.6.24", package = "sqlx-rt-oldapi" }
sqlx-rt = { path = "../sqlx-rt", version = "0.6.25", package = "sqlx-rt-oldapi" }
base64 = { version = "0.22", default-features = false, optional = true, features = ["std"] }
bigdecimal_ = { version = "0.4.1", optional = true, package = "bigdecimal" }
rust_decimal = { version = "1.19.0", optional = true }
Expand Down
9 changes: 5 additions & 4 deletions sqlx-core/src/mssql/types/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,12 @@ fn decode_numeric(bytes: &[u8], _precision: u8, mut scale: u8) -> Result<f64, Bo
let mut fixed_bytes = [0u8; 16];
fixed_bytes[0..rest.len()].copy_from_slice(rest);
let mut numerator = u128::from_le_bytes(fixed_bytes);
let mut decimal_part = 0.;
while scale > 0 {
decimal_part += (numerator % 10) as f64 / 10_f64.powf(scale as f64);
while numerator % 10 == 0 && scale > 0 {
numerator /= 10;
scale -= 1;
}
Ok(sign * ((numerator as f64) + decimal_part))
let denominator = 10u128.pow(scale as u32);
let integer_part = (numerator / denominator) as f64;
let fractional_part = (numerator % denominator) as f64 / denominator as f64;
Ok(sign * (integer_part + fractional_part))
}
6 changes: 3 additions & 3 deletions sqlx-macros/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sqlx-macros-oldapi"
version = "0.6.24"
version = "0.6.25"
repository = "https://github.com/lovasoa/sqlx"
description = "Macros for SQLx, the rust SQL toolkit. Not intended to be used directly."
license = "MIT OR Apache-2.0"
Expand Down Expand Up @@ -75,8 +75,8 @@ heck = { version = "0.5" }
either = "1.6.1"
once_cell = "1.9.0"
proc-macro2 = { version = "1.0.36", default-features = false }
sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.24", default-features = false, features = ["any"], path = "../sqlx-core" }
sqlx-rt = { version = "0.6.24", default-features = false, path = "../sqlx-rt", package = "sqlx-rt-oldapi" }
sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.25", default-features = false, features = ["any"], path = "../sqlx-core" }
sqlx-rt = { version = "0.6.25", default-features = false, path = "../sqlx-rt", package = "sqlx-rt-oldapi" }
serde = { version = "1.0.132", features = ["derive"], optional = true }
serde_json = { version = "1.0.73", optional = true }
sha2 = { version = "0.10.0", optional = true }
Expand Down
2 changes: 1 addition & 1 deletion sqlx-rt/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sqlx-rt-oldapi"
version = "0.6.24"
version = "0.6.25"
repository = "https://github.com/launchbadge/sqlx"
license = "MIT OR Apache-2.0"
description = "Runtime abstraction used by SQLx, the Rust SQL toolkit. Not intended to be used directly."
Expand Down
13 changes: 13 additions & 0 deletions tests/mssql/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ test_type!(f64(
test_type!(numeric<f64>(Mssql,
"CAST(12 AS NUMERIC)" == 12_f64,
"CAST(0.7 AS NUMERIC(2,1))" == 0.7_f64,
"CAST(0.3 AS NUMERIC(2,1))" == 0.3_f64,
"CAST(0.47 AS DECIMAL(3,2))" == 0.47_f64,
"CAST(0.29 AS DECIMAL(3,2))" == 0.29_f64,
"CAST(0.5678 AS NUMERIC(10,4))" == 0.5678_f64,
"CAST(0.0003 AS NUMERIC(10,4))" == 0.0003_f64,
"CAST(0.00003 AS NUMERIC(10,5))" == 0.00003_f64,
Expand All @@ -63,6 +66,16 @@ test_type!(numeric<f64>(Mssql,
"CAST(123456789.0123456789 AS NUMERIC(38,10))" == 123_456_789.012_345_67_f64,
"CAST(123456789.0123456789012 AS NUMERIC(38,13))" == 123_456_789.012_345_67_f64,
"CAST(123456789.012345678901234 AS NUMERIC(38,15))" == 123_456_789.012_345_67_f64,

"CAST(1.0000000000000001 AS NUMERIC(18,16))" == 1.0000000000000001_f64,
"CAST(0.99999999999999 AS NUMERIC(18,14))" == 0.99999999999999_f64,
"CAST(2.00000000000001 AS NUMERIC(18,14))" == 2.00000000000001_f64,
"CAST(333.33333333333333 AS NUMERIC(18,14))" == 333.33333333333333_f64,
"CAST(0.14285714285714 AS NUMERIC(18,14))" == 0.14285714285714_f64,
"CAST(9999999.99999999 AS NUMERIC(16,8))" == 9999999.99999999_f64, // Close to the precision limit
"CAST(9007199254740992 AS NUMERIC(16,0))" == 9007199254740992_f64, // 2^53, largest integer that can be exactly represented as a f64
"CAST(0.000123456 AS NUMERIC(38,38))" == 0.000123456_f64,
"CAST(1e-38 AS NUMERIC(38,38))" == 1e-38_f64,
));

test_type!(str_nvarchar<String>(Mssql,
Expand Down

0 comments on commit d3faa99

Please sign in to comment.