11/*
2- * Copyright 2024 -present Alibaba Inc.
2+ * Copyright 2026 -present Alibaba Inc.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
1414 * limitations under the License.
1515 */
1616
17- #include " paimon/format/parquet/parquet_input_stream_impl .h"
17+ #include " paimon/common/utils/arrow/arrow_input_stream_adapter .h"
1818
19- #include < functional >
19+ #include < cstdint >
2020#include < utility>
2121
2222#include " arrow/api.h"
23- #include " arrow/util/future .h"
23+ #include " fmt/format .h"
2424#include " paimon/common/utils/arrow/status_utils.h"
25+ #include " paimon/common/utils/math.h"
26+ #include " paimon/common/utils/options_utils.h"
2527#include " paimon/fs/file_system.h"
2628#include " paimon/macros.h"
2729#include " paimon/result.h"
2830#include " paimon/status.h"
2931
30- namespace arrow ::io {
31- struct IOContext ;
32- } // namespace arrow::io
32+ namespace paimon {
3333
34- namespace paimon ::parquet {
34+ namespace {
3535
36- ParquetInputStreamImpl::ParquetInputStreamImpl (
37- const std::shared_ptr<::paimon::InputStream>& input_stream,
36+ template <typename To, typename From>
37+ arrow::Status ValidateArrowIoRange (From value, const char * name) {
38+ if (!InRange<To>(value)) {
39+ return arrow::Status::Invalid (fmt::format (" {} value {} is out of bound of type {}" , name,
40+ value, OptionsUtils::GetTypeName<To>()));
41+ }
42+ return arrow::Status::OK ();
43+ }
44+
45+ } // namespace
46+
47+ ArrowInputStreamAdapter::ArrowInputStreamAdapter (
48+ const std::shared_ptr<paimon::InputStream>& input_stream,
3849 const std::shared_ptr<arrow::MemoryPool>& pool, uint64_t file_size)
3950 : input_stream_(input_stream), pool_(pool), file_size_(file_size) {}
4051
41- ParquetInputStreamImpl ::~ParquetInputStreamImpl () {
52+ ArrowInputStreamAdapter ::~ArrowInputStreamAdapter () {
4253 [[maybe_unused]] auto status = DoClose ();
4354}
4455
45- arrow::Status ParquetInputStreamImpl ::Seek (int64_t position) {
56+ arrow::Status ArrowInputStreamAdapter ::Seek (int64_t position) {
4657 return ToArrowStatus (input_stream_->Seek (position, SeekOrigin::FS_SEEK_SET ));
4758}
4859
49- arrow::Result<int64_t > ParquetInputStreamImpl::Read (int64_t nbytes, void * out) {
50- Result<int32_t > read_bytes = input_stream_->Read (static_cast <char *>(out), nbytes);
60+ arrow::Result<int64_t > ArrowInputStreamAdapter::Read (int64_t nbytes, void * out) {
61+ ARROW_RETURN_NOT_OK (ValidateArrowIoRange<uint32_t >(nbytes, " nbytes" ));
62+ Result<int32_t > read_bytes =
63+ input_stream_->Read (static_cast <char *>(out), static_cast <uint32_t >(nbytes));
5164 if (!read_bytes.ok ()) {
5265 return ToArrowStatus (read_bytes.status ());
5366 }
5467 return read_bytes.value ();
5568}
5669
57- arrow::Result<std::shared_ptr<arrow::Buffer>> ParquetInputStreamImpl ::Read (int64_t nbytes) {
70+ arrow::Result<std::shared_ptr<arrow::Buffer>> ArrowInputStreamAdapter ::Read (int64_t nbytes) {
5871 ARROW_ASSIGN_OR_RAISE (std::shared_ptr<arrow::ResizableBuffer> buffer,
5972 arrow::AllocateResizableBuffer (nbytes, pool_.get ()));
6073 ARROW_ASSIGN_OR_RAISE (int64_t read_bytes, Read (nbytes, buffer->mutable_data ()));
6174 if (read_bytes < nbytes) {
62- RETURN_NOT_OK (buffer->Resize (read_bytes));
75+ ARROW_RETURN_NOT_OK (buffer->Resize (read_bytes));
6376 }
6477 return std::shared_ptr<arrow::Buffer>(std::move (buffer));
6578}
6679
67- arrow::Result<int64_t > ParquetInputStreamImpl::ReadAt (int64_t position, int64_t nbytes, void * out) {
68- Result<int32_t > read_bytes = input_stream_->Read (static_cast <char *>(out), nbytes, position);
80+ arrow::Result<int64_t > ArrowInputStreamAdapter::ReadAt (int64_t position, int64_t nbytes,
81+ void * out) {
82+ ARROW_RETURN_NOT_OK (ValidateArrowIoRange<uint64_t >(position, " position" ));
83+ ARROW_RETURN_NOT_OK (ValidateArrowIoRange<uint32_t >(nbytes, " nbytes" ));
84+ Result<int32_t > read_bytes = input_stream_->Read (
85+ static_cast <char *>(out), static_cast <uint32_t >(nbytes), static_cast <uint64_t >(position));
6986 if (!read_bytes.ok ()) {
7087 return ToArrowStatus (read_bytes.status ());
7188 }
7289 return read_bytes.value ();
7390}
7491
75- arrow::Result<std::shared_ptr<arrow::Buffer>> ParquetInputStreamImpl ::ReadAt (int64_t position,
76- int64_t nbytes) {
92+ arrow::Result<std::shared_ptr<arrow::Buffer>> ArrowInputStreamAdapter ::ReadAt (int64_t position,
93+ int64_t nbytes) {
7794 ARROW_ASSIGN_OR_RAISE (std::shared_ptr<arrow::ResizableBuffer> buffer,
7895 arrow::AllocateResizableBuffer (nbytes, pool_.get ()));
7996 ARROW_ASSIGN_OR_RAISE (int64_t read_bytes, ReadAt (position, nbytes, buffer->mutable_data ()));
8097 if (read_bytes < nbytes) {
81- RETURN_NOT_OK (buffer->Resize (read_bytes));
98+ ARROW_RETURN_NOT_OK (buffer->Resize (read_bytes));
8299 }
83100 return std::shared_ptr<arrow::Buffer>(std::move (buffer));
84101}
85102
86- arrow::Future<std::shared_ptr<arrow::Buffer>> ParquetInputStreamImpl ::ReadAsync (
103+ arrow::Future<std::shared_ptr<arrow::Buffer>> ArrowInputStreamAdapter ::ReadAsync (
87104 const arrow::io::IOContext& io_context, int64_t position, int64_t nbytes) {
105+ auto fut = arrow::Future<std::shared_ptr<arrow::Buffer>>::Make ();
106+ auto range_status = ValidateArrowIoRange<uint64_t >(position, " position" );
107+ if (!range_status.ok ()) {
108+ fut.MarkFinished (range_status);
109+ return fut;
110+ }
111+ range_status = ValidateArrowIoRange<uint32_t >(nbytes, " nbytes" );
112+ if (!range_status.ok ()) {
113+ fut.MarkFinished (range_status);
114+ return fut;
115+ }
116+
88117 arrow::Result<std::shared_ptr<arrow::Buffer>> buffer_result =
89118 arrow::AllocateResizableBuffer (nbytes, pool_.get ());
90- auto fut = arrow::Future<std::shared_ptr<arrow::Buffer>>::Make ();
91119 if (PAIMON_UNLIKELY (!buffer_result.ok ())) {
92120 fut.MarkFinished (buffer_result.status ());
93121 return fut;
@@ -105,23 +133,23 @@ arrow::Future<std::shared_ptr<arrow::Buffer>> ParquetInputStreamImpl::ReadAsync(
105133 return fut;
106134}
107135
108- arrow::Result<int64_t > ParquetInputStreamImpl ::Tell () const {
136+ arrow::Result<int64_t > ArrowInputStreamAdapter ::Tell () const {
109137 Result<int64_t > position = input_stream_->GetPos ();
110138 if (!position.ok ()) {
111139 return ToArrowStatus (position.status ());
112140 }
113141 return position.value ();
114142}
115143
116- arrow::Result<int64_t > ParquetInputStreamImpl ::GetSize () {
144+ arrow::Result<int64_t > ArrowInputStreamAdapter ::GetSize () {
117145 return static_cast <int64_t >(file_size_);
118146}
119147
120- bool ParquetInputStreamImpl ::closed () const {
148+ bool ArrowInputStreamAdapter ::closed () const {
121149 return closed_;
122150}
123151
124- arrow::Status ParquetInputStreamImpl ::DoClose () {
152+ arrow::Status ArrowInputStreamAdapter ::DoClose () {
125153 if (!closed_) {
126154 Status status = input_stream_->Close ();
127155 if (!status.ok ()) {
@@ -132,4 +160,4 @@ arrow::Status ParquetInputStreamImpl::DoClose() {
132160 return arrow::Status::OK ();
133161}
134162
135- } // namespace paimon::parquet
163+ } // namespace paimon
0 commit comments