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

@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 previously approved these changes Jul 9, 2026

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

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29975 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit fb7a8dfb66da7c750db6101d2dd6c2bb38331e90, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17608	4254	4172	4172
q2	2064	345	216	216
q3	10251	1459	870	870
q4	4686	479	342	342
q5	7532	876	588	588
q6	189	173	140	140
q7	782	879	628	628
q8	9366	1653	1559	1559
q9	5724	4413	4428	4413
q10	6767	1796	1520	1520
q11	502	347	328	328
q12	736	558	439	439
q13	18074	3458	2811	2811
q14	269	267	236	236
q15	q16	800	785	718	718
q17	1044	978	957	957
q18	6946	5730	5641	5641
q19	1194	1259	1072	1072
q20	726	646	566	566
q21	5521	2579	2456	2456
q22	434	362	303	303
Total cold run time: 101215 ms
Total hot run time: 29975 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4423	4500	4432	4432
q2	305	325	216	216
q3	4596	4985	4412	4412
q4	2134	2237	1381	1381
q5	4507	4373	4405	4373
q6	237	175	129	129
q7	1739	2842	1707	1707
q8	2597	2264	2244	2244
q9	8004	7996	7764	7764
q10	4774	4747	4298	4298
q11	609	415	413	413
q12	759	768	630	630
q13	3112	3390	2796	2796
q14	287	288	257	257
q15	q16	699	723	613	613
q17	1311	1308	1280	1280
q18	7465	7109	7043	7043
q19	1089	1076	1071	1071
q20	2215	2223	1980	1980
q21	5327	4713	4678	4678
q22	535	479	399	399
Total cold run time: 56724 ms
Total hot run time: 52116 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 181241 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit fb7a8dfb66da7c750db6101d2dd6c2bb38331e90, data reload: false

query5	4318	630	493	493
query6	460	233	216	216
query7	4861	611	338	338
query8	349	194	172	172
query9	8786	4104	4151	4104
query10	473	350	297	297
query11	5823	2365	2155	2155
query12	173	106	103	103
query13	1269	631	442	442
query14	6281	5342	5022	5022
query14_1	4332	4368	4318	4318
query15	219	210	186	186
query16	1034	484	499	484
query17	943	753	601	601
query18	2459	471	337	337
query19	208	185	149	149
query20	109	106	108	106
query21	227	154	133	133
query22	13666	13750	13328	13328
query23	17417	16620	16793	16620
query23_1	16311	16348	16276	16276
query24	7498	1838	1296	1296
query24_1	1297	1299	1301	1299
query25	539	443	357	357
query26	1333	351	223	223
query27	2567	591	372	372
query28	4453	2066	2057	2057
query29	1061	610	489	489
query30	340	259	222	222
query31	1128	1101	1028	1028
query32	104	61	64	61
query33	528	311	279	279
query34	1172	1121	657	657
query35	797	770	666	666
query36	1372	1352	1184	1184
query37	164	103	94	94
query38	1875	1705	1650	1650
query39	925	932	910	910
query39_1	890	872	874	872
query40	242	163	143	143
query41	66	62	61	61
query42	90	86	92	86
query43	319	325	296	296
query44	1507	780	777	777
query45	195	188	178	178
query46	1106	1207	726	726
query47	2426	2366	2204	2204
query48	410	415	308	308
query49	590	434	316	316
query50	1026	436	333	333
query51	10627	10921	10773	10773
query52	84	86	75	75
query53	270	281	208	208
query54	285	257	217	217
query55	75	71	65	65
query56	284	284	289	284
query57	1407	1426	1298	1298
query58	283	275	264	264
query59	1618	1675	1461	1461
query60	295	265	260	260
query61	159	149	150	149
query62	688	645	577	577
query63	250	199	204	199
query64	2867	1014	873	873
query65	4889	4806	4795	4795
query66	1824	504	386	386
query67	29588	29592	29356	29356
query68	3074	1579	1052	1052
query69	429	319	274	274
query70	1075	973	931	931
query71	344	341	300	300
query72	3067	2790	2576	2576
query73	850	789	423	423
query74	5261	4970	4787	4787
query75	2638	2606	2250	2250
query76	2338	1245	818	818
query77	369	397	304	304
query78	12349	12408	11791	11791
query79	1405	1164	813	813
query80	777	589	483	483
query81	487	331	284	284
query82	572	157	129	129
query83	397	329	312	312
query84	324	166	142	142
query85	1064	592	509	509
query86	412	295	297	295
query87	1836	1819	1756	1756
query88	3746	2839	2819	2819
query89	450	411	350	350
query90	1787	200	203	200
query91	200	191	161	161
query92	65	63	57	57
query93	1537	1527	952	952
query94	621	378	308	308
query95	784	571	476	476
query96	1031	791	375	375
query97	2695	2708	2563	2563
query98	212	209	209	209
query99	1162	1184	1019	1019
Total cold run time: 264882 ms
Total hot run time: 181241 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 25.11 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit fb7a8dfb66da7c750db6101d2dd6c2bb38331e90, data reload: false

query1	0.00	0.00	0.00
query2	0.10	0.05	0.05
query3	0.25	0.14	0.12
query4	1.60	0.14	0.14
query5	0.25	0.27	0.22
query6	1.24	1.11	1.09
query7	0.05	0.01	0.01
query8	0.06	0.04	0.03
query9	0.38	0.32	0.31
query10	0.58	0.55	0.58
query11	0.19	0.15	0.14
query12	0.19	0.14	0.13
query13	0.47	0.48	0.47
query14	1.00	1.01	1.01
query15	0.61	0.60	0.60
query16	0.32	0.32	0.33
query17	1.14	1.11	1.12
query18	0.23	0.21	0.21
query19	2.03	1.98	1.95
query20	0.02	0.01	0.02
query21	15.46	0.23	0.14
query22	4.75	0.06	0.05
query23	16.13	0.31	0.13
query24	2.89	0.44	0.32
query25	0.11	0.07	0.04
query26	0.75	0.20	0.15
query27	0.03	0.04	0.03
query28	3.53	0.87	0.51
query29	12.56	4.05	3.25
query30	0.27	0.15	0.16
query31	2.78	0.58	0.32
query32	3.24	0.58	0.50
query33	3.18	3.34	3.20
query34	15.68	4.27	3.53
query35	3.50	3.55	3.52
query36	0.56	0.44	0.41
query37	0.09	0.06	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.18	0.16
query41	0.09	0.04	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.66 s
Total hot run time: 25.11 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 56.52% (13/23) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 72.97% (29240/40074)
Line Coverage 56.60% (316103/558528)
Region Coverage 53.07% (263108/495802)
Branch Coverage 54.10% (115431/213354)

@csun5285 csun5285 force-pushed the fix-topn-pruned-struct-merge branch from fb7a8df to 26bb98e Compare July 13, 2026 02:20
@github-actions github-actions Bot removed the approved Indicates a PR has been approved by one committer. label Jul 13, 2026
@csun5285

Copy link
Copy Markdown
Contributor Author

run buildall

@csun5285

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.

I found one remaining test-coverage issue. The storage/query-reader changes themselves look consistent after tracing the pruned complex type path from FE access paths through TabletSchema, SegmentIterator pruning, BetaRowsetReader, VMergeIteratorContext block creation, and AGG_KEYS reader aggregation.

Critical checkpoint conclusions:

  • Goal/test proof: the code appears to implement the intended pruned complex-column merge/agg read fix, but the new regression does not reliably force one of the target paths because a separate fuzzy session gate is not pinned.
  • Scope/focus: the implementation is focused on the block type mismatch and aggregate-function argument typing; no unrelated behavior or persistence format change found.
  • Concurrency/lifecycle: no new shared-state race found. The pruned-type map pointer is backed by the rowset reader's StorageReadOptions TabletSchemaSPtr during iterator lifetime.
  • Compatibility/persistence: no persisted schema or mixed-version serialization change found. Aggregate-state handling still routes through the existing BE exec-version compatibility path.
  • Parallel paths: load, schema-change, vertical compaction, segcompaction, query BlockReader, and VMerge paths were checked. The remaining issue is test path selection, not source logic.
  • Tests: BE UT covers pruned VMerge block shape; regression covers default TopN, inline TopN, and AGG_KEYS reads, but the inline TopN portion needs the segment-limit gate pinned. The existing line-100 thread already covers the separate missing num_segments > 1 assertion, so I did not duplicate it.

Validation was static only per the review prompt; I did not run builds or tests.

// 2. Force the inline topn scan path (no VMaterializeNode). This is the exact
// path that used to fail with
// "[E-3110] Method insert_many_dict_data is not supported for TINYINT".
sql "SET topn_lazy_materialization_threshold = -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.

This still does not fully force the repaired inline TopN/VMergeIterator path. The test disables TopN lazy materialization, but the storage ordered-key read is gated separately by enable_segment_limit_pushdown: OlapScanner only sets read_orderby_key/read_orderby_key_limit when that flag participates in can_push_down_segment_limit, and the variable is fuzzy/randomized in regression runs. If it is false, this DUP_KEYS scan keeps need_ordered_result=false, so BetaRowsetReader::is_merge_iterator() will not select VMergeIterator even if the rowset is overlapping and multi-segment, and these value checks can pass through the normal scan path. Please pin this section with SET enable_segment_limit_pushdown = true (or a SET_VAR hint) before the inline TopN assertions so the regression always exercises the path this fix targets.

@csun5285 csun5285 force-pushed the fix-topn-pruned-struct-merge branch from 26bb98e to d6e68bf Compare July 13, 2026 02:54
@csun5285

Copy link
Copy Markdown
Contributor Author

run buildall

@csun5285

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.

Static review completed. I found two regression-test issues that should be fixed before this lands: the deterministic SQL value checks should use qt/order_qt baselines with a generated .out file, and the suite should not drop the tables at the end after already dropping them before setup.

Implementation checkpoints: I did not find a correctness issue in the pruned complex-column type propagation into VMergeIterator, and the TabletSchema lifetime is held through the reader options on the production path. The aggregate-function type change also looks aligned: BlockReader now uses the actual stored/pruned block type, while load, vertical compaction, and schema-change paths use full-schema blocks and full-schema types. I did not identify new concurrency, storage lock-order, persistence, compatibility, or observability concerns in the changed implementation.

Test/duplicate context: existing thread r3544580724 still covers the missing num_segments > 1 proof, so I did not duplicate it. Existing thread r3567770409 appears resolved by SET enable_segment_limit_pushdown = true. No additional user focus was provided. Review was static only per the review-only runner instructions; I did not run builds or tests.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29883 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit d6e68bf4d5c7142db3234ba1ae51c44c5bc90517, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17787	4248	4238	4238
q2	2027	337	211	211
q3	10268	1437	809	809
q4	4688	477	343	343
q5	7558	857	584	584
q6	192	179	139	139
q7	789	850	688	688
q8	9369	1515	1623	1515
q9	5648	4445	4425	4425
q10	6649	1809	1525	1525
q11	514	344	319	319
q12	691	564	440	440
q13	18100	3397	2761	2761
q14	270	275	250	250
q15	q16	799	791	714	714
q17	1041	1030	964	964
q18	7065	5743	5542	5542
q19	1360	1281	1113	1113
q20	775	687	532	532
q21	5887	2598	2472	2472
q22	450	369	299	299
Total cold run time: 101927 ms
Total hot run time: 29883 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4527	4341	4435	4341
q2	301	321	224	224
q3	4602	4987	4408	4408
q4	2043	2161	1349	1349
q5	4450	4324	4304	4304
q6	248	178	128	128
q7	1722	2165	1759	1759
q8	2577	2338	2225	2225
q9	8093	8097	7915	7915
q10	4759	4727	4286	4286
q11	581	439	411	411
q12	772	764	536	536
q13	3254	3594	2954	2954
q14	311	302	272	272
q15	q16	720	745	632	632
q17	1375	1358	1502	1358
q18	7750	7265	7195	7195
q19	1156	1077	1084	1077
q20	2218	2208	1925	1925
q21	5259	4750	4564	4564
q22	533	451	417	417
Total cold run time: 57251 ms
Total hot run time: 52280 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 180666 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit d6e68bf4d5c7142db3234ba1ae51c44c5bc90517, data reload: false

query5	4315	657	501	501
query6	463	214	204	204
query7	4838	619	344	344
query8	337	187	191	187
query9	8767	4143	4058	4058
query10	484	353	302	302
query11	5913	2373	2142	2142
query12	151	104	103	103
query13	1244	641	438	438
query14	6303	5292	4992	4992
query14_1	4320	4317	4307	4307
query15	217	213	185	185
query16	995	503	464	464
query17	1050	742	598	598
query18	2477	477	347	347
query19	210	201	156	156
query20	117	111	109	109
query21	233	157	143	143
query22	13639	13585	13521	13521
query23	17679	16528	16180	16180
query23_1	16337	16397	16318	16318
query24	7575	1764	1322	1322
query24_1	1358	1315	1313	1313
query25	580	467	400	400
query26	1340	380	221	221
query27	2545	566	378	378
query28	4482	1997	2029	1997
query29	1100	639	518	518
query30	346	271	226	226
query31	1123	1098	991	991
query32	112	65	63	63
query33	534	336	266	266
query34	1167	1122	647	647
query35	782	771	688	688
query36	1406	1379	1199	1199
query37	155	108	94	94
query38	1883	1740	1651	1651
query39	920	932	886	886
query39_1	867	894	878	878
query40	238	158	141	141
query41	67	64	63	63
query42	93	94	99	94
query43	321	321	294	294
query44	1452	783	769	769
query45	200	193	178	178
query46	1064	1185	733	733
query47	2337	2307	2235	2235
query48	385	409	300	300
query49	567	441	310	310
query50	1089	398	349	349
query51	10919	10899	10665	10665
query52	85	87	82	82
query53	262	274	206	206
query54	275	226	228	226
query55	76	74	66	66
query56	277	277	295	277
query57	1443	1402	1283	1283
query58	283	260	266	260
query59	1566	1625	1422	1422
query60	308	271	248	248
query61	152	141	153	141
query62	694	651	587	587
query63	259	208	206	206
query64	2857	1057	833	833
query65	4827	4779	4763	4763
query66	1880	503	388	388
query67	29544	29713	29411	29411
query68	3253	1510	986	986
query69	403	298	275	275
query70	1082	999	958	958
query71	337	327	305	305
query72	3085	2714	2574	2574
query73	834	738	402	402
query74	5106	4968	4776	4776
query75	2620	2614	2227	2227
query76	2328	1212	808	808
query77	346	381	289	289
query78	12416	12261	11828	11828
query79	1370	1087	774	774
query80	737	546	454	454
query81	487	329	291	291
query82	556	158	127	127
query83	367	324	288	288
query84	313	159	127	127
query85	957	606	511	511
query86	404	277	285	277
query87	1834	1817	1763	1763
query88	3676	2820	2822	2820
query89	463	413	355	355
query90	1889	201	200	200
query91	198	194	161	161
query92	62	61	54	54
query93	1523	1501	1051	1051
query94	607	375	325	325
query95	793	506	556	506
query96	1091	828	354	354
query97	2670	2694	2528	2528
query98	219	211	205	205
query99	1138	1169	1051	1051
Total cold run time: 265428 ms
Total hot run time: 180666 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.98 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit d6e68bf4d5c7142db3234ba1ae51c44c5bc90517, data reload: false

query1	0.01	0.01	0.01
query2	0.10	0.05	0.06
query3	0.25	0.14	0.13
query4	1.60	0.14	0.15
query5	0.28	0.23	0.23
query6	1.23	1.10	1.03
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.39	0.32	0.33
query10	0.56	0.57	0.56
query11	0.20	0.14	0.14
query12	0.18	0.14	0.14
query13	0.47	0.47	0.47
query14	1.00	1.00	1.01
query15	0.61	0.58	0.59
query16	0.31	0.34	0.32
query17	1.09	1.08	1.12
query18	0.23	0.21	0.21
query19	2.02	1.95	2.01
query20	0.02	0.01	0.01
query21	15.48	0.20	0.13
query22	4.96	0.05	0.06
query23	16.15	0.31	0.12
query24	2.97	0.43	0.32
query25	0.11	0.05	0.04
query26	0.73	0.22	0.16
query27	0.05	0.04	0.04
query28	3.53	0.88	0.53
query29	12.53	4.08	3.21
query30	0.28	0.15	0.15
query31	2.77	0.60	0.31
query32	3.24	0.59	0.48
query33	3.28	3.19	3.16
query34	15.46	4.30	3.54
query35	3.53	3.52	3.54
query36	0.56	0.43	0.44
query37	0.08	0.06	0.07
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.16	0.16
query41	0.08	0.03	0.04
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.78 s
Total hot run time: 24.98 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 86.96% (20/23) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 56.92% (23557/41385)
Line Coverage 40.59% (230387/567586)
Region Coverage 36.50% (182064/498845)
Branch Coverage 37.58% (81285/216309)

…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 d6e68bf to 3c43f4c Compare July 13, 2026 07:59
@csun5285

Copy link
Copy Markdown
Contributor Author

/review

@csun5285

Copy link
Copy Markdown
Contributor Author

run buildall

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

Static review completed for the current patch. I did not find a new blocking issue to raise.

Checkpoint conclusions:

  • Goal/test coverage: The change targets pruned nested complex-column reads where VMergeIterator and AGG reader aggregation previously built full-type blocks/functions while the segment sub-iterators had been pruned. The C++ fix aligns VMergeIterator block construction and AGG reader aggregate-function argument types with the actual pruned block type. Coverage now includes a focused BE unit test plus a regression test for inline TopN/VMergeIterator and AGG merge reads.
  • Scope/minimality: The implementation is limited to aggregate-function type plumbing, merge iterator block materialization, and targeted tests.
  • Concurrency/lifecycle: No new locks, threads, or persistent lifecycle states were introduced. The pruned-type map is held on the scanner's copied TabletSchema and is carried through reader options for the iterator lifetime.
  • Compatibility/persistence: No storage-format, FE-BE protocol, or edit-log compatibility change is introduced. Non-query load, schema-change, and compaction paths continue to use full tablet-column types.
  • Parallel paths: I checked query merge/union/direct behavior, AGG reader aggregation, MemTable load aggregation, schema-change MultiBlockMerger, vertical compaction, and aggregate-state UNION handling; no missed equivalent path was substantiated.
  • Tests: The current regression addresses the existing review-thread concerns: it asserts OVERLAPPING plus num_segments > 1, pins enable_segment_limit_pushdown for the inline TopN path, uses qt_* output backed by the generated .out file, and avoids final table drops. No additional user focus was provided.

Validation limits: This was a static review only. Per the review prompt I did not run builds or tests; the checkout is also shallow and lacks .worktree_initialized/thirdparty/installed.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29440 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 3c43f4cd96d8041713391701fe6746c40fba6708, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17685	4033	4128	4033
q2	2073	319	219	219
q3	10270	1443	800	800
q4	4685	515	343	343
q5	7570	902	580	580
q6	179	172	139	139
q7	791	831	639	639
q8	9323	1533	1470	1470
q9	5677	4413	4408	4408
q10	6753	1818	1538	1538
q11	505	344	316	316
q12	689	551	423	423
q13	18080	3415	2779	2779
q14	261	260	234	234
q15	q16	789	785	711	711
q17	987	1018	894	894
q18	6903	5738	5596	5596
q19	1308	1399	1017	1017
q20	755	633	549	549
q21	5911	2668	2453	2453
q22	435	361	299	299
Total cold run time: 101629 ms
Total hot run time: 29440 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4347	4225	4275	4225
q2	286	315	210	210
q3	4612	4967	4401	4401
q4	2069	2141	1350	1350
q5	4470	4312	4319	4312
q6	228	178	127	127
q7	1718	1905	1766	1766
q8	2656	2221	2188	2188
q9	7973	8271	7860	7860
q10	4766	4709	4271	4271
q11	571	431	402	402
q12	750	766	546	546
q13	3352	3558	2915	2915
q14	300	312	290	290
q15	q16	742	777	651	651
q17	1311	1311	1292	1292
q18	7903	7321	7262	7262
q19	1133	1112	1046	1046
q20	2198	2208	1926	1926
q21	5251	4551	4393	4393
q22	557	455	395	395
Total cold run time: 57193 ms
Total hot run time: 51828 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 181615 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 3c43f4cd96d8041713391701fe6746c40fba6708, data reload: false

query5	4341	667	519	519
query6	470	213	210	210
query7	4877	620	327	327
query8	348	197	176	176
query9	8777	4138	4100	4100
query10	489	372	308	308
query11	5874	2418	2184	2184
query12	159	106	101	101
query13	1271	592	452	452
query14	6289	5399	5083	5083
query14_1	4448	4410	4386	4386
query15	217	211	182	182
query16	998	476	455	455
query17	928	738	565	565
query18	2454	477	348	348
query19	198	200	160	160
query20	115	110	106	106
query21	222	160	137	137
query22	13659	13658	13312	13312
query23	17460	16607	16123	16123
query23_1	16306	16322	16148	16148
query24	7621	1824	1323	1323
query24_1	1330	1292	1303	1292
query25	583	493	432	432
query26	1325	374	211	211
query27	2598	596	374	374
query28	4451	2041	2037	2037
query29	1111	656	534	534
query30	347	269	241	241
query31	1130	1103	1004	1004
query32	115	66	62	62
query33	533	344	277	277
query34	1174	1188	650	650
query35	792	810	683	683
query36	1412	1379	1187	1187
query37	160	115	98	98
query38	1886	1709	1654	1654
query39	927	906	893	893
query39_1	875	879	865	865
query40	256	171	152	152
query41	74	71	70	70
query42	98	94	95	94
query43	340	345	293	293
query44	1477	807	803	803
query45	221	196	179	179
query46	1050	1208	771	771
query47	2360	2350	2290	2290
query48	406	422	317	317
query49	610	461	348	348
query50	1038	437	337	337
query51	10722	10596	10663	10596
query52	88	91	78	78
query53	264	283	206	206
query54	313	276	241	241
query55	78	75	70	70
query56	331	306	321	306
query57	1430	1419	1336	1336
query58	300	268	264	264
query59	1639	1735	1454	1454
query60	329	289	262	262
query61	182	174	180	174
query62	703	699	599	599
query63	244	210	209	209
query64	2801	1058	887	887
query65	4908	4807	4771	4771
query66	1814	533	405	405
query67	29710	29356	29351	29351
query68	3290	1609	961	961
query69	458	312	262	262
query70	1086	993	937	937
query71	354	320	301	301
query72	3137	2755	2472	2472
query73	865	801	432	432
query74	5110	4954	4780	4780
query75	2760	2672	2278	2278
query76	2320	1285	858	858
query77	369	389	298	298
query78	12336	12477	11651	11651
query79	1401	1188	773	773
query80	1275	582	461	461
query81	524	321	276	276
query82	602	164	124	124
query83	367	328	291	291
query84	323	158	131	131
query85	966	591	569	569
query86	438	307	277	277
query87	1852	1829	1763	1763
query88	3787	2801	2807	2801
query89	460	408	364	364
query90	1945	209	212	209
query91	207	193	165	165
query92	67	63	53	53
query93	1674	1551	965	965
query94	737	337	329	329
query95	773	498	452	452
query96	1039	761	361	361
query97	2719	2683	2588	2588
query98	219	217	210	210
query99	1140	1185	986	986
Total cold run time: 267069 ms
Total hot run time: 181615 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.88 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 3c43f4cd96d8041713391701fe6746c40fba6708, data reload: false

query1	0.00	0.00	0.01
query2	0.09	0.05	0.05
query3	0.25	0.14	0.13
query4	1.61	0.14	0.16
query5	0.24	0.23	0.21
query6	1.23	1.03	1.04
query7	0.03	0.01	0.00
query8	0.05	0.04	0.04
query9	0.37	0.30	0.32
query10	0.54	0.55	0.55
query11	0.19	0.14	0.13
query12	0.18	0.15	0.14
query13	0.46	0.47	0.48
query14	1.03	1.02	1.01
query15	0.61	0.59	0.60
query16	0.31	0.33	0.32
query17	1.08	1.10	1.09
query18	0.22	0.22	0.20
query19	2.05	2.01	2.00
query20	0.02	0.01	0.01
query21	15.44	0.20	0.13
query22	4.96	0.06	0.05
query23	16.17	0.32	0.11
query24	2.87	0.42	0.32
query25	0.10	0.05	0.03
query26	0.76	0.21	0.15
query27	0.04	0.04	0.04
query28	3.50	0.93	0.55
query29	12.50	3.98	3.18
query30	0.27	0.15	0.15
query31	2.76	0.59	0.31
query32	3.24	0.59	0.48
query33	3.21	3.18	3.24
query34	15.44	4.25	3.50
query35	3.53	3.51	3.55
query36	0.55	0.42	0.43
query37	0.09	0.06	0.06
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.09	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.42 s
Total hot run time: 24.88 s

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants