fix(column): return error instead of panic on Decimal/BigInt overflow#1857
fix(column): return error instead of panic on Decimal/BigInt overflow#1857wucm667 wants to merge 7 commits into
Conversation
When inserting values that exceed the range of Decimal128/256 or Int128/UInt128/Int256/UInt256 columns, the driver previously panicked with 'math/big: buffer too small' in bigIntToRaw(), killing the caller goroutine with no way to recover. Changes: - bigIntToRaw now uses deferred recover to catch FillBytes panics and returns a proper error instead - Added explicit signed range check: positive values exceeding 2^(n*8-1)-1 are caught before FillBytes (which treats values as unsigned and won't panic for these) - Decimal32/64 now check for overflow before silent IntPart() truncation - append() in both BigInt and Decimal now propagate errors through Append() and AppendRow() - Added unit tests for all four Decimal sizes and BigInt overflow/valid boundary cases Fixes ClickHouse#1849 Signed-off-by: wucm667 <stevenwucongmin@gmail.com>
SummaryThe PR replaces a Must fix
Should fix
Nits
Verdict
|
- Add negative signed overflow check in bigIntToRaw: values in (-2^n, -2^(n-1)-1] no longer silently encode incorrectly - Remove defer/recover since explicit BitLen guards now catch all overflow cases - Remove unnecessary new(big.Int).Set(v) defensive copy - Fix error message style: lowercase, no colon, consistent with project conventions - Use NewFromString instead of NewFromFloat for exact boundary test values - Add TestBigIntNegativeOverflowReturnsError - Add regression test tests/issues/issue_1849_test.go Signed-off-by: wucm667 <stevenwucongmin@gmail.com>
The regression test called batch.AppendRow which does not exist on the Batch interface (it belongs to BatchColumn), causing a build failure across all CI matrix jobs. Rewrite the test to: - Use batch.Append (the correct Batch method) - Cover both native TCP and HTTP protocols - Cover the database/sql surface via Begin/Prepare/Exec - Test positive and negative overflow for both Decimal128 and Int128
SummaryReplaces a panic ( Should fix
Nits
VerdictRequest changes — small set of fixes (out-of-sync PR description, inconsistent error wrapping across |
| // overflow1849Cases captures the four overflow scenarios that previously | ||
| // either panicked (BigInt) or silently truncated (Decimal). For each case the | ||
| // driver must now return an error containing "overflow". | ||
| func overflow1849Cases(t *testing.T) []struct { |
There was a problem hiding this comment.
I understand you are trying to reuse the cases here.
But it's more readable and maintainable if we split it to each test cases. Also we can fix names (e.g: big2_127, min128, belowMin128 are confusing) and even shorter name with each test case context makes more sense.
Also I think it would more sense if we splitting test cases completely one for Decimal and one for BigInt instead of having two columns in same table
My expecations are something like
TestDecimalOverflowTestDecimalSilentDataCorruptionTestBigIntOverflow
And have test cases inside the tests itself with single table and single column. Also we can avoid any type values in that case.
What do you think?
…nctions Split the single TestIssue1849 into three independent test functions addressing reviewer feedback from kavirajk: - TestDecimalOverflow: Decimal(38,0) precision overflow, uses decimal.Decimal directly (no any type), named table with single column - TestDecimalSilentDataCorruption: Decimal32/64 IntPart() silent truncation regression, separate sub-tests for each size - TestBigIntOverflow: Int128/UInt128 range overflow and unsigned negative rejection, uses *big.Int directly (no any type) Each test covers all 4 surface combinations (Native TCP, Native HTTP, Std TCP, Std HTTP) with explicit typed table-driven test cases. Variable names use descriptive identifiers (justAboveMaxInt128, justBelowMinInt128) instead of cryptic shorthand. Shared helpers (runDecimalOverflowTest, runBigIntOverflowTest) avoid boilerplate duplication while keeping test cases inline and readable. Signed-off-by: wucm667 <stevenwucongmin@gmail.com>
fix(column): return error instead of panic on Decimal/BigInt overflow
When inserting values that exceed the range of
Decimal128/256orInt128/UInt128/Int256/UInt256columns, the driver previously panicked withmath/big: buffer too smallinbigIntToRaw(), killing the caller goroutine with no way to recover.Decimal32/64had a similar issue where overflow was silently truncated viaIntPart()casts.Changes
bigIntToRawnow uses deferredrecoverto catchFillBytespanics and returns a proper error2^(n*8-1)-1are caught beforeFillBytes(which treats values as unsigned and won't panic for these)Decimal32/64now check for overflow before silentIntPart()truncationappend()in bothBigIntandDecimalnow propagate errors throughAppend()andAppendRow()Before
After
Fixes #1849