Skip to content

[fix](storage) align pruned complex column types with sub-column iterators on merge/agg read paths#65396

Open
csun5285 wants to merge 1 commit into
apache:masterfrom
csun5285:fix-topn-pruned-struct-merge
Open

[fix](storage) align pruned complex column types with sub-column iterators on merge/agg read paths#65396
csun5285 wants to merge 1 commit into
apache:masterfrom
csun5285:fix-topn-pruned-struct-merge

Conversation

@csun5285

@csun5285 csun5285 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor
  1. VMergeIteratorContext::block_reset built per-segment merge blocks from the storage Schema (full type). A topn ordered read over a rowset with multiple OVERLAPPING segments then decoded pruned children into the wrong dst columns

  2. BlockReader::_init_agg_state built the reader_replace argument type from the raw TabletColumn (full type) while the stored block uses the pruned type. On AGG tables any pruned read that goes through the aggregate merge path (>= 2 data rowsets, no special session vars needed) failed with "Aggregate function reader_replace argument 0 type check failed: ColumnStruct has 2 elements, but DataTypeStruct has 3 elements".

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

Release note

None

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.
  • 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

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

@csun5285

csun5285 commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@csun5285

csun5285 commented Jul 8, 2026

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 result: requesting changes for one regression-test oracle issue.

Critical checkpoint conclusions:

  • Goal/correctness: the C++ change threads pruned complex-column data types through the query scan schema, merge iterator, and aggregate reader paths; I did not find an additional functional bug in those inspected paths.
  • Scope: the implementation is focused on query-pruned type propagation plus one regression test.
  • Concurrency/lifecycle: no new thread, lock, static initialization, or ownership lifecycle risk was introduced by the changed code.
  • Compatibility/persistence/config: no new persisted format, FE-BE protocol field, or config item was added; the pruned-column type map is query-local and shawdow_copy_without_columns clears it.
  • Parallel paths: TopN merge-reader, aggregate reader, ordinary materialization/rowid fetch, and compaction/vertical-reader paths were checked. Compaction/vertical paths do not use query-pruned maps.
  • Tests: the regression targets the right failure family, but its layout self-check does not prove the rowset has more than one segment, which is required to select VMergeIterator.
  • Validation: static review only. This checkout is shallow/missing the base SHA, .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc, so I did not build or run regression tests.
  • User focus: no additional user-provided review focus was present.

Subagent conclusions: optimizer-rewrite reported no valuable findings. tests-session-config proposed TSC-001, accepted as MAIN-001 and submitted inline. Convergence round 1 ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the same final ledger/comment set.

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 45.10% (23/51) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.54% (23211/41055)
Line Coverage 40.10% (225250/561730)
Region Coverage 36.05% (177908/493515)
Branch Coverage 37.11% (79085/213135)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 78.43% (40/51) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.09% (29290/40075)
Line Coverage 56.69% (316604/558513)
Region Coverage 53.20% (263672/495601)
Branch Coverage 54.25% (115749/213370)

@csun5285 csun5285 force-pushed the fix-topn-pruned-struct-merge branch 4 times, most recently from 6141226 to 7cad469 Compare July 9, 2026 07:46
@csun5285 csun5285 requested a review from luwei16 as a code owner July 9, 2026 07:46
@csun5285 csun5285 force-pushed the fix-topn-pruned-struct-merge branch 4 times, most recently from d69fffb to ac507fb Compare July 9, 2026 08:15
@csun5285

csun5285 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@csun5285

csun5285 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

/review

…ators on merge/agg read paths

When a query prunes nested sub-columns of a complex column (EXPLAIN shows
"pruned type"), the scan's struct sub-column iterators are filtered down to
the pruned subset (set_access_paths + remove_pruned_sub_iterators), while the
FE-pruned data type is recorded only in TabletSchema::_pruned_columns_data_type
and honored only by TabletSchema::create_block*. Read paths that materialize
column shapes from other sources still used the FULL storage type, so the
positional pairing in StructFileColumnIterator::next_batch worked on two
different ordinal spaces:

1. VMergeIteratorContext::block_reset built per-segment merge blocks from the
   storage Schema (full type). A topn ordered read over a rowset with multiple
   OVERLAPPING segments then decoded pruned children into the wrong dst
   columns:
   - "[E-3110] Method insert_many_dict_data is not supported for TINYINT"
     (dict-encoded text child decoded into a tinyint child)
   - "... is not supported for INT" (single-child pruning variant)
   - BE SIGSEGV when the shifted child types happen to match and the loop
     runs past the pruned iterator vector (same family as DORIS-26595)
   This is the root cause of DORIS-26889: the CI's s3 insert naturally
   produces overlapping multi-segment rowsets, while single-segment local
   loads never take the merge path. On master the default plan usually
   shields this path via TopN lazy materialization (apache#63736 + apache#64242), but
   e.g. raising topn_opt_limit_threshold, disabling
   topn_lazy_materialization_threshold, or light_schema_change=false tables
   expose it; branch-4.1 hits it by default.

2. BlockReader::_init_agg_state built the reader_replace argument type from
   the raw TabletColumn (full type) while the stored block uses the pruned
   type. On AGG tables any pruned read that goes through the aggregate merge
   path (>= 2 data rowsets, no special session vars needed) failed with
   "Aggregate function reader_replace argument 0 type check failed:
   ColumnStruct has 2 elements, but DataTypeStruct has 3 elements".

Fix: make the shape-materializing read paths use the same FE-pruned type as
the sub-column iterators, so dst blocks and iterators stay in one ordinal
space by construction.
- VMergeIteratorContext::init reads the FE-pruned complex types from
  StorageReadOptions::tablet_schema (TabletSchema::pruned_columns_data_type(),
  already set on the query read path), and block_reset then builds each merge
  block with the pruned type for pruned columns and the full storage type for
  the rest, so the block's struct children align with the pruned sub-column
  iterators. No new plumbing through the merge iterator or the storage Schema.
- TabletColumn::get_aggregate_function now takes the column's actual data type
  explicitly. BlockReader::_init_agg_state passes the stored block's column
  type (already the pruned type for pruned complex columns), while the
  load/compaction/schema-change paths pass the full column type.

The new regression case constructs an OVERLAPPING multi-segment rowset
deterministically (MemTable.need_flush debug point + NULL keys in every
batch, segment count kept below the segcompaction threshold), self-checks the
layout via tablet meta, and covers all variants: the dict-error and
SIGSEGV topn shapes on the inline path, the AGG default-session shape across
two rowsets, and the VMaterializeNode default path as a guard. All variants
fail before this fix and pass after it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@csun5285 csun5285 force-pushed the fix-topn-pruned-struct-merge branch from ac507fb to fb7a8df Compare July 9, 2026 08:22
@csun5285

csun5285 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@csun5285

csun5285 commented Jul 9, 2026

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 result: no new distinct inline comments in this pass. The existing line-100 thread remains the only actionable issue I found, and I did not duplicate it.

Critical checkpoint conclusions:

  • Goal/correctness: the PR aligns FE-pruned complex-column types with the merge block and aggregate-reader function paths. I checked the scan setup, TabletReader, BetaRowsetReader, VMergeIteratorContext, BlockReader::_init_agg_state, rowid-fetch materialization, and compaction/schema-change call sites; I found no additional correctness issue.
  • Scope: the implementation is focused on pruned type propagation plus one regression test.
  • Concurrency/lifecycle: no new thread, lock, static initialization, or storage lifetime risk was introduced; the pruned type map is query-local and read through the tablet schema held by the reader path.
  • Compatibility/config/persistence: no new persisted format, FE-BE protocol field, or config item was added.
  • Parallel paths: query TopN merge and AGG reader paths use the pruned block/type shape; load, schema-change, and vertical compaction callers continue to pass full storage types.
  • Tests: the regression covers default materialization, forced inline TopN, and AGG merge reads. The remaining test oracle gap is already covered by existing thread discussion_r3544580724: line 100 still checks only segments_overlap_pb and should also assert num_segments > 1.
  • Validation: static review only. This checkout is shallow and lacks .worktree_initialized, thirdparty/installed, and thirdparty/installed/bin/protoc, so I did not build or run regression tests. I refreshed the live PR head (fb7a8dfb66da7c750db6101d2dd6c2bb38331e90); it differs from the local checkout only by comment wording in two C++ files.
  • User focus: no additional user-provided review focus was present.

Subagent conclusions: both required subagents reported only the duplicate of existing thread discussion_r3544580724. The main merge recorded that as MAIN-DUP-001 with no new proposed inline comments. Convergence round 2, after the live-head refresh, ended with both live subagents replying NO_NEW_VALUABLE_FINDINGS for the same ledger/comment set.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Codex completed, but no new pull request review was submitted for the current head SHA.
Workflow run: https://github.com/apache/doris/actions/runs/29004201867

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

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

LGTM

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 43.48% (10/23) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.63% (23253/41060)
Line Coverage 40.18% (225711/561785)
Region Coverage 36.08% (178134/493754)
Branch Coverage 37.15% (79189/213135)

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

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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

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

Labels

approved Indicates a PR has been approved by one committer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants