Skip to content

Hybrid scan reports correct number of input RGs - #23052

Merged
rapids-bot[bot] merged 5 commits into
NVIDIA:mainfrom
mhaseeb123:bug/report-correct-num-input-rgs-in-hybrid-scan
Jul 7, 2026
Merged

Hybrid scan reports correct number of input RGs#23052
rapids-bot[bot] merged 5 commits into
NVIDIA:mainfrom
mhaseeb123:bug/report-correct-num-input-rgs-in-hybrid-scan

Conversation

@mhaseeb123

@mhaseeb123 mhaseeb123 commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

Follow up from #23013

This PR fixes the hybrid scan reader to report the correct number of input row groups in output metadata when all rows are pruned via row mask (two-step read case) and an empty output table chunk is produced

Checklist

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

@copy-pr-bot

copy-pr-bot Bot commented Jun 30, 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.

@github-actions github-actions Bot added the libcudf Affects libcudf (C++/CUDA) code. label Jun 30, 2026
@mhaseeb123 mhaseeb123 added bug Something isn't working 3 - Ready for Review Ready for review by team non-breaking Non-breaking change labels Jun 30, 2026
// Other valid types in the future would be UUID (still treated as string) and FLOAT16 (which
// for now would also be treated as a string).

/**

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.

Simply reformatted

return logical_type->type != LogicalType::DECIMAL;
}

/**

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.

Add docstring

return output_dtypes;
}

/**

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.

Simple helper

std::vector<std::vector<size_type>>(row_group_indices.size(), std::vector<size_type>{});
prepare_data(read_mode::READ_ALL, empty_row_groups, {}, {});
// Set correct number of input row groups to the output metadata
_file_itm_data.num_input_row_groups = count_row_groups(row_group_indices);

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.

Make sure to write the correct number of input row groups as we will be materializing no row groups in this early exit

auto const empty_row_groups =
std::vector<std::vector<size_type>>(row_group_indices.size(), std::vector<size_type>{});
prepare_data(read_mode::CHUNKED_READ, empty_row_groups, {}, {});
// Set correct number of input row groups to the output metadata

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.

Same here

std::invalid_argument);
}

TEST_F(HybridScanTest, AllRowsPrunedReportsInputRowGroups)

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.

Test:

  • Small 10 row parquet file
  • Set row mask to all false and read in two-steps (filter and payload)
  • Should get empty table chunk out but the metadata should report 1 input row group

@mhaseeb123
mhaseeb123 marked this pull request as ready for review June 30, 2026 21:27
@mhaseeb123
mhaseeb123 requested a review from a team as a code owner June 30, 2026 21:27
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8531383b-a41f-432d-bb6b-6f8f6b2f01a3

📥 Commits

Reviewing files that changed from the base of the PR and between 060408d and 3a53fb9.

📒 Files selected for processing (1)
  • cpp/tests/io/experimental/hybrid_scan_test.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • cpp/tests/io/experimental/hybrid_scan_test.cpp

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Fixed hybrid scan reporting when a filter prunes all rows, ensuring the metadata for input row-group count remains accurate.
    • Applied consistently across filter-column and payload-column materialization, including related chunking behavior.
  • Tests
    • Added a regression test for the “all rows pruned” scenario to verify both empty results and correct row-group metadata reporting.

Walkthrough

This change adds a count_row_groups helper in hybrid_scan_impl.cpp and uses it to populate _file_itm_data.num_input_row_groups in early-return branches where all rows are pruned, across filter/payload materialization and chunking setup functions. A new test validates this metadata is correctly preserved.

Changes

Hybrid Scan Pruned Row-Group Metadata Fix

Layer / File(s) Summary
Row-group counting helper
cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
Adds inline count_row_groups helper summing per-source row-group vector sizes; existing is_treat_fixed_length_as_string documentation is updated without changing behavior.
Pruned-branch metadata population
cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
In materialize_filter_columns, materialize_payload_columns, setup_chunking_for_filter_columns, and setup_chunking_for_payload_columns, sets _file_itm_data.num_input_row_groups via count_row_groups(row_group_indices) when all rows are pruned after prepare_data.
Test coverage for pruned scenario
cpp/tests/io/experimental/hybrid_scan_test.cpp
Adds AllRowsPrunedReportsInputRowGroups test writing a 2-column parquet file, filtering all rows out, materializing filter and payload columns, and asserting empty results with correct num_input_row_groups.

Estimated code review effort: 2 (Simple) | ~12 minutes

Suggested labels: cuIO

Suggested reviewers: vuule, Matt711, bdice, qbacpey

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.36% 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 is concise and accurately summarizes the main bug fix in hybrid scan metadata.
Description check ✅ Passed The description directly matches the change: fixing row-group metadata when all rows are pruned and adding tests.
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.

@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)

539-547: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Correct fix, but consider consolidating the duplicated early-pruned logic.

The num_input_row_groups assignment correctly uses the original row_group_indices (not the zeroed-out empty_row_groups) and is applied after prepare_data so it isn't overwritten — this addresses the prior review feedback at the old lines 583/713 correctly.

That said, this exact 3-statement pattern (build empty_row_groups, call prepare_data, set num_input_row_groups) is now duplicated across 4 call sites. This duplication is precisely why a prior PR (#23013) fixed only some of these spots and this followup PR had to patch the rest. Extracting a small private helper would prevent a future partial fix.

♻️ Proposed helper to consolidate the early-pruned branches
+void hybrid_scan_reader_impl::prepare_for_all_rows_pruned(
+  read_mode mode, std::span<std::vector<size_type> const> row_group_indices)
+{
+  auto const empty_row_groups =
+    std::vector<std::vector<size_type>>(row_group_indices.size(), std::vector<size_type>{});
+  prepare_data(mode, empty_row_groups, {}, {});
+  // Set correct number of input row groups to the output metadata
+  _file_itm_data.num_input_row_groups = count_row_groups(row_group_indices);
+}

Then each call site collapses to, e.g.:

-    auto const empty_row_groups =
-      std::vector<std::vector<size_type>>(row_group_indices.size(), std::vector<size_type>{});
-    prepare_data(read_mode::READ_ALL, empty_row_groups, {}, {});
-    // Set correct number of input row groups to the output metadata
-    _file_itm_data.num_input_row_groups = count_row_groups(row_group_indices);
+    prepare_for_all_rows_pruned(read_mode::READ_ALL, row_group_indices);

Also applies to: 577-585, 648-656, 708-716

🤖 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 539 - 547,
The early-pruned branch logic is duplicated in several places, including the
code around read_chunk_internal and the other early-return call sites, where
empty_row_groups is built, prepare_data is called, and
_file_itm_data.num_input_row_groups is set. Extract that repeated 3-step
sequence into a small private helper and have each pruned branch call it, so the
num_input_row_groups assignment still happens after prepare_data and stays
consistent across all sites.
🤖 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/tests/io/experimental/hybrid_scan_test.cpp`:
- Around line 919-934: The metadata assertion in the hybrid scan test is
comparing against `row_groups.size()`, which counts sources rather than total
row groups and can miss regressions in `materialize_filter_columns`. Update the
`filter_result.metadata.num_input_row_groups` check to compare against the
actual row-group count derived from the nested `row_groups` structure, and use a
signed-safe comparison helper such as `std::cmp_equal` to avoid the
`size_type`/`size_t` mismatch. Make the same adjustment in the related payload
assertion block so both checks validate true row-group totals instead of source
count.

---

Nitpick comments:
In `@cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp`:
- Around line 539-547: The early-pruned branch logic is duplicated in several
places, including the code around read_chunk_internal and the other early-return
call sites, where empty_row_groups is built, prepare_data is called, and
_file_itm_data.num_input_row_groups is set. Extract that repeated 3-step
sequence into a small private helper and have each pruned branch call it, so the
num_input_row_groups assignment still happens after prepare_data and stays
consistent across all sites.
🪄 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: db150bf4-0ded-4462-bd3f-a630399fd993

📥 Commits

Reviewing files that changed from the base of the PR and between aa8cfca and 0e66f69.

📒 Files selected for processing (2)
  • cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp
  • cpp/tests/io/experimental/hybrid_scan_test.cpp

Comment thread cpp/tests/io/experimental/hybrid_scan_test.cpp Outdated
Comment thread cpp/src/io/parquet/experimental/hybrid_scan_impl.cpp Outdated
Comment thread cpp/tests/io/experimental/hybrid_scan_test.cpp Outdated
@mhaseeb123 mhaseeb123 added 5 - Ready to Merge Testing and reviews complete, ready to merge 4 - Needs Review Waiting for reviewer to review or respond and removed 3 - Ready for Review Ready for review by team 5 - Ready to Merge Testing and reviews complete, ready to merge labels Jul 1, 2026
@mhaseeb123

Copy link
Copy Markdown
Contributor Author

/merge

@rapids-bot
rapids-bot Bot merged commit 6d8ebac into NVIDIA:main Jul 7, 2026
136 checks passed
@mhaseeb123
mhaseeb123 deleted the bug/report-correct-num-input-rgs-in-hybrid-scan branch July 7, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

4 - Needs Review Waiting for reviewer to review or respond bug Something isn't working libcudf Affects libcudf (C++/CUDA) code. non-breaking Non-breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants