[Data] Add support for reading ORC files - #64600
Conversation
|
Warning Gemini encountered an error creating the review. You can try again by commenting |
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>
8e92ffb to
bacf7df
Compare
|
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. |
|
/gemini review |
There was a problem hiding this comment.
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.
| def __init__( | ||
| self, | ||
| paths: Union[str, List[str]], | ||
| **file_based_datasource_kwargs, | ||
| ): | ||
| super().__init__(paths, **file_based_datasource_kwargs) |
There was a problem hiding this comment.
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>
|
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 |
|
@WFY123wfy I don't have bandwidth to review, but I'll ask a colleague |
dstrodtman
left a comment
There was a problem hiding this comment.
Doc changes are straightforward. Stamping to make sure the Vale changes don't remain blocking (just adding the API entry).
ayushk7102
left a comment
There was a problem hiding this comment.
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?
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>
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. |
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>
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>
ayushk7102
left a comment
There was a problem hiding this comment.
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>
Signed-off-by: Richard Liaw <rliaw@berkeley.edu>
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>
1e32a71 to
f7e30a6
Compare
|
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. |
|
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 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 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. |
|
actually, https://github.com/ray-project/ray/pull/64540/changes seems to be a V2 implementation |
|
@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? |
|
Yes, that seems fine. We can get your current PR merged by tomorrow, with
projection pushdown.
…On Thu, Aug 6, 2026 at 11:53 PM feiye_wu ***@***.***> wrote:
*WFY123wfy* left a comment (ray-project/ray#64600)
<#64600 (comment)>
@ayushk7102 <https://github.com/ayushk7102> previously confirmed V1 +
projection pushdown as the path forward. Given the ongoing V2 work in
#64540 <#64540>, I’d like to
double‑check this is still the agreed plan. Should I keep implementing
projection pushdown within this V1‑based PR?
—
Reply to this email directly, view it on GitHub
<#64600?email_source=notifications&email_token=ABCRZZMUF6TYECVMKSNM2A35IV4GVA5CNFSNUABFM5UWIORPF5TWS5BNNB2WEL2JONZXKZKDN5WW2ZLOOQXTKMRRGM2TONJUGI42M4TFMFZW63VHNVSW45DJN5XKKZLWMVXHJLDGN5XXIZLSL5RWY2LDNM#issuecomment-5213575429>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABCRZZPHZJ2CZAWP6BSSVET5IV4GVAVCNFSNUABEKJSXA33TNF2G64TZHM3TCOJTGIZTIOJ3JFZXG5LFHM2DQMZYGQ3DKMZWGKQXMAQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
| # 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 |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit 5ecc1dd. Configure here.
|
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>
5ecc1dd to
c125382
Compare
There was a problem hiding this comment.
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).
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() == [] |
There was a problem hiding this comment.
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.
Reviewed by Cursor Bugbot for commit c125382. Configure here.
|
test still failing |


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 newORCDatasourcethat reads eachfile 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 canfollow.
Related issues
Closes #37890
Additional information
Mirrors the
read_avro/read_parquetAPI.file_extensionsdefaults to["orc"]. No new dependency (pyarrowalready shipspyarrow.orc). Adds tests intest_orc.pyand docs inloading_data.rst.