Skip to content

[Feature](func) Support AggFn percentile_approx_array - #65847

Open
linrrzqqq wants to merge 6 commits into
apache:masterfrom
linrrzqqq:percentile-approx-array
Open

[Feature](func) Support AggFn percentile_approx_array#65847
linrrzqqq wants to merge 6 commits into
apache:masterfrom
linrrzqqq:percentile-approx-array

Conversation

@linrrzqqq

@linrrzqqq linrrzqqq commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

Release note

doc: apache/doris-website#4016

Support function PERCENTILE_APPROX_ARRAY

performance:

Doris> select percentile_approx(FUniqID, 0.01), percentile_approx(FUniqID, 0.99) from hits_100m;
+----------------------------------+----------------------------------+
| percentile_approx(FUniqID, 0.01) | percentile_approx(FUniqID, 0.99) |
+----------------------------------+----------------------------------+
|                                0 |            9.170476181709914e+18 |
+----------------------------------+----------------------------------+
1 row in set (13.962 sec)

Doris> select percentile_approx_array(FUniqID, [0.01, 0.99]) from hits_100m;
+------------------------------------------------+
| percentile_approx_array(FUniqID, [0.01, 0.99]) |
+------------------------------------------------+
| [0, 9.170476181709914e+18]                     |
+------------------------------------------------+
1 row in set (7.869 sec)

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

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

/review

@linrrzqqq

Copy link
Copy Markdown
Collaborator 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.

Review result: request changes for one performance-path issue. I did not find a data-correctness defect in the new percentile calculation, nullable execution, or distributed state handling.

Critical checkpoint conclusions:

  • Goal and proof: the FE/BE implementation adds percentile_approx_array with optional compression and returns multiple requested levels from one TDigest. The regression and BE tests cover coercion, unsorted/duplicate/boundary levels, empty/all-null inputs, grouped results, serialization/merge, invalid levels, and compression normalization; test execution was not independently run in this review environment.
  • Scope: the change is focused on function registration, expression binding, TDigest batch lookup, aggregate state, and directly related tests.
  • Concurrency: no shared mutable state or cross-thread ownership is introduced; aggregate states are query/pipeline-owned and phase-sequenced.
  • Lifecycle: state vectors and the digest use RAII, and reset/read/merge preserve the uninitialized, initialized-empty, and initialized-populated invariants.
  • Configuration: no configuration item is added or changed.
  • Compatibility: no existing storage or wire format is changed; this is a new function/state format, and FE/BE arities, physical types, and result nullability agree.
  • Parallel and conditional paths: row-wise, grouped, no-key batch, range, streaming, nullable-wrapper, empty/all-null, state/combinator, and merge paths were traced. Constant materialization and array offsets remain row-aligned; incompatible partial states fail before mutation.
  • Test results: the checked-in regression output is consistent with the TDigest implementation and preserves requested level order. Negative cases use the required error-test form, and grouped output is ordered.
  • Observability: no additional logs or metrics are needed for this pure aggregate function; existing analysis/runtime errors identify invalid quantiles and incompatible states.
  • Transactions, persistence, and data writes: not applicable; the patch changes query-time expression and aggregate execution only.
  • FE-BE propagation: no new thrift variable is introduced; registration, signatures, explicit coercion, outer non-nullability, nullable array elements, and empty-input behavior match across FE and BE.
  • Performance: the one accepted inline issue asks that release-mode checks be removed from the per-quantile loop in accordance with the repository hot-path rule. The single-digest design and monotonic cumulative cursor otherwise implement the advertised optimization.
  • Other risks: no additional substantiated issue remained after the full changed-file and upstream/downstream scans.

User focus: no additional user-provided focus was supplied; the full PR was reviewed.

Validation: static review of the authoritative PR diff and related code only. Per the runner review instructions, no local build or test was attempted.

Comment thread be/src/util/tdigest.h Outdated
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17858	3956	3962	3956
q2	2077	326	201	201
q3	10223	1404	824	824
q4	4682	473	336	336
q5	7521	862	554	554
q6	185	169	135	135
q7	762	861	624	624
q8	9976	1642	1573	1573
q9	6198	4310	4380	4310
q10	6824	1727	1491	1491
q11	510	354	325	325
q12	755	583	455	455
q13	18103	3351	2741	2741
q14	270	263	238	238
q15	q16	788	784	700	700
q17	1046	1037	991	991
q18	7027	5861	5678	5678
q19	1423	1270	1095	1095
q20	842	661	594	594
q21	5840	2602	2480	2480
q22	443	357	298	298
Total cold run time: 103353 ms
Total hot run time: 29599 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4380	4334	4307	4307
q2	286	309	215	215
q3	4576	4962	4421	4421
q4	2043	2166	1354	1354
q5	4369	4262	4254	4254
q6	236	176	129	129
q7	1963	1958	1655	1655
q8	2468	2131	2115	2115
q9	7795	7730	7841	7730
q10	4661	4675	4195	4195
q11	590	412	392	392
q12	885	813	530	530
q13	3333	3517	2993	2993
q14	289	308	280	280
q15	q16	711	749	653	653
q17	1368	1329	1362	1329
q18	8077	7525	6991	6991
q19	1073	1116	1097	1097
q20	2231	2208	1947	1947
q21	5217	4537	4417	4417
q22	524	465	434	434
Total cold run time: 57075 ms
Total hot run time: 51438 ms

@hello-stephen

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

query5	4316	625	484	484
query6	463	230	217	217
query7	4895	610	358	358
query8	336	187	172	172
query9	8787	4061	4045	4045
query10	497	359	302	302
query11	5881	2300	2166	2166
query12	161	104	102	102
query13	1280	604	433	433
query14	6243	5228	4880	4880
query14_1	4244	4166	4187	4166
query15	213	205	169	169
query16	1029	419	447	419
query17	1101	692	544	544
query18	2485	457	339	339
query19	214	187	144	144
query20	112	109	104	104
query21	238	173	132	132
query22	13553	13618	13384	13384
query23	17280	16402	16168	16168
query23_1	16211	16228	16057	16057
query24	7717	1718	1238	1238
query24_1	1267	1251	1246	1246
query25	533	442	353	353
query26	1351	361	210	210
query27	2609	586	358	358
query28	4495	1981	1972	1972
query29	1106	654	476	476
query30	341	263	224	224
query31	1109	1098	961	961
query32	106	61	60	60
query33	510	305	248	248
query34	1193	1128	626	626
query35	754	772	656	656
query36	1175	1191	1064	1064
query37	155	104	89	89
query38	1876	1702	1651	1651
query39	877	866	847	847
query39_1	847	829	850	829
query40	246	158	145	145
query41	64	61	63	61
query42	96	90	91	90
query43	323	322	281	281
query44	1402	767	765	765
query45	198	181	172	172
query46	1031	1187	711	711
query47	2111	2117	2021	2021
query48	412	407	280	280
query49	578	413	298	298
query50	1032	420	340	340
query51	10626	10491	10414	10414
query52	85	88	76	76
query53	267	271	202	202
query54	300	240	215	215
query55	73	72	65	65
query56	293	302	275	275
query57	1312	1300	1183	1183
query58	294	249	252	249
query59	1563	1599	1415	1415
query60	323	269	255	255
query61	152	154	169	154
query62	554	507	440	440
query63	244	198	206	198
query64	3001	1153	1003	1003
query65	4726	4571	4565	4565
query66	1848	542	403	403
query67	29239	29179	28338	28338
query68	3371	1471	884	884
query69	411	324	285	285
query70	1061	960	974	960
query71	389	371	326	326
query72	3230	2700	2379	2379
query73	826	856	412	412
query74	5086	4960	4812	4812
query75	2571	2540	2195	2195
query76	2346	1187	776	776
query77	349	374	268	268
query78	12030	11853	11333	11333
query79	2437	1121	750	750
query80	1634	533	505	505
query81	537	330	290	290
query82	602	161	120	120
query83	373	326	296	296
query84	280	156	126	126
query85	1004	590	534	534
query86	435	292	280	280
query87	1820	1826	1774	1774
query88	3747	2789	2827	2789
query89	437	381	328	328
query90	1895	199	196	196
query91	200	187	159	159
query92	64	61	56	56
query93	1761	1550	965	965
query94	809	345	316	316
query95	778	533	463	463
query96	1096	778	341	341
query97	2624	2648	2512	2512
query98	215	216	199	199
query99	1089	1119	976	976
Total cold run time: 265888 ms
Total hot run time: 176303 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.10	0.06	0.05
query3	0.28	0.15	0.14
query4	1.61	0.14	0.14
query5	0.23	0.22	0.21
query6	1.27	1.12	1.09
query7	0.03	0.01	0.00
query8	0.05	0.03	0.04
query9	0.39	0.32	0.30
query10	0.54	0.54	0.57
query11	0.19	0.13	0.13
query12	0.18	0.14	0.14
query13	0.47	0.47	0.48
query14	1.02	0.99	1.00
query15	0.62	0.58	0.59
query16	0.32	0.34	0.31
query17	1.11	1.15	1.15
query18	0.23	0.21	0.20
query19	1.98	1.90	1.95
query20	0.02	0.01	0.01
query21	15.45	0.24	0.15
query22	4.88	0.04	0.04
query23	16.15	0.31	0.12
query24	2.99	0.43	0.31
query25	0.10	0.04	0.04
query26	0.73	0.20	0.16
query27	0.05	0.05	0.04
query28	3.57	0.98	0.55
query29	12.55	4.13	3.27
query30	0.27	0.15	0.15
query31	2.78	0.56	0.31
query32	3.23	0.61	0.49
query33	3.09	3.18	3.18
query34	15.65	4.27	3.52
query35	3.51	3.52	3.53
query36	0.56	0.46	0.44
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.16	0.15
query41	0.09	0.03	0.02
query42	0.04	0.03	0.03
query43	0.05	0.03	0.03
Total cold run time: 96.74 s
Total hot run time: 25.03 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 85.71% (210/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 57.59% (24043/41745)
Line Coverage 41.34% (236776/572799)
Region Coverage 37.11% (186949/503709)
Branch Coverage 38.35% (84064/219209)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 2.22% (1/45) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 92.65% (227/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.90% (30499/40720)
Line Coverage 59.12% (336533/569270)
Region Coverage 55.67% (281444/505598)
Branch Coverage 57.06% (125157/219351)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 92.65% (227/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.90% (30501/40720)
Line Coverage 59.12% (336577/569270)
Region Coverage 55.67% (281471/505598)
Branch Coverage 57.07% (125174/219351)

@linrrzqqq
linrrzqqq force-pushed the percentile-approx-array branch from 9a8a351 to 4877373 Compare July 22, 2026 03:09
@linrrzqqq

Copy link
Copy Markdown
Collaborator 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 conclusion

Changes requested. The core two- and three-argument function is wired end to end, but three parallel/correctness paths remain broken:

  • batched TDigest left-tail rounding can differ from equivalent scalar calls;
  • automatic _foreach discovery exposes an unusable callable form;
  • _merge/_union fail after an aggregate state crosses a slot boundary.

Critical checkpoint conclusions

  • Goal and scope: FE registration/signatures, visitor dispatch, BE factory/state, and the regression/BE tests implement the intended single-digest array API. The patch is otherwise focused on that feature.
  • Correctness and lifecycle: I traced row, grouped, selected, no-key batch, range/window, nullable/all-null, empty-level, reset, serialization/deserialization/merge, output offsets, and nested null maps. Ownership and state lifecycles are sound; the three inline issues are the remaining correctness failures.
  • Concurrency: No new shared concurrency, lock-ordering, or static-lifecycle concern is introduced; state is aggregate-instance local.
  • Configuration: No configuration item is added or changed.
  • Compatibility and parallel paths: FE/BE physical and result types agree, and the new serialized state is self-contained. No existing persisted or wire format is changed. The dynamically synthesized _foreach and projected/stored _merge/_union paths need the inline fixes.
  • Errors and tests: Finite/range validation and incompatible-state failures are explicit. The added deterministic regression and BE unit tests cover the main, negative, empty, and serialize/merge paths, but need the three focused cases called out inline.
  • Observability: Existing analysis/runtime errors are sufficient for this pure aggregate function; no new logging or metrics are required.
  • Transactions, persistence, and data writes: Not applicable; this patch changes query-time expression and aggregate execution only.
  • FE-BE propagation: No new thrift/session variable is introduced. Function arities, coercion, result/item nullability, and empty-input behavior otherwise align across FE and BE.
  • Performance: One digest plus one sorted forward scan is the intended optimization, and the earlier release-check hot-loop concern is fixed on the current head. The left-tail branch still needs to preserve scalar rounding.
  • User focus: No additional user-provided focus was supplied; the full PR was reviewed.

Validation was static per the review-runner contract; no local build or test was run.

Comment thread be/src/util/tdigest.h Outdated
@linrrzqqq

Copy link
Copy Markdown
Collaborator 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 30th, 2026 7:58 AM.
Workflow run: https://github.com/apache/doris/actions/runs/30098285838

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

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

run buildall

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

/review

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17692	4066	4013	4013
q2	2026	316	193	193
q3	10291	1389	807	807
q4	4688	475	341	341
q5	7514	839	545	545
q6	181	171	138	138
q7	777	793	619	619
q8	9680	1513	1603	1513
q9	6175	4322	4325	4322
q10	6813	1738	1450	1450
q11	514	352	325	325
q12	773	559	458	458
q13	18134	3371	2781	2781
q14	283	276	254	254
q15	q16	782	785	720	720
q17	1029	1011	1031	1011
q18	6687	5891	5512	5512
q19	1740	1218	989	989
q20	767	666	558	558
q21	5851	2641	2368	2368
q22	443	356	294	294
Total cold run time: 102840 ms
Total hot run time: 29211 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4384	4286	4275	4275
q2	287	322	211	211
q3	4532	4942	4390	4390
q4	2053	2133	1375	1375
q5	4371	4236	4244	4236
q6	226	175	132	132
q7	1747	1980	1781	1781
q8	2518	2401	2146	2146
q9	7767	7784	7784	7784
q10	4664	4644	4214	4214
q11	572	413	381	381
q12	760	753	546	546
q13	3402	3633	3015	3015
q14	307	302	269	269
q15	q16	707	733	663	663
q17	1345	1317	1306	1306
q18	7995	7393	6933	6933
q19	1099	1056	1089	1056
q20	2216	2209	1932	1932
q21	5188	4595	4431	4431
q22	515	452	426	426
Total cold run time: 56655 ms
Total hot run time: 51502 ms

@hello-stephen

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

query5	4295	621	480	480
query6	471	217	208	208
query7	4887	607	338	338
query8	334	188	169	169
query9	8793	4099	4074	4074
query10	491	337	313	313
query11	5944	2316	2090	2090
query12	159	100	101	100
query13	1241	603	426	426
query14	6177	5218	4845	4845
query14_1	4215	4208	4191	4191
query15	208	214	179	179
query16	1022	466	431	431
query17	1108	677	565	565
query18	2421	454	338	338
query19	200	182	140	140
query20	109	105	103	103
query21	237	156	132	132
query22	13493	13478	13372	13372
query23	17284	16351	16100	16100
query23_1	16180	16272	16210	16210
query24	8259	1748	1274	1274
query24_1	1295	1329	1311	1311
query25	587	459	397	397
query26	1321	372	213	213
query27	2579	611	391	391
query28	4488	2007	1997	1997
query29	1057	609	495	495
query30	353	264	230	230
query31	1121	1090	975	975
query32	106	62	61	61
query33	526	324	264	264
query34	1173	1127	649	649
query35	762	800	662	662
query36	1211	1200	1060	1060
query37	152	106	94	94
query38	1885	1717	1651	1651
query39	890	872	865	865
query39_1	841	839	828	828
query40	250	170	148	148
query41	72	68	69	68
query42	94	94	92	92
query43	326	321	281	281
query44	1408	780	778	778
query45	198	186	173	173
query46	1091	1196	746	746
query47	2141	2120	2006	2006
query48	420	414	293	293
query49	587	431	313	313
query50	1084	435	334	334
query51	11017	11189	10698	10698
query52	89	87	81	81
query53	259	284	202	202
query54	296	251	239	239
query55	79	73	69	69
query56	320	299	302	299
query57	1315	1295	1216	1216
query58	297	261	289	261
query59	1601	1630	1421	1421
query60	308	282	263	263
query61	177	167	170	167
query62	545	499	439	439
query63	245	203	201	201
query64	2889	1037	843	843
query65	4747	4664	4615	4615
query66	1824	503	386	386
query67	29302	29240	29089	29089
query68	3196	1562	976	976
query69	404	291	263	263
query70	1103	924	914	914
query71	353	323	292	292
query72	2992	2648	2405	2405
query73	813	808	448	448
query74	5046	4934	4718	4718
query75	2528	2492	2146	2146
query76	2341	1168	765	765
query77	339	381	282	282
query78	11792	11929	11354	11354
query79	2135	1210	797	797
query80	1338	547	460	460
query81	542	337	294	294
query82	603	160	117	117
query83	357	317	295	295
query84	280	158	132	132
query85	985	614	525	525
query86	428	296	286	286
query87	1817	1821	1766	1766
query88	3698	2874	2777	2777
query89	442	381	337	337
query90	1861	199	198	198
query91	205	189	158	158
query92	65	63	55	55
query93	1712	1502	953	953
query94	729	349	293	293
query95	809	623	502	502
query96	1023	802	361	361
query97	2649	2615	2489	2489
query98	207	206	202	202
query99	1086	1120	976	976
Total cold run time: 265091 ms
Total hot run time: 177985 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.10	0.05	0.04
query3	0.26	0.14	0.17
query4	1.61	0.14	0.13
query5	0.25	0.23	0.22
query6	1.25	1.08	1.08
query7	0.04	0.00	0.00
query8	0.06	0.04	0.04
query9	0.37	0.32	0.32
query10	0.53	0.57	0.53
query11	0.19	0.13	0.14
query12	0.18	0.14	0.14
query13	0.45	0.47	0.48
query14	1.02	1.02	1.02
query15	0.61	0.59	0.59
query16	0.32	0.33	0.32
query17	1.09	1.09	1.12
query18	0.23	0.22	0.21
query19	2.03	1.94	1.88
query20	0.02	0.01	0.01
query21	15.43	0.22	0.13
query22	4.76	0.05	0.06
query23	16.12	0.30	0.12
query24	2.96	0.41	0.31
query25	0.10	0.06	0.03
query26	0.74	0.21	0.16
query27	0.04	0.04	0.03
query28	3.51	0.95	0.55
query29	12.53	4.07	3.28
query30	0.27	0.15	0.16
query31	2.77	0.57	0.31
query32	3.22	0.59	0.48
query33	3.23	3.27	3.20
query34	15.60	4.18	3.52
query35	3.56	3.51	3.52
query36	0.54	0.44	0.44
query37	0.08	0.07	0.06
query38	0.05	0.03	0.03
query39	0.04	0.03	0.03
query40	0.18	0.17	0.15
query41	0.08	0.03	0.03
query42	0.04	0.02	0.02
query43	0.04	0.04	0.03
Total cold run time: 96.51 s
Total hot run time: 24.99 s

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

Changes requested. The core two- and three-argument percentile_approx_array path is wired through FE, BE, scalar-equivalence unit tests, and regression output, but the synthesized _state path has one additional P2 correctness gap: a null value lets an invalid quantile bypass both FE post-rewrite validation and BE state initialization, producing a serialized empty state. The inline comment gives a concrete trigger and fix direction.

Critical checkpoints

  • Goal, correctness, and scope: The change is focused and the direct aggregate substantially achieves its goal. FE/BE signatures, array nullability, empty/all-null results, registration, visitor dispatch, serialization, reset, result insertion, and both merge orders were traced. The _state legality bypass prevents the feature from being complete.
  • Concurrency and lifecycle: No new shared-thread, lock, static-initialization, or concurrently owned lifecycle is introduced. Aggregate state ownership is query/group-local; no additional lifetime or resource defect was found.
  • Configuration, compatibility, and cross-module contracts: No configuration, Thrift field, or other transmitted variable is added. FE and BE types agree, and the new state format was checked for uninitialized, empty, populated, and merged states. No separate mixed-version defect was substantiated.
  • Parallel paths and conditions: Direct, constant-folded, DISTINCT, window, _state, _merge, _union, and _foreach exposures were reviewed. Existing threads already cover _foreach, projected/stored _merge/_union, and batched left-tail precision; they are not duplicated here. DISTINCT analytic syntax is parser-rejected for this function, and direct DISTINCT uses planner deduplication.
  • Tests and results: The added BE and regression coverage exercises direct, grouped, null, empty, invalid, non-finite, serialization, and scalar-equivalence cases, and the checked-in results are consistent with those queries. It lacks the accepted _state null-plus-invalid-quantile case. Per the review contract, no local build or test was run. Current CI shows compile, CheckStyle, clang-format, macOS BE UT, vault regression, and performance passing; Linux BE UT, FE UT, and several regression suites remain pending.
  • Observability, transactions, persistence, and writes: No new logging/metrics need, transaction protocol, catalog persistence, or storage-write path is introduced.
  • Performance: The batched sorted traversal avoids repeated scalar searches, and no new CPU/memory issue was found beyond the already-known left-tail precision thread. The prior hot-loop check issue is fixed at the current head.
  • User focus: No additional user-provided focus was specified; the complete PR was reviewed.

Two normal full-review passes and a separate risk-focused pass converged on this frozen comment set with no further valuable findings.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 2.22% (1/45) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 92.65% (227/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 75.29% (31086/41291)
Line Coverage 59.86% (346435/578742)
Region Coverage 56.65% (291408/514388)
Branch Coverage 57.98% (130143/224465)

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

Changes requested for three P2 correctness gaps:

  • stored _merge/_union inputs can now bypass nested type/shape legality checks;
  • an unmatched correlated scalar _merge returns NULL instead of the declared [];
  • the newly exposed _union has the parallel correlated zero-row mismatch, returning NULL instead of a non-null empty aggregate state.

Critical checkpoint conclusions

  • Goal and functional proof: The FE/BE implementation otherwise adds the intended two- and three-argument percentile_approx_array API, computes requested levels with one TDigest, and carries its constants through state serialization and merge. The three inline cases prevent the full direct/combinator surface from meeting that goal.
  • Scope and clarity: The new aggregate implementation is focused, but the changed generic state-combinator legality guards affect every stored aggregate state; MF-1 is the resulting cross-function regression.
  • Concurrency: No new thread, shared mutable state, lock, atomic, or lock-order path is introduced. Aggregate state remains query/group-local and phase-sequenced.
  • Lifecycle: State create/reset/destroy, uninitialized/empty/populated ownership, serialization/deserialization, merge, and result insertion were traced. Optional digest ownership and array-column offsets/null maps are consistent; no special static-initialization or cyclic-lifetime issue remains.
  • Configuration: No configuration item is added or changed.
  • Compatibility: No existing Thrift, storage, or serialized layout is changed. FE/BE function names, arities, physical types, intermediate state types, and ordinary return nullability align; the TDigest maximum-sentinel fix preserves its layout.
  • Parallel paths: Scalar versus batch TDigest evaluation, row/group/no-key/range aggregation, nullable/all-null/empty input, direct/state/merge/union/foreach, stored/subquery state boundaries, and correlated/uncorrelated scalar subqueries were reviewed. MF-1, MF-2, and MF-3 are the remaining failures.
  • Conditional checks and error handling: Constant materialization, quantile/compression validation, incompatible-state rejection, and BE invariant handling are otherwise explicit. The new stored-state guard drops type-safe nested legality checks (MF-1), while exact planner class tests miss merge/union empty-result contracts (MF-2/MF-3).
  • Test coverage: The BE unit and regression changes cover direct and compressed calls, unsorted/duplicate/boundary levels, nullable/grouped/empty input, TDigest scalar parity, serialization, merge/union, invalid constants, and _foreach rejection. Missing cases are an illegal stored subtype plus unmatched correlated _merge and _union keys.
  • Test results: The checked-in deterministic outputs are consistent with the reviewed implementation, but the three missing cases leave the asserted behavior incomplete. Results were inspected statically and were not independently regenerated.
  • Observability: This pure query-time aggregate introduces no new distributed operational lifecycle requiring logs or metrics; existing analysis/runtime errors are sufficient for the covered failures.
  • Transactions and persistence: No transaction, EditLog, catalog-replay, failover, or persisted metadata path is changed.
  • Data writes: No storage write, publish, crash-recovery, or atomicity path is involved.
  • FE-BE variables: No new session/Thrift variable is transmitted. Registration, coercion, outer/item nullability, state names, and serialization contracts otherwise agree across FE and BE.
  • Performance and memory: The single-digest batched traversal avoids repeated scalar searches; per-group ownership is limited to the level vectors and one TDigest. No additional CPU, allocation, or memory-accounting issue remained after the hot-loop concern in the existing thread was fixed.
  • Other issues and user focus: All changed files and necessary upstream/downstream paths were swept through three review rounds. No additional user-provided focus was supplied, and no fourth patch-scoped issue remained.

Validation was static against authoritative diff head d7cf7025bfdbe7a20624d6b8dedd98e0d367edfb; per the review-runner contract, no local build or test was attempted. At the final sweep, CheckStyle, clang-format, license, dependency, secret, and large-file checks were passing; BE UT (macOS) was still in progress.

@linrrzqqq
linrrzqqq force-pushed the percentile-approx-array branch from e812264 to d7cf702 Compare July 26, 2026 17:50
@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17646	4096	4023	4023
q2	2047	326	204	204
q3	10292	1409	882	882
q4	4677	466	338	338
q5	7480	843	572	572
q6	179	169	134	134
q7	757	813	618	618
q8	9334	1450	1553	1450
q9	5581	4349	4366	4349
q10	6765	1714	1444	1444
q11	512	355	325	325
q12	737	579	457	457
q13	18090	3511	2827	2827
q14	281	259	242	242
q15	q16	795	784	708	708
q17	1049	943	1006	943
q18	6789	5717	5403	5403
q19	1326	1212	1149	1149
q20	835	683	604	604
q21	5897	2578	2415	2415
q22	425	347	306	306
Total cold run time: 101494 ms
Total hot run time: 29393 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4403	4329	4346	4329
q2	286	315	206	206
q3	4627	4989	4380	4380
q4	2020	2158	1377	1377
q5	4398	4257	4295	4257
q6	230	177	126	126
q7	1737	1669	2059	1669
q8	2620	2184	2227	2184
q9	7975	8079	7738	7738
q10	4689	4645	4172	4172
q11	560	406	396	396
q12	791	760	552	552
q13	3209	3646	2907	2907
q14	314	299	272	272
q15	q16	691	740	679	679
q17	1364	1305	1290	1290
q18	7981	7237	7366	7237
q19	1233	1153	1178	1153
q20	2211	2190	1931	1931
q21	5247	4534	4497	4497
q22	504	458	415	415
Total cold run time: 57090 ms
Total hot run time: 51767 ms

@hello-stephen

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

query5	4380	626	477	477
query6	460	217	197	197
query7	4946	615	344	344
query8	331	185	173	173
query9	8779	4157	4096	4096
query10	495	385	295	295
query11	5814	2342	2099	2099
query12	167	105	101	101
query13	1262	622	417	417
query14	6244	5209	4936	4936
query14_1	4252	4250	4249	4249
query15	208	200	175	175
query16	1016	472	473	472
query17	963	751	552	552
query18	2429	452	331	331
query19	205	183	141	141
query20	106	104	111	104
query21	231	158	135	135
query22	13606	13560	13306	13306
query23	17248	16435	16044	16044
query23_1	16233	16136	16174	16136
query24	7644	1729	1247	1247
query24_1	1277	1266	1261	1261
query25	537	430	354	354
query26	1325	350	199	199
query27	2685	600	355	355
query28	4490	1997	1967	1967
query29	1086	595	471	471
query30	329	264	220	220
query31	1111	1090	997	997
query32	117	59	60	59
query33	510	317	246	246
query34	1174	1142	665	665
query35	757	832	693	693
query36	1172	1190	1035	1035
query37	159	106	89	89
query38	1903	1688	1634	1634
query39	862	856	835	835
query39_1	823	830	827	827
query40	248	161	136	136
query41	64	62	62	62
query42	91	91	91	91
query43	320	323	281	281
query44	1408	782	760	760
query45	205	189	173	173
query46	1038	1215	706	706
query47	2118	2108	1997	1997
query48	392	408	274	274
query49	579	429	302	302
query50	1034	432	330	330
query51	11086	11141	11064	11064
query52	90	86	75	75
query53	256	272	208	208
query54	299	224	225	224
query55	73	70	64	64
query56	291	310	274	274
query57	1320	1300	1215	1215
query58	280	264	256	256
query59	1587	1631	1423	1423
query60	302	267	251	251
query61	156	152	156	152
query62	555	490	422	422
query63	245	197	200	197
query64	2857	1040	874	874
query65	4720	4582	4638	4582
query66	1880	498	375	375
query67	29525	29269	29106	29106
query68	3257	1526	1004	1004
query69	421	298	262	262
query70	1065	984	976	976
query71	377	346	313	313
query72	3058	2720	2598	2598
query73	839	763	434	434
query74	5063	4967	4727	4727
query75	2540	2507	2145	2145
query76	2322	1181	788	788
query77	365	366	289	289
query78	11766	11973	11354	11354
query79	1198	1192	759	759
query80	624	577	500	500
query81	462	338	293	293
query82	245	163	120	120
query83	326	329	303	303
query84	308	163	132	132
query85	971	706	625	625
query86	314	300	267	267
query87	1820	1814	1731	1731
query88	3665	2796	2773	2773
query89	420	361	321	321
query90	2194	202	181	181
query91	198	185	160	160
query92	59	58	52	52
query93	1674	1570	910	910
query94	519	342	312	312
query95	812	504	555	504
query96	1115	763	362	362
query97	2606	2612	2489	2489
query98	216	206	202	202
query99	1103	1107	981	981
Total cold run time: 262600 ms
Total hot run time: 178303 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.10	0.05	0.05
query3	0.26	0.13	0.14
query4	1.61	0.14	0.14
query5	0.23	0.21	0.22
query6	1.24	1.11	1.03
query7	0.04	0.00	0.01
query8	0.06	0.04	0.03
query9	0.38	0.31	0.32
query10	0.55	0.55	0.56
query11	0.20	0.13	0.14
query12	0.17	0.15	0.14
query13	0.46	0.46	0.46
query14	1.03	1.01	0.98
query15	0.60	0.59	0.58
query16	0.32	0.31	0.31
query17	1.08	1.08	1.08
query18	0.21	0.21	0.21
query19	2.01	1.96	1.91
query20	0.01	0.01	0.01
query21	15.44	0.22	0.13
query22	4.89	0.06	0.05
query23	16.12	0.31	0.12
query24	2.86	0.42	0.32
query25	0.11	0.04	0.03
query26	0.74	0.21	0.14
query27	0.04	0.05	0.03
query28	3.55	0.88	0.52
query29	12.55	4.19	3.32
query30	0.27	0.15	0.15
query31	2.78	0.58	0.31
query32	3.22	0.58	0.48
query33	3.40	3.17	3.29
query34	15.60	4.21	3.49
query35	3.54	3.48	3.52
query36	0.56	0.42	0.43
query37	0.09	0.07	0.06
query38	0.06	0.04	0.04
query39	0.04	0.04	0.03
query40	0.19	0.16	0.15
query41	0.08	0.03	0.02
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.77 s
Total hot run time: 24.78 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 85.71% (210/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 58.14% (24651/42396)
Line Coverage 42.21% (246341/583606)
Region Coverage 38.08% (195530/513506)
Branch Coverage 39.19% (88204/225058)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 93.47% (229/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.84% (30526/41341)
Line Coverage 57.92% (335776/579706)
Region Coverage 54.25% (279504/515259)
Branch Coverage 55.14% (124102/225064)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 93.47% (229/245) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.84% (30526/41341)
Line Coverage 57.92% (335770/579706)
Region Coverage 54.22% (279389/515259)
Branch Coverage 55.13% (124085/225064)

Mryange
Mryange previously approved these changes Jul 29, 2026
@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jul 29, 2026
@github-actions

Copy link
Copy Markdown
Contributor

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

Comment thread be/src/util/tdigest.h Outdated
Comment thread be/src/exprs/aggregate/aggregate_function_percentile.h Outdated
Comment thread be/src/exprs/aggregate/aggregate_function_percentile.h Outdated
@linrrzqqq linrrzqqq closed this Jul 31, 2026
@linrrzqqq linrrzqqq reopened this Jul 31, 2026
@github-actions github-actions Bot removed the approved Indicates a PR has been approved by one committer. label Jul 31, 2026
@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17588	3983	3974	3974
q2	2077	352	212	212
q3	10201	1457	820	820
q4	4761	478	340	340
q5	8281	889	560	560
q6	316	172	136	136
q7	794	796	602	602
q8	10336	1604	1613	1604
q9	5534	4098	4127	4098
q10	6742	1642	1374	1374
q11	501	367	318	318
q12	721	586	441	441
q13	18216	3425	2750	2750
q14	260	257	246	246
q15	q16	735	729	654	654
q17	1004	972	1065	972
q18	7039	5775	5518	5518
q19	1199	1347	1058	1058
q20	810	742	578	578
q21	5793	2650	2587	2587
q22	416	360	306	306
Total cold run time: 103324 ms
Total hot run time: 29148 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4305	4191	4190	4190
q2	285	323	213	213
q3	4550	4952	4427	4427
q4	2183	2248	1442	1442
q5	4299	4172	4149	4149
q6	230	171	125	125
q7	1733	1568	1390	1390
q8	2259	1911	1880	1880
q9	6824	6861	6764	6764
q10	4290	4299	3852	3852
q11	532	382	349	349
q12	711	715	498	498
q13	2981	3293	2739	2739
q14	288	298	256	256
q15	q16	665	690	601	601
q17	1241	1204	1212	1204
q18	7435	6893	6606	6606
q19	1080	1075	1103	1075
q20	2202	2233	1933	1933
q21	5328	4628	4437	4437
q22	517	461	428	428
Total cold run time: 53938 ms
Total hot run time: 48558 ms

@hello-stephen

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

query5	3883	640	473	473
query6	468	225	250	225
query7	4778	599	344	344
query8	331	185	191	185
query9	8671	4081	4074	4074
query10	435	346	305	305
query11	4483	2199	2025	2025
query12	149	100	97	97
query13	1205	602	430	430
query14	5268	4667	4400	4400
query14_1	3814	3827	3782	3782
query15	202	200	176	176
query16	643	506	488	488
query17	694	724	587	587
query18	483	470	354	354
query19	211	199	191	191
query20	104	102	100	100
query21	182	161	136	136
query22	12985	13011	12808	12808
query23	17298	16386	15981	15981
query23_1	16171	16133	16092	16092
query24	7410	1653	1249	1249
query24_1	1287	1215	1202	1202
query25	528	437	349	349
query26	1175	355	205	205
query27	2594	567	386	386
query28	4446	2065	2034	2034
query29	1036	616	463	463
query30	340	261	220	220
query31	1112	1089	951	951
query32	101	61	59	59
query33	510	305	239	239
query34	1177	1079	641	641
query35	743	753	643	643
query36	797	789	727	727
query37	146	102	89	89
query38	1839	1662	1586	1586
query39	840	822	791	791
query39_1	783	811	776	776
query40	253	167	143	143
query41	64	63	65	63
query42	94	92	95	92
query43	321	322	277	277
query44	1435	773	762	762
query45	191	173	171	171
query46	1032	1155	674	674
query47	1519	1522	1494	1494
query48	374	414	304	304
query49	581	413	307	307
query50	1094	449	326	326
query51	10948	10763	10646	10646
query52	91	90	76	76
query53	254	277	206	206
query54	301	252	236	236
query55	77	77	69	69
query56	347	301	286	286
query57	1022	1001	915	915
query58	292	272	255	255
query59	1527	1611	1405	1405
query60	312	275	252	252
query61	143	144	147	144
query62	401	318	262	262
query63	230	192	197	192
query64	2766	1057	860	860
query65	3879	3850	3822	3822
query66	1814	486	363	363
query67	28265	28288	27984	27984
query68	3229	1573	983	983
query69	404	313	257	257
query70	886	774	769	769
query71	355	328	314	314
query72	3095	2645	2377	2377
query73	832	769	416	416
query74	4660	4474	4302	4302
query75	2380	2325	2014	2014
query76	2340	1150	742	742
query77	331	381	281	281
query78	11232	11144	10749	10749
query79	1217	1117	723	723
query80	626	572	468	468
query81	438	322	282	282
query82	228	152	114	114
query83	313	324	301	301
query84	298	163	133	133
query85	893	604	522	522
query86	290	235	216	216
query87	1794	1792	1709	1709
query88	3710	2827	2809	2809
query89	358	332	284	284
query90	2162	210	190	190
query91	202	188	160	160
query92	65	59	58	58
query93	1584	1640	986	986
query94	532	359	310	310
query95	777	576	502	502
query96	1071	788	333	333
query97	2480	2434	2338	2338
query98	199	199	196	196
query99	717	735	603	603
Total cold run time: 242372 ms
Total hot run time: 169751 ms

@hello-stephen

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

query1	0.01	0.01	0.00
query2	0.10	0.05	0.05
query3	0.26	0.14	0.13
query4	1.61	0.14	0.15
query5	0.24	0.22	0.23
query6	1.16	0.83	0.80
query7	0.04	0.01	0.00
query8	0.05	0.04	0.04
query9	0.37	0.33	0.33
query10	0.55	0.58	0.56
query11	0.19	0.13	0.14
query12	0.17	0.14	0.14
query13	0.46	0.47	0.47
query14	1.02	0.99	1.00
query15	0.61	0.58	0.58
query16	0.33	0.31	0.32
query17	1.11	1.08	1.09
query18	0.20	0.19	0.19
query19	2.02	2.02	1.95
query20	0.02	0.02	0.01
query21	15.44	0.22	0.14
query22	4.87	0.05	0.05
query23	16.13	0.31	0.11
query24	3.00	0.43	0.33
query25	0.12	0.05	0.05
query26	0.71	0.20	0.15
query27	0.04	0.05	0.04
query28	3.51	0.80	0.36
query29	12.53	3.95	3.18
query30	0.27	0.15	0.15
query31	2.77	0.57	0.31
query32	3.22	0.58	0.48
query33	3.23	3.11	3.15
query34	15.54	3.96	3.32
query35	3.21	3.25	3.21
query36	0.55	0.44	0.43
query37	0.09	0.07	0.06
query38	0.06	0.04	0.04
query39	0.04	0.03	0.03
query40	0.17	0.15	0.14
query41	0.09	0.03	0.02
query42	0.04	0.02	0.04
query43	0.05	0.03	0.04
Total cold run time: 96.2 s
Total hot run time: 23.88 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 3.85% (2/52) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 83.98% (283/337) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 59.16% (25639/43341)
Line Coverage 43.25% (257313/595012)
Region Coverage 38.96% (204116/523917)
Branch Coverage 40.29% (93098/231094)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 87.65% (291/332) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 75.72% (32011/42273)
Line Coverage 60.34% (356623/591037)
Region Coverage 56.94% (299303/525685)
Branch Coverage 58.37% (134917/231132)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 72.58% (45/62) 🎉
Increment coverage report
Complete coverage report

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.

4 participants