Skip to content

[improvement](parquet) Lazily materialize complex residual columns#65965

Open
Gabriel39 wants to merge 3 commits into
apache:masterfrom
Gabriel39:agent/parquet-complex-residual-lazy-materialization
Open

[improvement](parquet) Lazily materialize complex residual columns#65965
Gabriel39 wants to merge 3 commits into
apache:masterfrom
Gabriel39:agent/parquet-complex-residual-lazy-materialization

Conversation

@Gabriel39

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: #65921

Problem Summary:

The V2 Parquet scanner already evaluates single-column predicates round by round, but a multi-column residual (including the children of a compound AND) still caused every predicate column to be materialized before expression evaluation. Expression short circuiting therefore happened after Parquet decode/IO and could not avoid later-only columns.

This PR follows expression-triggered lazy materialization:

  • preserve conjunct order and split safe compound AND residuals into ordered expression stages;
  • record each stage's slot dependencies and materialize only the next reachable columns;
  • read later columns with the surviving selection, or skip them entirely when an earlier stage rejects the batch;
  • prefetch only the first reachable predicate stage;
  • retain the original eager path for stateful/error-sensitive expressions that are unsafe on selected rows;
  • add unit coverage and a Release microbenchmark scenario based on the Parquet benchmark framework from [bench](parquet) Add native reader microbenchmark matrix #65921.

Correctness/counter validation (6 input rows):

  • an earlier two-column AND child filters all rows: ReaderReadRows=12, ReaderSkipRows=6 (the third column is never decoded);
  • when 3 rows survive the first residual: the later column reads only those 3 rows (ReaderReadRows=15, ReaderSelectRows=3, ReaderSkipRows=3).

Release microbenchmark:

CPU: Intel Xeon Platinum 8457C, pinned to CPU 8
Build: RELEASE
Filter: ^ParquetReader/complex_residual_scan/plain/null_10/alternating/sel_10/
Protocol: 3 warmups, then A-B-B-A; 5 repetitions per group; min_time=1s

Pair 1 median CPU: before 1,377,041 ns; after 1,318,811 ns (-4.23%)
Pair 2 median CPU: before 2,140,937 ns; after 2,124,862 ns (-0.75%)
Paired geometric normalization: -2.50% CPU time
Selected rows: 1,460 in every run

The host had high concurrent load and CPU scaling enabled, so the paired groups and run conditions are reported explicitly rather than relying on wall time. Both A/B pairs improve in the same direction.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (Release microbenchmark above)
    • No need to test or manual test.
  • Behavior changed:

    • No. The SQL result is unchanged; only predicate-column materialization timing changes.
    • 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?

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@Gabriel39
Gabriel39 marked this pull request as ready for review July 23, 2026 11:39
@Gabriel39
Gabriel39 requested a review from yiguolei as a code owner July 23, 2026 11:39
@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Jul 28th, 2026 5:08 PM.
Workflow run: https://github.com/apache/doris/actions/runs/30003365048

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

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17603	4088	4071	4071
q2	2016	327	199	199
q3	10315	1456	832	832
q4	4681	462	337	337
q5	7506	848	561	561
q6	178	168	139	139
q7	803	819	617	617
q8	9342	1488	1543	1488
q9	5477	4289	4283	4283
q10	6757	1774	1459	1459
q11	498	353	318	318
q12	700	572	460	460
q13	18109	3427	2780	2780
q14	266	262	237	237
q15	q16	786	778	708	708
q17	1018	986	999	986
q18	6854	5896	5568	5568
q19	1329	1257	1036	1036
q20	786	645	583	583
q21	5974	2658	2324	2324
q22	434	352	309	309
Total cold run time: 101432 ms
Total hot run time: 29295 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4442	4369	4357	4357
q2	287	320	214	214
q3	4603	4920	4368	4368
q4	2061	2134	1394	1394
q5	4371	4263	4239	4239
q6	226	173	126	126
q7	1716	1615	2126	1615
q8	2598	2155	2142	2142
q9	7985	8218	7683	7683
q10	4704	4678	4156	4156
q11	546	399	369	369
q12	780	748	544	544
q13	3314	3654	2970	2970
q14	307	320	271	271
q15	q16	706	715	667	667
q17	1338	1364	1361	1361
q18	7887	7284	7248	7248
q19	1177	1122	1145	1122
q20	2220	2194	1927	1927
q21	5201	4648	4403	4403
q22	508	456	401	401
Total cold run time: 56977 ms
Total hot run time: 51577 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 177005 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 bbbdeb12d183a0e464926d0c8e5eafff5e8e61d5, data reload: false

query5	4317	636	487	487
query6	469	218	204	204
query7	4839	598	351	351
query8	346	188	167	167
query9	8780	4035	4005	4005
query10	494	354	299	299
query11	5930	2308	2191	2191
query12	163	103	100	100
query13	1272	615	453	453
query14	6271	5192	4829	4829
query14_1	4219	4218	4253	4218
query15	211	201	181	181
query16	1014	505	466	466
query17	1130	736	578	578
query18	2475	481	363	363
query19	217	196	149	149
query20	111	107	109	107
query21	236	159	138	138
query22	13542	13548	13334	13334
query23	17284	16463	16058	16058
query23_1	16195	16168	16141	16141
query24	7671	1804	1274	1274
query24_1	1298	1298	1312	1298
query25	571	457	389	389
query26	1323	356	225	225
query27	2580	596	385	385
query28	4431	2002	1991	1991
query29	1073	629	501	501
query30	343	264	225	225
query31	1125	1101	979	979
query32	105	65	61	61
query33	539	324	261	261
query34	1219	1154	650	650
query35	772	787	677	677
query36	1165	1211	1054	1054
query37	157	118	101	101
query38	1889	1706	1647	1647
query39	913	917	830	830
query39_1	836	839	829	829
query40	247	168	141	141
query41	66	64	64	64
query42	97	92	96	92
query43	327	332	283	283
query44	1478	758	766	758
query45	204	178	170	170
query46	1046	1190	751	751
query47	2072	2119	1966	1966
query48	378	389	280	280
query49	599	416	305	305
query50	1048	424	350	350
query51	10713	10602	10496	10496
query52	84	90	75	75
query53	267	273	200	200
query54	277	229	211	211
query55	73	73	67	67
query56	342	294	304	294
query57	1301	1299	1184	1184
query58	277	254	254	254
query59	1634	1643	1413	1413
query60	318	268	248	248
query61	153	151	147	147
query62	538	496	432	432
query63	244	198	199	198
query64	2797	1029	859	859
query65	4716	4656	4654	4654
query66	1814	546	380	380
query67	29311	29191	29036	29036
query68	3241	1556	1024	1024
query69	417	292	259	259
query70	1042	942	985	942
query71	389	317	323	317
query72	3026	2719	2329	2329
query73	843	753	417	417
query74	5055	4896	4727	4727
query75	2518	2518	2129	2129
query76	2319	1180	794	794
query77	341	380	268	268
query78	11858	11919	11254	11254
query79	1389	1117	742	742
query80	1310	551	461	461
query81	518	329	288	288
query82	636	157	120	120
query83	391	319	300	300
query84	276	153	129	129
query85	979	605	517	517
query86	430	296	256	256
query87	1842	1842	1762	1762
query88	3715	2795	2800	2795
query89	441	370	329	329
query90	1929	207	205	205
query91	204	197	160	160
query92	63	61	57	57
query93	1757	1550	1011	1011
query94	701	318	302	302
query95	790	522	474	474
query96	1022	810	345	345
query97	2633	2627	2492	2492
query98	213	208	204	204
query99	1095	1134	957	957
Total cold run time: 263757 ms
Total hot run time: 177005 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.10	0.05	0.05
query3	0.25	0.14	0.13
query4	1.61	0.13	0.13
query5	0.24	0.25	0.22
query6	1.21	1.04	1.10
query7	0.04	0.01	0.01
query8	0.06	0.04	0.04
query9	0.38	0.31	0.31
query10	0.55	0.54	0.57
query11	0.18	0.14	0.13
query12	0.18	0.14	0.13
query13	0.46	0.48	0.46
query14	1.02	1.00	1.02
query15	0.61	0.59	0.59
query16	0.31	0.32	0.32
query17	1.06	1.10	1.06
query18	0.22	0.20	0.21
query19	2.00	1.98	1.95
query20	0.01	0.01	0.01
query21	15.47	0.21	0.14
query22	4.88	0.05	0.06
query23	16.13	0.31	0.11
query24	2.98	0.44	0.33
query25	0.11	0.05	0.05
query26	0.72	0.21	0.14
query27	0.03	0.04	0.04
query28	3.58	0.95	0.52
query29	12.50	4.15	3.28
query30	0.29	0.15	0.17
query31	2.76	0.61	0.31
query32	3.21	0.59	0.49
query33	3.28	3.15	3.18
query34	15.49	4.18	3.51
query35	3.53	3.51	3.53
query36	0.55	0.43	0.43
query37	0.09	0.07	0.07
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.53 s
Total hot run time: 24.91 s

@Gabriel39
Gabriel39 force-pushed the agent/parquet-complex-residual-lazy-materialization branch from bbbdeb1 to 913663e Compare July 23, 2026 12:14
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: You've hit your usage limit. Visit https://chatgpt.com/codex/settings/usage to purchase more credits or try again at Jul 28th, 2026 5:08 PM.
Workflow run: https://github.com/apache/doris/actions/runs/30006206434

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

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17710	4011	4025	4011
q2	2059	321	191	191
q3	10261	1436	802	802
q4	4678	475	340	340
q5	7528	853	579	579
q6	192	178	140	140
q7	772	824	620	620
q8	9343	1502	1446	1446
q9	5565	4349	4348	4348
q10	6804	1770	1499	1499
q11	506	353	346	346
q12	717	583	444	444
q13	18141	3388	2786	2786
q14	265	280	247	247
q15	q16	796	787	714	714
q17	960	1018	1069	1018
q18	6800	5730	5567	5567
q19	1176	1355	976	976
q20	790	708	605	605
q21	5545	2581	2258	2258
q22	427	352	298	298
Total cold run time: 101035 ms
Total hot run time: 29235 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4420	4281	4319	4281
q2	298	318	211	211
q3	4561	4971	4414	4414
q4	2067	2147	1329	1329
q5	4384	4263	4288	4263
q6	226	171	127	127
q7	1737	1613	1776	1613
q8	2748	2242	2204	2204
q9	8076	8264	7813	7813
q10	4667	4663	4204	4204
q11	596	409	409	409
q12	758	770	541	541
q13	3269	3652	2858	2858
q14	306	304	302	302
q15	q16	757	744	659	659
q17	1354	1363	1355	1355
q18	8105	7434	7329	7329
q19	1170	1141	1136	1136
q20	2226	2226	1920	1920
q21	5234	4498	4374	4374
q22	522	441	395	395
Total cold run time: 57481 ms
Total hot run time: 51737 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 178100 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 913663edbed74febce5a2e8b80b683f59e8ba80d, data reload: false

query5	4325	631	478	478
query6	473	225	214	214
query7	4926	627	331	331
query8	337	185	164	164
query9	8783	4007	4019	4007
query10	482	356	310	310
query11	5926	2291	2115	2115
query12	165	102	103	102
query13	1272	558	433	433
query14	6232	5209	4891	4891
query14_1	4281	4245	4231	4231
query15	217	219	182	182
query16	1015	478	486	478
query17	947	745	582	582
query18	2467	482	349	349
query19	212	199	156	156
query20	108	112	105	105
query21	231	160	136	136
query22	13620	13640	13312	13312
query23	17404	16456	16183	16183
query23_1	16270	16130	16179	16130
query24	7764	1765	1292	1292
query24_1	1298	1289	1267	1267
query25	574	463	393	393
query26	1375	377	218	218
query27	2569	610	373	373
query28	4492	1982	1994	1982
query29	1079	625	487	487
query30	345	264	230	230
query31	1133	1091	991	991
query32	107	65	63	63
query33	531	321	252	252
query34	1203	1167	634	634
query35	792	793	676	676
query36	1199	1170	1093	1093
query37	159	116	99	99
query38	1889	1712	1662	1662
query39	918	878	839	839
query39_1	843	866	821	821
query40	238	162	144	144
query41	67	64	64	64
query42	94	90	92	90
query43	317	322	281	281
query44	1421	782	748	748
query45	194	187	176	176
query46	1065	1177	735	735
query47	2146	2127	1954	1954
query48	409	391	292	292
query49	572	419	316	316
query50	1065	447	369	369
query51	10518	10809	10554	10554
query52	86	84	72	72
query53	267	282	203	203
query54	276	226	229	226
query55	72	72	64	64
query56	307	285	279	279
query57	1312	1270	1211	1211
query58	292	266	261	261
query59	1592	1632	1435	1435
query60	304	274	253	253
query61	156	150	150	150
query62	553	502	428	428
query63	243	207	207	207
query64	2841	1075	874	874
query65	4755	4615	4640	4615
query66	1839	547	387	387
query67	29245	29274	29122	29122
query68	3005	1560	1015	1015
query69	422	313	266	266
query70	1048	939	966	939
query71	370	339	319	319
query72	3023	2678	2376	2376
query73	854	782	435	435
query74	5048	4905	4709	4709
query75	2533	2492	2115	2115
query76	2340	1173	752	752
query77	345	383	283	283
query78	11982	11889	11276	11276
query79	1433	1189	779	779
query80	636	557	456	456
query81	536	331	294	294
query82	576	155	120	120
query83	403	313	299	299
query84	331	162	126	126
query85	965	613	516	516
query86	356	292	272	272
query87	1822	1816	1740	1740
query88	3698	2802	2784	2784
query89	449	387	329	329
query90	1958	200	195	195
query91	200	189	169	169
query92	60	58	53	53
query93	1588	1566	1073	1073
query94	539	359	315	315
query95	764	600	473	473
query96	1070	768	358	358
query97	2619	2604	2513	2513
query98	217	214	196	196
query99	1093	1109	980	980
Total cold run time: 262744 ms
Total hot run time: 178100 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.05	0.04
query3	0.28	0.13	0.13
query4	1.61	0.13	0.14
query5	0.23	0.22	0.22
query6	1.19	1.05	1.07
query7	0.04	0.00	0.01
query8	0.06	0.04	0.04
query9	0.38	0.32	0.31
query10	0.55	0.56	0.61
query11	0.19	0.13	0.14
query12	0.19	0.15	0.14
query13	0.47	0.48	0.48
query14	1.02	1.01	1.01
query15	0.62	0.59	0.60
query16	0.31	0.34	0.32
query17	1.05	1.09	1.09
query18	0.24	0.21	0.21
query19	2.04	1.92	1.90
query20	0.02	0.02	0.01
query21	15.46	0.18	0.13
query22	4.97	0.05	0.05
query23	16.13	0.33	0.12
query24	2.91	0.43	0.33
query25	0.12	0.05	0.04
query26	0.72	0.21	0.16
query27	0.04	0.05	0.03
query28	3.51	0.94	0.53
query29	12.56	4.19	3.30
query30	0.27	0.15	0.15
query31	2.76	0.56	0.31
query32	3.23	0.58	0.48
query33	3.23	3.22	3.16
query34	15.53	4.23	3.56
query35	3.53	3.49	3.53
query36	0.55	0.43	0.45
query37	0.08	0.07	0.07
query38	0.05	0.04	0.03
query39	0.03	0.04	0.03
query40	0.18	0.16	0.16
query41	0.09	0.03	0.04
query42	0.04	0.02	0.02
query43	0.04	0.04	0.04
Total cold run time: 96.63 s
Total hot run time: 25.02 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 82.82% (135/163) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 57.99% (24522/42285)
Line Coverage 42.00% (244290/581579)
Region Coverage 37.90% (194086/512060)
Branch Coverage 39.01% (87385/224005)

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 85.89% (140/163) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 75.24% (31025/41234)
Line Coverage 59.71% (344979/577767)
Region Coverage 56.52% (290416/513865)
Branch Coverage 57.79% (129497/224097)

@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 status: incomplete formal convergence. The third and final permitted subagent round found the localized-CAST issue below, so the review did not reach an all-NO_NEW_VALUABLE_FINDINGS round. The three-round cap is exhausted; every candidate currently known has nevertheless been independently checked, deduplicated, and resolved in this review.

Checkpoint conclusions:

  • Goal and data correctness: staged lazy materialization is coherent for expressions that are correctly classified as selected-row safe, and the selection/cursor/delete invariants hold on the paths inspected. However, localized ordinary CAST nodes are misclassified and can now suppress a conversion error; see the inline request.
  • Scope and focus: all eight changed files and the relevant expression, ColumnMapper, reader, delete, and benchmark paths were reviewed. No additional user focus was provided.
  • Concurrency, lifecycle, and memory: scheduler state remains serial and request/row-group scoped; retained expression owners and reset behavior are sound, and the new scratch structures are bounded by predicate count.
  • Configuration, compatibility, protocol, persistence, transactions, and data writes: no such contracts are changed by this read-only Parquet scheduling patch.
  • Parallel paths and conditions: safe versus eager fallback, nested AND/OR, constants and nullable WHERE behavior, dense/select/skip cursor consumption, dictionary and direct filtering, virtual columns, position/equality deletes, empty batches, pending output, page/batch boundaries, and Row Group transitions were traced. No additional correctness defect was substantiated.
  • Tests and proof: the new scanner tests validate the bespoke two-stage harness, but do not prove the documented production arithmetic expression, an all-pass long chain, or a localized failing cast. The scenario matrix also does not assert its advertised total. No local build or test was run because the governing review-runner contract prohibits it. Current CI reports compile, BE/macOS UT, regression, formatter/style, coverage, secrets, and performance checks passing; the automated code-review check remains pending.
  • Error handling and observability: Status propagation is otherwise preserved. Existing counters expose reads/selects/skips and actual compaction, but not repeated no-op mapping walks.
  • Performance: the per-stage alignment loop is quadratic for high-survival chains. Separately, the PR's reported 2.50% improvement is inconclusive under the benchmark guide because the run used a high-load, CPU-scaling-enabled host, paired medians drift roughly 55%-61%, and no variability/confidence evidence is reported.

Please address the four inline issues before merge.

Comment thread be/benchmark/parquet/AGENTS.md Outdated
Comment thread be/benchmark/parquet/benchmark_parquet_reader.hpp Outdated
Comment thread be/src/format_v2/parquet/parquet_scan.cpp
Comment thread be/src/format_v2/parquet/parquet_scan.cpp
@Gabriel39
Gabriel39 force-pushed the agent/parquet-complex-residual-lazy-materialization branch from 913663e to 8eb8cdb Compare July 23, 2026 15:56
@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17635	4113	4084	4084
q2	2033	360	217	217
q3	10223	1475	856	856
q4	4719	469	342	342
q5	7696	863	570	570
q6	189	173	137	137
q7	790	840	628	628
q8	10110	1571	1564	1564
q9	5910	4315	4330	4315
q10	6819	1737	1470	1470
q11	510	361	330	330
q12	769	590	471	471
q13	18087	3723	2741	2741
q14	262	260	248	248
q15	q16	796	783	714	714
q17	1143	938	883	883
q18	6969	5861	5477	5477
q19	1278	1186	985	985
q20	814	693	617	617
q21	5725	2645	2436	2436
q22	429	352	306	306
Total cold run time: 102906 ms
Total hot run time: 29391 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4392	4377	4322	4322
q2	293	323	219	219
q3	4636	5005	4429	4429
q4	2173	2165	1347	1347
q5	4419	4290	4318	4290
q6	236	173	125	125
q7	2171	1905	1587	1587
q8	2534	2193	2143	2143
q9	8081	7974	8118	7974
q10	4764	4784	4273	4273
q11	837	418	375	375
q12	746	749	529	529
q13	3218	3662	3001	3001
q14	305	307	288	288
q15	q16	746	759	666	666
q17	1375	1433	1388	1388
q18	8092	7232	6856	6856
q19	1141	1081	1095	1081
q20	2232	2219	1961	1961
q21	5266	4585	4474	4474
q22	512	465	386	386
Total cold run time: 58169 ms
Total hot run time: 51714 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 177149 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 8eb8cdb0d881d5b40181daf9a2821201925962d5, data reload: false

query5	4315	633	467	467
query6	460	227	203	203
query7	4928	599	339	339
query8	336	193	170	170
query9	8772	4068	4019	4019
query10	462	368	305	305
query11	6944	2376	2186	2186
query12	155	109	103	103
query13	1257	620	434	434
query14	6663	5234	4889	4889
query14_1	4279	4270	4267	4267
query15	216	211	190	190
query16	1042	462	460	460
query17	1088	690	534	534
query18	2514	464	333	333
query19	215	182	147	147
query20	108	108	102	102
query21	229	153	131	131
query22	13563	13522	13296	13296
query23	17132	16465	16124	16124
query23_1	16146	16207	16144	16144
query24	7462	1741	1271	1271
query24_1	1306	1292	1273	1273
query25	545	451	378	378
query26	1097	329	214	214
query27	2617	565	385	385
query28	4430	2010	2024	2010
query29	1095	620	486	486
query30	344	272	235	235
query31	1118	1087	971	971
query32	111	65	61	61
query33	527	320	267	267
query34	1160	1163	642	642
query35	764	779	680	680
query36	1198	1197	1063	1063
query37	152	112	90	90
query38	1868	1707	1645	1645
query39	867	870	859	859
query39_1	832	833	839	833
query40	243	173	144	144
query41	71	73	74	73
query42	98	93	93	93
query43	319	321	292	292
query44	1393	779	760	760
query45	203	184	175	175
query46	1089	1195	698	698
query47	2152	2172	2057	2057
query48	414	426	298	298
query49	587	432	317	317
query50	1124	435	358	358
query51	10688	10512	10610	10512
query52	92	89	75	75
query53	259	276	206	206
query54	300	247	229	229
query55	77	71	65	65
query56	315	333	296	296
query57	1332	1308	1215	1215
query58	298	280	259	259
query59	1517	1631	1387	1387
query60	342	283	265	265
query61	180	168	172	168
query62	547	499	446	446
query63	241	210	209	209
query64	2649	1026	823	823
query65	4712	4625	4622	4622
query66	1770	501	381	381
query67	29229	29195	29022	29022
query68	3335	1599	1042	1042
query69	412	305	251	251
query70	1035	980	969	969
query71	363	349	300	300
query72	3000	2668	2426	2426
query73	835	807	434	434
query74	5044	4906	4675	4675
query75	2512	2489	2123	2123
query76	2317	1153	776	776
query77	345	356	278	278
query78	11879	11791	11329	11329
query79	2309	1124	776	776
query80	1681	556	461	461
query81	518	341	289	289
query82	607	151	116	116
query83	364	330	288	288
query84	282	161	130	130
query85	956	622	555	555
query86	462	276	286	276
query87	1822	1822	1739	1739
query88	3720	2802	2771	2771
query89	431	370	323	323
query90	1923	194	188	188
query91	202	201	165	165
query92	62	59	54	54
query93	1790	1548	977	977
query94	741	361	291	291
query95	762	509	576	509
query96	1102	778	350	350
query97	2621	2633	2510	2510
query98	215	209	200	200
query99	1082	1125	972	972
Total cold run time: 265583 ms
Total hot run time: 177149 ms

@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: request changes. Two new patch-scoped issues remain: staged residual decoding can suppress a strict-mode native conversion error, and the new complex-residual benchmark measures duplicate expression teardown.

Critical checkpoint conclusions:

  • Goal and proof: the patch does lazily materialize later residual columns for valid safe-AND workloads, and the added scan/profile tests exercise the intended staged path. It does not yet preserve the prior strict-cast error result for invalid later-column physical values; see the P1 inline comment.
  • Scope and focus: the implementation is generally focused across scheduler, profile, benchmark, documentation, and tests. No additional user-provided review focus was supplied.
  • Concurrency: no new shared cross-thread state, locks, atomics, or lock ordering are introduced; the new schedule, selection, and profile state are reader-scoped.
  • Lifecycle and static initialization: no cross-TU static-order issue was found. The benchmark's new expression ownership has a lifecycle defect: ReaderSession teardown happens after timing resumes and the context remains request-owned, producing the P2 inline comment.
  • Configuration: no configuration item is added. The P1 path is reachable through the existing query-session enable_strict_cast option, which is propagated to native Parquet materialization.
  • Compatibility: no function-symbol, storage-format, wire-protocol, or rolling-upgrade contract is changed.
  • Parallel paths: safe staged execution, unsafe whole-expression fallback, dense/sparse/dictionary/direct reads, empty selections, later batches, output materialization, and position/equality-delete paths were traced. Their row/cursor alignment is sound; the physical conversion-validation boundary is the remaining semantic gap.
  • Conditional checks: the selected-row safety recursion is clear and the unsafe expression fallback is correct, but it checks only VExpr behavior and does not prove that deferred physical decoding is error-free.
  • Test coverage: the new all-pass/staged/profile and benchmark-registration tests are useful. Missing coverage is a strict-cast partial-survival invalid-INT96 differential case and benchmark teardown kept outside the timed region.
  • Test results: no result file is added or required for these C++ tests, and the asserted rows/counters are internally consistent. I did not run local builds or tests because the governing review task prohibits them. Live CI currently has compile, FE UT, Cloud UT, formatting, style, license, and secret checks passing; BE UT, regression, performance, and the code-review job are still pending.
  • Observability: the added residual-stage and alignment counters are appropriate and no extra INFO logging is needed. Existing thread discussion_r3639110107 already covers the remaining shrinking-stage quadratic alignment cost, so it is not duplicated here.
  • Transactions, persistence, data writes, and FE/BE variable propagation: not applicable; this is a read-path scheduler/benchmark change and adds no persisted state, transaction boundary, data mutation, or new cross-process variable.
  • Performance: the lazy-read direction is sound, but the complex-residual benchmark cannot be trusted for comparison until session/expression teardown is excluded from steady-state timing.
  • Other issues: after three review rounds and final changed-file/candidate sweeps, no additional non-duplicate issue remained.

// space before evaluating it. This is the scanner-side equivalent of expression-triggered
// lazy columns: a conjunct that rejects the batch prevents later-only columns from decoding.
for (const auto& stage : schedule.remaining_stages) {
RETURN_IF_ERROR(materialize_predicate_positions(stage.required_positions));

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.

[P1] Preserve decode failures for rows skipped by later stages

This safety check covers the VExpr tree, but the later column is also subject to physical-to-logical conversion while it is materialized. After an earlier AND child rejects a row, materialize_predicate_positions() calls the native reader with that row filtered out; decode_selected_values() handles FILTERED_CONTENT with skip_values(), and the sparse path runs the SerDe only for selected ranges. For example, with enable_strict_cast=true, an out-of-range INT96 value in a row rejected by stage 1 used to make eager materialization return DataQualityError, while the staged path skips that payload and can return rows successfully. This is below the format::Cast safeguard from the existing thread. Please either limit staged materialization to file-column conversions that are total for every physical value, or validate filtered payloads equivalently to eager decoding, and cover a strict-cast partial-survival invalid-INT96 case.

}

struct ReaderSession {
~ReaderSession() {

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] Destroy the expression session while timing is paused

run_reader() resumes timing immediately after reader->close(), but the local session is destroyed only at the end of the loop body. For this new case, that destructor calls context->close() in the measured region. The reader still retains the request that owns the same prepared context, and VExprContext::~VExprContext() closes it again because explicit close() does not clear _opened; request/reader destruction is timed as well. That makes the complex-residual number include duplicate expression teardown even though the benchmark contract excludes setup/close work. Please reset/destroy the session while timing is paused and use a single close ownership path.

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.12	0.05	0.04
query3	0.24	0.14	0.13
query4	1.61	0.14	0.14
query5	0.23	0.22	0.22
query6	1.21	1.07	1.06
query7	0.04	0.00	0.01
query8	0.06	0.03	0.04
query9	0.38	0.33	0.31
query10	0.56	0.55	0.59
query11	0.19	0.13	0.14
query12	0.18	0.14	0.14
query13	0.45	0.46	0.48
query14	1.03	1.01	1.00
query15	0.61	0.59	0.59
query16	0.33	0.33	0.32
query17	1.11	1.13	1.13
query18	0.20	0.20	0.21
query19	2.05	1.98	1.97
query20	0.02	0.01	0.01
query21	15.45	0.22	0.13
query22	4.88	0.05	0.05
query23	16.14	0.31	0.12
query24	3.00	0.41	0.32
query25	0.13	0.05	0.03
query26	0.74	0.20	0.15
query27	0.05	0.04	0.04
query28	3.53	0.91	0.52
query29	12.46	4.16	3.29
query30	0.29	0.15	0.15
query31	2.76	0.58	0.31
query32	3.22	0.59	0.49
query33	3.14	3.26	3.18
query34	15.44	4.18	3.54
query35	3.52	3.52	3.51
query36	0.54	0.44	0.43
query37	0.10	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.04	0.04
query40	0.17	0.16	0.15
query41	0.08	0.04	0.03
query42	0.04	0.03	0.02
query43	0.04	0.04	0.03
Total cold run time: 96.43 s
Total hot run time: 25.06 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 84.62% (154/182) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 58.06% (24566/42313)
Line Coverage 42.09% (244993/582075)
Region Coverage 37.99% (194677/512409)
Branch Coverage 39.10% (87687/224269)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 87.91% (160/182) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 75.16% (31006/41256)
Line Coverage 59.66% (344978/578240)
Region Coverage 56.44% (290231/514188)
Branch Coverage 57.72% (129491/224329)

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.

2 participants