Skip to content

Commit d3faa99

Browse files
committed
Further improved decimal to floating point conversion in Microsoft SQL Server
1 parent dced7b4 commit d3faa99

File tree

10 files changed

+63
-44
lines changed

10 files changed

+63
-44
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## 0.6.25
9+
10+
- Further improved decimal to floating point conversion in Microsoft SQL Server
11+
812
## 0.6.24
913

1014
- Improved decimal to floating point conversion in Postgres and Microsoft SQL Server

Cargo.lock

Lines changed: 30 additions & 29 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ members = [
2020

2121
[package]
2222
name = "sqlx-oldapi"
23-
version = "0.6.24"
23+
version = "0.6.25"
2424
license = "MIT OR Apache-2.0"
2525
readme = "README.md"
2626
repository = "https://github.com/lovasoa/sqlx"
@@ -125,8 +125,8 @@ bstr = ["sqlx-core/bstr"]
125125
git2 = ["sqlx-core/git2"]
126126

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

131131
[dev-dependencies]
132132
anyhow = "1.0.52"

examples/postgres/axum-social-with-tests/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ edition = "2021"
88
[dependencies]
99
# Primary crates
1010
axum = { version = "0.5.13", features = ["macros"] }
11-
sqlx = { package = "sqlx-oldapi", version = "0.6.24", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }
11+
sqlx = { package = "sqlx-oldapi", version = "0.6.25", path = "../../../", features = ["runtime-tokio-rustls", "postgres", "time", "uuid"] }
1212
tokio = { version = "1.20.1", features = ["rt-multi-thread", "macros"] }
1313

1414
# Important secondary crates

sqlx-cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlx-cli"
3-
version = "0.6.24"
3+
version = "0.6.25"
44
description = "Command-line utility for SQLx, the Rust SQL toolkit."
55
edition = "2021"
66
readme = "README.md"

sqlx-core/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlx-core-oldapi"
3-
version = "0.6.24"
3+
version = "0.6.25"
44
repository = "https://github.com/lovasoa/sqlx"
55
description = "Core of SQLx, the rust SQL toolkit. Not intended to be used directly."
66
license = "MIT OR Apache-2.0"
@@ -101,7 +101,7 @@ offline = ["serde", "either/serde"]
101101
paste = "1.0.6"
102102
ahash = "0.8.3"
103103
atoi = "2.0.0"
104-
sqlx-rt = { path = "../sqlx-rt", version = "0.6.24", package = "sqlx-rt-oldapi" }
104+
sqlx-rt = { path = "../sqlx-rt", version = "0.6.25", package = "sqlx-rt-oldapi" }
105105
base64 = { version = "0.22", default-features = false, optional = true, features = ["std"] }
106106
bigdecimal_ = { version = "0.4.1", optional = true, package = "bigdecimal" }
107107
rust_decimal = { version = "1.19.0", optional = true }

sqlx-core/src/mssql/types/float.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,12 @@ fn decode_numeric(bytes: &[u8], _precision: u8, mut scale: u8) -> Result<f64, Bo
8585
let mut fixed_bytes = [0u8; 16];
8686
fixed_bytes[0..rest.len()].copy_from_slice(rest);
8787
let mut numerator = u128::from_le_bytes(fixed_bytes);
88-
let mut decimal_part = 0.;
89-
while scale > 0 {
90-
decimal_part += (numerator % 10) as f64 / 10_f64.powf(scale as f64);
88+
while numerator % 10 == 0 && scale > 0 {
9189
numerator /= 10;
9290
scale -= 1;
9391
}
94-
Ok(sign * ((numerator as f64) + decimal_part))
92+
let denominator = 10u128.pow(scale as u32);
93+
let integer_part = (numerator / denominator) as f64;
94+
let fractional_part = (numerator % denominator) as f64 / denominator as f64;
95+
Ok(sign * (integer_part + fractional_part))
9596
}

sqlx-macros/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlx-macros-oldapi"
3-
version = "0.6.24"
3+
version = "0.6.25"
44
repository = "https://github.com/lovasoa/sqlx"
55
description = "Macros for SQLx, the rust SQL toolkit. Not intended to be used directly."
66
license = "MIT OR Apache-2.0"
@@ -75,8 +75,8 @@ heck = { version = "0.5" }
7575
either = "1.6.1"
7676
once_cell = "1.9.0"
7777
proc-macro2 = { version = "1.0.36", default-features = false }
78-
sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.24", default-features = false, features = ["any"], path = "../sqlx-core" }
79-
sqlx-rt = { version = "0.6.24", default-features = false, path = "../sqlx-rt", package = "sqlx-rt-oldapi" }
78+
sqlx-core = { package = "sqlx-core-oldapi", version = "0.6.25", default-features = false, features = ["any"], path = "../sqlx-core" }
79+
sqlx-rt = { version = "0.6.25", default-features = false, path = "../sqlx-rt", package = "sqlx-rt-oldapi" }
8080
serde = { version = "1.0.132", features = ["derive"], optional = true }
8181
serde_json = { version = "1.0.73", optional = true }
8282
sha2 = { version = "0.10.0", optional = true }

sqlx-rt/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sqlx-rt-oldapi"
3-
version = "0.6.24"
3+
version = "0.6.25"
44
repository = "https://github.com/launchbadge/sqlx"
55
license = "MIT OR Apache-2.0"
66
description = "Runtime abstraction used by SQLx, the Rust SQL toolkit. Not intended to be used directly."

tests/mssql/types.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ test_type!(f64(
5454
test_type!(numeric<f64>(Mssql,
5555
"CAST(12 AS NUMERIC)" == 12_f64,
5656
"CAST(0.7 AS NUMERIC(2,1))" == 0.7_f64,
57+
"CAST(0.3 AS NUMERIC(2,1))" == 0.3_f64,
58+
"CAST(0.47 AS DECIMAL(3,2))" == 0.47_f64,
59+
"CAST(0.29 AS DECIMAL(3,2))" == 0.29_f64,
5760
"CAST(0.5678 AS NUMERIC(10,4))" == 0.5678_f64,
5861
"CAST(0.0003 AS NUMERIC(10,4))" == 0.0003_f64,
5962
"CAST(0.00003 AS NUMERIC(10,5))" == 0.00003_f64,
@@ -63,6 +66,16 @@ test_type!(numeric<f64>(Mssql,
6366
"CAST(123456789.0123456789 AS NUMERIC(38,10))" == 123_456_789.012_345_67_f64,
6467
"CAST(123456789.0123456789012 AS NUMERIC(38,13))" == 123_456_789.012_345_67_f64,
6568
"CAST(123456789.012345678901234 AS NUMERIC(38,15))" == 123_456_789.012_345_67_f64,
69+
70+
"CAST(1.0000000000000001 AS NUMERIC(18,16))" == 1.0000000000000001_f64,
71+
"CAST(0.99999999999999 AS NUMERIC(18,14))" == 0.99999999999999_f64,
72+
"CAST(2.00000000000001 AS NUMERIC(18,14))" == 2.00000000000001_f64,
73+
"CAST(333.33333333333333 AS NUMERIC(18,14))" == 333.33333333333333_f64,
74+
"CAST(0.14285714285714 AS NUMERIC(18,14))" == 0.14285714285714_f64,
75+
"CAST(9999999.99999999 AS NUMERIC(16,8))" == 9999999.99999999_f64, // Close to the precision limit
76+
"CAST(9007199254740992 AS NUMERIC(16,0))" == 9007199254740992_f64, // 2^53, largest integer that can be exactly represented as a f64
77+
"CAST(0.000123456 AS NUMERIC(38,38))" == 0.000123456_f64,
78+
"CAST(1e-38 AS NUMERIC(38,38))" == 1e-38_f64,
6679
));
6780

6881
test_type!(str_nvarchar<String>(Mssql,

0 commit comments

Comments
 (0)