Skip to content

Add page-level I/O and materialization in Hybrid Scan - #23375

Open
mhaseeb123 wants to merge 12 commits into
rapidsai:mainfrom
mhaseeb123:feature/sparse-page-io-hybrid
Open

Add page-level I/O and materialization in Hybrid Scan#23375
mhaseeb123 wants to merge 12 commits into
rapidsai:mainfrom
mhaseeb123:feature/sparse-page-io-hybrid

Conversation

@mhaseeb123

@mhaseeb123 mhaseeb123 commented Jul 21, 2026

Copy link
Copy Markdown
Member

Description

Part of #23362

This PR adds new hybrid scan APIs to support page-level (sparse) I/O for payload columns. This includes:

  • API to compute (pruned) page-level I/O byte range for payload columns
  • Infrastructure to only decompress and decode these sparse pages into the output table
  • End-to-end test coverage and some negative tests. More extensive tests will land in Enable page-level payload I/O in hybrid scan #23362

Checklist

  • I am familiar with the Contributing Guidelines.
  • New or existing tests cover these changes.
  • The documentation is up to date with these changes.

Preserve page locations and variable-width offset state needed to safely
reconstruct columns from a sparse subset of Parquet data pages.
Expose multifile page-range planning and consume the selected payload pages so
hybrid scan avoids fetching pruned Parquet payload data.
@mhaseeb123
mhaseeb123 requested a review from a team as a code owner July 21, 2026 17:43
@mhaseeb123
mhaseeb123 requested review from mattgara and simoneves and removed request for a team July 21, 2026 17:43
@github-actions github-actions Bot added the libcudf Affects libcudf (C++/CUDA) code. label Jul 21, 2026
@mhaseeb123
mhaseeb123 marked this pull request as draft July 21, 2026 17:49
@copy-pr-bot

copy-pr-bot Bot commented Jul 21, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

rapids-bot Bot pushed a commit that referenced this pull request Jul 24, 2026
Part of #23362

This PR includes bug fixes and supporting features needed to enable page pruning with page-level (sparse) I/O (for payload columns) in hybrid scan, that is upcoming in #23375 and includes end to end tests.

Authors:
  - Muhammad Haseeb (https://github.com/mhaseeb123)

Approvers:
  - Paul Mattione (https://github.com/pmattione-nvidia)
  - Vukasin Milovanovic (https://github.com/vuule)
  - Bradley Dice (https://github.com/bdice)
  - Nghia Truong (https://github.com/ttnghia)

URL: #23374
@mhaseeb123
mhaseeb123 changed the base branch from feature/sparse-page-io-foundation to main July 28, 2026 00:40
@mhaseeb123
mhaseeb123 force-pushed the feature/sparse-page-io-hybrid branch from ce70f6f to 1cf8e93 Compare July 31, 2026 23:26
@mhaseeb123
mhaseeb123 marked this pull request as ready for review July 31, 2026 23:33
@mhaseeb123 mhaseeb123 changed the title Add sparse page I/O to hybrid scan Add page-level (sparse) materializers in Hybrid Scan Jul 31, 2026
@mhaseeb123 mhaseeb123 changed the title Add page-level (sparse) materializers in Hybrid Scan Add page-level I/O and materialization in Hybrid Scan Jul 31, 2026
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added sparse, page-level payload scanning for hybrid multifile Parquet reads.
    • Added row-mask-based page selection and targeted chunking for more efficient filtered reads.
    • Added support for dictionary pages, pruned pages, and chunked multifile scans.
  • Bug Fixes

    • Improved handling of empty buffers, sparse page metadata, dictionary data, and page masks.
    • Added validation for missing offset indexes and inconsistent page data.

Walkthrough

The PR adds payload page-range APIs, sparse page-data chunking, page-level pass masks, sparse Parquet preprocessing, and multifile hybrid-scan coverage for pruning, dictionaries, missing offset indexes, and row-group ordering.

Changes

Sparse payload hybrid scan

Layer / File(s) Summary
Payload range planning
cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp, cpp/src/io/parquet/experimental/hybrid_scan_helpers.hpp, cpp/src/io/parquet/experimental/hybrid_scan_impl.*, cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp
Adds flattened payload page ranges, source indices, dictionary-page ranges, offset-index validation, pruned-page representation, and a page-data chunking overload.
Sparse page preprocessing
cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu, cpp/src/io/parquet/reader_impl_preprocess_utils.*, cpp/src/io/parquet/reader_impl.*, cpp/src/io/parquet/io_utils/parquet_io_utils.cpp
Validates sparse page spans, decodes page headers, tracks sparse I/O state, handles sparse dictionary pointers, and safely represents empty device buffers.
Sparse pass chunking and masks
cpp/src/io/parquet/experimental/hybrid_scan_chunking.cu, cpp/src/io/parquet/experimental/hybrid_scan_impl.*, cpp/src/io/parquet/experimental/page_index_filter.cu
Pass setup accepts current data-page masks. Sparse mode initializes page metadata, builds masks from page spans, and accounts for sparse input sizes.
Multifile integration and validation
cpp/tests/io/experimental/hybrid_scan_multifile_composer.*, cpp/tests/io/experimental/hybrid_scan_multifile*_test.cpp
Adds sparse multifile composition and coverage for empty masks, missing offset indexes, dictionary pages, asymmetric row-group ordering, and fully pruned payload data.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested labels: cuIO, improvement

Suggested reviewers: simoneves, mattgara, vuule

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.26% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding page-level I/O and materialization support to Hybrid Scan.
Description check ✅ Passed The description directly explains the page-level sparse I/O, materialization, APIs, and test coverage added by the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.


// Must be called as soon as we create the pass
set_pass_page_mask(data_page_mask);
setup_next_pass(column_chunk_data, data_page_mask);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

set_pass_page_mask is now moved inside the setup_next_pass


// Setup page information for the chunk (which we can access without decompressing)
setup_compressed_data(column_chunk_data);
if (_sparse_page_io) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Use either the dense or sparse overloads of the setup_compressed_data and set_pass_page_mask APIs.

* @param schema_indices Schema indices from the first source
* @return A pair indicating column-index and offset-index presence, respectively
*/
[[nodiscard]] std::pair<bool, bool> page_index_presence(

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Simply moved from private to public scope

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp (1)

466-487: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the column_chunk_data parameter doc for the sparse branch.

The doc comments for handle_chunking (line 470) and setup_next_pass (line 483) still read "Device spans of buffers containing column chunk data." With _sparse_page_io enabled, hybrid_scan_chunking.cu now passes page-level spans (one span per logical page) through this same parameter, not per-chunk column data. Update the doc to state that this parameter holds page-level data spans when sparse I/O is active, so future readers do not assume a fixed per-chunk buffer layout.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp` around lines 466 - 487,
Update the column_chunk_data parameter documentation in handle_chunking and
setup_next_pass to describe page-level data spans when _sparse_page_io is
enabled, while preserving the existing description for non-sparse usage.
🧹 Nitpick comments (3)
cpp/tests/io/experimental/hybrid_scan_multifile_composer.cpp (1)

170-205: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider extracting the shared setup and filter phase.

Lines 170-205 duplicate lines 103-140 of chunked_hybrid_scan_multifile almost exactly: options build, reader construction, page-index setup, row-group filtering, row-mask build, chunk limits, and the filter-column chunk loop. Only the payload phase differs. Extract a small helper that returns the reader, inputs, row groups, row mask, and filter tables. This keeps the two composers in sync when the filter path changes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/tests/io/experimental/hybrid_scan_multifile_composer.cpp` around lines
170 - 205, Extract the duplicated filter setup and materialization flow from the
current composer and chunked_hybrid_scan_multifile into a shared helper, reusing
the existing options/reader construction, page-index setup, row-group filtering,
row-mask creation, chunk-limit configuration, and filter_tables loop. Have the
helper return the reader, inputs, row groups, row mask, and filter tables needed
by each payload phase, then update both callers to use it while preserving their
distinct payload processing.
cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp (1)

1418-1435: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename the outer chunk_idx to avoid shadowing.

Line 1420 declares chunk_idx for the accumulate pass. Line 1435 declares another chunk_idx in the mask-building loop. The two variables have different meanings in the same function. A future edit inside the inner loop could read the wrong one. Consider computing the offsets with an explicit scan and a distinct name.

♻️ Proposed refactor
   // Find the first logical page-data span for every column chunk.
   auto page_offsets            = std::vector<std::size_t>(chunks.size());
-  auto chunk_idx               = std::size_t{0};
+  auto offset_cursor           = std::size_t{0};
   auto const num_logical_pages = std::accumulate(
     chunks.begin(), chunks.end(), std::size_t{0}, [&](auto offset, auto const& chunk) {
-      page_offsets[chunk_idx++] = offset;
+      page_offsets[offset_cursor++] = offset;
       return offset + chunk.num_dict_pages + chunk.num_data_pages;
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp` around lines 1418 -
1435, Rename the outer chunk index used by the page-offset accumulation in the
surrounding function to a distinct name, such as a page-offset scan index, so it
cannot be confused with the inner chunk_idx declared in the mask-building loop.
Update only its declaration and use in the accumulate pass; preserve the inner
loop’s chunk_idx and existing offset behavior.
cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp (1)

197-202: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add Doxygen documentation for the two new declarations.

payload_pages_byte_ranges (lines 197-202) and the new setup_chunking_for_payload_columns overload (lines 269-277) have no @brief/@copydoc block. Every other declaration in this file, including the sibling setup_chunking_for_payload_columns overload directly above it, documents parameters with a @copydoc tag referencing the public API. Add matching @copydoc blocks for both new declarations to keep the file consistent and to support Doxygen-based linting.

As per coding guidelines, "Use doxygen as a documentation generator and linter for C++ and CUDA code" applies to this file.

Also applies to: 269-277

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp` around lines 197 - 202,
Add matching Doxygen `@copydoc` blocks for payload_pages_byte_ranges and the new
setup_chunking_for_payload_columns overload, using the corresponding public API
declarations as references. Place each block immediately above its declaration
and document parameters consistently with the existing sibling overload.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp`:
- Around line 270-271: Update the exception documentation for
hybrid_scan_reader_impl::payload_pages_byte_ranges to state cudf::logic_error,
matching the existing CUDF_EXPECTS behavior and
SparsePayloadPagesWithoutOffsetIndexes test; do not change the implementation
exception type.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp`:
- Around line 97-110: Update dictionary_page_range to return std::nullopt before
accessing page_locations.front() when page_locations is empty, while preserving
the existing offset-range behavior for non-empty indexes. Add a concise Doxygen
comment describing the helper’s purpose, inputs, and optional return result,
consistent with get_output_types and count_row_groups.

In `@cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu`:
- Around line 196-207: Add the same positive-row-count precondition used by
setup_compressed_data to setup_sparse_compressed_data, asserting
_pass_itm_data->num_rows > 0 with the established error message before
calculating page counts. Keep the existing offset-index and page-span
validations unchanged.

---

Outside diff comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp`:
- Around line 466-487: Update the column_chunk_data parameter documentation in
handle_chunking and setup_next_pass to describe page-level data spans when
_sparse_page_io is enabled, while preserving the existing description for
non-sparse usage.

---

Nitpick comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp`:
- Around line 1418-1435: Rename the outer chunk index used by the page-offset
accumulation in the surrounding function to a distinct name, such as a
page-offset scan index, so it cannot be confused with the inner chunk_idx
declared in the mask-building loop. Update only its declaration and use in the
accumulate pass; preserve the inner loop’s chunk_idx and existing offset
behavior.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp`:
- Around line 197-202: Add matching Doxygen `@copydoc` blocks for
payload_pages_byte_ranges and the new setup_chunking_for_payload_columns
overload, using the corresponding public API declarations as references. Place
each block immediately above its declaration and document parameters
consistently with the existing sibling overload.

In `@cpp/tests/io/experimental/hybrid_scan_multifile_composer.cpp`:
- Around line 170-205: Extract the duplicated filter setup and materialization
flow from the current composer and chunked_hybrid_scan_multifile into a shared
helper, reusing the existing options/reader construction, page-index setup,
row-group filtering, row-mask creation, chunk-limit configuration, and
filter_tables loop. Have the helper return the reader, inputs, row groups, row
mask, and filter tables needed by each payload phase, then update both callers
to use it while preserving their distinct payload processing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 697975d5-e5fa-4229-acef-d654727c9b5e

📥 Commits

Reviewing files that changed from the base of the PR and between 3b3cea4 and 1cf8e93.

📒 Files selected for processing (17)
  • cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_chunking.cu
  • cpp/src/io/parquet/experimental/hybrid_scan_helpers.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu
  • cpp/src/io/parquet/experimental/page_index_filter.cu
  • cpp/src/io/parquet/io_utils/parquet_io_utils.cpp
  • cpp/src/io/parquet/reader_impl.hpp
  • cpp/src/io/parquet/reader_impl_preprocess.cu
  • cpp/src/io/parquet/reader_impl_preprocess_utils.cu
  • cpp/src/io/parquet/reader_impl_preprocess_utils.cuh
  • cpp/tests/io/experimental/hybrid_scan_multifile_composer.cpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_composer.hpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_test.cpp

Comment thread cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp Outdated
Comment thread cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
Comment thread cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp (1)

1419-1435: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Rename the outer chunk_idx and replace the side-effecting std::accumulate.

Line 1420 declares chunk_idx, and line 1435 declares another chunk_idx that shadows it inside the lambda capture. The shadowing compiles, but it makes the two counters hard to tell apart and can trigger -Wshadow. The std::accumulate at line 1421 also mutates page_offsets and chunk_idx inside the reduction operator. A plain loop states the intent directly.

♻️ Proposed refactor
   // Find the first logical page-data span for every column chunk.
-  auto page_offsets            = std::vector<std::size_t>(chunks.size());
-  auto chunk_idx               = std::size_t{0};
-  auto const num_logical_pages = std::accumulate(
-    chunks.begin(), chunks.end(), std::size_t{0}, [&](auto offset, auto const& chunk) {
-      page_offsets[chunk_idx++] = offset;
-      return offset + chunk.num_dict_pages + chunk.num_data_pages;
-    });
+  auto page_offsets          = std::vector<std::size_t>(chunks.size());
+  auto num_logical_pages     = std::size_t{0};
+  for (std::size_t idx = 0; idx < chunks.size(); ++idx) {
+    page_offsets[idx] = num_logical_pages;
+    num_logical_pages += chunks[idx].num_dict_pages + chunks[idx].num_data_pages;
+  }
   CUDF_EXPECTS(page_data.size() == num_logical_pages,
                "Sparse page span count does not match the number of logical pages");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp` around lines 1419 -
1435, Rename the outer page-offset indexing variable used by the logical-page
count setup to a distinct name, leaving the inner chunk traversal variable in
the column-order lambda unchanged. Replace the side-effecting std::accumulate
that fills page_offsets with a straightforward loop over chunks that records
each offset and advances the running logical-page count.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp`:
- Around line 853-861: Guard the all-pages-pruned early return in the
surrounding scan flow so it only executes when page_data is non-empty. Preserve
the existing all_of check for non-empty page_data, allowing
setup_sparse_compressed_data to validate empty or mismatched input instead of
silently producing an empty result.

---

Nitpick comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp`:
- Around line 1419-1435: Rename the outer page-offset indexing variable used by
the logical-page count setup to a distinct name, leaving the inner chunk
traversal variable in the column-order lambda unchanged. Replace the
side-effecting std::accumulate that fills page_offsets with a straightforward
loop over chunks that records each offset and advances the running logical-page
count.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6c7ae62e-2570-4878-8ba9-14c805d9060e

📥 Commits

Reviewing files that changed from the base of the PR and between 3b3cea4 and acde80d.

📒 Files selected for processing (17)
  • cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_chunking.cu
  • cpp/src/io/parquet/experimental/hybrid_scan_helpers.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu
  • cpp/src/io/parquet/experimental/page_index_filter.cu
  • cpp/src/io/parquet/io_utils/parquet_io_utils.cpp
  • cpp/src/io/parquet/reader_impl.hpp
  • cpp/src/io/parquet/reader_impl_preprocess.cu
  • cpp/src/io/parquet/reader_impl_preprocess_utils.cu
  • cpp/src/io/parquet/reader_impl_preprocess_utils.cuh
  • cpp/tests/io/experimental/hybrid_scan_multifile_composer.cpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_composer.hpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_test.cpp
🚧 Files skipped from review as they are similar to previous changes (15)
  • cpp/src/io/parquet/experimental/page_index_filter.cu
  • cpp/src/io/parquet/io_utils/parquet_io_utils.cpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_composer.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_multifile.cpp
  • cpp/src/io/parquet/reader_impl_preprocess.cu
  • cpp/src/io/parquet/experimental/hybrid_scan_chunking.cu
  • cpp/src/io/parquet/experimental/hybrid_scan_helpers.hpp
  • cpp/src/io/parquet/reader_impl_preprocess_utils.cuh
  • cpp/src/io/parquet/reader_impl.hpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu
  • cpp/tests/io/experimental/hybrid_scan_multifile_test.cpp
  • cpp/src/io/parquet/reader_impl_preprocess_utils.cu
  • cpp/tests/io/experimental/hybrid_scan_multifile_composer.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp

Comment thread cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp Outdated

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp (1)

538-560: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate offset-index topology before emitting sparse ranges.

page_index_presence(...).second verifies index presence only. It does not verify that find_colchunk_iter_offset(...) returned a value or that each page location is valid.

At Line [560], colchunk_offset.value() throws when a selected column is missing. Invalid offsets, non-positive page sizes, empty page locations, or inconsistent page rows can also produce invalid ranges or a page-span count that does not match sparse preprocessing.

Validate every selected chunk and its page locations before using them. Fall back to get_input_column_chunk_byte_ranges() or raise a clear error when the topology is incomplete.

As per coding guidelines: “Prevent invalid memory access” and “Validate inputs such as negative dimensions and null pointers.”

Also applies to: 594-617

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp` around lines 538 - 560,
Validate each selected column chunk and its page locations in the hybrid scan
flow before dereferencing colchunk_offset or emitting sparse ranges. In the
loops computing chunk_page_counts and handling the corresponding page ranges,
reject missing offsets, empty locations, non-positive page sizes, invalid
offsets, and inconsistent page-row metadata; fall back to
get_input_column_chunk_byte_ranges() or raise a clear error when validation
fails. Ensure the validated page-span count matches sparse preprocessing.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp`:
- Around line 538-560: Validate each selected column chunk and its page
locations in the hybrid scan flow before dereferencing colchunk_offset or
emitting sparse ranges. In the loops computing chunk_page_counts and handling
the corresponding page ranges, reject missing offsets, empty locations,
non-positive page sizes, invalid offsets, and inconsistent page-row metadata;
fall back to get_input_column_chunk_byte_ranges() or raise a clear error when
validation fails. Ensure the validated page-span count matches sparse
preprocessing.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: d825116a-6343-42d7-9ec2-52efd19d1194

📥 Commits

Reviewing files that changed from the base of the PR and between b2518c7 and dda2c9d.

📒 Files selected for processing (6)
  • cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp
  • cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu
  • cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_test.cpp
🚧 Files skipped from review as they are similar to previous changes (5)
  • cpp/src/io/parquet/experimental/hybrid_scan_preprocess.cu
  • cpp/tests/io/experimental/hybrid_scan_multifile_filters_test.cpp
  • cpp/include/cudf/io/experimental/hybrid_scan_multifile.hpp
  • cpp/tests/io/experimental/hybrid_scan_multifile_test.cpp
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.hpp

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

Labels

3 - Ready for Review Ready for review by team feature request New feature or request libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant