fix: support all packed value lengths in NumericFieldStats.decodeLong#15817
Merged
romseygeek merged 3 commits intoapache:mainfrom Mar 13, 2026
Merged
Conversation
The previous implementation only handled Integer.BYTES (4) and Long.BYTES (8), throwing IllegalArgumentException for other lengths. This broke fields using 2-byte point values such as HalfFloatPoint. Replace the switch with a generic big-endian decoder that handles any length from 1 to 8 bytes. For point fields wider than Long.BYTES (e.g. InetAddressPoint), getStatsFromPoints returns null to fall through to the DocValuesSkipper path.
NumericFieldStats.decodeLong
romseygeek
approved these changes
Mar 13, 2026
Contributor
romseygeek
left a comment
There was a problem hiding this comment.
LGTM, thanks for updating @salvatore-campagna
romseygeek
pushed a commit
that referenced
this pull request
Mar 13, 2026
) The previous implementation only handled Integer.BYTES (4) and Long.BYTES (8), throwing IllegalArgumentException for other lengths. This broke fields using 2-byte point values such as HalfFloatPoint. Replaces the switch with a generic big-endian decoder that handles any length from 1 to 8 bytes. For point fields wider than Long.BYTES (e.g. InetAddressPoint), getStatsFromPoints returns null to fall through to the DocValuesSkipper path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
NumericFieldStats.decodeLong(introduced in #15760) only handled 4-byte (IntField) and 8-byte (LongField) packed point values via a switch onpacked.length. Any other width caused anIllegalArgumentException, crashing the query for queries using byte lengths other than 4 or 8.HalfFloatPointproduces 2-byte packed values. A range query on such a field triggered the exception. The original PR only testedIntField(4 bytes) andLongField(8 bytes), so CI did not catch the bug:Solution
Replace the switch-based decoder with a generic loop that handles any packed value length from 1 to 8 bytes. All Lucene point types use the same encoding: big-endian byte order with the sign bit flipped. The loop reads the bytes sequentially, re-flips the sign bit on the first byte, and sign-extends the result into a
long. This is allocation-free, unlikeNumericUtils.sortableBytesToBigInt, which copies the array and creates aBigInteger.For point fields wider than 8 bytes (e.g.
InetAddressPointat 16 bytes,BigIntegerPointat 16 bytes),getStatsFromPointsnow returnsnullinstead of throwing, allowinggetStatsto fall through to theDocValuesSkipperpath. These wider point types are never used withSortedNumericDocValuesRangeQueryin practice, but the graceful fallback avoids unexpected failures.Tests
TestNumericFieldStats.testGetStatsWithAllByteWidths: exercisesdecodeLongwith min, zero, and max values at every byte width from 1 to 8TestNumericFieldStats.testGetStatsReturnsNullForWidePointValues: verifies gracefulnullreturn forInetAddressPoint(16 bytes)TestHalfFloatPoint.testNumericFieldStats: integration test with realHalfFloatPoint(2 bytes)Follows up on #15760.