Skip to content

[fix](agg) Align complex aggregate null ordering - #67439

Open
Mryange wants to merge 3 commits into
apache:masterfrom
Mryange:fix-array-aggregate-ordering
Open

[fix](agg) Align complex aggregate null ordering#67439
Mryange wants to merge 3 commits into
apache:masterfrom
Mryange:fix-array-aggregate-ordering

Conversation

@Mryange

@Mryange Mryange commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Problem Summary: Complex-type min, max, min_by, and max_by used a NULL ordering direction different from ordinary SQL array comparisons. This could select inconsistent results for arrays containing NULL elements. The aggregate comparison direction is aligned with SQL array ordering, and regression expectations are updated.

apache/doris-website#4121

Release note

Complex-type aggregate ordering now follows SQL array NULL ordering.

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?

@Mryange

Mryange commented Sep 2, 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.

I found two correctness issues in the current head. First, changing the shared complex comparator hint to +1 reverses nested NULL ordering for unary complex min/max (and merge/window paths), conflicting with Doris' documented ARRAY aggregate order; the unchanged plain min(arr) expectation already exposes the inconsistency. Please scope the policy or reconcile the aggregate contract and tests. Second, the id=5 max_by(arr, weight) expected row selects a NULL weight even though the nullable variadic wrapper skips rows with any NULL argument; it should remain [1, null, 3, 4]. The new coverage also does not exercise sliding-window/incremental complex min/max behavior.


bool change_if_less(const IColumn& column, size_t row_num, Arena& arena) {
if (!has() || column_data->compare_at(0, row_num, column, -1) == 1) {
if (!has() || column_data->compare_at(0, row_num, column, 1) == 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.

SingleValueDataComplexType is also the state for unary complex min/max, not just the *_by key. With this +1, nested ColumnNullable treats NULL as greatest, so [10,NULL] beats [10,5] for max(arr) and loses for min(arr). That conflicts with Doris' documented ARRAY aggregate order (NULL is smallest) and the unchanged maxmin_array_2 expectation. Please keep the aggregate comparator policy consistent with the documented contract (or scope a different hint to the intended *_by path) and add/update plain, merge, and window coverage.

3 [3, 1] [11, 22, 33, 44]
4 [3, 1] [10]
5 [1, null, 3, 4] [1, 2, 3, 4]
5 [11, null, null, 55] [1, 2, 3, 4]

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.

max_by(arr, weight) still uses the nullable weight column as an INT key. AggregateFunctionNullVariadicInline::add drops any row where an argument is NULL, so id=5's [11, null, null, 55] row (weight=NULL) cannot be selected; the maximum eligible weight is 5, yielding [1, null, 3, 4]. Please restore this expected value and retain the NULL-key case to verify it stays skipped.

@Mryange

Mryange commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@Mryange

Mryange commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

### What problem does this PR solve?

Issue Number: N/A

Problem Summary: Array NULL ordering changes also affect associated values selected by complex MIN_BY and MAX_BY regression queries. Update the remaining expected results to match the ordering keys exercised by each query.

### Release note

None

### Check List (For Author)

- Test: Regression test
    - test_aggregate_all_functions2
- Behavior changed: No
- Does this need documentation: No
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17619	3100	3115	3100
q2	2130	262	223	223
q3	10221	911	520	520
q4	4669	264	206	206
q5	7657	578	406	406
q6	138	117	95	95
q7	527	514	380	380
q8	9234	904	942	904
q9	3413	2411	2388	2388
q10	6519	852	719	719
q11	401	202	185	185
q12	615	259	202	202
q13	18140	1518	1166	1166
q14	159	156	138	138
q15	q16	451	401	369	369
q17	1342	871	823	823
q18	3047	2246	2233	2233
q19	1255	896	722	722
q20	385	291	203	203
q21	5625	1845	1922	1845
q22	324	262	228	228
Total cold run time: 93871 ms
Total hot run time: 17055 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3517	3429	3413	3413
q2	527	406	379	379
q3	2247	2303	2159	2159
q4	1202	1175	903	903
q5	2158	2086	2080	2080
q6	166	122	89	89
q7	1055	911	854	854
q8	1605	1416	1448	1416
q9	3136	3127	3115	3115
q10	1838	1777	1631	1631
q11	361	270	253	253
q12	455	425	353	353
q13	1466	1542	1159	1159
q14	179	168	165	165
q15	q16	397	394	368	368
q17	3577	3327	3175	3175
q18	4816	4485	4709	4485
q19	958	873	856	856
q20	1026	970	848	848
q21	3894	3247	3173	3173
q22	416	347	325	325
Total cold run time: 34996 ms
Total hot run time: 31199 ms

@hello-stephen

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

query5	4278	418	349	349
query6	394	131	134	131
query7	4924	399	229	229
query8	293	127	119	119
query9	8708	2908	2904	2904
query10	403	231	183	183
query11	5389	1051	911	911
query12	119	73	72	72
query13	1188	412	302	302
query14	6165	2203	2091	2091
query14_1	1988	2011	1967	1967
query15	178	123	115	115
query16	923	372	353	353
query17	802	452	368	368
query18	2336	320	235	235
query19	173	136	110	110
query20	74	72	71	71
query21	208	103	91	91
query22	5397	5396	5307	5307
query23	6808	6309	5992	5992
query23_1	6017	5992	6066	5992
query24	7281	1095	773	773
query24_1	755	792	801	792
query25	396	273	232	232
query26	1226	225	125	125
query27	2801	430	255	255
query28	4679	1495	1513	1495
query29	918	413	335	335
query30	253	153	129	129
query31	810	404	330	330
query32	125	68	72	68
query33	442	213	181	181
query34	995	838	503	503
query35	401	391	352	352
query36	574	551	534	534
query37	118	81	70	70
query38	1000	878	803	803
query39	472	496	477	477
query39_1	444	483	462	462
query40	196	90	79	79
query41	59	52	54	52
query42	73	74	72	72
query43	243	243	212	212
query44	1020	538	543	538
query45	119	107	101	101
query46	802	830	509	509
query47	752	770	709	709
query48	310	324	234	234
query49	524	234	186	186
query50	743	263	193	193
query51	8300	8227	8384	8227
query52	67	77	59	59
query53	191	197	146	146
query54	231	170	158	158
query55	83	59	55	55
query56	203	158	186	158
query57	686	673	720	673
query58	209	167	161	161
query59	1233	1262	1100	1100
query60	245	200	192	192
query61	120	134	117	117
query62	374	203	188	188
query63	175	143	146	143
query64	2941	793	639	639
query65	1631	1578	1565	1565
query66	1812	264	203	203
query67	9585	9551	9762	9551
query68	2750	1121	752	752
query69	337	226	201	201
query70	674	630	587	587
query71	240	176	167	167
query72	2263	1685	1496	1496
query73	625	618	345	345
query74	1571	1226	1137	1137
query75	1156	1095	958	958
query76	2291	753	535	535
query77	252	261	225	225
query78	3885	3668	3201	3201
query79	1828	841	588	588
query80	1203	324	269	269
query81	498	153	130	130
query82	627	121	93	93
query83	288	210	195	195
query84	287	114	91	91
query85	784	341	277	277
query86	384	181	177	177
query87	1010	975	893	893
query88	2773	2107	2105	2105
query89	278	198	175	175
query90	1953	135	129	129
query91	137	124	97	97
query92	82	62	69	62
query93	1393	1061	683	683
query94	635	268	224	224
query95	513	349	237	237
query96	792	536	272	272
query97	1049	1047	1028	1028
query98	146	134	132	132
query99	418	342	320	320
Total cold run time: 175911 ms
Total hot run time: 82000 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.08	0.04	0.03
query3	0.25	0.10	0.11
query4	1.60	0.10	0.11
query5	0.18	0.17	0.16
query6	1.23	0.69	0.69
query7	0.03	0.01	0.00
query8	0.05	0.03	0.03
query9	0.28	0.22	0.21
query10	0.34	0.35	0.34
query11	0.17	0.12	0.11
query12	0.14	0.12	0.12
query13	0.32	0.31	0.31
query14	0.45	0.44	0.44
query15	0.37	0.35	0.36
query16	0.23	0.23	0.21
query17	0.71	0.67	0.72
query18	0.18	0.17	0.16
query19	1.15	1.15	1.09
query20	0.02	0.01	0.01
query21	15.45	0.16	0.11
query22	5.06	0.05	0.04
query23	16.22	0.25	0.10
query24	3.01	0.31	0.24
query25	0.10	0.04	0.04
query26	0.74	0.17	0.11
query27	0.03	0.04	0.02
query28	3.62	0.60	0.28
query29	12.45	3.14	2.55
query30	0.25	0.13	0.12
query31	2.75	0.37	0.17
query32	3.52	0.31	0.24
query33	1.50	1.48	1.57
query34	15.36	2.23	1.77
query35	1.75	1.72	1.72
query36	0.45	0.30	0.27
query37	0.05	0.03	0.04
query38	0.05	0.03	0.03
query39	0.03	0.02	0.02
query40	0.11	0.08	0.07
query41	0.08	0.03	0.03
query42	0.03	0.02	0.03
query43	0.03	0.03	0.02
Total cold run time: 90.43 s
Total hot run time: 14.62 s

@Mryange

Mryange commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17650	3138	3089	3089
q2	2108	252	234	234
q3	10228	882	503	503
q4	4671	249	207	207
q5	7673	570	384	384
q6	140	113	91	91
q7	533	520	391	391
q8	9236	902	893	893
q9	3439	2390	2378	2378
q10	6500	832	722	722
q11	402	195	179	179
q12	620	261	198	198
q13	18122	1530	1159	1159
q14	158	151	139	139
q15	q16	425	394	365	365
q17	1395	921	864	864
q18	3069	2270	2229	2229
q19	1272	892	718	718
q20	379	279	202	202
q21	5619	1576	1846	1576
q22	326	269	229	229
Total cold run time: 93965 ms
Total hot run time: 16750 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3479	3454	3413	3413
q2	490	397	376	376
q3	2283	2271	2208	2208
q4	1194	1172	889	889
q5	2145	2085	2094	2085
q6	164	116	85	85
q7	1046	908	879	879
q8	1599	1414	1411	1411
q9	3102	3104	3100	3100
q10	1852	1781	1639	1639
q11	357	272	252	252
q12	448	426	348	348
q13	1496	1546	1158	1158
q14	176	180	162	162
q15	q16	400	403	355	355
q17	3583	3277	3174	3174
q18	4804	4376	4710	4376
q19	873	890	879	879
q20	988	962	843	843
q21	3868	3138	3266	3138
q22	398	344	328	328
Total cold run time: 34745 ms
Total hot run time: 31098 ms

@hello-stephen

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

query5	4249	395	341	341
query6	380	129	129	129
query7	4967	408	229	229
query8	285	124	119	119
query9	8707	2876	2867	2867
query10	409	231	181	181
query11	5372	1033	907	907
query12	112	71	70	70
query13	1188	420	340	340
query14	6145	2188	2076	2076
query14_1	1967	1958	1948	1948
query15	176	122	113	113
query16	922	367	364	364
query17	780	427	337	337
query18	2336	324	228	228
query19	160	141	102	102
query20	68	71	70	70
query21	206	98	83	83
query22	5307	5226	5255	5226
query23	6838	6192	5901	5901
query23_1	5987	5974	5975	5974
query24	7345	1079	773	773
query24_1	761	752	777	752
query25	409	269	224	224
query26	1237	225	121	121
query27	2796	426	259	259
query28	4689	1475	1462	1462
query29	916	416	329	329
query30	249	157	132	132
query31	822	391	322	322
query32	121	95	72	72
query33	451	198	165	165
query34	1004	821	479	479
query35	407	388	343	343
query36	562	529	525	525
query37	115	78	67	67
query38	1007	838	842	838
query39	473	490	474	474
query39_1	451	460	449	449
query40	198	87	77	77
query41	54	51	49	49
query42	72	70	68	68
query43	234	242	212	212
query44	1026	540	541	540
query45	106	102	97	97
query46	804	845	532	532
query47	747	757	710	710
query48	313	312	236	236
query49	524	224	189	189
query50	759	263	190	190
query51	8179	8205	8067	8067
query52	67	66	58	58
query53	203	201	148	148
query54	220	160	150	150
query55	73	61	58	58
query56	193	200	162	162
query57	658	662	658	658
query58	217	182	277	182
query59	1196	1224	1107	1107
query60	256	188	164	164
query61	127	133	124	124
query62	353	208	176	176
query63	172	145	142	142
query64	2805	775	655	655
query65	1604	1576	1618	1576
query66	1900	258	222	222
query67	9832	9790	9659	9659
query68	2997	1238	749	749
query69	349	222	206	206
query70	674	633	610	610
query71	257	177	164	164
query72	2260	1705	1467	1467
query73	668	592	337	337
query74	1981	1230	1115	1115
query75	1187	1094	948	948
query76	2379	727	534	534
query77	256	248	214	214
query78	3970	3692	3219	3219
query79	2922	789	567	567
query80	1548	331	297	297
query81	526	158	144	144
query82	635	135	95	95
query83	300	217	189	189
query84	300	108	91	91
query85	803	332	282	282
query86	482	173	172	172
query87	1017	971	894	894
query88	3907	2126	2106	2106
query89	274	196	176	176
query90	2170	132	130	130
query91	130	115	98	98
query92	98	73	67	67
query93	3257	1151	672	672
query94	654	255	180	180
query95	544	349	221	221
query96	830	567	284	284
query97	1049	1085	969	969
query98	200	140	132	132
query99	418	351	308	308
Total cold run time: 181758 ms
Total hot run time: 81398 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.08	0.04	0.04
query3	0.24	0.11	0.12
query4	1.61	0.10	0.09
query5	0.17	0.16	0.15
query6	1.28	0.68	0.70
query7	0.04	0.00	0.01
query8	0.05	0.04	0.03
query9	0.30	0.23	0.21
query10	0.35	0.35	0.35
query11	0.17	0.12	0.12
query12	0.14	0.12	0.12
query13	0.31	0.31	0.31
query14	0.45	0.46	0.47
query15	0.36	0.34	0.35
query16	0.22	0.21	0.23
query17	0.68	0.68	0.71
query18	0.19	0.16	0.17
query19	1.23	1.22	1.14
query20	0.02	0.01	0.01
query21	15.45	0.17	0.12
query22	5.05	0.05	0.04
query23	16.19	0.26	0.10
query24	3.04	0.31	0.25
query25	0.10	0.05	0.03
query26	0.79	0.16	0.14
query27	0.04	0.03	0.03
query28	3.61	0.59	0.29
query29	12.42	3.20	2.62
query30	0.25	0.11	0.11
query31	2.76	0.37	0.16
query32	3.52	0.33	0.22
query33	1.39	1.55	1.48
query34	15.42	2.16	1.74
query35	1.78	1.71	1.68
query36	0.46	0.30	0.29
query37	0.06	0.04	0.04
query38	0.05	0.03	0.03
query39	0.03	0.02	0.03
query40	0.12	0.07	0.08
query41	0.08	0.02	0.02
query42	0.03	0.02	0.03
query43	0.03	0.03	0.03
Total cold run time: 90.56 s
Total hot run time: 14.74 s

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants