Skip to content

[SPARK-57103][SQL] Add Comparable to TimestampNanosVal#56187

Closed
stevomitric wants to merge 2 commits into
apache:masterfrom
stevomitric:stevomitric/SPARK-57103-compare
Closed

[SPARK-57103][SQL] Add Comparable to TimestampNanosVal#56187
stevomitric wants to merge 2 commits into
apache:masterfrom
stevomitric:stevomitric/SPARK-57103-compare

Conversation

@stevomitric
Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Make TimestampNanosVal implement Comparable<TimestampNanosVal>, ordered lexicographically by epochMicros then nanosWithinMicro.

This is the first of SPARK-57103 (ordering + compare + hash for nanosecond timestamp types). Follow-ups will

  • wire PhysicalDataType.ordering for the two nanos physical types
  • extend the hash expressions (hash, xxhash64, murmur3).

Why are the changes needed?

TimestampNanosVal (added in SPARK-56981) is the physical value class for TimestampNTZNanosType(p) / TimestampLTZNanosType(p). Without a compareTo, Catalyst cannot give it an Ordering, which blocks ORDER BY, sort-merge join, sort-based GROUP BY, DISTINCT, and any other operator that needs total order on the type.

Does this PR introduce any user-facing change?

No.

How was this patch tested?

New UT in this PR.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.7)

### What changes were proposed in this pull request?

Make `TimestampNanosVal` implement `Comparable<TimestampNanosVal>`,
ordered lexicographically by `epochMicros` then `nanosWithinMicro`.

This is the first of a planned three-PR breakdown of SPARK-57103
(ordering + compare + hash for nanosecond timestamp types). Follow-ups
will (1) wire `PhysicalDataType.ordering` for the two nanos physical
types and (2) extend the hash expressions (`hash`, `xxhash64`, `murmur3`).

### Why are the changes needed?

`TimestampNanosVal` (added in SPARK-56981) is the physical value class
for `TimestampNTZNanosType(p)` / `TimestampLTZNanosType(p)`. Without a
`compareTo`, Catalyst cannot give it an `Ordering`, which blocks
`ORDER BY`, sort-merge join, sort-based `GROUP BY`, `DISTINCT`, and any
other operator that needs total order on the type.

### Does this PR introduce _any_ user-facing change?

No. `TimestampNanosVal` is `@Unstable` and the new nanos types remain
gated by `spark.sql.timestampNanosTypes.enabled`. This PR only adds a
`compareTo` on the value class.

### How was this patch tested?

Six new unit tests in `TimestampNanosSuite` covering:
- primary/secondary ordering on `(epochMicros, nanosWithinMicro)`,
- consistency with `equals` (`a.compareTo(b) == 0` iff `a.equals(b)`),
- `Long.MIN_VALUE` / `Long.MAX_VALUE` boundaries (Long.compare protects
  against the subtraction-overflow pitfall),
- pre-epoch negative values,
- antisymmetry and transitivity,
- `Arrays.sort` integration end-to-end.

`build/mvn -pl common/unsafe -am test -Dtest=TimestampNanosSuite`:
Tests run: 12, Failures: 0, Errors: 0, Skipped: 0.

### Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.7)
@stevomitric stevomitric changed the title [WIP][SPARK-57103][SQL] Add Comparable to TimestampNanosVal [SPARK-57103][SQL] Add Comparable to TimestampNanosVal May 28, 2026
@stevomitric
Copy link
Copy Markdown
Contributor Author

@MaxGekk please take a look.

Copy link
Copy Markdown
Member

@MaxGekk MaxGekk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test for null. According to the doc of Comparable, compareTo shall throw NPE on null, see

Throws:
NullPointerException – if the specified object is null

Address review feedback from @MaxGekk: assert that
TimestampNanosVal.compareTo(null) throws NullPointerException,
matching the Comparable contract.

The behavior was already correct (NPE on `that.epochMicros`
dereference); this change only adds the test.
@stevomitric
Copy link
Copy Markdown
Contributor Author

Could you add a test for null. According to the doc of Comparable, compareTo shall throw NPE on null, see
Throws:
NullPointerException – if the specified object is null

Added. Waiting for CI.

@MaxGekk
Copy link
Copy Markdown
Member

MaxGekk commented May 29, 2026

+1, LGTM. Merging to master/4.x.
Thank you, @stevomitric.

@MaxGekk MaxGekk closed this in 0b0ffb7 May 29, 2026
MaxGekk pushed a commit that referenced this pull request May 29, 2026
### What changes were proposed in this pull request?

Make `TimestampNanosVal` implement `Comparable<TimestampNanosVal>`, ordered lexicographically by `epochMicros` then `nanosWithinMicro`.

This is the first of SPARK-57103 (ordering + compare + hash for nanosecond timestamp types). Follow-ups will
- wire `PhysicalDataType.ordering` for the two nanos physical types
- extend the hash expressions (`hash`, `xxhash64`, `murmur3`).

### Why are the changes needed?

`TimestampNanosVal` (added in SPARK-56981) is the physical value class for `TimestampNTZNanosType(p)` / `TimestampLTZNanosType(p)`. Without a `compareTo`, Catalyst cannot give it an `Ordering`, which blocks `ORDER BY`, sort-merge join, sort-based `GROUP BY`, `DISTINCT`, and any other operator that needs total order on the type.

### Does this PR introduce _any_ user-facing change?

No.

### How was this patch tested?
New UT in this PR.

### Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 4.7)

Closes #56187 from stevomitric/stevomitric/SPARK-57103-compare.

Authored-by: Stevo Mitric <stevomitric2000@gmail.com>
Signed-off-by: Max Gekk <max.gekk@gmail.com>
(cherry picked from commit 0b0ffb7)
Signed-off-by: Max Gekk <max.gekk@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants