fix(drivers): preserve BIGINT precision past JS Number.MAX_SAFE_INTEGER#220
Merged
debba merged 2 commits intoMay 19, 2026
Merged
Conversation
Snowflake-style ids and other BIGINT values above 2^53 - 1 lost their last digits in the UI because the read path serialised them as JSON numbers, which JSON.parse on the frontend rounds to the nearest IEEE 754 double. Add a common helper that emits i64/u64 values as JSON strings only when they fall outside JS's safe range, and wire it through every place a driver hands a 64-bit integer to the renderer: MySQL's scalar fallback (both signed and unsigned), Postgres' INT8 / XID8 / MONEY paths, and SQLite's INTEGER path. Small values stay native numbers so sorting, filtering and editing keep working untouched. Mirror the change on the write-back side: a JSON string that parses as an i64 outside the safe range is bound as a native integer, so editing or deleting by a large bigint primary key still matches the row. The Postgres PK predicate wraps the bind in CAST AS bigint to satisfy tokio-postgres' strict type checking; MySQL and SQLite rely on their implicit numeric coercion. Closes TabularisDB#210
…esting Mirrors the text_demo / json_demo pattern with seven rows that exercise the JS-safe-integer boundary from both sides: small values that stay JSON numbers, the 2^53 / 2^53 - 1 boundary, the snowflake id from the original report, i64::MAX, a u64 value above i64::MAX, and a negative snowflake. Postgres also covers xid8 and money since both are backed by 64-bit integers.
Collaborator
|
Looks good and thanks for demo seed :) |
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.
Summary
2^53 - 1(e.g. snowflake ids like844197938335842304) lost their last digits in the UI because the read path emitted them as JSON numbers and the frontend'sJSON.parserounds to the nearest IEEE 754 double.drivers::common::safe_inthelper emitsi64/u64as a JSON string only when the value falls outside JS's safe integer range; smaller values stay native numbers, so the wire format for the 99% case is byte-identical to before.u64/i64scalar fallback), Postgres (INT8,XID8,MONEY), and SQLite (INTEGER).CAST AS bigintto satisfy tokio-postgres' strict type checking; MySQL and SQLite rely on their implicit numeric coercion.bigint_demoadded to MySQL and Postgres init scripts so the boundary cases are reproducible without ad-hoc SQL (mirrors thetext_demo/json_demopattern).Behaviour notes
handleSortinEditor.tsxbuilds anORDER BYclause and the filter toolbar builds aWHEREclause; the comparison happens in the database against the native BIGINT column, never in JS. The grid has no client-side global/quick filter that could trip over a mixed number/string column.i64before binding.Test plan
cargo test --lib drivers→ 297 passedcargo build --libclean, no new clippy warnings on touched filesbigint_demotable):844197938335842304displays exactly (was…842300)9223372036854775807displays exactly18446744073709551614(BIGINT UNSIGNED above i64::MAX) displays exactly42and9007199254740991stay JSON numbers (sortable numerically)id = 7777777777777777777succeedsbigint_demotable):BIGINT,XID8andMONEYcolumnsnoteon snowflake PK row → exactly one row updatedamounton snowflake row → bigint outside safe range round-trips through SETid = 7777777777777777777succeeds