Skip to content

Scalar NaN and signed-zero sort keys split WindowGroupLimit rank peers #5468

Description

@sunchao

Describe the bug

Native WindowGroupLimitExec can drop rows that Spark retains when a scalar FLOAT or DOUBLE ordering key contains different NaN representations or both zero signs. This is a follow-up to #4870.

Spark considers all NaNs equal and greater than non-NaN values, and treats -0.0 and +0.0 as equal. Arrow row encoding compares their raw total-order representations instead. Consequently, native RANK / DENSE_RANK cutoffs can split one Spark peer group. Native sorting also needs to agree: with a secondary ordering key, sorting by raw NaN payload or zero sign can make equal peers noncontiguous.

Steps to reproduce

On Spark 3.5 or later, enable native execution and spark.comet.exec.localTableScan.enabled=true, keeping spark.comet.exec.strictFloatingPoint=false.

Build a local table with runtime NaNs, for example java.lang.Double.longBitsToDouble(0x7ff8000000000001L) and java.lang.Double.longBitsToDouble(0xfff8000000000002L), plus finite values and a partition containing both zero signs. Avoid a Parquet round trip that can canonicalize NaN payloads. Filter a query of this shape to its top rank:

SELECT * FROM (
  SELECT *, RANK() OVER (PARTITION BY p ORDER BY v DESC NULLS LAST) AS rnk
  FROM floating_window_peers
) WHERE rnk <= 1

A regression fixture retaining eight rows in Spark returns only four in unpatched Comet. This reproduces for both FLOAT and DOUBLE with native Sort, Window, and WindowGroupLimit operators. Adding a secondary ordering key also exposes the sorting inconsistency.

Expected behavior

Scalar floating-point sort keys, window peer comparisons, and native range-partition keys/boundaries should use consistent Spark-compatible normalization. Only comparison keys should change; returned values must preserve their original NaN payloads and zero signs.

Additional context

The existing strict-floating-point fallback remains an opt-out. Floating-point values nested in arrays or structs are a separate compatibility limitation.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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