Skip to content

round on LongType with scale <= -19 returns 0 instead of overflowing #5070

Description

@andygrove

Describe the bug

round on a LongType column with scale <= -19 returns 0 for every row, in both ANSI and legacy mode.

Comet's CometRound serde correctly serializes ansiEnabled (spark/src/main/scala/org/apache/comet/serde/arithmetic.scala:415-423) and the native kernel honors it for the normal path (integer_round! uses checked vs wrapping arithmetic). But when 10^(-scale) overflows the native integer type, native/spark-expr/src/math_funcs/round.rs:66-72 and :79-96 return Ok(0) for the whole batch, ignoring fail_on_error.

For Int64 with scale <= -19, 10^19 > i64::MAX, so this path is reachable. Spark computes BigDecimal(x).setScale(-19, HALF_UP) and then toLongExact: for |x| >= 5e18 the rounded value is 1e19, which does not fit a long, so ANSI throws ARITHMETIC_OVERFLOW and legacy mode wraps. Comet silently returns 0 in both modes.

Int8/Int16/Int32 are unaffected: their maximum values always round to 0 at the overflowing scale.

Steps to reproduce

SET spark.sql.ansi.enabled=true;
SELECT round(CAST(5000000000000000000 AS LONG), -19);

Spark: throws ARITHMETIC_OVERFLOW (legacy mode: wrapped value).
Comet: returns 0.

Expected behavior

The overflow-of-10^(-scale) path should replicate Spark: throw under ANSI, wrap under legacy, instead of returning 0.

Additional context

Found by an ANSI-mode audit of all native expressions against Spark 4.1.1. There is no ANSI SQL file test for round (spark/src/test/resources/sql-tests/expressions/math/round.sql has no ANSI or negative-scale overflow case).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions