Skip to content

Conversation

@c5soft
Copy link

@c5soft c5soft commented May 27, 2025

Refactor sqlx-core/src/mssql/types/bigdecimal.rs and sqlx-core/src/mssql/types/decimal.rs, Add Money type support to mssql

Copy link
Collaborator

@lovasoa lovasoa left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for this comprehensive PR! These are valuable additions to the MSSQL driver!

To help with maintainability and review process, could you please:

  1. Split into separate PRs - Each concern (dependency updates, SSL options docs, Money type support) would be easier to review and merge independently
  2. Eliminate code duplication - The Money parsing logic in bigdecimal.rs and decimal.rs could be extracted into a shared helper function
  3. Add comprehensive tests - This is super important! Please ensure every new line of code has test coverage. You can look at existing tests for other mssql types.

The implementation looks solid technically - just want to make sure we have solid test coverage before merging. Thanks again for tackling these important improvements!

DataType::MoneyN | DataType::Money | DataType::SmallMoney => {
// Money is stored as an 8-byte integer representing the amount in ten-thousandths of a currency unit
let bytes = value.as_bytes()?;
// println!("bytes: {:?}", bytes);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented code

Comment on lines 64 to 80
DataType::MoneyN | DataType::Money | DataType::SmallMoney => {
// Money is stored as an 8-byte integer representing the amount in ten-thousandths of a currency unit
let bytes = value.as_bytes()?;
// println!("bytes: {:?}", bytes);
if bytes.len() != 8 && bytes.len() != 4 {
return Err(
err_protocol!("expected 8/4 bytes for Money, got {}", bytes.len()).into(),
);
}
let amount: i64 = if bytes.len() == 8 {
let amount_h = i32::from_le_bytes(bytes[0..4].try_into()?) as i64;
let amount_l = u32::from_le_bytes(bytes[4..8].try_into()?) as i64;
(amount_h << 32) | amount_l
} else {
i32::from_le_bytes(bytes.try_into()?) as i64
};
Ok(Decimal::new(amount, 4))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we avoid duplicating the logic ?

Cargo.lock Outdated
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
version = 3
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

@lovasoa
Copy link
Collaborator

lovasoa commented May 27, 2025

If the money type actually fits in either an i32 or an i64, we should probably implement Decode for these types, and then just code i64::decode from the decimal and bigdecimal implementations

@c5soft
Copy link
Author

c5soft commented Jun 4, 2025

If the money type actually fits in either an i32 or an i64, we should probably implement Decode for these types, and then just code i64::decode from the decimal and bigdecimal implementations

In MSSQL, the MONEY and SMALLMONEY types are specialized variants of DECIMAL with fixed decimal precision:
MONEY is equivalent to DECIMAL(19,4) (19 total digits with 4 decimal places)
SMALLMONEY corresponds to DECIMAL(10,4) (10 total digits with 4 decimal places)
When mapping these to Rust, the most suitable data types are rust_decimal or bigdecimal to preserve exact precision without floating-point errors.
In financial software development, the MONEY data type is widely used. Therefore, we strongly recommend adding support for the MONEY type in sqlx-oldapi. The code I've submitted has been tested in production applications and should be feasible.

@lovasoa
Copy link
Collaborator

lovasoa commented Jun 4, 2025

Hi !

I'm okay to merge that without adding decoding to i64 or i32. But you still need to address my comments above before we can integrate your contribution:

  1. Split into separate PRs - Each concern (dependency updates, SSL options docs, Money type support) would be easier to review and merge independently
  2. Eliminate code duplication - The Money parsing logic in bigdecimal.rs and decimal.rs could be extracted into a shared helper function
  3. Add comprehensive tests - This is super important! Please ensure every new line of code has test coverage. You can look at existing tests for other mssql types.

@c5soft c5soft closed this Jun 5, 2025
@c5soft
Copy link
Author

c5soft commented Jun 5, 2025

close this PR and create a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants