Skip to content

feat: expose info for new ORC reader (FB-2919) - #41

Merged
lorenzhs merged 2 commits into
release-24.0.0from
lorenz/orc
Aug 11, 2026
Merged

feat: expose info for new ORC reader (FB-2919)#41
lorenzhs merged 2 commits into
release-24.0.0from
lorenz/orc

Conversation

@lorenzhs

Copy link
Copy Markdown
Collaborator

Our new ORC reader needs access to some currently not exposed information. Expose it.

  • stripe footer range
  • stripe stream & footer ranges

We also need to override CordedRandomAccessFile::ReadAt for ORC, which was so far declared final and always returned NotImplemented.

Lastly, stop seeking to the stripe start in ORCFileReader::Impl::NextStripeReader for 0-row-seeks: this allows us to not fetch e.g. Bloom filter streams if we don't want them.

… start

A caller that owns its own I/O needs to know which bytes a stripe read will
touch before liborc asks for them, so it can fetch them up front and serve the
reads from memory. Add ORCFileReader::GetStripeStreamRanges, which reports the
data streams of every column liborc selects for a set of include_indices.

The selected set is taken from RowReader::getSelectedColumns rather than
recomputed, because selection expands beyond the requested indices to their
descendants and all of their ancestors -- an ancestor's PRESENT stream carries
the nullability of the struct holding a requested leaf -- and a second
implementation of that rule could only drift from the one the row reader uses.
Building the row reader costs no stripe I/O: it selects off the file footer.

Index streams are excluded. They are only needed to seek inside a stripe or to
evaluate a search argument, and NextStripeReader was requesting them even when
it had neither reason to: it seeks unconditionally, and seekToRow loads the
stripe index even for a zero-row seek, which drags in the bloom filters
alongside the row indexes. The bloom filters can be an order of magnitude larger
than the indexes and nothing reads them without a search argument. Skip the seek
when already positioned at the stripe's first row; the row reader starts there
regardless, and previousRow_ is only observable through getRowNumber(), which
next() recomputes.

Also relax CordedRandomAccessFile::ReadAt(position, nbytes, void*) from final to
override. The ORC adapter reaches a file through liborc's InputStream::read,
which copies into a caller-owned buffer and so can never take the corded path;
leaving it final forces such a file to be a separate class. The Buffer-returning
overload stays final.
GetStripeStreamRanges cannot answer until the stripe footer is readable, since
the footer is what names the streams. A caller doing its own I/O therefore needs
the footer's extent before it has the footer -- and StripeInformation, which it
already has, does not carry it.

Report it from the file footer, where the offset and the index, data and footer
lengths all sit and are already parsed. This reads nothing, so it composes with
GetStripeStreamRanges: ask for the range, make it available, then ask what the
streams are.
@lorenzhs
lorenzhs requested a review from a team August 11, 2026 13:30
@lorenzhs
lorenzhs merged commit 57f2937 into release-24.0.0 Aug 11, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants