Repository navigation
A decimal longer than a double keeps every digit, so 12345678901234567.89 is not 1.2345678901234568e16 - #1413
Merged
Conversation
…7.89 is not 1.2345678901234568e16 Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
WaylandYang
requested changes
Oct 25, 2026
WaylandYang
left a comment
Contributor
There was a problem hiding this comment.
This only affects values over 15 significant digits, which is the intended behaviour. Please update the type-restoration open question in ADR 0018 to say that long exact values stay strings. Optionally, keep the number when the f64 prints back to the same digits.
Signed-off-by: Rudy Celekli <rudy@gradiahq.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
WaylandYang
approved these changes
Oct 27, 2026
WaylandYang
left a comment
Contributor
There was a problem hiding this comment.
Thanks. This conflicted with #1410 only because both added a test at the same spot in mysql.rs; I merged dev into the branch and kept both tests. Approving and merging.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
coerceturns a numeric string into a JSON number. When the value is not ani64, it parses it asf64, whatever the column type. Anf64holds about 15 significant digits. An exactDECIMAL,NUMERIC,NUMBERor Snowflakefixedvalue with more digits than that is silently rounded before it reaches the model.From a live MariaDB 11.4, a
DECIMAL(20,2)holding12345678901234567.89came back as1.2345678901234568e+16. That is a different amount, and the model quotes it as the stored figure. The same happens to SnowflakeNUMBER(38,0)identifiers pasti64, and to DatabricksDECIMALcolumns, because both go throughcoerce.The codebase already intends to keep these exact. The comment on MySQL's
Cell::Decimalsays that values beyond f64 precision stay strings. ClickHouse'scellkeeps aDecimal(P, S)with P > 15 as a string for the same reason. The sharedcoercedid not follow either rule.What changes
For an exact numeric type,
coerceonly converts throughf64when the value has at most 15 significant digits. Leading and trailing zeros are ignored, so1234.50is still1234.5and100000000000000000000is still1e20. A longer value stays as the string the database sent.DOUBLE,FLOATandREALare unchanged, because an approximate type has nothing more to lose.How it was checked
an_exact_decimal_longer_than_a_double_stays_exact, coversDECIMAL(20,2)andfixedpast 15 digits. It checks that a short decimal, a trailing-zero integer and aDOUBLEare still numbers.a_decimal_longer_than_a_double_keeps_every_digit_mysql, uses theFxfixture. It expects{"total":"12345678901234567.89","fee":1234.5}.UTOPIA_TEST_MYSQL_URL=mysql://root:pw@127.0.0.1:13306/sales cargo test -p utopia-server --bins query_engine, run againstmariadb:11.4: 74 passed.left: Number(1.2345678901234568e+16),right: String("12345678901234567.89"). The live test fails withleft: ["{\"total\":1.2345678901234568e+16,\"fee\":1234.5}"].cargo fmt --all --checkandcargo clippy -p utopia-server --all-targets -- -D warningspass.Before review
git commit -s)cargo fmt --all --check,cargo clippyandcargo testpass for the touched crateRequested ADR follow-up
Updated ADR 0018 as requested in review. This appended revision changes documentation only; Rust and Cargo files are byte-for-byte unchanged from the prior public head.
cargo fmt --all --checkandgit diff --checkpass. No new Rust test run or live-cluster acceptance is claimed for this revision. Final-head CI remains required.