[
https://issues.apache.org/jira/browse/PHOENIX-8045?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Andrew Kyle Purtell updated PHOENIX-8045:
-----------------------------------------
Description:
During server-side scan execution Phoenix builds result rows for aggregation
and state tracking using {{{}ByteUtil.getLargestPossibleRowKeyInRange(){}}}.
This utility should construct a synthetic key that falls within the active
scan's boundaries so that downstream client verification logic accepts the
payload. In the table's end region, the upper limit is an empty byte array
({{{}HConstants.EMPTY_END_ROW{}}}), conceptually representing positive infinity
rather than a literal byte sequence.
Because lexicographical comparison places any non-empty byte array after an
empty array, the check misinterprets the empty bound as a zero-length floor
rather than an unbounded ceiling. Consequently, the assertion fails, logs an
unexpected range error, and returns null. Callers then fall back to degenerate
keys, such as the start key, stop row, or an empty key, which fail subsequent
client side range checks and causes valid results to be discarded during
background workloads like index builds.
The fix makes {{ByteUtil}} consistent with the client side region boundary
contract defined in {{{}ScanUtil.verifyKeyInScanRange(){}}}. An empty end key
is treated as an unbounded range, skipping the upper limit comparison entirely.
was:
During server-side scan execution Phoenix builds result rows for aggregation
and state tracking using {{{}ByteUtil.getLargestPossibleRowKeyInRange(){}}}.
This utility must construct a deterministic synthetic key that falls within the
active scan's boundaries so that downstream client verification logic accepts
the payload. In the table's end region, the upper limit is an empty byte array
({{{}HConstants.EMPTY_END_ROW{}}}), conceptually representing positive infinity
rather than a literal byte sequence.
Because lexicographical comparison places any non-empty byte array after an
empty array, the check misinterprets the empty bound as a zero-length floor
rather than an unbounded ceiling. Consequently, the assertion fails, logs an
unexpected range error, and returns null. Callers then fall back to degenerate
keys, such as the start key, stop row, or an empty key, which fail subsequent
client side range checks and causes valid results to be discarded during
background workloads like index builds.
The fix makes {{ByteUtil}} consistent with the client side region boundary
contract defined in {{{}ScanUtil.verifyKeyInScanRange(){}}}. An empty end key
is treated as an unbounded range, skipping the upper limit comparison entirely.
> Treat an empty end key as no upper bound in getLargestPossibleRowKeyInRange
> ---------------------------------------------------------------------------
>
> Key: PHOENIX-8045
> URL: https://issues.apache.org/jira/browse/PHOENIX-8045
> Project: Phoenix
> Issue Type: Bug
> Components: core
> Affects Versions: 5.3.2
> Reporter: Andrew Kyle Purtell
> Assignee: Andrew Kyle Purtell
> Priority: Major
> Fix For: 5.4.0, 5.3.3
>
>
> During server-side scan execution Phoenix builds result rows for aggregation
> and state tracking using {{{}ByteUtil.getLargestPossibleRowKeyInRange(){}}}.
> This utility should construct a synthetic key that falls within the active
> scan's boundaries so that downstream client verification logic accepts the
> payload. In the table's end region, the upper limit is an empty byte array
> ({{{}HConstants.EMPTY_END_ROW{}}}), conceptually representing positive
> infinity rather than a literal byte sequence.
> Because lexicographical comparison places any non-empty byte array after an
> empty array, the check misinterprets the empty bound as a zero-length floor
> rather than an unbounded ceiling. Consequently, the assertion fails, logs an
> unexpected range error, and returns null. Callers then fall back to
> degenerate keys, such as the start key, stop row, or an empty key, which fail
> subsequent client side range checks and causes valid results to be discarded
> during background workloads like index builds.
> The fix makes {{ByteUtil}} consistent with the client side region boundary
> contract defined in {{{}ScanUtil.verifyKeyInScanRange(){}}}. An empty end key
> is treated as an unbounded range, skipping the upper limit comparison
> entirely.
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)