Skip to content

fix: order -NaN below +NaN in Literal comparison - #861

Open
LuciferYang wants to merge 2 commits into
apache:mainfrom
LuciferYang:fix-nan-sign-ordering
Open

fix: order -NaN below +NaN in Literal comparison#861
LuciferYang wants to merge 2 commits into
apache:mainfrom
LuciferYang:fix-nan-sign-ordering

Conversation

@LuciferYang

Copy link
Copy Markdown
Contributor

What

Literal::operator<=> orders a negative NaN as greater than a positive NaN, the opposite of the total ordering documented and tested in this file. CompareFloat returns lhs_is_negative <=> rhs_is_negative for the both-NaN case, so -NaN <=> +NaN is true <=> false = greater. The adjacent comment says "-NAN < NAN", and FloatSpecialValuesComparison / DoubleSpecialValuesComparison assert -NaN < -Infinity < ... < +Infinity < +NaN, both of which this branch contradicts.

Fixes #860.

How

Swap the operands so a negative sign bit sorts below a positive one:

return rhs_is_negative <=> lhs_is_negative;

Testing

The existing FloatNaNComparison / DoubleNaNComparison tests only cover same-sign NaN pairs (qNaN vs sNaN, which are equivalent), so the mixed-sign case was unexercised. Added FloatSignedNaNComparison and DoubleSignedNaNComparison asserting -NaN < +NaN and the reverse. Verified fail-without (the new tests report greater/less swapped) / pass-with. Full expression_test passes (495 tests).

CompareFloat returned lhs_is_negative <=> rhs_is_negative for the
both-NaN case, so -NaN compared as greater than +NaN. That contradicts
the adjacent "-NAN < NAN" comment and the FloatSpecialValuesComparison /
DoubleSpecialValuesComparison tests, which assert the total ordering
-NaN < -Infinity < ... < +Infinity < +NaN.

Swap the operands so a negative sign bit sorts below a positive one. The
existing NaN tests only covered same-sign pairs (qNaN vs sNaN), so the
mixed-sign case was unexercised; add FloatSignedNaNComparison and
DoubleSignedNaNComparison to cover it.
Copilot AI review requested due to automatic review settings July 29, 2026 12:56
@LuciferYang
LuciferYang marked this pull request as draft July 29, 2026 12:57
@LuciferYang
LuciferYang marked this pull request as ready for review July 29, 2026 13:05
@LuciferYang

Copy link
Copy Markdown
Contributor Author

cc @wgtmac FYI

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes NaN total-ordering behavior in Literal::operator<=> so that -NaN sorts below +NaN, aligning implementation with the documented and tested ordering and adding missing mixed-sign NaN coverage (Fixes #860).

Changes:

  • Corrected NaN sign-bit comparison in CompareFloat to order -NaN < +NaN.
  • Added new float/double tests covering mixed-sign NaN comparisons.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/iceberg/test/literal_test.cc Adds regression tests for signed NaN ordering for float and double.
src/iceberg/expression/literal.cc Fixes NaN ordering logic to sort negative-sign NaNs below positive-sign NaNs.

Comment thread src/iceberg/test/literal_test.cc Outdated
Comment on lines +220 to +221
auto neg_nan = Literal::Float(-std::numeric_limits<float>::quiet_NaN());
auto pos_nan = Literal::Float(std::numeric_limits<float>::quiet_NaN());
Comment on lines +447 to +449
// A negative sign bit sorts below a positive one (-NaN < +NaN), so a
// negative operand must compare as less.
return rhs_is_negative <=> lhs_is_negative;
std::numeric_limits<T>::quiet_NaN() does not guarantee a sign bit, so
build the mixed-sign NaN operands with std::copysign to keep the test
deterministic across platforms.
Copilot AI review requested due to automatic review settings July 29, 2026 16:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

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.

bug: Literal comparison orders -NaN as greater than +NaN, contradicting the documented total ordering

2 participants