Skip to content

Conversation

@fredr
Copy link
Contributor

@fredr fredr commented Apr 8, 2025

A first stab at adding support for the Numeric type as well as a to/from implementation for string as that is kind of the only std type that can hold a numeric, and makes it a bit easier to verify correctness.

Would appreciate if you had the time to review this. Happy to fix any feedback. I'm thinking any ToSql and FromSql implementations can be added as followups to this one.

The protocol is quite strait forward, the string conversion is more finicky, but added a bunch of test to hopefully catch all corner cases. Let me know if you think there is any tests that should be added for those.

Partially solves #307 and #1223

@fredr fredr force-pushed the fredr/numeric-protocol branch from e3dc77f to ba79c93 Compare April 8, 2025 19:02
@fredr
Copy link
Contributor Author

fredr commented Sep 16, 2025

Refactored the to/from string code a bit, its a bit hairy because of scientific notation, but should be a bit more readable now

Copy link
Member

@paolobarbolini paolobarbolini left a comment

Choose a reason for hiding this comment

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

I've left a couple of comments, including one on how you see this get used.

The final version should also have tests in tokio-postgres/tests/test/types/ and commits squashed.


fn split_decimal(s: &[u8]) -> (&[u8], Option<&[u8]>) {
let mut s = s.splitn(2, |&b| b == b'.');
let first = s.next().unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

Quickly scrolling through the code it's non-obvious that this panic is unreachable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

split will always have something in the first "split" even if the predicate doesnt match or s is an empty slice, so the first next should always be Some here (unless I have missed something?), should I clarify that in a comment or "expect" or something?

sign: NumericSign,
scale: u16,
weight: i16,
digits: Vec<i16>,
Copy link
Member

Choose a reason for hiding this comment

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

Do you see this get used through the FromStr and Display impls? digits does not get currently exposed (I'm curious, I like that we expose very little in the API). Would a future bigdecimal implementation too go through a formatted string?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That is an oversight actually. The FromStr and Display can be used, but it is probably possible to implement directly between the types.

The reason I added the FromStr and Display is only because they have to be implemented here, where the type is defined (and ofc, it makes it easy to convert to most other types, since most other types have to/from string conversion).

@fredr
Copy link
Contributor Author

fredr commented Nov 17, 2025

Thanks for reviewing this! I'll wait with squashing until we are happy with the PR. Regarding tests in tokio-postgres, from what I can tell, those are more tests of types that implement ToSql and FromSql, so not sure exactly what I should add for tests for this pr? I assume when we start adding bigdecimal and other types, those will be tested there, but not the protocol type? or should I add something there that uses FromStr and Display?

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