Skip to content

[Data] Add support for reading ORC files - #64600

Open
WFY123wfy wants to merge 16 commits into
ray-project:masterfrom
WFY123wfy:feature/data-read-orc
Open

[Data] Add support for reading ORC files#64600
WFY123wfy wants to merge 16 commits into
ray-project:masterfrom
WFY123wfy:feature/data-read-orc

Conversation

@WFY123wfy

Copy link
Copy Markdown
Contributor

Description

Ray Data can read Parquet, CSV, JSON, and Avro, but not Apache ORC — a columnar format widely used in the Hive/Spark ecosystem (supported by both Dask and Spark). This adds ray.data.read_orc(), backed by a new ORCDatasource that reads each
file with pyarrow.orc.read_table. ORC keeps its metadata footer at the end of the file, so the datasource opens files for random access rather than as a sequential stream. Read-only for now, mirroring how Avro shipped; write support can
follow.

Related issues

Closes #37890

Additional information

Mirrors the read_avro / read_parquet API. file_extensions defaults to ["orc"]. No new dependency (pyarrow already ships pyarrow.orc). Adds tests in test_orc.py and docs in loading_data.rst.

import ray
ds = ray.data.read_orc("s3://bucket/path/")

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

Add `ray.data.read_orc()` to read Apache ORC files into a Dataset, backed
by a new `ORCDatasource` that reads each file with `pyarrow.orc.read_table`.
ORC stores its metadata footer at the end of the file, so the datasource
opens files for random access rather than as a sequential stream.

Closes ray-project#37890

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy
WFY123wfy force-pushed the feature/data-read-orc branch from 8e92ffb to bacf7df Compare July 8, 2026 15:07
@WFY123wfy
WFY123wfy marked this pull request as ready for review July 8, 2026 15:11
@WFY123wfy
WFY123wfy requested review from a team as code owners July 8, 2026 15:11
@ray-gardener ray-gardener Bot added docs An issue or change related to documentation data Ray Data-related issues community-contribution Contributed by the community labels Jul 8, 2026
@WFY123wfy

Copy link
Copy Markdown
Contributor Author

Adds ORC read support (#37890), mirroring the existing read_avro / read_parquet datasource pattern. Read-only for now; write support can follow separately.

Tests in test_orc.py pass locally against a nightly build, and the readthedocs and Bugbot checks are green. The microcheck failure (#49686) appears to be a CI infra issue — the docker image pull failed after retries, not a lint/test failure (I reproduced all pre-commit hooks locally with no failures).

@scottjlee @richardliaw — would you be able to review, or help re-trigger CI?Happy to iterate on any feedback.

@WFY123wfy

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for reading ORC files in Ray Data by implementing ORCDatasource, exposing the read_orc API, and adding corresponding unit tests and documentation. Feedback on the changes highlights a bug where **open_args are silently ignored in _open_input_source, preventing configuration arguments from being passed to the filesystem. Additionally, it is recommended to remove the redundant __init__ method in ORCDatasource to simplify the class.

Comment thread python/ray/data/_internal/datasource/orc_datasource.py
Comment on lines +15 to +20
def __init__(
self,
paths: Union[str, List[str]],
**file_based_datasource_kwargs,
):
super().__init__(paths, **file_based_datasource_kwargs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The __init__ method is redundant as it only calls super().__init__ with the exact same arguments. Removing this boilerplate simplifies the class and improves maintainability.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — removed in the latest commit. Thanks!

The __init__ only forwarded its arguments to the parent FileBasedDatasource
without adding any behavior, so it can be dropped and the class inherits the
parent constructor directly. Also drop the now-unused List/Union imports.

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy

Copy link
Copy Markdown
Contributor Author

CI is green and I've addressed the review comments. This adds ORC read support (closes #37890), read-only for now, following the existing read_avro datasource pattern. Tests pass locally against a nightly build.

@bveeramani @justinvyu @owenowenisme — would any of you have a chance to review
when you get a moment? Happy to iterate on any feedback. Thanks!

@bveeramani

Copy link
Copy Markdown
Member

@WFY123wfy I don't have bandwidth to review, but I'll ask a colleague

@dstrodtman dstrodtman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doc changes are straightforward. Stamping to make sure the Vale changes don't remain blocking (just adding the API entry).

@ayushk7102 ayushk7102 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for contributing! This PR will be a good addition to Ray Data for ORC as a V1 datasource.

We are eventually planning to move all readers (that can support chunking, indexing) to the Datasource V2 API.

A good reference for this is parquet_reader.py. Would it make sense to migrate ORC to the V2 API as a follow-up?

Comment thread python/ray/data/_internal/datasource/orc_datasource.py Outdated
Comment thread python/ray/data/_internal/datasource/orc_datasource.py
Comment thread python/ray/data/tests/datasource/test_orc.py
Read one ORC stripe at a time through a BlockOutputBuffer instead of loading
the whole file at once. This bounds per-task memory usage on large files while
keeping output blocks at the target block size (small stripes are coalesced,
large ones are split), mirroring AvroDatasource's buffering.

Add tests for reading Hive-partitioned files (with and without a partition
filter) and for reading files with multiple stripes.

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy

Copy link
Copy Markdown
Contributor Author

Thanks a lot for contributing! This PR will be a good addition to Ray Data for ORC as a V1 datasource.

We are eventually planning to move all readers (that can support chunking, indexing) to the Datasource V2 API.

A good reference for this is parquet_reader.py. Would it make sense to migrate ORC to the V2 API as a follow-up?

Thanks! Migrating to the Datasource V2 API makes sense, and parquet_reader.py is a helpful reference. I'd prefer to do it as a separate follow-up PR so this one stays focused on landing V1 ORC support. Happy to take that on afterward.

@WFY123wfy
WFY123wfy requested a review from ayushk7102 July 22, 2026 15:13
Comment thread python/ray/data/_internal/datasource/orc_datasource.py Outdated
Drop the manual BlockOutputBuffer in ORCDatasource._read_stream. Since
read_stripe yields Arrow tables (which are already blocks), the read operator's
BlockMapTransformFn handles output block shaping against the target block size.
_read_stream now yields one stripe at a time, which still bounds per-task memory
on large files without duplicating the shaping logic.

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy
WFY123wfy requested a review from ayushk7102 July 28, 2026 13:02
Comment thread python/ray/data/read_api.py Outdated
ORC uses random access (open_input_file) and doesn't consume stream open args,
so exposing arrow_open_stream_args in read_orc was a no-op that could mislead
users. Remove it from the public signature, matching read_images which also
omits it.

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy
WFY123wfy requested a review from ayushk7102 July 29, 2026 10:22
Comment thread python/ray/data/tests/datasource/test_orc.py Outdated

@ayushk7102 ayushk7102 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM except 1 nit. Thanks for working on this!

Co-authored-by: Ayush Kumar <ayushk7102@gmail.com>
Signed-off-by: feiye_wu <46945405+WFY123wfy@users.noreply.github.com>
Comment thread python/ray/data/read_api.py Outdated
Signed-off-by: Richard Liaw <rliaw@berkeley.edu>
@richardliaw
richardliaw enabled auto-merge (squash) July 30, 2026 06:09
@github-actions github-actions Bot added the go add ONLY when ready to merge, run all tests label Jul 30, 2026
Comment thread python/ray/data/_internal/datasource/orc_datasource.py Outdated
auto-merge was automatically disabled July 30, 2026 08:39

Head branch was pushed to by a user without write access

- Explicitly import pyarrow.fs for the type annotation and use the
  PartitionStyle enum so the datasource and tests pass pyrefly type
  checking.
- Add a regression test that reads an empty ORC file as an empty
  dataset.

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy
WFY123wfy force-pushed the feature/data-read-orc branch from 1e32a71 to f7e30a6 Compare July 30, 2026 10:23
@WFY123wfy

Copy link
Copy Markdown
Contributor Author

Heads up: The earlier premerge failure has been fixed, and I’ve force-pushed the commit f7e30a6. All checks are green, and the two existing approvals remain valid. The branch is now out-of-date with master. Auto-merge was disabled due to the force push.
@richardliaw Could you please re-enable auto-merge (or update the branch) when you have time? Thanks!

@WFY123wfy

Copy link
Copy Markdown
Contributor Author

The branch has been updated with master, and all checks are green. @richardliaw could you please re‑enable auto‑merge at your convenience? Thanks!

@ayushk7102

ayushk7102 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

The branch has been updated with master, and all checks are green. @richardliaw could you please re‑enable auto‑merge at your convenience? Thanks!

Hey @WFY123wfy, thanks for contributing to a V1 of Ray Data's read_orc API!

With Ray 2.56, we have set the default path to be datasource V2 for all formats that can support it. With newer Ray verisons, we have also made the decision that we want to support V2 from the start with any new format (again, if compatible).

Would you be interested in moving this PR towards a V2 path for read_orc? I'd be happy to spend time on review, and we can move this along in a expedited way given that a majority of the legwork is done for V1.

Also, we could support an enriched ORC reader with projection pushdown and (potentially predicate pushdown),

Also, this draft PR that we are working on implementing bin-packing for load balanced Parquet reads should also apply to ORC. We can wait for this to merge, as we're going to genericise this algorithm so that it is usable by any datasource.

@ayushk7102

Copy link
Copy Markdown
Contributor

The branch has been updated with master, and all checks are green. @richardliaw could you please re‑enable auto‑merge at your convenience? Thanks!

Hey @WFY123wfy, thanks for contributing to a V1 of Ray Data's read_orc API!

With Ray 2.56, we have set the default path to be datasource V2 for all formats that can support it. With newer Ray verisons, we have also made the decision that we want to support V2 from the start with any new format (again, if compatible).

Would you be interested in moving this PR towards a V2 path for read_orc? I'd be happy to spend time on review, and we can move this along in a expedited way given that a majority of the legwork is done for V1.

Also, we could support an enriched ORC reader with projection pushdown and (potentially predicate pushdown),

Also, this draft PR that we are working on implementing bin-packing for load balanced Parquet reads should also apply to ORC. We can wait for this to merge, as we're going to genericise this algorithm so that it is usable by any datasource.

Hey @WFY123wfy, sorry for the back-and-forth. After further discussion with the team, we can land V1 ORC as a first step. Can we support projection pushdown as part of V1?

We can then work on V2 as a follow up.

@richardliaw

Copy link
Copy Markdown
Contributor

actually, https://github.com/ray-project/ray/pull/64540/changes seems to be a V2 implementation

@WFY123wfy

Copy link
Copy Markdown
Contributor Author

@ayushk7102 previously confirmed V1 + projection pushdown as the path forward. Given the ongoing V2 work in #64540, I’d like to double‑check this is still the agreed plan. Should I keep implementing projection pushdown within this V1‑based PR?

@richardliaw

richardliaw commented Aug 7, 2026 via email

Copy link
Copy Markdown
Contributor

# First pass: walk in declared order and pick the first "cheap" type.
for field in orc_schema:
if str(field.type).split("[", 1)[0].split("(", 1)[0] in cheap_kinds:
return field.name

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Carrier type matching never hits ints

Medium Severity

_pick_carrier_column treats cheap kinds as exact base names like int, date, float, and time, but str(field.type) yields forms such as int64, date32, and double. The intended preference for narrow fixed-width columns almost never matches, so empty or partition-only projections often fall back to the first schema field and can pull large string or binary columns on big ORC files.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5ecc1dd. Configure here.

@richardliaw

Copy link
Copy Markdown
Contributor

seems like test failing?

ORC now prunes physical columns at stripe-read time via the
supports_projection_pushdown protocol, so pure select_columns()
is removed from the optimized plan. Adds 6 tests covering
physical-only, multi-stripe, empty, partition-only, mixed, and
include_paths projections.

Signed-off-by: wufeiye1 <wufeiye1@jd.com>
@WFY123wfy
WFY123wfy force-pushed the feature/data-read-orc branch from 5ecc1dd to c125382 Compare August 8, 2026 15:35

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Reviewed by Cursor Bugbot for commit c125382. Configure here.


ds = ray.data.read_orc(path).select_columns([])
assert ds.count() == 5000
assert ds.take_all() == []

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty projection take assertion wrong

Medium Severity

test_read_orc_projection_pushdown_empty asserts both count() == 5000 and take_all() == []. An empty projection still yields one row per input row (backed by the internal stub column), so take_all() cannot be an empty list while count() is nonzero. This matches the reported failing test after projection pushdown landed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit c125382. Configure here.

@richardliaw

Copy link
Copy Markdown
Contributor

test still failing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-contribution Contributed by the community data Ray Data-related issues docs An issue or change related to documentation go add ONLY when ready to merge, run all tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Data] Add support for Apache ORC format

5 participants