Skip to content

Flaky test: client-v2 testDynamicWithPrimitives intermittently fails with ArithmeticException: Rounding necessary #2964

Description

@polyglotAI-bot

Describe the bug

DataTypeTests.testDynamicWithPrimitives (module client-v2, group integration) is flaky: it intermittently fails with

java.lang.ArithmeticException: Rounding necessary
	at java.base/java.math.BigDecimal.divideAndRound(...)
	at ...DataTypeTests.testDynamicWithPrimitives(DataTypeTests.java)

Observed in CI on the client-v2 + ClickHouse 25.8 matrix job (roughly ~1% of runs); passes on most runs and most server versions.

Root cause

The shared test fixture DataTypesTestingPOJO assigns its four Decimal fields from an unseeded Random:

decimal32  = BigDecimal.valueOf(random.nextDouble());
decimal64  = BigDecimal.valueOf(random.nextDouble());
decimal128 = BigDecimal.valueOf(random.nextDouble());
decimal256 = BigDecimal.valueOf(random.nextDouble());

testDynamicWithPrimitives inserts each value into a Dynamic column and, for the Decimal* cases, verifies the round-trip with

BigDecimal tmpDec = row.getBigDecimal("field").stripTrailingZeros();
if (tmpDec.divide((BigDecimal) value, RoundingMode.UNNECESSARY).equals(BigDecimal.ONE)) { continue; }

When a BigDecimal is written into a Dynamic column, the type is inferred from the value's precision() (SerializerUtils.valueToColumnForDynamicType): the width is chosen by precision, but the scale is forced to that width's maximum (Decimal32→9, Decimal64→18, Decimal128→38, Decimal256→76). A small-magnitude random.nextDouble() can produce a value whose scale() exceeds that fixed scale (e.g. 0.0123456789 → precision 9 → Decimal32(9), but scale 10 > 9). The value is then rounded on write, the read-back value no longer equals the original, and divide(value, RoundingMode.UNNECESSARY) throws Rounding necessary. Because the input is random, the failure is non-deterministic.

Expected behaviour

The test should be deterministic. Making the Decimal samples fixed values whose scale is within each inferred width's capacity keeps the round-trip exact and preserves the assertion's intent, while also letting the four samples genuinely exercise Decimal32/64/128/256 (the random doubles almost always landed in Decimal64).

Environment

  • clickhouse-java: main (client-v2)
  • ClickHouse server: reproduced deterministically with a crafted small-scale value on current main; originally observed on CI with server 25.8

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions