diff --git a/java/core/src/java/org/apache/orc/impl/InStream.java b/java/core/src/java/org/apache/orc/impl/InStream.java index bf23a95087..9ea85b7f57 100644 --- a/java/core/src/java/org/apache/orc/impl/InStream.java +++ b/java/core/src/java/org/apache/orc/impl/InStream.java @@ -233,9 +233,13 @@ public void seek(long desired) throws IOException { } else { for (DiskRangeList curRange = bytes; curRange != null; curRange = curRange.next) { + // Accept this stream's logical end when later ranges belong to other streams. + boolean isLogicalEnd = + desired == length && positionFile == curRange.getEnd(); if (curRange.getOffset() <= positionFile && - (curRange.next == null ? positionFile <= curRange.getEnd() : - positionFile < curRange.getEnd())) { + (isLogicalEnd || + (curRange.next == null ? positionFile <= curRange.getEnd() : + positionFile < curRange.getEnd()))) { position = desired; setCurrent(curRange, true); return; diff --git a/java/core/src/test/org/apache/orc/impl/TestInStream.java b/java/core/src/test/org/apache/orc/impl/TestInStream.java index 596afcf304..ad483c7ec8 100644 --- a/java/core/src/test/org/apache/orc/impl/TestInStream.java +++ b/java/core/src/test/org/apache/orc/impl/TestInStream.java @@ -790,6 +790,19 @@ public long getNext() { } } + @Test + public void testSeekToLogicalEndWithLaterDiskRange() throws IOException { + BufferChunk streamRange = new BufferChunk(ByteBuffer.allocate(10), 100); + streamRange.insertAfter(new BufferChunk(ByteBuffer.allocate(10), 120)); + try (InStream.UncompressedStream stream = + new InStream.UncompressedStream("test", streamRange, 100, 10)) { + stream.seek(10); + assertSame(streamRange, stream.currentRange); + assertEquals(0, stream.available()); + assertEquals(-1, stream.read()); + } + } + private static byte[] input(int... data) { byte[] result = new byte[data.length]; for(int i = 0; i < data.length; ++i) {