Skip to content

[fix](nereids) Refresh signatures after type-changing rewrites - #67887

Open
morrySnow wants to merge 1 commit into
apache:masterfrom
morrySnow:fix/refresh-derived-struct-signatures
Open

[fix](nereids) Refresh signatures after type-changing rewrites#67887
morrySnow wants to merge 1 commit into
apache:masterfrom
morrySnow:fix/refresh-derived-struct-signatures

Conversation

@morrySnow

@morrySnow morrySnow commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Problem

Nereids rewrites preserve resolved function signatures so overload selection, coercion, and value-dependent precision remain stable. However, signatures for complex constructors also contain argument and return metadata derived from their current children. Reusing that metadata after outer-join nullability changes can make FE describe a nested struct differently from the column produced by BE.

An attempted raw-child type gate exposed the opposite failure: rewritten children may already have the resolved coercion type, so treating that as a new overload input can apply type promotion twice.

Root cause

The framework mixed two independent responsibilities:

  • the resolved function binding, whose overload, coercion, and precision decisions must remain frozen; and
  • child-derived complex metadata, which must follow current nested types and nullability.

Comparing current children with the origin function's raw children is not a safe boundary. For example, tiny integer literals resolve lcm(2, 4) to a SMALLINT signature. A rewrite supplies the already-coerced SMALLINT children; rejecting reuse and computing the signature again promotes them to INT, after which analysis rejects the SMALLINT arguments.

Reproduction

The CI witness is SELECT lcm(2, 4): the first resolution chooses SMALLINT, while a repeated signature computation chose INT and failed argument validation.

The complex-type regression constructs a map whose value is a datetime struct, passes it through map_entries and map_from_entries, and inspects the microsecond-bearing value. Before the fix, FE retained stale nested field nullability and BE rejected the declared/actual struct column mismatch. Outer-join tests cover nullable extension for struct, named_struct, nested structures, and to_json.

Fix

  • Always preserve an eligible origin function's already-resolved signature; do not compare rewritten children with pre-coercion raw children or repeat overload/signature computation.
  • Add a framework-level ChildDerivedSignature hook that refreshes only argument and return metadata owned by the current children, without searching overloads or rerunning generic promotion/precision logic.
  • Apply the hook to struct, named_struct, map, map_entries, map_from_entries, and complex-input to_json, keeping nested signatures self-consistent across the full propagation chain.
  • Reuse the exact signature object when the derived metadata is unchanged, preserving idempotence for same-type Slot replacement and ordinary precision functions.
  • Return a status rather than reaching a fatal backend cast when struct metadata is incompatible.

Tests

  • Focused red/green witness: the LCM test failed before the follow-up (expected SMALLINT, got INT) and passes after it.
  • DerivedFunctionSignatureTest, MapConstructionFunctionsTest, StructLiteralTest, and NullableAliasTest: 35 tests, 0 failures/errors.
  • derived_struct_signature regression: 1 suite, 0 failures/fatal scripts.
  • fold_constant_numeric_arithmatic regression: 1 suite, 0 failures/fatal scripts, including lcm(2, 4).
  • Full FE build/checkstyle passed with 0 Checkstyle violations.
  • The affected backend production and test translation units compiled with real build flags under clang 16. A fresh GCC 11 unit-test tree was blocked by an existing C++20 toolchain incompatibility, so backend runtime coverage is left to CI.

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

@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@morrySnow
morrySnow force-pushed the fix/refresh-derived-struct-signatures branch from 7824e24 to 893e26c Compare September 11, 2026 18:36
@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 91.67% (11/12) 🎉
Increment coverage report
Complete coverage report

@morrySnow
morrySnow force-pushed the fix/refresh-derived-struct-signatures branch from 893e26c to 98b4312 Compare September 11, 2026 20:51
@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 91.67% (11/12) 🎉
Increment coverage report
Complete coverage report

@morrySnow morrySnow changed the title [fix](nereids) Refresh derived struct signatures after rewrites [fix](function) Refresh derived struct signatures after rewrites Sep 12, 2026
@morrySnow
morrySnow marked this pull request as draft September 12, 2026 03:08
@morrySnow
morrySnow force-pushed the fix/refresh-derived-struct-signatures branch from 98b4312 to 281f985 Compare September 12, 2026 10:00
@morrySnow morrySnow changed the title [fix](function) Refresh derived struct signatures after rewrites [fix](nereids) Refresh signatures after type-changing rewrites Sep 12, 2026
@morrySnow
morrySnow marked this pull request as ready for review September 12, 2026 10:00
@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17652	3050	3076	3050
q2	2096	264	221	221
q3	10238	874	527	527
q4	4670	253	214	214
q5	7659	587	388	388
q6	142	120	95	95
q7	534	512	391	391
q8	9235	894	976	894
q9	3455	2434	2418	2418
q10	6524	863	728	728
q11	388	198	181	181
q12	619	262	199	199
q13	18129	1553	1150	1150
q14	155	155	144	144
q15	q16	434	400	381	381
q17	1438	876	797	797
q18	3165	2347	2295	2295
q19	1270	890	789	789
q20	378	292	196	196
q21	5626	1701	1899	1701
q22	324	272	229	229
Total cold run time: 94131 ms
Total hot run time: 16988 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3405	3357	3340	3340
q2	495	392	379	379
q3	2245	2311	2151	2151
q4	1203	1178	921	921
q5	2204	2162	2147	2147
q6	175	118	86	86
q7	1034	931	847	847
q8	1601	1420	1415	1415
q9	3189	3158	3154	3154
q10	1887	1838	1666	1666
q11	359	273	254	254
q12	461	430	345	345
q13	1494	1567	1171	1171
q14	183	170	166	166
q15	q16	398	407	365	365
q17	3660	3433	3266	3266
q18	4922	4525	4952	4525
q19	952	851	856	851
q20	1005	998	820	820
q21	3844	3227	3231	3227
q22	396	352	335	335
Total cold run time: 35112 ms
Total hot run time: 31431 ms

@hello-stephen

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

query5	4251	420	364	364
query6	388	139	125	125
query7	4914	418	239	239
query8	319	132	125	125
query9	8719	2938	2904	2904
query10	402	222	183	183
query11	5402	1076	947	947
query12	124	74	76	74
query13	1192	454	327	327
query14	6093	2250	2109	2109
query14_1	2010	2008	1992	1992
query15	177	120	111	111
query16	916	384	367	367
query17	798	440	376	376
query18	2345	353	238	238
query19	167	140	110	110
query20	92	73	73	73
query21	202	102	87	87
query22	5423	5398	5540	5398
query23	7122	6505	6188	6188
query23_1	6176	6179	6147	6147
query24	7234	1103	765	765
query24_1	760	783	796	783
query25	436	298	270	270
query26	1234	227	133	133
query27	2782	398	255	255
query28	4702	1512	1517	1512
query29	926	441	350	350
query30	251	159	134	134
query31	826	417	347	347
query32	131	76	74	74
query33	471	222	177	177
query34	1003	827	486	486
query35	408	438	357	357
query36	580	562	533	533
query37	121	81	74	74
query38	1015	853	853	853
query39	506	498	483	483
query39_1	472	463	465	463
query40	206	94	80	80
query41	60	58	60	58
query42	77	76	74	74
query43	251	242	212	212
query44	1006	542	526	526
query45	118	111	107	107
query46	815	850	550	550
query47	778	789	731	731
query48	322	325	239	239
query49	581	235	186	186
query50	757	268	201	201
query51	8197	8182	8148	8148
query52	74	67	59	59
query53	208	240	151	151
query54	221	173	161	161
query55	77	59	55	55
query56	217	192	155	155
query57	700	635	684	635
query58	189	164	163	163
query59	1219	1249	1119	1119
query60	233	204	174	174
query61	120	109	113	109
query62	339	198	180	180
query63	183	141	142	141
query64	2683	667	651	651
query65	1652	1642	1743	1642
query66	1804	251	194	194
query67	10287	9959	9793	9793
query68	3012	1172	705	705
query69	353	223	212	212
query70	672	667	643	643
query71	258	186	157	157
query72	2333	1687	1522	1522
query73	650	588	336	336
query74	1995	1247	1164	1164
query75	1188	1128	976	976
query76	2385	713	544	544
query77	260	270	215	215
query78	4045	3757	3298	3298
query79	2362	876	607	607
query80	1612	332	273	273
query81	492	160	138	138
query82	624	132	97	97
query83	278	216	193	193
query84	295	112	87	87
query85	776	342	283	283
query86	389	183	175	175
query87	1031	997	906	906
query88	2777	2128	2133	2128
query89	282	198	177	177
query90	2035	132	132	132
query91	137	124	96	96
query92	81	73	70	70
query93	1365	1073	666	666
query94	640	244	215	215
query95	517	246	308	246
query96	835	619	283	283
query97	1078	1114	1014	1014
query98	144	137	142	137
query99	430	348	313	313
Total cold run time: 179209 ms
Total hot run time: 83247 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.07	0.04	0.04
query3	0.25	0.10	0.12
query4	1.60	0.10	0.10
query5	0.18	0.16	0.16
query6	1.23	0.71	0.70
query7	0.03	0.00	0.00
query8	0.04	0.03	0.03
query9	0.29	0.22	0.22
query10	0.36	0.34	0.35
query11	0.16	0.12	0.12
query12	0.15	0.13	0.12
query13	0.31	0.30	0.31
query14	0.45	0.47	0.47
query15	0.38	0.34	0.34
query16	0.21	0.24	0.22
query17	0.70	0.74	0.71
query18	0.19	0.17	0.17
query19	1.17	1.18	1.14
query20	0.01	0.01	0.01
query21	15.44	0.15	0.12
query22	5.04	0.04	0.05
query23	16.17	0.25	0.12
query24	2.99	0.34	0.25
query25	0.09	0.04	0.04
query26	0.76	0.16	0.13
query27	0.03	0.03	0.03
query28	3.62	0.55	0.28
query29	12.41	3.12	2.58
query30	0.25	0.12	0.13
query31	2.75	0.39	0.17
query32	3.51	0.33	0.24
query33	1.37	1.54	1.55
query34	15.37	2.25	1.88
query35	1.83	1.77	1.74
query36	0.46	0.30	0.29
query37	0.06	0.03	0.04
query38	0.05	0.03	0.03
query39	0.03	0.03	0.02
query40	0.11	0.07	0.09
query41	0.07	0.02	0.03
query42	0.03	0.02	0.02
query43	0.03	0.03	0.03
Total cold run time: 90.25 s
Total hot run time: 15.08 s

### What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: Nereids rewrites intentionally preserve a bound function's resolved signature so overload selection, coercion, and value-dependent precision remain stable. A raw-child type gate confused pre-coercion literals with rewritten children that already carried the resolved argument types: recomputing lcm after TINYINT-to-SMALLINT promotion promoted the signature a second time to INT and caused analysis to reject valid SMALLINT children. At the same time, unconditional reuse can leave nested struct, map, and array metadata stale when an outer-join rewrite changes child nullability. Preserve the resolved binding for every eligible rewrite and add a targeted child-derived signature hook that refreshes only current-child complex metadata without searching overloads or rerunning generic signature computation. The hook keeps argument and return metadata self-consistent for struct/map constructors, map entry conversions, and to_json, while retaining object identity when metadata is unchanged. Return a backend status for incompatible struct metadata rather than reaching a fatal cast.

### Release note

Rewritten function signatures keep their resolved overload and promotion decisions while nested complex-type metadata follows current child nullability, preventing both repeated type promotion and struct-column mismatches.

### Check List (For Author)

- Test:
    - Unit Test: DerivedFunctionSignatureTest, MapConstructionFunctionsTest, StructLiteralTest, and NullableAliasTest (35 tests).
    - Regression test: derived_struct_signature (1 suite, 0 failures/fatal scripts).
    - Regression test: fold_constant_numeric_arithmatic (1 suite, 0 failures/fatal scripts), including lcm(2, 4).
    - Build/checkstyle: DISABLE_BUILD_UI=ON ./build.sh --fe (success, 0 Checkstyle violations).
    - Backend validation: affected production and test translation units compiled with the real build flags under clang 16; the fresh GCC 11 unit-test tree was blocked by an existing C++20 toolchain incompatibility.
- Behavior changed: Yes. Resolved overload, coercion, and precision decisions remain frozen across equivalent rewrites; only explicitly child-derived complex signature metadata is refreshed from current children.
- Does this need documentation: No.
@morrySnow
morrySnow force-pushed the fix/refresh-derived-struct-signatures branch from 281f985 to 1196eb9 Compare September 12, 2026 11:40
@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17677	3062	3051	3051
q2	2048	250	215	215
q3	10285	857	499	499
q4	4670	251	201	201
q5	7679	559	387	387
q6	137	110	93	93
q7	522	502	379	379
q8	9243	826	840	826
q9	3475	2395	2411	2395
q10	6525	839	722	722
q11	393	197	178	178
q12	613	252	199	199
q13	18132	1534	1168	1168
q14	155	151	138	138
q15	q16	434	394	369	369
q17	1406	853	828	828
q18	3076	2315	2260	2260
q19	1260	828	788	788
q20	381	282	206	206
q21	5609	1729	1801	1729
q22	328	266	227	227
Total cold run time: 94048 ms
Total hot run time: 16858 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	3422	3391	3346	3346
q2	515	392	373	373
q3	2191	2282	2191	2191
q4	1196	1174	899	899
q5	2198	2149	2130	2130
q6	163	118	93	93
q7	1062	940	867	867
q8	1593	1419	1387	1387
q9	3159	3134	3145	3134
q10	1846	1811	1638	1638
q11	352	276	252	252
q12	448	430	337	337
q13	1486	1511	1146	1146
q14	181	169	161	161
q15	q16	394	394	358	358
q17	3576	3364	3311	3311
q18	4813	4468	4723	4468
q19	847	899	868	868
q20	989	951	839	839
q21	3842	3298	3211	3211
q22	394	353	314	314
Total cold run time: 34667 ms
Total hot run time: 31323 ms

@hello-stephen

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

query5	4249	413	335	335
query6	378	139	124	124
query7	4953	438	229	229
query8	293	127	120	120
query9	8681	2893	2904	2893
query10	389	215	186	186
query11	5398	1032	911	911
query12	122	72	72	72
query13	1190	475	342	342
query14	6110	2214	2069	2069
query14_1	1966	1969	1952	1952
query15	175	123	106	106
query16	897	369	339	339
query17	751	431	340	340
query18	2310	311	230	230
query19	155	135	103	103
query20	75	70	70	70
query21	199	101	88	88
query22	5385	5233	5248	5233
query23	6674	6242	5826	5826
query23_1	6007	6083	6034	6034
query24	7280	1102	789	789
query24_1	771	762	761	761
query25	403	289	248	248
query26	1212	243	127	127
query27	2780	429	252	252
query28	4703	1492	1485	1485
query29	928	429	356	356
query30	251	155	134	134
query31	823	401	323	323
query32	126	74	76	74
query33	462	221	188	188
query34	988	819	490	490
query35	407	410	351	351
query36	582	594	530	530
query37	118	87	73	73
query38	1002	856	855	855
query39	489	469	469	469
query39_1	475	464	470	464
query40	208	94	78	78
query41	58	59	57	57
query42	75	74	73	73
query43	242	240	215	215
query44	992	529	542	529
query45	113	112	104	104
query46	763	852	536	536
query47	758	762	719	719
query48	329	313	229	229
query49	541	248	213	213
query50	766	244	198	198
query51	8294	8319	8268	8268
query52	69	71	59	59
query53	198	202	143	143
query54	204	162	166	162
query55	80	65	56	56
query56	207	184	175	175
query57	714	739	621	621
query58	202	161	160	160
query59	1241	1224	1099	1099
query60	224	177	175	175
query61	99	106	121	106
query62	358	210	181	181
query63	169	140	140	140
query64	2632	709	628	628
query65	1704	1587	1607	1587
query66	1864	274	207	207
query67	9856	9984	9850	9850
query68	2860	1232	754	754
query69	332	225	189	189
query70	668	639	641	639
query71	250	213	164	164
query72	2220	1683	1475	1475
query73	673	599	336	336
query74	1821	1221	1162	1162
query75	1201	1101	974	974
query76	2295	703	531	531
query77	250	262	219	219
query78	4125	3645	3299	3299
query79	2720	798	568	568
query80	1584	321	270	270
query81	508	153	133	133
query82	626	128	98	98
query83	270	209	193	193
query84	295	113	92	92
query85	787	348	281	281
query86	469	194	163	163
query87	1017	976	887	887
query88	2985	2103	2083	2083
query89	286	199	174	174
query90	2141	134	131	131
query91	127	119	97	97
query92	89	70	72	70
query93	1893	1085	687	687
query94	636	227	205	205
query95	522	331	233	233
query96	820	596	257	257
query97	1047	1022	1022	1022
query98	173	136	137	136
query99	417	340	309	309
Total cold run time: 178644 ms
Total hot run time: 82107 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.08	0.04	0.04
query3	0.24	0.11	0.11
query4	1.60	0.10	0.10
query5	0.17	0.15	0.16
query6	1.27	0.68	0.70
query7	0.04	0.01	0.00
query8	0.05	0.03	0.03
query9	0.29	0.22	0.21
query10	0.36	0.34	0.35
query11	0.16	0.12	0.12
query12	0.15	0.13	0.12
query13	0.31	0.30	0.32
query14	0.45	0.46	0.46
query15	0.37	0.34	0.34
query16	0.23	0.24	0.22
query17	0.67	0.66	0.69
query18	0.17	0.17	0.17
query19	1.21	1.15	1.12
query20	0.02	0.01	0.01
query21	15.43	0.17	0.12
query22	5.04	0.04	0.04
query23	16.19	0.27	0.10
query24	3.02	0.33	0.25
query25	0.10	0.04	0.03
query26	0.81	0.16	0.11
query27	0.03	0.02	0.03
query28	3.66	0.56	0.29
query29	12.45	3.22	2.64
query30	0.26	0.11	0.11
query31	2.76	0.39	0.18
query32	3.51	0.32	0.24
query33	1.36	1.40	1.51
query34	15.38	2.21	1.79
query35	1.77	1.75	1.75
query36	0.46	0.31	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.11	0.08	0.08
query41	0.08	0.03	0.02
query42	0.03	0.03	0.02
query43	0.04	0.03	0.02
Total cold run time: 90.48 s
Total hot run time: 14.77 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