[BUG] Fix null handling in mixed semi joins - #23861
Conversation
Signed-off-by: Allen Xu <allxu@nvidia.com>
Signed-off-by: Allen Xu <allxu@nvidia.com>
|
/ok to test 2527072 |
There was a problem hiding this comment.
Pull request overview
Fixes incorrect null handling in mixed left-semi/left-anti joins by ensuring right-side conditional-row comparison uses the null-state of right_conditional (not the equality table), and by making conditional-row deduplication use null-equal semantics so the hash-set comparator remains reflexive and avoids pathological duplicate-null clustering.
Changes:
- Derive the conditional comparator’s null-state from
right_conditionaland forcenull_equality::EQUALfor conditional-row deduplication. - Add regression coverage for nullable conditional columns with non-nullable equality keys across semi/anti joins,
EQUAL/UNEQUALnull-equality, and null-first/null-last ordering.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| cpp/src/join/mixed_join_semi.cu | Fixes conditional comparator null handling and enforces reflexive null-equal semantics for conditional-row deduplication. |
| cpp/tests/join/mixed_join_tests.cu | Adds a targeted regression test matrix covering the reported null-order-dependent mixed semi/anti join failures. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| auto const preprocessed_right_condtional = | ||
| cudf::detail::row::equality::preprocessed_table::create(right_conditional, stream, temp_mr); | ||
| auto const row_comparator_conditional_right = cudf::detail::row::equality::two_table_comparator{ | ||
| preprocessed_right_condtional, preprocessed_right_condtional}; | ||
| auto const right_conditional_nulls = cudf::nullate::DYNAMIC{cudf::has_nulls(right_conditional)}; |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 12 included reviews per hour; 10 remain after this review. 📝 WalkthroughSummary by CodeRabbit
WalkthroughThe mixed join comparator now derives null handling from ChangesMixed join null handling
Estimated code review effort: 3 (Moderate) | ~15–30 minutes Merge Risk: ⚪ Minimal · up to This localized change corrects nullable conditional-value handling and duplicate-null deduplication in mixed semi joins, with broad regression coverage and sanitizer validation reported; no actionable merge-blocking risk remains. Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Linked Issues checkExplanation The changes satisfy issue [
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
/merge |
Description
Closes #23860.
mixed_join_semibuilds separate right-side comparators for the equality and conditional tables. The conditional comparator was using the null-state derived from the equality table, so nullable conditional values could be compared as non-null whenever the equality keys contained no nulls. This made right-side representative selection order-dependent and could produce an incorrect left-semi or left-anti gather map.This change:
right_conditional;compare_nullssetting, so the hash-set comparator remains reflexive and duplicate null rows do not form a long linear-probing cluster;EQUALandUNEQUAL, null-first and null-last row order, and predicates that both reject and require null representatives.The added
has_nullscall is a host-side metadata scan over the conditional columns; it does not add a device pass.Related downstream report: NVIDIA/cudf-spark#14076.
Validation performed locally on an NVIDIA RTX 5880 Ada Generation GPU:
pre-commit run --files cpp/src/join/mixed_join_semi.cu cpp/tests/join/mixed_join_tests.cu: all applicable hooks passedJOIN_TEST: 810 passed, 2 skippedcompute-sanitizer --tool memcheck: 0 errorsEQUAL31-33 ms andUNEQUAL30-31 ms after the fix. Before the follow-up deduplication fix,UNEQUALtook 829-831 ms for the same input.The same 30-row harness was also run on GH200 against the exact cuDF revision from the downstream failing build (
a6bd95e24bebc35c5ea92283410df4f48bf3be89): the original implementation failed all 1,000 null-first iterations, while the patched object failed 0/1,000.Checklist