Skip to content

Fix residual NotNaN for null partition values - #3689

Merged
kevinjqliu merged 2 commits into
apache:mainfrom
BharatDeva:fix/residual-not-nan-null-3498
Aug 21, 2026
Merged

Fix residual NotNaN for null partition values#3689
kevinjqliu merged 2 commits into
apache:mainfrom
BharatDeva:fix/residual-not-nan-null-3498

Conversation

@BharatDeva

Copy link
Copy Markdown
Contributor

Rationale for this change

ResidualVisitor.visit_not_nan currently treats a partition value of None as AlwaysFalse(). That is inconsistent with the normal evaluator behavior and with Iceberg Java semantics: None is not NaN, so NotNaN(None) should evaluate to true.

This PR addresses only that residual-evaluator edge case from #3498. The stricter metrics-evaluator items discussed in the issue are already covered by other active work.

Are these changes tested?

Yes. I updated the existing residual evaluator expectations for both double and float identity partitions and ran the targeted test file in a WSL-native checkout:

pytest tests/expressions/test_residual_evaluator.py -q

Result:

11 passed in 0.05s

Additional checks:

ruff check pyiceberg/expressions/visitors.py tests/expressions/test_residual_evaluator.py
git diff --check

Both passed.

Are there any user-facing changes?

Yes. Residual evaluation for NotNaN now treats null partition values as not-NaN instead of false. Please add the changelog label if this behavior change should appear in release notes.

@github-actions

Copy link
Copy Markdown

This pull request has been marked as stale due to 30 days of inactivity. It will be closed in 1 week if no further activity occurs. If you think that's incorrect or this pull request requires a review, please simply write any comment. If closed, you can revive the PR at any time and @mention a reviewer or discuss it on the dev@iceberg.apache.org list. Thank you for your contributions.

@github-actions github-actions Bot added the stale label Aug 21, 2026

@kevinjqliu kevinjqliu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM!

Comment on lines +1855 to +1858
if isinstance(val, SupportsFloat) and math.isnan(val):
return self.visit_false()
else:
return self.visit_true()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

previously for None, isinstance(None, SupportsFloat) is false, so it returned AlwaysFalse().

Comment on lines 213 to +216
residual = res_eval.residual_for(Record(None))
assert residual == AlwaysTrue()

residual = res_eval.residual_for(Record(float("nan")))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

None is now true.
NaN is now false.

@kevinjqliu
kevinjqliu requested a balanced review from Copilot August 21, 2026 17:18
@kevinjqliu
kevinjqliu force-pushed the fix/residual-not-nan-null-3498 branch from 8086dd8 to bbeaee9 Compare August 21, 2026 17:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Fixes residual evaluation so NotNaN correctly treats null identity-partition values as not-NaN.

Changes:

  • Returns AlwaysFalse only for actual NaN values.
  • Adds float and double regression coverage for null partitions.

Reviewed changes

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

File Description
pyiceberg/expressions/visitors.py Corrects NotNaN residual semantics.
tests/expressions/test_residual_evaluator.py Tests null values for float and double partitions.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@kevinjqliu
kevinjqliu merged commit df0e73e into apache:main Aug 21, 2026
18 checks passed
@kevinjqliu

Copy link
Copy Markdown
Contributor

thanks for the PR @BharatDeva

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants