Skip to content

[enhancement](variant) Support deep Variant object leaf projection - #66575

Open
Gabriel39 wants to merge 4 commits into
apache:branch-4.1from
Gabriel39:dev/variant-deep-object-leaf-projection-4.1
Open

[enhancement](variant) Support deep Variant object leaf projection#66575
Gabriel39 wants to merge 4 commits into
apache:branch-4.1from
Gabriel39:dev/variant-deep-object-leaf-projection-4.1

Conversation

@Gabriel39

@Gabriel39 Gabriel39 commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary:

File Scanner V2 carried Variant access paths as a list of string segments, but the BE Parquet mapper only projected one top-level shredded leaf. Deep object paths therefore fell back even when every nested typed_value wrapper was physically available. The FE access-path comparator also joined segments with dots, so an object key such as a.b could collide with the nested path a/b before the paths reached BE.

This change reuses the existing access-path list without any Thrift or Proto change. It compares FE paths segment by segment, merges sibling and prefix paths through the shared BE access-path tree, and traverses arbitrary-depth object typed_value wrappers for Iceberg and Paimon native Parquet scans. Numeric segments, repeated ancestors, missing leaves, unshredded files, and ambiguous physical leaf identities conservatively fall back to the complete Variant root. Numeric array indexes remain unsupported with a TODO for typed path segments.

Release note

Support arbitrary-depth object-only Variant leaf projection for Iceberg and Paimon native Parquet scans.

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes. Iceberg and Paimon native Parquet scans can physically project deeply shredded Variant object leaves while preserving conservative fallback behavior.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

@Gabriel39
Gabriel39 requested a review from yiguolei as a code owner August 7, 2026 08:10
@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: All Codex review accounts are usage-limited; earliest retry is 2026-08-08T03:32:00Z.
Workflow run: https://github.com/apache/doris/actions/runs/31160616690

Please trigger /review again after that time.

@Gabriel39
Gabriel39 force-pushed the dev/variant-deep-object-leaf-projection-4.1 branch from bd7fc68 to 4c8217f Compare August 7, 2026 08:42
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: All Codex review accounts are usage-limited; earliest retry is 2026-08-08T03:32:00Z.
Workflow run: https://github.com/apache/doris/actions/runs/31162925837

Please trigger /review again after that time.

@Gabriel39 Gabriel39 changed the title [Enhancement] Support deep Variant object leaf projection [enhancement](variant) Support deep Variant object leaf projection Aug 7, 2026
@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (13/13) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.79% (30529/41373)
Line Coverage 57.77% (336077/581714)
Region Coverage 54.63% (279612/511865)
Branch Coverage 55.58% (125296/225422)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100.00% (11/11) 🎉
Increment coverage report
Complete coverage report

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions 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.

Review summary

Requesting changes for four P2 issues: the new ancestor-residual gate suppresses valid Variant statistics pruning; row-group physical projection is finalized after page-index and avoided-byte planning; the mixed-row-group unit fixture does not contain residual data that proves fallback I/O; and the Paimon regression asserts eligibility instead of the actual row-group projection outcome.

Critical checkpoint conclusions:

  • Architecture and layering: FE path-segment transport, BE access-tree construction, and recursive physical mapping remain coherent; no separate layering or identity defect was substantiated.
  • Lifecycle and state: row-group reader construction, dictionary probes, lazy reads, prefetch/reset, and Variant appends use the row-group request once it exists. The accepted planning issue is that this physical shape is produced after OffsetIndex selection and pruning-byte accounting.
  • Schema, compatibility, and result correctness: dotted/case-sensitive keys and numeric, repeated, missing, complex, Iceberg, Paimon, and external-writer fallback paths were traced. The remaining fallbacks are conservative; no separate result-materialization defect was found.
  • Filtering and pruning: residual row predicates remain in place, but requiring unrelated ancestor overflow to be null regresses otherwise valid footer and page-index pruning.
  • Performance and observability: late finalization leaves stale OffsetIndex and FilteredBytes planning artifacts, and VariantLeafProjections no longer proves that a row group retained leaf projection.
  • Tests: the patch adds broad unit and integration coverage, but the two inline test findings leave the full-fallback physical branch and the Paimon leaf-retention outcome unproven.
  • User focus: no additional focus was provided; the complete 20-file patch was reviewed.
  • Validation: static review only, as required by the task; no build, test, or source modification was performed.

Completion status: INCOMPLETE under the bundle's convergence rule. A valuable OffsetIndex finding emerged in the third and final allowed discovery round. It was independently verified, deduplicated into the late-planning comment, and all current candidates are adjudicated, but a fourth convergence round was not permitted.

typed_object == nullptr || typed_object->kind != ParquetColumnSchemaKind::STRUCT) {
return std::nullopt;
}
fallback_values.push_back(fallback);

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.

[P2] Do not gate leaf statistics on unrelated ancestor overflow

The Variant shredding contract makes a partially shredded object's value keys disjoint from the fields represented by its typed_value. Consequently a root/ancestor residual may legitimately be non-null because it contains unrelated fields while this requested descendant is still completely represented by its own wrapper. Adding every ancestor here changes even a shallow v['n'] predicate from checking n.value to also requiring the root residual to be empty, which disables row-group and page-index pruning for valid rows such as {n: 5, extra: 7}. Please keep the all-null proof on the requested field's corresponding value column; ancestor overflow cannot shadow that shredded key in a conforming Parquet Variant.

request.count_star_placeholder_columns;
VariantRowGroupProjectionCounts variant_projection_counts;
if (file_context.contains_variant) {
const auto predicate_counts = finalize_variant_projections_for_row_group(

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.

[P2] Finalize the physical projection before row-group planning

finalize_native_row_group_read_plan() has already run with the leaf candidate before this fallback is applied. If this row group expands to the full Variant wrapper, newly added leaves are absent from the loaded OffsetIndexes, so their readers take the non-OffsetIndex path and walk page gaps even when page pruning produced sparse selected_ranges. The same ordering also makes a group pruned before reaching this line account FilteredBytes from the leaf candidate instead of the full physical request. Please build the row-group-local physical columns before pruning/page-index planning and use that shape for requested leaf IDs and avoided-byte accounting, while keeping the immutable logical request for conjunct semantics.

auto second_row_group = metadata.row_groups[0];
auto& root_residual = second_row_group.columns[2].meta_data.statistics;
DORIS_CHECK(root_residual.__isset.null_count);
root_residual.__set_null_count(second_row_group.num_rows - 1);

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.

[P2] Exercise real residual data in the fallback row group

This duplicates the first row group's Column Chunks and changes only footer null_count; the underlying terminal residual page is still all null. As a result, the test's rows, typed n values, and projection counters are unchanged even if reader construction or deferred I/O mistakenly keeps using the leaf-only request for the row group marked as full projection. Please use a real second row group with a non-null terminal fallback value and assert the value reconstructed from that branch, so the test fails when the row-group-scoped physical shape is ignored.

"""
assertEquals(2, deepProjectionRows.size())
String deepProjectionProfile = new ProfileAction(context).getProfileBySql(
deepProjectionToken, ["VariantLeafProjections"], 30000L, 500L)

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.

[P2] Assert the actual row-group projection outcome

VariantLeafProjections is now incremented from the candidate count in ParquetReader::open(), before any row-group residual statistics decide whether the candidate is retained. This fixture also writes tags/extra outside its shredding schema, so the root residual is populated and the current finalizer can full-project every row group while this assertion still passes. Poll VariantLeafProjectionRowGroupColumns (and ideally require VariantFullProjectionRowGroupColumns == 0) against a fully shredded fixture so an always-fallback regression cannot satisfy the test.

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Your access token could not be refreshed because your refresh token was already used. Please log out and sign in again.
Workflow run: https://github.com/apache/doris/actions/runs/31251838526

Please inspect the workflow logs and rerun the review after the underlying issue is resolved.

yiguolei
yiguolei previously approved these changes Aug 8, 2026
@yiguolei

yiguolei commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

run buildall

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Aug 8, 2026
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

1 similar comment
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions 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.

Review summary

Requesting changes for one P1 correctness defect and one P2 performance/resource regression:

  • Direct explode(v) access-path propagation erases the array-container transition, allowing a row-group leaf projection to omit root residual arrays that the generator must materialize.
  • Row-group planning deep-copies complete recursive projection/request state per candidate and retains the projection-bearing plan twice, multiplying planning CPU and memory for many-row-group, wide/deep scans.

Critical checkpoint conclusions:

  • Architecture and layering: FE segment comparison, BE access-tree construction, and exact object-key mapping are otherwise coherent, but the legacy untyped v/k boundary cannot represent that direct Variant explode consumes the root as an array.
  • Lifecycle and state: eager and queued planning, footer/dictionary/Bloom/PageIndex/OffsetIndex consumers, reader construction, EOF/reset, and aggregate paths use the intended logical or row-group physical request. No separate cursor, lifetime, or stale-plan correctness defect survived.
  • Schema, compatibility, and result correctness: for genuine object-key descent, the Parquet Variant shredding contract supports checking only the corresponding terminal fallback. That proof does not apply after generator provenance is erased; valid heterogeneous external files can then fail direct explode.
  • Filtering and pruning: footer and page-index statistics remain conservative for supported object paths, including missing, repeated, contradictory, or non-all-null terminal metadata. No distinct pruning defect remains beyond the accepted generator case.
  • Performance and observability: pruning totals and the new opened-row-group projection counters are correctly updated. The accepted P2 is the unbounded recursive copy/dual-retention representation, not a counter-total defect.
  • Tests: the patch substantially improves mixed-row-group and external Paimon/Iceberg outcome coverage. It still lacks a direct-explode heterogeneous shredded fixture and a many-row-group, wide/deep planning regression check.
  • User focus: no additional focus was provided; all 21 changed files and their production/runtime consumers were reviewed.
  • Validation: static review only, as required by the task; no build, test, or source modification was performed.

Completion status: CONVERGED in Round 2. Three full-coverage reviewers and two targeted adversarial reviewers reported no new distinct finding in the convergence round; every candidate is accepted, dismissed, or deduplicated.

Comment thread be/src/format_v2/parquet/parquet_reader.cpp
Comment thread be/src/format_v2/parquet/parquet_scan.cpp Outdated
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot removed the approved Indicates a PR has been approved by one committer. label Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants