jeanlyn opened a new pull request, #2722:
URL: https://github.com/apache/orc/pull/2722

   ### What changes were proposed in this pull request?
   
   Allow `InStream.UncompressedStream.seek(long)` and 
`InStream.CompressedStream.seek(long)` to seek to the end of the stream 
(`desired == length`) by parking the stream at EOF, instead of throwing 
`IllegalArgumentException` / `IOException`.
   
   ### Why are the changes needed?
   
   The row group index of an **all-null trailing row group** legitimately 
points at the end of the stream (both the Java and C++ writers record such 
positions). When predicate pushdown (SARG) selects *only* that row group, 
`StripePlanner.processStream` computes a zero-byte read range for the stream 
(`start == end`), so the stream is created with `bytes == null`. 
`UncompressedStream.seek()` then only special-cases `desired == 0 && bytes == 
null`, and a seek to `desired == length` falls through the range loop and 
throws:
   
   ```
   Caused by: java.lang.IllegalArgumentException: Seek in column 2 kind DATA to 
8192 is outside of the data
       at 
org.apache.orc.impl.InStream$UncompressedStream.seek(InStream.java:...)
   ```
   
   A full scan (no SARG) reads the same file fine, as does the C++ reader. See 
[ORC-2226](https://issues.apache.org/jira/browse/ORC-2226) for a minimal 
reproduction (also reproduced on 2.1.2 and 2.3.1).
   
   ### How was this patch tested?
   
   New unit tests:
   
   - `TestInStream#testUncompressedSeekToEndOfStream` — seeking an 
`UncompressedStream` with no backing bytes to `length` is accepted, `read()` 
then returns `-1`, `available()` returns `0`, and seeking *past* the end 
(`length + 1`) still throws.
   - `TestInStream#testCompressedSeekToEndOfStream` — same for 
`CompressedStream`.
   - `TestRecordReaderImpl#testSargOnAllNullTrailingRowGroup` — end-to-end 
regression: writes an uncompressed file whose trailing row group is all-NULL 
for a string column, then reads it with a SARG that selects only that row group 
(fails before the fix, passes after).
   
   ### Notes for reviewers
   
   - The change only *relaxes* an over-strict bounds check. Seeks beyond the 
stream end (`desired > length`), and non-zero seeks on streams with no backing 
bytes other than `desired == length`, still throw — genuinely corrupt files are 
not masked.
   - For compressed streams, a stream-end position recorded by the writer 
always has an uncompressed offset of 0, so the `seek(PositionProvider)` 
follow-up never attempts to read a chunk header at EOF.
   - Behavior now matches the C++ reader, which tolerates seek-to-end.
   - Cross-module impact: none; no file-format or API changes. Subclasses 
(`EncryptedStream`, `EncryptedCompressedStream`) inherit the fix.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to