Skip to content

fix: Preserve integer values in round() for large Int64 and UInt64 inputs#22697

Open
pchintar wants to merge 1 commit into
apache:mainfrom
pchintar:round-large-integer-handling
Open

fix: Preserve integer values in round() for large Int64 and UInt64 inputs#22697
pchintar wants to merge 1 commit into
apache:mainfrom
pchintar:round-large-integer-handling

Conversation

@pchintar
Copy link
Copy Markdown

@pchintar pchintar commented Jun 1, 2026

Which issue does this PR close?

Rationale for this change

round() should not change integer values when the scale is non-negative, since no fractional digits need to be rounded.

Currently, core round() coerces large Int64 values through Float64, causing precision loss:

SELECT round(arrow_cast(9007199254740993, 'Int64'));

Before/Current Buggy Output:

9007199254740992.0

Expected:

9007199254740993

The Spark-compatible round() also fails for UInt64 values above i64::MAX even when the scale is non-negative:

SELECT round(arrow_cast(18446744073709551615, 'UInt64'));

Before/Current Buggy Output:

round: UInt64 value 18446744073709551615 exceeds i64::MAX and cannot be rounded

What changes are included in this PR?

  • Preserved integer inputs in core round() for non-negative scales instead of routing them through Float64.

  • Preserved UInt64 values in Spark-compatible round() when the scale is non-negative, avoiding unnecessary UInt64 -> i64 conversion.

  • Added SQLLogicTest coverage for:

    • Int64 values above 2^53 in core round().
    • UInt64::MAX in Spark-compatible round().
    • Both one-argument and two-argument forms.

Are these changes tested?

Yes.

cargo fmt --all
git diff --check
cargo test -p datafusion-sqllogictest --test sqllogictests -- spark/math/round.slt
cargo test -p datafusion-functions round
cargo test -p datafusion-spark round

I also verified the core regression queries manually:

SELECT arrow_typeof(round(arrow_cast(9007199254740993, 'Int64'))),
       round(arrow_cast(9007199254740993, 'Int64'));

Result:

Int64 9007199254740993
SELECT arrow_typeof(round(arrow_cast(9007199254740993, 'Int64'), 2)),
       round(arrow_cast(9007199254740993, 'Int64'), 2);

Result:

Int64 9007199254740993

Are there any user-facing changes?

No.

@github-actions github-actions Bot added sqllogictest SQL Logic Tests (.slt) functions Changes to functions implementation spark labels Jun 1, 2026
@pchintar pchintar force-pushed the round-large-integer-handling branch from e565975 to 7832c0c Compare June 1, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

functions Changes to functions implementation spark sqllogictest SQL Logic Tests (.slt)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

round() mishandles large Int64 and UInt64 values

1 participant