Fix UnsupportedOperationException on nested sort during early termination - #22534
Fix UnsupportedOperationException on nested sort during early termination#22534serhiy-bzhezytskyy wants to merge 3 commits into
Conversation
…tion (opensearch-project#17140, opensearch-project#21537) The nested MultiValueMode.select(...parentDocs, childDocs...) variants returned an AbstractNumericDocValues/AbstractBinaryDocValues/AbstractSortedDocValues that overrode only advanceExact, not advance(int). Since opensearch-project#12089 enabled point-based sort optimization, NumericComparator's competitive iterator calls advance() during early termination (track_total_hits:false), hitting the base UnsupportedOperationException. Implements advance() on all four nested selects that lacked it (long, unsigned-long, binary, sorted/keyword). For the numeric/binary selects advanceExact always returns true (missing-value fallback), so advance(target) positions on target. The sorted select is sparse (no missing-value fallback for ords), so advance() walks the parent bitset to the next parent that has an ord. Adds MultiValueModeTests coverage. Signed-off-by: serhiy-bzhezytskyy <me@serhiy-bzhezytskyy.com>
PR Reviewer Guide 🔍(Review updated until commit d5278db)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to d5278db
Previous suggestionsSuggestions up to commit 0b6e88c
|
|
❌ Gradle check result for 0b6e88c: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
The gradle-check failure is Could someone re-run gradle-check when convenient? Thanks! |
|
Persistent review updated to latest commit d5278db |
|
❌ Gradle check result for d5278db: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
Merged The This PR touches only |
msfroh
left a comment
There was a problem hiding this comment.
This is great! Thank you @serhiy-bzhezytskyy.
Out of curiosity, if we remove the advance() method from AbstractNumericDocValues, do we still compile?
Overall, I think with Lucene's changes to sorting logic, we need advance implementations for any subclass of AbstractNumericDocValues. That means we should probably remove the implementation that throws UnsupportedOperationException. That can be a follow-up PR, though.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #22534 +/- ##
=========================================
Coverage 71.39% 71.40%
+ Complexity 76808 76807 -1
=========================================
Files 6148 6148
Lines 357994 358025 +31
Branches 52179 52187 +8
=========================================
+ Hits 255607 255647 +40
- Misses 82054 82071 +17
+ Partials 20333 20307 -26 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
No — I tried it. Removing it breaks compilation at 12 subclasses:
|
The three existing advance() tests exercise the numeric selects only, so the ordinals and binary paths the fix touches were untested. Both new tests fail without the change. Signed-off-by: serhiy-bzhezytskyy <me@serhiy-bzhezytskyy.com>
|
@msfroh fyi pushed two tests covering the ords and binary selects — the paths codecov flagged. |
Description
The nested
MultiValueMode.select(...parentDocs, childDocs...)variants returned a doc-values instance that overrode onlyadvanceExact, notadvance(int). Since #12089 enabled the point-based sort optimization,NumericComparator's competitive iterator callsadvance()during early termination (i.e.track_total_hits: false), which hit the baseAbstractNumericDocValues.advance()and threwUnsupportedOperationException. Withtrack_total_hits: truethere's no early termination, soadvance()isn't called — which is why the failure only appeared without it.This implements
advance()on the nested selects:advanceExactalways returnstrue(a missing value is emitted when no children match), so every parent doc has a value andadvance(target)positions directly ontarget.advanceExactcan returnfalse(no missing-value fallback for ords), so values are sparse;advance()walks the parent bitset to the next parent that has an ord.advance(), but asvalues.advance(target)(advancing the child values iterator). Aligned it to the same parent-positioning semantics as the others, per the discussion on [Bug]: Intermittent UnsupportedOperationException errors with nested queries #17140.Tests added to
MultiValueModeTestscovering the numeric, unsigned-long, and double nested selects. FullMultiValueModeTestsand the sort / comparator-source suites pass locally.Related Issues
Resolves #17140
Resolves #21537
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.