Skip to content

Bare -0.0 literals in SQL file tests are coerced through decimal, so signed-zero coverage is vacuous #5271

Description

@andygrove

Describe the bug

A bare -0.0 literal in a Comet SQL file test does not produce a negative zero. Spark parses -0.0 as decimal(1,1), decimal has no signed zero, and the coercion to double or float yields +0.0. CAST(-0.0 AS DOUBLE) has the same problem, because the cast source is still the decimal literal.

The result is that a number of our SQL fixtures read as signed-zero coverage while testing nothing. To get an actual negative zero you have to go through the string form, double('-0.0') or float('-0.0').

How this was found

While reviewing #5235 I wrote a nested-array fixture using bare -0.0 and it passed against the unpatched merge-base, which it should not have. Switching the literals to double('-0.0') made it fail as expected:

!== Spark Answer ==                                 == Comet Answer (unpatched) ==
![List(List(-0.0)),List(List(0.0)),true]            [List(List(-0.0)),List(List(0.0)),false]
![List(List(0.0)),List(List(-0.0)),true]            [List(List(0.0)),List(List(-0.0)),false]
![List(List(1.0, -0.0)),List(List(1.0, 0.0)),true]  [List(List(1.0, -0.0)),List(List(1.0, 0.0)),false]

Known instance

spark/src/test/resources/sql-tests/expressions/array/arrays_overlap.sql:120

INSERT INTO test_overlap_dbl VALUES ..., (array(0.0), array(-0.0)), ...

Both sides store [0.0], so the row is not exercising signed zero at all.

What needs doing

Audit spark/src/test/resources/sql-tests/ for the pattern and convert the affected literals. About 35 files mention -0.0, in three shapes, and the first two are the broken ones:

  • bare -0.0 in a VALUES row for a double/float column
  • CAST(-0.0 AS DOUBLE) / CAST(-0.0 AS FLOAT)
  • double('-0.0') / float('-0.0'), which is correct

Files worth checking first, since they are specifically about float edge cases: arrays_overlap.sql, array_union.sql, array_except.sql, array_intersect.sql, array_distinct.sql, array_min.sql, array_insert.sql, array_compact.sql, array_repeat.sql, sort_array_strict_fp.sql, shuffle.sql, shuffle_with_seed.sql.

Each conversion should be checked to confirm the query still passes. Some of them may start failing, which would surface real signed-zero divergences that the vacuous form has been hiding.

Worth a note in the SQL file test docs as well, so the next person writing float edge-case fixtures does not hit this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpriority:mediumFunctional bugs, performance regressions, broken featuresrequires-triagetestTesting related

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions