Pin Tiberius to a fork carrying the decimal(38,38) Numeric fix - #157
Conversation
tiberius 0.12.3 from crates.io asserts `scale < 38` in `Numeric::new_with_scale` and describes a fraction-only scale-38 value as the invalid `numeric(39,38)`, so a valid `decimal(38,38)` declaration (ADR-0044, mapped verbatim by ADR-0062) could never reach SQL Server. Upstream main still carries the assertion and the open hardening PR tiberius-rs/tiberius#436 fixes only the assertion. Activate ADR-0069's fork rung: pin the maintainer-controlled fork victorchutw/tiberius by full commit SHA 65c1a32f (upstream "Bump v0.12.3" plus one Numeric patch that accepts scale <= 38 and computes the precision of a value without integral digits as max(scale, 1)). The lock records the same revision and nothing else moves. Add a direct offline smoke test of the pinned revision, record the activation, verification posture, upstream trace, and crates.io exit in ADR-0069, and note in ADR-0062 that decimal(38,38) is not a third representability sliver. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Local checks on
The |
Name the smoke test without the glossary-avoided "numeric", prove scale-39 rejection with should_panic(expected) like the rest of the repo, keep one determinism assertion, trim the Cargo.toml comment to the sibling style, and make ADR-0069 name the fork's test-module edits and the branch/revision relationship precisely. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Two-axis review ( Standards — no hard violations (CONTRIBUTING Spec — every acceptance criterion met; two recorded deviations in letter, not substance: the fork base is upstream |
There was a problem hiding this comment.
🔵 Needs a closer look
變更核心資料庫 driver 依賴來源(改為 fork git pin)屬供應鏈與相容性風險面較高的變更,建議由 maintainer 最終人工確認後再合併。
Pull request overview
此 PR 針對 SQL Server 連線器依賴的 Tiberius 0.12.3 在 decimal(38,38)(scale 38)會 panic、且對純小數值的 precision 描述錯誤(會變成 numeric(39,38))的問題,依 ADR-0069 的「fork rung」策略,改以 maintainer 控制的 fork 之 immutable commit SHA 釘死依賴,並加入離線 smoke test 與 ADR 更新,確保 Data Spark 的 Decimal 合約(ADR-0044 / ADR-0062)可完整覆蓋到 decimal(38,38)。
Changes:
- 將
tiberius依賴由 crates.io0.12.3改為 pin 到victorchutw/tiberius的指定 commit SHA,並同步更新Cargo.lock。 - 新增
tests/tiberius_dependency.rs:離線驗證 scale 38 不再 panic、precision 一律為 38、且 scale 39 仍維持 panic。 - 更新 ADR-0069 / ADR-0062,記錄 fork activation、修補內容與不新增 representability sliver 的結論。
File summaries
| File | Description |
|---|---|
| tests/tiberius_dependency.rs | 新增離線 smoke test,鎖定 scale-38 invariant(precision 38、scale 39 仍 panic)。 |
| docs/adr/0069-take-tiberius-from-crates-io-and-accept-its-stale-rustls-stack.md | 記錄 fork rung activation、pin 的 commit SHA、修補範圍與驗證姿勢。 |
| docs/adr/0062-map-dataset-fields-to-exact-fit-sql-server-column-types.md | 補充說明 decimal(38,38) 不是第三 sliver:問題屬於依賴缺陷且已由 pinned revision 修正。 |
| Cargo.toml | 將 tiberius 改為 git rev pin 到 maintainer fork。 |
| Cargo.lock | 將 tiberius source 由 crates.io 改為 git rev,避免其他依賴邊緣變動。 |
Review details
- Files reviewed: 4/5 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The opening paragraph described the crates.io source and caret requirement in the present tense, contradicting the fork pin now in Cargo.toml. State both as the original decision, point at the fork activation that replaced only the source, and note that the lockfile discipline carries over. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Merge-ready at |
|
Merge authorization: the maintainer instructed the agent to merge this PR ("merge") in the active agent session on 2026-09-02; recording it here per docs/agents/gitops.md before merging. Single-use, this PR only. |
Closes #156
Why
Data Spark's declared Decimal contract admits
decimal(38,38)(ADR-0044) and the SQL Server mapping carries it verbatim (ADR-0062), but tiberius 0.12.3 from crates.io panics on scale 38 (assertion failed: scale < 38) and, with the assertion lifted, still describes a fraction-only scale-38 value as the invalidnumeric(39,38). Upstreammaincarries the assertion and the open hardening PR tiberius-rs/tiberius#436 fixes only half. ADR-0069's response ladder names the answer: a pinned revision on a maintainer-controlled fork carrying the minimal patch.What
victorchutw/tiberius, branchdata-spark/numeric-scale-38, based on upstreamc34fab2("Bump v0.12.3" — thev0.12.3tag plus its own manifest version bump; the tree is byte-identical to the published 0.12.3 sources, whereas the tag commit itself still declares 0.12.2). One patch,src/tds/numeric.rsplus tests: acceptscale <= 38(39 still rejected) and compute the precision of a value without integral digits asmax(scale, 1), so0.05isnumeric(2,2)and a scale-38 fraction isnumeric(38,38);integral_digits + scaleis preserved otherwise. Commit: victorchutw/tiberius@65c1a32Cargo.tomlby full commit SHA (no branch tracking);Cargo.lockrecords the same revision and nothing else moves (the lock diff is the onetiberiusentry — a hand-limited edit, accepted by--locked, becausecargo update -p tiberiusalso flipped unrelatedwindows-sys/getrandomedges of other crates).tests/tiberius_dependency.rs: scaled value-1at scale 38 builds deterministically with precision 38, the whole scale-38 magnitude range reports precision 38, and scale 39 still panics. Red against crates.io 0.12.3 (same panic as the issue), green on the pin.decimal(38,38)exact-fit mapping and adds no third representability sliver. ADR-0044 andCONTEXT.mdare unchanged.Upstream trace
Factual reproduction of the precision-39 defect on PR #436's head and the complete invariant: tiberius-rs/tiberius#436 (comment). Upstream merge or release is not a condition; the ADR names the exit.
Fork verification before adoption
Feature set
tds73,rustls,chrono(Data Spark's), SQL Server 2022 CU26 container, tokio and async-std runtimes, run in arust:1-bookwormcontainer because the fork's v0.12.3 dev-dependencies needlibssl-dev:bulkDECIMAL(38,38)and bucket-edge bulk round trips)querySELECT @P1scale-38 and bucket-edge round trips withCONVERT(VARCHAR)text checks)deadlocks/login_errorscustom-certUnsupportedCertVersionon the unpatched base as well — they need upstream's custom-certificate container imagerust_decimal,bigdecimalClippy adds no warning inside the patched line ranges (the remaining warnings are pre-existing legacy-constant and
thread_locallints on untouched lines).Local checks
cargo fmt --check,cargo clippy --locked --all-targets -- -D warnings,cargo test --locked,cargo build --release --locked --bin data-spark, andcargo audit(unchanged four accepted advisories) — see the results comment below.After merge
Move #134 from
blockedtoready-for-agent(AC7); it already carries the production-seamDecimal128(38,38)scaled-1regression criterion.🤖 Generated with Claude Code