Skip to content

[fix](iceberg) Honor partial name mappings for legacy files#65784

Open
Gabriel39 wants to merge 12 commits into
apache:masterfrom
Gabriel39:ai/doris-27020-strict-partial-name-mapping
Open

[fix](iceberg) Honor partial name mappings for legacy files#65784
Gabriel39 wants to merge 12 commits into
apache:masterfrom
Gabriel39:ai/doris-27020-strict-partial-name-mapping

Conversation

@Gabriel39

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: Legacy Iceberg Parquet and ORC files without field IDs are resolved through name mapping. With a partial mapping, FE omitted the optional mapping metadata for unmapped fields, so both V1 and V2 BE readers fell back to the current physical name and read unrelated data.

This change preserves table-level mapping presence by transporting explicit empty per-field lists and makes those lists authoritative in both readers. Unmapped fields now materialize their default or NULL, while mapped aliases and scans without name mapping retain their existing behavior.

Release note

Fix reads of migrated Iceberg files with partial name mapping so fields omitted from the mapping materialize their default value or NULL instead of matching a physical column by the current name.

Check List (For Author)

  • Test: Unit Test
    • ExternalUtilTest (6 tests)
    • Focused V1 and V2 name-mapping BE unit tests under ASAN (10 tests)
  • Behavior changed: Yes. Partial Iceberg name mappings are now authoritative for legacy files without field IDs.
  • Does this need documentation: No

### What problem does this PR solve?

Issue Number: N/A

Related PR: N/A

Problem Summary: Legacy Iceberg Parquet and ORC files without field IDs are resolved through name mapping. With a partial mapping, FE omitted the optional mapping metadata for unmapped fields, so both V1 and V2 BE readers fell back to the current physical name and read unrelated data. Preserve table-level mapping presence by transporting explicit empty per-field lists and make those lists authoritative in both readers, so unmapped fields materialize their default or NULL while mapped aliases and scans without name mapping retain their existing behavior.

### Release note

Fix reads of migrated Iceberg files with partial name mapping so fields omitted from the mapping materialize their default value or NULL instead of matching a physical column by the current name.

### Check List (For Author)

- Test: Unit Test
    - ExternalUtilTest
    - Focused V1 and V2 name-mapping BE unit tests under ASAN
- Behavior changed: Yes. Partial Iceberg name mappings are now authoritative for legacy files without field IDs.
- Does this need documentation: No
@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 18, 2026 13:03
@Gabriel39
Gabriel39 requested a review from yiguolei as a code owner July 18, 2026 13:03
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17697	4015	4010	4010
q2	2031	317	197	197
q3	10257	1418	797	797
q4	4686	465	340	340
q5	7491	831	558	558
q6	176	170	136	136
q7	726	824	616	616
q8	9939	1499	1520	1499
q9	6239	4341	4346	4341
q10	6825	1734	1456	1456
q11	515	361	317	317
q12	732	570	452	452
q13	18119	3314	2726	2726
q14	267	258	248	248
q15	q16	782	777	701	701
q17	1037	1030	1094	1030
q18	6712	5729	5420	5420
q19	1516	1358	1047	1047
q20	784	668	541	541
q21	5957	2627	2274	2274
q22	424	352	292	292
Total cold run time: 102912 ms
Total hot run time: 28998 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4412	4373	4386	4373
q2	309	319	213	213
q3	4679	5034	4400	4400
q4	2049	2180	1366	1366
q5	4368	4246	4242	4242
q6	236	181	122	122
q7	1715	2077	1730	1730
q8	2454	2176	2134	2134
q9	7792	7679	7691	7679
q10	4680	4654	4214	4214
q11	629	407	369	369
q12	868	834	576	576
q13	3303	3572	2945	2945
q14	316	307	259	259
q15	q16	721	722	648	648
q17	1333	1334	1295	1295
q18	7983	7339	6860	6860
q19	1128	1080	1061	1061
q20	2229	2190	1944	1944
q21	5213	4492	4420	4420
q22	523	455	402	402
Total cold run time: 56940 ms
Total hot run time: 51252 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 completed against the current head after three convergence rounds. Two blocking correctness issues remain.

Checkpoint conclusions:

  • Goal/minimality: the patch fixes top-level non-empty partial mappings, but the same authoritative-presence contract is incomplete for nested V2 projections and for a present globally empty mapping. The changes are otherwise focused.
  • Flow/parallel paths: traced FE extraction and Thrift transport through V1 Parquet/ORC, V2 field-id/BY_NAME mapping, nested projection, equality-delete hidden dependencies, and position-delete/deletion-vector paths. No additional reachable defect survived convergence.
  • Compatibility/state: no wire type, persisted format, configuration, concurrency, locking, lifecycle, or ownership contract changes were introduced. Mixed-version descriptors retain the pre-existing behavior rather than creating a new serialization incompatibility.
  • Tests: the added tests cover scalar top-level non-empty partial mappings, but not whole/pruned nested materialization or absent-versus-present-[] transport/results.
  • Performance/observability: the added metadata bit has negligible cost and is included in debug output; no per-row hot-path regression was found.
  • Validation: static review only, as required by the review task. Remote compile, CheckStyle, clang-format, license, secret, and dependency checks pass. The macOS BE UT workflow failed because it selected JDK 25 while the build requires JDK 17; Doris BE/FE and regression jobs were still running at submission.

Requesting changes because both findings can silently bind unrelated legacy values instead of producing the Iceberg initial default/NULL.

Comment thread be/src/format_v2/table_reader.cpp
Comment thread fe/fe-core/src/main/java/org/apache/doris/datasource/ExternalUtil.java Outdated
@hello-stephen

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

query5	4312	618	476	476
query6	475	230	215	215
query7	4858	566	333	333
query8	338	189	177	177
query9	8809	4046	4061	4046
query10	474	373	305	305
query11	6117	2354	2126	2126
query12	162	103	104	103
query13	1323	606	436	436
query14	6576	5221	4932	4932
query14_1	4285	4259	4251	4251
query15	219	212	185	185
query16	1016	467	405	405
query17	1128	715	584	584
query18	2717	482	347	347
query19	217	189	149	149
query20	114	109	108	108
query21	240	156	134	134
query22	13552	13613	13430	13430
query23	17286	16503	16084	16084
query23_1	16233	16262	16202	16202
query24	7454	1730	1292	1292
query24_1	1317	1248	1247	1247
query25	586	479	396	396
query26	1330	354	223	223
query27	2615	602	381	381
query28	4458	1983	2009	1983
query29	1157	630	508	508
query30	344	273	233	233
query31	1117	1090	975	975
query32	114	63	63	63
query33	536	313	256	256
query34	1149	1127	665	665
query35	761	797	663	663
query36	1193	1190	1094	1094
query37	152	104	87	87
query38	1892	1699	1666	1666
query39	887	871	831	831
query39_1	825	840	882	840
query40	247	163	142	142
query41	64	61	62	61
query42	96	93	90	90
query43	326	323	285	285
query44	1409	781	756	756
query45	195	187	172	172
query46	1047	1216	714	714
query47	2126	2099	2042	2042
query48	411	387	302	302
query49	583	414	307	307
query50	1040	440	339	339
query51	10528	10835	10537	10537
query52	85	87	79	79
query53	261	279	201	201
query54	281	234	219	219
query55	78	70	65	65
query56	310	287	289	287
query57	1326	1300	1257	1257
query58	287	269	236	236
query59	1558	1640	1424	1424
query60	338	272	276	272
query61	146	148	146	146
query62	535	496	428	428
query63	240	204	204	204
query64	2759	1026	888	888
query65	4715	4682	4645	4645
query66	1780	526	381	381
query67	29408	29263	29087	29087
query68	3043	1475	966	966
query69	400	287	300	287
query70	1054	974	942	942
query71	382	343	316	316
query72	3003	2667	2319	2319
query73	850	737	440	440
query74	5068	4911	4687	4687
query75	2521	2503	2136	2136
query76	2368	1176	765	765
query77	349	375	284	284
query78	11927	11937	11290	11290
query79	1478	1156	730	730
query80	1296	550	461	461
query81	576	332	283	283
query82	606	159	126	126
query83	373	331	298	298
query84	281	168	131	131
query85	987	625	519	519
query86	436	287	274	274
query87	1824	1825	1756	1756
query88	3733	2805	2778	2778
query89	434	374	318	318
query90	1910	193	198	193
query91	197	187	161	161
query92	59	61	52	52
query93	1663	1463	999	999
query94	740	352	308	308
query95	771	515	477	477
query96	1061	852	351	351
query97	2625	2630	2474	2474
query98	217	212	202	202
query99	1105	1114	976	976
Total cold run time: 264178 ms
Total hot run time: 177114 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 d3b1a185a56a52f50eebb0b1748f884308852fbe, data reload: false

query1	0.01	0.01	0.01
query2	0.09	0.04	0.05
query3	0.26	0.14	0.13
query4	1.62	0.13	0.14
query5	0.24	0.22	0.22
query6	1.29	1.05	1.05
query7	0.04	0.00	0.00
query8	0.06	0.04	0.03
query9	0.37	0.33	0.33
query10	0.57	0.55	0.54
query11	0.19	0.14	0.15
query12	0.19	0.14	0.14
query13	0.45	0.47	0.47
query14	1.02	1.01	1.02
query15	0.61	0.59	0.60
query16	0.31	0.33	0.32
query17	1.11	1.07	1.09
query18	0.22	0.20	0.20
query19	2.03	1.92	1.98
query20	0.02	0.02	0.01
query21	15.41	0.19	0.13
query22	4.93	0.06	0.05
query23	16.16	0.31	0.11
query24	3.08	0.42	0.31
query25	0.12	0.05	0.03
query26	0.74	0.21	0.14
query27	0.05	0.03	0.03
query28	3.51	0.97	0.54
query29	12.49	4.12	3.29
query30	0.28	0.15	0.15
query31	2.77	0.60	0.30
query32	3.23	0.59	0.49
query33	3.18	3.22	3.18
query34	15.65	4.20	3.52
query35	3.51	3.50	3.53
query36	0.56	0.43	0.43
query37	0.10	0.06	0.07
query38	0.04	0.04	0.03
query39	0.04	0.03	0.03
query40	0.19	0.16	0.16
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.9 s
Total hot run time: 24.91 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (13/13) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 57.44% (23945/41688)
Line Coverage 41.17% (235514/572026)
Region Coverage 37.00% (186115/502950)
Branch Coverage 38.20% (83567/218786)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (3/3) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (13/13) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 73.41% (29854/40666)
Line Coverage 57.24% (325419/568507)
Region Coverage 53.73% (271233/504842)
Branch Coverage 54.66% (119658/218928)

@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: 29403 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit c88080583101fe53c759f205ff66fb1c54ee411d, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17630	4132	4081	4081
q2	1992	334	211	211
q3	10262	1418	841	841
q4	4677	467	336	336
q5	7477	835	553	553
q6	189	183	141	141
q7	754	818	615	615
q8	9786	1670	1537	1537
q9	6167	4312	4313	4312
q10	6808	1743	1477	1477
q11	513	347	319	319
q12	745	578	459	459
q13	18120	3346	2728	2728
q14	266	279	247	247
q15	q16	787	778	711	711
q17	1036	935	908	908
q18	6925	5781	5479	5479
q19	1364	1284	1057	1057
q20	789	725	643	643
q21	5862	2602	2454	2454
q22	440	368	294	294
Total cold run time: 102589 ms
Total hot run time: 29403 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4466	4381	4321	4321
q2	281	313	208	208
q3	4584	4938	4413	4413
q4	2074	2148	1371	1371
q5	4429	4339	4331	4331
q6	233	177	134	134
q7	1725	2177	1736	1736
q8	2504	2206	2228	2206
q9	7888	7689	7721	7689
q10	4680	4666	4188	4188
q11	566	425	385	385
q12	860	816	530	530
q13	3346	3534	3072	3072
q14	304	316	278	278
q15	q16	690	722	665	665
q17	1363	1332	1341	1332
q18	7947	7330	6873	6873
q19	1137	1074	1073	1073
q20	2214	2211	1935	1935
q21	5231	4563	4509	4509
q22	505	455	424	424
Total cold run time: 57027 ms
Total hot run time: 51673 ms

@hello-stephen

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

query5	4321	615	495	495
query6	469	225	213	213
query7	4844	608	350	350
query8	332	184	167	167
query9	8808	4035	4056	4035
query10	479	381	312	312
query11	5926	2342	2139	2139
query12	154	104	103	103
query13	1281	601	425	425
query14	6256	5178	4876	4876
query14_1	4203	4219	4256	4219
query15	210	201	181	181
query16	1008	477	456	456
query17	1135	746	566	566
query18	2486	495	348	348
query19	207	227	148	148
query20	115	113	113	113
query21	229	159	138	138
query22	13443	13647	13234	13234
query23	17280	16482	16113	16113
query23_1	16200	16280	16195	16195
query24	7680	1753	1276	1276
query24_1	1331	1280	1282	1280
query25	578	458	385	385
query26	1350	363	216	216
query27	2676	576	385	385
query28	4431	2015	1986	1986
query29	1100	615	500	500
query30	339	264	233	233
query31	1114	1094	1001	1001
query32	109	59	58	58
query33	506	313	237	237
query34	1152	1153	639	639
query35	753	802	661	661
query36	1169	1163	1054	1054
query37	154	104	94	94
query38	1873	1700	1672	1672
query39	870	866	848	848
query39_1	842	836	835	835
query40	245	168	139	139
query41	69	64	62	62
query42	92	94	96	94
query43	327	321	275	275
query44	1418	753	737	737
query45	188	184	175	175
query46	1060	1162	726	726
query47	2132	2173	1997	1997
query48	384	391	295	295
query49	574	420	301	301
query50	1065	441	335	335
query51	10449	10571	10577	10571
query52	86	87	75	75
query53	258	279	199	199
query54	275	223	218	218
query55	76	71	68	68
query56	319	295	288	288
query57	1318	1281	1209	1209
query58	272	270	252	252
query59	1556	1639	1434	1434
query60	293	270	259	259
query61	150	148	142	142
query62	545	495	433	433
query63	244	206	200	200
query64	2827	1037	876	876
query65	4752	4632	4604	4604
query66	1817	512	377	377
query67	29189	29140	29017	29017
query68	2986	1489	1004	1004
query69	402	303	270	270
query70	1081	946	977	946
query71	393	330	334	330
query72	3018	2645	2355	2355
query73	858	771	423	423
query74	5042	4895	4713	4713
query75	2495	2481	2129	2129
query76	2336	1153	778	778
query77	354	374	279	279
query78	11901	11907	11160	11160
query79	1506	1150	792	792
query80	1271	544	457	457
query81	570	339	283	283
query82	617	154	120	120
query83	359	319	309	309
query84	292	158	137	137
query85	960	602	513	513
query86	433	280	273	273
query87	1827	1822	1732	1732
query88	3655	2782	2780	2780
query89	437	378	320	320
query90	1960	204	196	196
query91	206	193	171	171
query92	63	62	55	55
query93	1693	1473	996	996
query94	717	364	309	309
query95	802	518	565	518
query96	1133	777	337	337
query97	2622	2623	2528	2528
query98	218	206	196	196
query99	1090	1112	966	966
Total cold run time: 262890 ms
Total hot run time: 177192 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.09	0.05	0.05
query3	0.25	0.14	0.13
query4	1.62	0.14	0.14
query5	0.24	0.24	0.22
query6	1.23	1.07	1.08
query7	0.04	0.01	0.00
query8	0.06	0.03	0.04
query9	0.38	0.31	0.32
query10	0.56	0.56	0.54
query11	0.20	0.15	0.14
query12	0.18	0.14	0.14
query13	0.47	0.48	0.47
query14	1.03	1.02	1.01
query15	0.63	0.61	0.60
query16	0.32	0.31	0.32
query17	1.17	1.10	1.15
query18	0.22	0.20	0.20
query19	2.10	1.92	1.93
query20	0.02	0.01	0.02
query21	15.43	0.21	0.13
query22	4.85	0.05	0.05
query23	16.13	0.30	0.13
query24	2.90	0.45	0.34
query25	0.10	0.05	0.04
query26	0.73	0.22	0.14
query27	0.04	0.03	0.03
query28	3.54	0.87	0.53
query29	12.47	4.18	3.30
query30	0.30	0.15	0.15
query31	2.77	0.61	0.32
query32	3.22	0.59	0.50
query33	3.16	3.19	3.22
query34	15.61	4.19	3.54
query35	3.51	3.48	3.57
query36	0.56	0.42	0.43
query37	0.09	0.06	0.07
query38	0.05	0.05	0.04
query39	0.04	0.03	0.03
query40	0.18	0.16	0.16
query41	0.10	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.68 s
Total hot run time: 25.07 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.

Requesting changes: two P1 correctness blockers remain.

Critical checkpoint conclusions

  • Goal: The patch correctly preserves authoritative Iceberg mapping presence for ordinary same-version ID-less legacy reads, but it does not preserve matching IDs in mixed-ID files and is not semantically stable across the supported rolling-upgrade phases.
  • Scope and minimality: The implementation is otherwise focused on FE transport plus V1/V2 name matching; the two existing review threads for valid root [] presence and nested presence propagation are fixed on the current head.
  • Concurrency: No new threads, shared mutable state, locks, or lock-order concerns are introduced.
  • Lifecycle: No static-initialization, ownership, or special resource-lifecycle behavior changes.
  • Configuration: No configuration item is added or changed.
  • Compatibility: TField.name_mapping remains wire-decodable, but its interpretation changes without version negotiation. Old/new BEs can split one scan during BE-first rollout, and old/new FEs can produce different plans during the following FE rollout (second inline finding).
  • Parallel paths: FE regular/system-table schemas, hidden equality-delete dependencies, V1/V2, Parquet/ORC, whole/pruned complex fields, and position-delete paths were traced. V1 and V2 both globally downgrade mixed-ID schemas and lose an authoritative matching ID (first inline finding).
  • Conditional logic: The new mapping-presence condition is documented and propagated through the changed builders, but the surrounding all-fields-have-IDs condition is too coarse for the strict branch. No other distinct conditional-path issue survived review.
  • Test coverage: Added FE and BE unit tests cover absent, empty, partial, and nested presence/helper state, but miss mixed-ID Parquet/ORC behavior, old-FE/mixed-BE and mixed-FE execution, and the resulting observable value/default behavior.
  • Test results: No regression output file is changed. This review was static-only as required by the task; no local build or test was run.
  • Observability: Existing parse-failure logging is sufficient for the new FE parse path; the accepted failures are silent wrong-result cases that require correctness fixes rather than additional logging.
  • Persistence and transactions: No EditLog, persisted format, transaction, or failover behavior changes.
  • Data writes: This is a read-path change and introduces no write atomicity or crash-recovery concern.
  • FE/BE state transport: All same-version mapping send/copy sites were checked. The existing optional list and new local presence bit are propagated, but the missing semantic version is the rolling-compatibility blocker above.
  • Performance and memory: The metadata boolean and small mapping copies add no material CPU, memory, allocation, or hot-path concern.
  • Other issues, focus, and completion: No additional user focus was supplied. After three normal/risk-focused convergence rounds, every candidate is accepted, deduplicated, or dismissed and all final reviewers returned NO_NEW_VALUABLE_FINDINGS on this exact two-comment set. The full review is complete.

Comment thread be/src/format/table/table_schema_change_helper.cpp Outdated
Comment thread be/src/format_v2/column_mapper.cpp
@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 100.00% (14/14) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 57.48% (23963/41688)
Line Coverage 41.23% (235862/572027)
Region Coverage 37.02% (186200/502950)
Branch Coverage 38.23% (83647/218786)

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (14/14) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 74.96% (30485/40666)
Line Coverage 59.12% (336086/568508)
Region Coverage 55.85% (281962/504842)
Branch Coverage 57.17% (125155/218928)

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

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.

Requesting changes: three P1 correctness blockers remain.

Critical checkpoint conclusions

  • Goal and tests: The patch moves V1 and V2 toward Iceberg's any-ID rule and preserves explicit mapping presence, but ID-less nested wrappers still diverge by scanner/format, nested binary initial defaults are lost during projection, and an unchanged V2 equality-delete test is deterministically contradicted by the new mode. The added tests primarily assert helper or transport state and do not cover these observable results.
  • Scope and minimality: The implementation is focused on FE mapping extraction/Thrift transport and BE matching. No unrelated production changes were found.
  • Concurrency, lifecycle, configuration, persistence, and writes: No new thread, lock, ownership, startup/shutdown, configuration, persisted-state, transaction, or data-write contract is introduced.
  • Compatibility and protocol: The optional Thrift presence marker is produced and consumed consistently on same-version paths, and absent old-FE state retains legacy behavior. The mixed-version semantic issue remains covered by the existing rolling-upgrade thread and is not duplicated here.
  • Parallel paths: V1/V2, Parquet/ORC, whole/pruned complex projections, schema-history reconstruction, hidden equality-delete dependencies, and both position-delete paths were traced. The position-delete candidate was dismissed because supported Iceberg position-delete schemas require fixed/matching IDs and the metadata-table scan does not transport the claimed authoritative mapping state.
  • Conditional and null/default behavior: V1's per-struct any-ID condition and V2's global current-node matcher do not implement each format's wrapper projection contract. Separately, recursive Base64 initial-default metadata is dropped before a newly missing nested child is materialized.
  • FE/BE transport: Mapping authority and nested Base64 defaults reach BE schema reconstruction. Authority now survives the changed access-path copy, but the nested default value/encoding metadata does not, which causes the second inline failure.
  • Error and nullability handling: No new status-propagation defect survived review. The accepted failures are silent wrong-result/default-materialization cases rather than missing diagnostics.
  • Observability: Existing debug-state additions are adequate; no separate logging or metric concern was found.
  • Performance and memory: Recursive schema scans and one metadata boolean are planning/setup work with negligible cost; no per-row hot-path or allocation regression was found.
  • User focus and completion: No additional user focus was supplied. After the final wording correction, all three reviewers independently returned NO_NEW_VALUABLE_FINDINGS on this exact three-comment set and anchors.
  • Validation: Static review only, because the review task prohibited builds and test execution. At submission, formatting, CheckStyle, license, dependency, secret, and Cloud UT checks pass; BE UT, FE UT, compile, code-review, and performance checks are pending. The macOS BE UT workflow failed during environment setup because it selected JDK 25 while the build requires JDK 17.

The review remains blocking because all three findings can change returned Iceberg row values or leave the checked-in reader test contract inconsistent with the implementation.

Comment thread be/src/format/table/table_schema_change_helper.cpp Outdated
Comment thread be/src/exec/scan/access_path_parser.cpp
Comment thread be/src/format_v2/table/iceberg_reader.h Outdated
@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17853	4086	4035	4035
q2	2029	335	205	205
q3	10301	1481	843	843
q4	4687	476	358	358
q5	7500	845	574	574
q6	177	170	138	138
q7	744	822	612	612
q8	9323	1656	1699	1656
q9	5714	4417	4353	4353
q10	6741	1735	1492	1492
q11	509	353	330	330
q12	738	587	462	462
q13	18095	3388	2781	2781
q14	271	267	246	246
q15	q16	796	788	705	705
q17	1044	920	1016	920
q18	6966	5781	5499	5499
q19	1306	1310	1183	1183
q20	828	691	553	553
q21	5924	2662	2426	2426
q22	434	361	303	303
Total cold run time: 101980 ms
Total hot run time: 29674 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4432	4369	4303	4303
q2	283	314	216	216
q3	4553	4940	4440	4440
q4	2062	2150	1389	1389
q5	4401	4262	4265	4262
q6	236	176	152	152
q7	1776	2054	1705	1705
q8	2466	2242	2111	2111
q9	7774	7736	7809	7736
q10	4723	4691	4283	4283
q11	590	455	405	405
q12	897	814	536	536
q13	3219	3556	3018	3018
q14	291	307	278	278
q15	q16	713	751	659	659
q17	1376	1389	1332	1332
q18	8125	7474	6987	6987
q19	1112	1053	1075	1053
q20	2236	2222	1927	1927
q21	5277	4674	4485	4485
q22	514	453	407	407
Total cold run time: 57056 ms
Total hot run time: 51684 ms

@hello-stephen

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

query5	4331	620	475	475
query6	466	227	198	198
query7	4933	615	341	341
query8	350	192	170	170
query9	8787	4068	4015	4015
query10	482	364	319	319
query11	5924	2362	2085	2085
query12	163	106	105	105
query13	1301	623	437	437
query14	6251	5185	4871	4871
query14_1	4251	4212	4266	4212
query15	222	204	185	185
query16	1053	490	451	451
query17	1145	705	576	576
query18	2502	480	355	355
query19	212	197	163	163
query20	114	114	106	106
query21	236	164	139	139
query22	13510	13537	13287	13287
query23	17295	16503	16132	16132
query23_1	16287	16266	16286	16266
query24	7675	1791	1246	1246
query24_1	1336	1298	1275	1275
query25	581	472	398	398
query26	1355	344	224	224
query27	2589	613	390	390
query28	4471	1989	2032	1989
query29	1123	645	520	520
query30	344	271	226	226
query31	1115	1093	980	980
query32	111	65	61	61
query33	539	328	272	272
query34	1182	1136	644	644
query35	781	790	671	671
query36	1202	1237	1082	1082
query37	155	109	99	99
query38	1880	1702	1670	1670
query39	879	887	866	866
query39_1	853	832	836	832
query40	287	163	140	140
query41	65	62	64	62
query42	99	89	90	89
query43	318	320	282	282
query44	1402	761	747	747
query45	194	183	176	176
query46	1100	1172	731	731
query47	2172	2145	2084	2084
query48	397	384	291	291
query49	576	423	316	316
query50	1048	460	333	333
query51	11068	11102	10853	10853
query52	87	83	78	78
query53	265	277	203	203
query54	274	234	229	229
query55	78	71	66	66
query56	292	305	298	298
query57	1321	1289	1201	1201
query58	296	273	254	254
query59	1571	1664	1471	1471
query60	306	268	254	254
query61	157	155	150	150
query62	547	494	440	440
query63	252	208	197	197
query64	2850	1071	912	912
query65	4697	4632	4624	4624
query66	1812	518	377	377
query67	29282	29166	29027	29027
query68	3089	1630	942	942
query69	412	305	258	258
query70	1082	966	936	936
query71	364	331	327	327
query72	3113	2712	2407	2407
query73	805	736	440	440
query74	5080	4896	4698	4698
query75	2546	2498	2133	2133
query76	2377	1197	797	797
query77	347	381	280	280
query78	11944	12055	11207	11207
query79	1527	1162	782	782
query80	1294	566	468	468
query81	576	329	291	291
query82	598	155	119	119
query83	371	325	295	295
query84	293	162	133	133
query85	980	622	519	519
query86	427	297	294	294
query87	1810	1822	1755	1755
query88	3711	2851	2771	2771
query89	441	378	332	332
query90	1895	208	197	197
query91	203	191	166	166
query92	61	59	58	58
query93	1755	1565	965	965
query94	719	369	309	309
query95	799	610	481	481
query96	1005	782	334	334
query97	2623	2644	2499	2499
query98	219	207	195	195
query99	1093	1103	980	980
Total cold run time: 264695 ms
Total hot run time: 177702 ms

@hello-stephen

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

query1	0.01	0.00	0.01
query2	0.14	0.08	0.08
query3	0.40	0.25	0.24
query4	1.61	0.23	0.24
query5	0.34	0.32	0.32
query6	1.15	0.67	0.67
query7	0.03	0.01	0.01
query8	0.09	0.07	0.07
query9	0.52	0.39	0.39
query10	0.61	0.60	0.60
query11	0.31	0.18	0.19
query12	0.32	0.19	0.19
query13	0.53	0.54	0.53
query14	0.95	0.94	0.93
query15	0.67	0.59	0.60
query16	0.39	0.39	0.40
query17	1.03	1.03	1.16
query18	0.32	0.31	0.30
query19	1.91	1.86	1.80
query20	0.02	0.02	0.01
query21	15.40	0.36	0.32
query22	4.94	0.14	0.14
query23	15.84	0.49	0.30
query24	2.48	0.61	0.44
query25	0.16	0.10	0.10
query26	0.74	0.27	0.22
query27	0.10	0.10	0.10
query28	3.46	0.96	0.51
query29	12.50	4.26	3.34
query30	0.37	0.27	0.26
query31	2.76	0.61	0.32
query32	3.23	0.60	0.48
query33	2.98	2.93	2.90
query34	15.68	4.13	3.39
query35	3.33	3.30	3.24
query36	0.65	0.53	0.50
query37	0.12	0.09	0.10
query38	0.08	0.06	0.07
query39	0.08	0.06	0.06
query40	0.20	0.19	0.18
query41	0.13	0.08	0.08
query42	0.08	0.06	0.06
query43	0.08	0.07	0.07
Total cold run time: 96.74 s
Total hot run time: 25.72 s

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

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.

Requesting changes for four silent read-correctness gaps in the Iceberg legacy-file paths. The inline comments cover branch default-marker pinning, V1 ORC container recursion, V1 position_deletes file-wide ID selection, and V2 Parquet wrapper projection.

Critical checkpoint conclusions:

  • Goal and proof: The PR aims to honor partial Iceberg name mappings and initial defaults consistently in V1/V2 legacy-file reads. It does not yet fully accomplish that goal because M1-M4 leave reachable schemas with carrier text, unrelated name-bound values, or synthesized NULL/defaults. The added tests are useful but omit those four shapes.
  • Scope and clarity: The change is cohesive around schema mapping/default transport, though its duplicated V1/V2 and ordinary/system-table implementations require the parallel-path fixes called out inline.
  • Concurrency: No new locks or concurrently mutated BE state were added. I checked statement binding versus cache refresh; ordinary mapping/default pinning is coherent, but M1 still selects branch marker metadata from a different schema generation.
  • Lifecycle: No static-initialization or ownership cycle issue was found. The new variable-width default paths copy borrowed StringView data into owning columns or literals while the decode buffer is alive.
  • Configuration: No new runtime configuration item is introduced.
  • Compatibility: The optional Thrift mapping-authority marker preserves old-FE/new-BE fallback and is safe for the documented BE-first rollout. No additional storage-format or symbol incompatibility was found.
  • Parallel paths: These are the main blockers: M2 loses file-wide ID mode in V1 ORC ARRAY/MAP recursion; M3 loses full-file evidence in the still-dispatched V1 position-delete reader; M4 omits Parquet wrapper projection in the V2 position-delete reader.
  • Conditions: The authoritative absent/empty mapping distinction and any-ID conditions are documented and generally propagated, but the recursive/container and specialized-reader gates in M2-M4 are incomplete.
  • Test coverage: Unit coverage spans mapping presence, defaults, mixed IDs, readers, and ownership. Missing cases are an old branch plus schema-only binary default, ORC array/map-contained ID-less leaves, V1 delete files with IDs only outside row, and V2 delete rows with an ID-less Parquet wrapper.
  • Test results: I reviewed the changed assertions and expected values and found no incorrect expected result. Per the review environment contract, I did not run builds or tests, so this conclusion is static-only.
  • Observability: Existing reader profiles/status errors and FE logging are sufficient for these metadata-read paths; no new metric or INFO log is required.
  • Persistence and transactions: This PR changes read-side metadata caches and scan schemas, not EditLog, transaction, or data-write behavior; crash atomicity and master failover are not applicable.
  • FE-BE variables: The new mapping-presence and Base64-marker metadata are sent through the production Iceberg serializer and consumed in both BE readers. Rolling compatibility is sound; M1 is a schema-selection defect rather than a missing serialization path.
  • Performance: Schema walks and immutable mapping copies are metadata-sized; no material CPU, memory-accounting, or I/O regression was found.
  • Other issues: After deduplication against all existing threads and convergence review, no additional actionable finding remains beyond the four inline comments.

User focus: no additional focus points were supplied; the full changed-file set was reviewed.

Validation: static review only; builds and tests were intentionally not run under the review contract.

Comment thread be/src/format/table/table_schema_change_helper.cpp Outdated
Comment thread be/src/format/table/table_schema_change_helper.cpp Outdated
Comment thread be/src/format_v2/table/iceberg_position_delete_sys_table_reader.cpp Outdated
@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 76.00% (57/75) 🎉
Increment coverage report
Complete coverage report

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review status: complete; requesting changes for one P1 data-correctness issue.

The patch otherwise establishes the intended authoritative Iceberg name-mapping behavior across FE metadata pinning, the optional FE/BE protocol flag, V1/V2 Parquet and ORC readers, initial defaults, and data/equality/position-delete paths. The remaining issue is that V2 performs ID-less Parquet wrapper discovery using the access-path-pruned table subtree. If the projected child is absent from an older file and only an unprojected physical sibling supplies the descendant ID that identifies the wrapper, V2 drops the physical parent and returns NULL instead of the child's Iceberg initial default. V1 retains the wrapper from the complete schema and returns the expected result.

Critical checkpoint conclusions:

  • Goal and proof: The implementation largely meets the legacy-file name-mapping goal, and the added FE/BE tests cover absent versus present-empty mappings, nested/default/binary cases, file-wide ID selection, both formats, and delete readers. The unprojected-sibling/default case in the inline finding is not covered and prevents full correctness.
  • Scope and focus: Although the patch is broad because it closes multiple reader-generation and format-specific gaps, its changes remain focused on schema identity, metadata transport, default materialization, and corresponding tests.
  • Concurrency and thread safety: No new mutable shared state, thread entry, lock, atomic, or lock-order dependency is introduced. Statement-pinned snapshot/cache values are immutable inputs to scan planning.
  • Error handling: Changed Status results are propagated, invariant-only checks fail loudly, and I found no swallowed error or speculative recovery path.
  • Memory safety and BE nullability: The binary/default paths copy temporary variable-width values into owned columns/literals, and complex rematerialization preserves nullable parent maps. I found no separate ownership, const/nullable-shape, or lifetime defect beyond the wrong missing-root choice in the inline finding.
  • Lifecycle/static initialization: No new special destruction lifecycle, circular ownership, or cross-translation-unit static initialization dependency is introduced.
  • Configuration: No configuration item or dynamic-reload behavior is added.
  • Compatibility: The new Thrift field is optional and the absent-field fallback preserves legacy behavior. The previously discussed mixed-version capability caveat is already covered by existing review thread r3609339722 and was not duplicated here.
  • Parallel paths: V1/V2, Parquet/ORC, ordinary reads, equality deletes, and position-delete system-table readers were traced. They are otherwise aligned; the accepted finding is the remaining V2/V1 divergence.
  • Special conditions: File-wide existential ID mode, authoritative mapping presence, and the Parquet-only ID-less-wrapper exception are documented and format-gated. Wrapper discovery still needs the complete schema identity view when access-path pruning removes identifying siblings.
  • Test coverage: The patch adds substantial FE and BE unit/result coverage, including negative/empty mapping cases and nested complex structures. A V2 reader-result test for a newly defaulted projected child whose only identifying physical descendant is an unprojected sibling is required.
  • Test results: No result file was changed. Per the review contract, I performed static review only and did not run local builds or tests. The macOS BE UT workflow did not reach compilation/tests because its runner supplied JDK 25 while the job requires JDK 17.
  • Observability: This is deterministic local schema mapping; existing scan errors/debug state are sufficient, and no new metric or INFO log is warranted.
  • Transactions and persistence: No edit-log, replay, transaction, or persisted Doris metadata format is changed.
  • Data writes: The patch changes read-time interpretation only; it adds no write, commit, rollback, or atomicity path.
  • FE-to-BE variables: Mapping aliases, authority presence, nested initial-default payloads, Base64 markers, and schema IDs are transported through the relevant scan-schema paths. The optional-field rollout behavior is noted above.
  • Performance: Added work is schema/setup-time traversal and mapping construction rather than row-loop work. I found no material CPU, memory, or allocation regression in the changed hot paths.
  • Other issues: No additional actionable finding remained after deduplication against existing review threads.

User focus: .code-review.sKMLu3/review_focus.txt specified no additional focus points.

const ColumnDefinition* wrapper = nullptr;
for (const auto& candidate : file_schema) {
if (candidate.has_identifier_field_id() || candidate.children.empty() ||
!has_shared_descendant_field_id(table_column, candidate)) {

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] Keep full-schema IDs available for wrapper discovery

table_column has already been pruned to the requested access path here. For table s#10<a#1 initial-default=7,b#2>, file s(no id)<b#2>, and projection s.a, file-wide ID mode is active, but this helper sees only a#1; it cannot use physical b#2 to identify s. V2 therefore marks the root missing and returns NULL instead of materializing a=7 under non-null s, while V1's full TField subtree retains the wrapper. Please keep a full-schema identity view for this lookup and add a V2 result test with nullable parent rows.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17580	4073	4070	4070
q2	2016	325	204	204
q3	10285	1479	827	827
q4	4681	471	346	346
q5	7505	832	556	556
q6	178	173	141	141
q7	750	800	607	607
q8	9327	1589	1652	1589
q9	5625	4431	4397	4397
q10	6769	1745	1491	1491
q11	513	359	329	329
q12	732	594	452	452
q13	18120	3396	2782	2782
q14	265	251	240	240
q15	q16	795	777	712	712
q17	1042	1068	1036	1036
q18	6886	5849	5461	5461
q19	1211	1359	1115	1115
q20	799	720	538	538
q21	5664	2667	2441	2441
q22	425	347	289	289
Total cold run time: 101168 ms
Total hot run time: 29623 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4426	4317	4321	4317
q2	289	314	213	213
q3	4612	4957	4405	4405
q4	2053	2179	1384	1384
q5	4388	4285	4251	4251
q6	232	176	124	124
q7	1734	1878	1705	1705
q8	2517	2193	2122	2122
q9	7847	7712	7647	7647
q10	4722	4669	4191	4191
q11	568	427	387	387
q12	747	750	525	525
q13	3334	3632	2923	2923
q14	303	328	286	286
q15	q16	720	732	677	677
q17	1373	1359	1345	1345
q18	7970	7410	7080	7080
q19	1083	1097	1083	1083
q20	2223	2214	1927	1927
q21	5268	4575	4489	4489
q22	519	461	406	406
Total cold run time: 56928 ms
Total hot run time: 51487 ms

@hello-stephen

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

query5	4334	616	485	485
query6	500	235	199	199
query7	4869	615	342	342
query8	343	194	180	180
query9	8812	4030	4021	4021
query10	450	346	298	298
query11	5949	2305	2103	2103
query12	160	103	102	102
query13	1254	579	418	418
query14	6264	5215	4899	4899
query14_1	4259	4211	4251	4211
query15	210	205	179	179
query16	989	486	468	468
query17	1096	700	554	554
query18	2421	486	349	349
query19	196	184	166	166
query20	109	108	107	107
query21	233	155	132	132
query22	13524	13624	13423	13423
query23	17430	16563	16233	16233
query23_1	16286	16344	16187	16187
query24	7648	1694	1279	1279
query24_1	1281	1251	1271	1251
query25	554	431	362	362
query26	1334	334	212	212
query27	2620	618	380	380
query28	4496	1992	1971	1971
query29	1088	635	511	511
query30	349	268	228	228
query31	1120	1099	974	974
query32	108	65	64	64
query33	537	329	261	261
query34	1180	1165	662	662
query35	768	786	674	674
query36	1210	1218	1034	1034
query37	155	112	97	97
query38	1867	1732	1667	1667
query39	882	870	865	865
query39_1	844	842	833	833
query40	246	165	143	143
query41	64	63	63	63
query42	98	90	95	90
query43	327	322	285	285
query44	1389	755	764	755
query45	185	188	178	178
query46	1042	1187	713	713
query47	2185	2161	2011	2011
query48	409	435	299	299
query49	571	405	315	315
query50	1053	418	341	341
query51	11146	10905	10999	10905
query52	86	90	75	75
query53	265	276	200	200
query54	274	269	225	225
query55	72	69	65	65
query56	303	298	299	298
query57	1324	1292	1200	1200
query58	280	258	254	254
query59	1554	1667	1460	1460
query60	316	279	252	252
query61	161	147	151	147
query62	541	500	428	428
query63	244	205	198	198
query64	2864	1061	898	898
query65	4753	4636	4667	4636
query66	1811	531	376	376
query67	29582	29316	29178	29178
query68	3323	1551	1053	1053
query69	406	306	280	280
query70	1065	964	938	938
query71	364	313	320	313
query72	3262	2761	2352	2352
query73	885	759	435	435
query74	5040	4911	4711	4711
query75	2642	2517	2131	2131
query76	2342	1159	808	808
query77	352	373	279	279
query78	11883	11872	11315	11315
query79	1407	1192	769	769
query80	668	550	477	477
query81	454	335	282	282
query82	575	153	120	120
query83	401	319	305	305
query84	275	164	134	134
query85	938	598	536	536
query86	367	284	283	283
query87	1829	1820	1768	1768
query88	3666	2767	2759	2759
query89	430	374	329	329
query90	2002	203	195	195
query91	204	187	160	160
query92	63	62	56	56
query93	1596	1436	949	949
query94	526	371	353	353
query95	809	594	509	509
query96	1064	788	382	382
query97	2670	2658	2513	2513
query98	220	211	206	206
query99	1092	1115	974	974
Total cold run time: 264055 ms
Total hot run time: 178220 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.15	0.09	0.08
query3	0.37	0.24	0.24
query4	1.61	0.25	0.25
query5	0.33	0.31	0.32
query6	1.15	0.67	0.68
query7	0.04	0.01	0.01
query8	0.08	0.07	0.08
query9	0.51	0.40	0.39
query10	0.61	0.61	0.60
query11	0.31	0.19	0.18
query12	0.31	0.19	0.19
query13	0.54	0.54	0.53
query14	0.94	0.93	0.92
query15	0.67	0.58	0.59
query16	0.40	0.40	0.41
query17	1.01	1.00	1.10
query18	0.32	0.30	0.30
query19	1.92	1.83	1.84
query20	0.02	0.01	0.02
query21	15.36	0.37	0.33
query22	4.95	0.14	0.13
query23	15.83	0.49	0.30
query24	2.36	0.59	0.43
query25	0.15	0.11	0.09
query26	0.73	0.27	0.22
query27	0.10	0.09	0.11
query28	3.46	0.92	0.54
query29	12.45	4.27	3.35
query30	0.38	0.25	0.26
query31	2.75	0.60	0.32
query32	3.22	0.62	0.47
query33	3.03	3.02	3.03
query34	15.68	4.08	3.40
query35	3.31	3.25	3.28
query36	0.63	0.53	0.49
query37	0.13	0.09	0.09
query38	0.08	0.08	0.07
query39	0.08	0.07	0.06
query40	0.20	0.19	0.17
query41	0.12	0.08	0.08
query42	0.08	0.06	0.06
query43	0.07	0.06	0.07
Total cold run time: 96.44 s
Total hot run time: 25.83 s

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

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.

Found two P1 rolling-upgrade correctness blockers. The final steady-state Iceberg semantics are otherwise coherent across the changed V1/V2 readers, but old FE descriptors do not version the new mixed-ID projection rule or the new interpretation of existing Base64-default fields, so a BE-first rollout can return different values from old and upgraded BEs in one distributed scan.

Checkpoint conclusions:

  • Goal and tests: The patch addresses authoritative partial name mappings, file-wide ID projection, wrapper retention, statement-pinned metadata, and initial defaults; focused FE/BE tests cover the intended final semantics, but mixed-release plan/execution tests for the two blockers are missing.
  • Scope: Large because it repairs all ordinary/equality/position-delete and Parquet/ORC parallel paths, but the changes remain within Iceberg schema evolution and its shared scanner metadata.
  • Concurrency: Immutable snapshot mapping copies and statement MVCC binding introduce no new race after pinning; no shared mutable BE state was added.
  • Lifecycle and static initialization: No new static-lifetime or shutdown behavior; decoded variable-width defaults are copied into owning columns/literals before temporary buffers expire.
  • Configuration: No new configuration or validation path.
  • Compatibility and rolling upgrade: Blocking. Field 9 safely versions authoritative mapping aliases, but it does not gate the any-ID mode change or decoded top-level and nested defaults already carried in fields 7/8.
  • Parallel paths: V1/V2 ordinary reads, equality deletes, and position-delete metadata reads now agree at steady state, including Parquet-only ID-less wrappers and strict ORC behavior; the compatibility capability must cover all of them.
  • Conditional/error handling: Absent versus present-empty mapping and wrapper ambiguity are explicit; invalid Base64 defaults return errors, while invalid mapping JSON retains its pre-existing warning-and-legacy-fallback behavior.
  • Test coverage and results: The diff adds broad focused unit coverage. Per the review harness I did not run local builds/tests. At the final status refresh, CheckStyle, clang-format, license, secrets, dependency, and Cloud UT checks passed; macOS BE UT failed before tests because JDK 25 was selected instead of required JDK 17; BE UT and the performance check failed, but their TeamCity diagnostics require authentication so I could not attribute a cause; FE UT and compile remained pending.
  • Observability: No new production state requiring metrics or logging was introduced; existing parse errors remain surfaced.
  • Persistence, transactions, and writes: Not changed.
  • FE-BE variables: Recursive IDs, aliases, mapping authority, initial defaults, and Base64 markers are transported consistently; a general compatible-FE scan-semantics version is still required for the two accepted behavior changes.
  • Performance: New schema traversal and immutable mapping copies occur at metadata binding or reader setup, not in the per-row hot path; no material regression identified.
  • Other issues: No additional actionable correctness issue found. No extra user-provided focus was supplied.

Comment thread be/src/format_v2/table/iceberg_reader.h Outdated
? format::TableColumnMappingMode::BY_FIELD_ID
: format::TableColumnMappingMode::BY_NAME;
if (!_data_reader.file_schema.empty() &&
schema_has_any_field_id(_data_reader.file_schema)) {

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] Version the new any-ID projection rule for rolling upgrades

This path is also reached by old-FE plans: TField IDs already existed, and no name-mapping property or field-9 marker is needed. During a BE-first rollout, for table a#1, b#2 over file a#1=10, b(no id)=20, old BEs choose name mode and return b=20, while upgraded BEs choose field-ID mode and synthesize b as missing. A single distributed scan can therefore combine different results. The new authority bit gates only name-mapping fallback and is absent here. Please add a scan-semantics capability emitted only by compatible FEs, retaining the legacy all-ID selection when it is absent, and apply it consistently to V1/V2 and position-delete paths.

// Doris internal Iceberg row locator is never a physical Iceberg data column. It is built
// from file path, row position and partition metadata for delete/update/merge.
mapping->virtual_column_type = TableVirtualColumnType::ICEBERG_ROWID;
} else if (table_column.initial_default_value.has_value()) {

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] Gate decoded initial defaults for mixed-version BEs

Thrift fields 7/8 and the FE's Base64 map already existed and were populated recursively before this PR. For an old-FE plan whose file lacks a UUID/BINARY/FIXED field, old BEs return the carrier/generic default at a projected root and NULL/type-default for a missing child; this branch plus the new V1 hook and recursive V1/V2 child materializers decode the logical bytes. During a BE-first rollout, fragments of one scan can therefore return different values. Field 9 does not gate this behavior. Please put all of these paths behind the same compatible-FE scan capability as the projection-mode change, retaining legacy behavior when it is absent, with mixed-BE coverage for root and nested fields in both readers.

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 76.62% (59/77) 🎉
Increment coverage report
Complete coverage report

@Gabriel39

Copy link
Copy Markdown
Contributor Author

run buildall

@Gabriel39

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.

Request changes: two P1 reader-correctness issues remain.

  1. V2 current-schema annotation gives an earlier historical alias the same priority as a later exact current name. A renamed field followed by a new field that reuses the old name can therefore attach the old field ID/defaults to the new projection, at both root and nested access paths.
  2. V1 ordinary mixed-ID mapping now follows Iceberg's any-ID rule, but hidden equality-delete expansion still uses an all-fields-have-IDs rule. After a key rename, that disagreement can synthesize an existing unprojected key as missing and allow equality-deleted rows to survive in both Parquet and ORC.

Critical checkpoint conclusions:

  • Goal and proof: The PR substantially implements authoritative partial name mappings, schema-pinned metadata, mixed-ID selection, initial defaults, and V1/V2 delete-reader propagation. The changed tests cover many positive, negative, legacy-plan, nested, binary, and wrapper cases, but they do not prove the two rename/name-reuse cases above, so the goal is not yet fully achieved.
  • Scope and focus: The 37-file FE/Thrift/BE/test change is broad because the contract crosses planner transport and V1/V2 readers, but the edits are generally focused on that contract. The two remaining mismatches are localized correctness gaps rather than unrelated scope growth.
  • Concurrency: No new thread entry, lock, lock ordering, or mutable shared reader state is introduced. The existing metadata-cache concurrency boundary is handled through the statement-pinned IcebergSnapshotCacheValue; all production constructors were traced to the same table generation.
  • Lifecycle and memory safety: No new cross-TU static-initialization dependency or special teardown path was found. Long VARBINARY/UUID default payloads are materialized into owning columns before temporary decode buffers die; root, nested, equality-delete, nullable-parent, and row-count lifetimes were checked without another defect.
  • Configuration: No configuration item is added or changed.
  • Compatibility: The optional Thrift additions are wire-compatible. The scan-semantics marker gates the new any-ID, wrapper, and initial-default result behavior so absent-version old-FE plans retain legacy behavior; the marker reaches every range through the shared mutable scan params object.
  • Parallel paths: Parquet/ORC, V1/V2, ordinary scans, position_deletes.row, and hidden equality-delete paths were compared. The second inline issue is the remaining V1 equality-path parity miss; outside the two inline issues, the position-delete and V2 equality paths are consistent.
  • Conditions and error handling: New version, authoritative-mapping, any-ID, and wrapper conditions are locally documented, and checked Status propagation remains intact. The hidden-key all-ID condition is no longer consistent with the ordinary semantics-v1 condition and is called out inline.
  • Test coverage and expected results: Added unit/result coverage is broad and deterministic in the reviewed fixtures, including absent versus present-empty mappings, partial mappings, old plans, nested containers, binary defaults, mixed IDs, wrappers, branches/snapshots, and delete readers. Missing coverage is top-level/nested exact-name-versus-alias reuse in V2 and renamed hidden equality keys in mixed-ID Parquet/ORC. No local build or test was run because the review-runner contract prohibited it.
  • Nullability and data correctness: Nullable struct-parent maps, const materialization, missing defaults, and equality-key row carriers were traced. The two inline findings are silent data-correctness failures; no additional nullable-shape or visible-version issue was substantiated.
  • Observability: This is deterministic scan-planning/materialization behavior and does not require new metrics or logging; existing errors carry sufficient schema/default context for the failing decode paths.
  • Persistence, transactions, and writes: No EditLog, transaction, storage-format write, or data-write path is modified.
  • FE-BE variables: Name-mapping authority, aliases, schema IDs, Base64 markers, initial defaults, and scan-semantics version are transported through the relevant FE construction and Thrift consumption paths. All production snapshot-cache constructors and the sole production schema-info caller were checked.
  • Performance: New work is schema-size initialization/projection traversal rather than row-by-row processing. No material CPU, allocation, or memory-accounting regression was found.
  • Other issues and user focus: No additional distinct issue remains after deduplication against the existing review threads. .code-review.lELdfJ/review_focus.txt contains no extra user-provided focus point.

}
column->identifier = context->schema_column->identifier;
column->name_mapping = context->schema_column->name_mapping;
column->has_name_mapping = context->schema_column->has_name_mapping;

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] Prefer exact current names before mapping aliases

A legal evolution can rename b#1 to renamed_b and then add a new b#2; a partial mapping may retain alias b only for #1 while #2 has an authoritative empty alias list. Because find_external_root_field() accepts either a current name or alias in one ordered pass, projecting current b can select #1 before reaching #2, and this assignment copies #1's ID/default metadata onto the projected field. ID-bearing and ID-less files can then return old field data instead of #2's initial default or NULL. Please search all siblings for an exact current name before trying aliases; find_schema_child_by_path() has the same ordering issue, so cover both shapes with V2 result tests.

RETURN_IF_ERROR(BuildTableInfoUtil::by_parquet_field_id_with_name_mapping(
get_scan_params().history_schema_info.front().root_field, *field_desc,
ctx->table_info_node));
ctx->table_info_node, supports_iceberg_scan_semantics_v1(&get_scan_params())));

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] Use the same file-wide ID mode for hidden delete keys

This call now makes ordinary mapping use field IDs when any field in the data file has an Iceberg ID, but hidden equality-key expansion still requires every field to have an ID before looking up the key by ID. For a mixed-ID file containing old_key#1 plus an unrelated ID-less sibling, after #1 is renamed to new_key, an unprojected equality-delete file can still call the key old_key. The StructNode is keyed by current name new_key, so the hidden path misses the physical #1 column, synthesizes NULL/default, and fails to delete matching rows. Please use the same any-ID decision under semantics v1 for hidden Parquet and ORC keys, retain the legacy rule for absent-version plans, and add renamed hidden-key result coverage.

@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: 29588 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit b301e6c31302c794c075f2b86fa5367d5034406a, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17725	4080	4091	4080
q2	2012	334	196	196
q3	10333	1527	838	838
q4	4684	469	335	335
q5	7502	892	557	557
q6	177	171	140	140
q7	757	816	615	615
q8	9376	1595	1647	1595
q9	5573	4390	4380	4380
q10	6730	1754	1468	1468
q11	495	355	324	324
q12	720	578	454	454
q13	18180	3448	2766	2766
q14	272	263	252	252
q15	q16	795	784	716	716
q17	1035	992	1066	992
q18	7001	5838	5494	5494
q19	1357	1388	1097	1097
q20	789	666	586	586
q21	5839	2613	2407	2407
q22	431	358	296	296
Total cold run time: 101783 ms
Total hot run time: 29588 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4413	4310	4342	4310
q2	283	313	213	213
q3	4617	4941	4411	4411
q4	2056	2158	1345	1345
q5	4371	4254	4265	4254
q6	231	182	126	126
q7	1751	1989	1707	1707
q8	2477	2205	2113	2113
q9	7833	7751	7759	7751
q10	4671	4625	4214	4214
q11	591	402	389	389
q12	737	743	532	532
q13	3472	3605	3012	3012
q14	314	313	289	289
q15	q16	708	754	639	639
q17	1353	1354	1331	1331
q18	7924	7374	6921	6921
q19	1133	1082	1064	1064
q20	2242	2204	1929	1929
q21	5212	4579	4398	4398
q22	503	463	398	398
Total cold run time: 56892 ms
Total hot run time: 51346 ms

@hello-stephen

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

query5	4400	632	489	489
query6	466	224	201	201
query7	4848	618	346	346
query8	338	187	178	178
query9	8748	4028	3997	3997
query10	497	364	320	320
query11	5888	2336	2098	2098
query12	164	103	100	100
query13	1269	619	454	454
query14	6229	5178	4863	4863
query14_1	4212	4256	4233	4233
query15	211	208	186	186
query16	1057	484	464	464
query17	1146	754	579	579
query18	2722	483	335	335
query19	199	184	142	142
query20	106	105	106	105
query21	240	155	132	132
query22	13578	13512	13264	13264
query23	17368	16479	16036	16036
query23_1	16158	16204	16271	16204
query24	7624	1788	1270	1270
query24_1	1260	1256	1278	1256
query25	540	446	348	348
query26	1339	359	208	208
query27	2594	605	383	383
query28	4460	1977	1966	1966
query29	1047	621	464	464
query30	333	265	229	229
query31	1124	1081	970	970
query32	107	59	59	59
query33	509	315	244	244
query34	1180	1188	650	650
query35	754	761	674	674
query36	1174	1173	1073	1073
query37	152	101	89	89
query38	1870	1683	1644	1644
query39	877	872	846	846
query39_1	861	837	843	837
query40	260	164	140	140
query41	67	64	62	62
query42	92	90	87	87
query43	319	319	275	275
query44	1410	759	784	759
query45	205	192	177	177
query46	1086	1184	706	706
query47	2144	2196	2097	2097
query48	414	421	290	290
query49	582	420	314	314
query50	1151	444	331	331
query51	11119	11049	10980	10980
query52	87	88	75	75
query53	268	277	209	209
query54	292	253	236	236
query55	76	71	68	68
query56	326	335	289	289
query57	1341	1316	1233	1233
query58	298	300	266	266
query59	1596	1690	1461	1461
query60	320	282	266	266
query61	179	180	172	172
query62	550	500	437	437
query63	247	196	212	196
query64	2911	1218	821	821
query65	4749	4510	4599	4510
query66	1801	494	387	387
query67	29524	29295	29055	29055
query68	3045	1492	956	956
query69	418	304	272	272
query70	1070	957	929	929
query71	381	339	313	313
query72	3074	2691	2325	2325
query73	865	786	436	436
query74	5071	4920	4691	4691
query75	2521	2487	2140	2140
query76	2328	1159	782	782
query77	340	379	287	287
query78	11919	11843	11336	11336
query79	1389	1186	708	708
query80	1266	559	474	474
query81	593	335	286	286
query82	611	158	123	123
query83	364	316	293	293
query84	278	161	126	126
query85	962	607	504	504
query86	419	310	279	279
query87	1825	1828	1719	1719
query88	3642	2750	2754	2750
query89	448	387	329	329
query90	1884	189	197	189
query91	204	211	156	156
query92	59	62	57	57
query93	1635	1539	1032	1032
query94	713	355	313	313
query95	800	576	449	449
query96	1065	831	366	366
query97	2608	2629	2514	2514
query98	216	212	201	201
query99	1078	1121	996	996
Total cold run time: 264471 ms
Total hot run time: 177382 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.15	0.08	0.08
query3	0.39	0.25	0.24
query4	1.62	0.25	0.24
query5	0.33	0.31	0.32
query6	1.16	0.68	0.66
query7	0.04	0.00	0.00
query8	0.09	0.07	0.07
query9	0.51	0.38	0.37
query10	0.59	0.59	0.57
query11	0.31	0.19	0.18
query12	0.31	0.18	0.18
query13	0.53	0.52	0.53
query14	0.94	0.92	0.94
query15	0.67	0.59	0.59
query16	0.39	0.40	0.40
query17	0.98	1.01	1.01
query18	0.29	0.28	0.28
query19	1.90	1.80	1.77
query20	0.02	0.02	0.02
query21	15.44	0.35	0.31
query22	4.84	0.14	0.13
query23	15.87	0.50	0.31
query24	2.58	0.61	0.43
query25	0.15	0.10	0.11
query26	0.75	0.27	0.22
query27	0.10	0.10	0.10
query28	3.39	0.95	0.53
query29	12.50	4.26	3.30
query30	0.37	0.26	0.26
query31	2.77	0.61	0.34
query32	3.23	0.61	0.48
query33	2.89	3.01	3.03
query34	15.81	4.07	3.32
query35	3.28	3.27	3.27
query36	0.65	0.54	0.51
query37	0.12	0.10	0.09
query38	0.09	0.07	0.07
query39	0.07	0.07	0.06
query40	0.20	0.19	0.17
query41	0.13	0.08	0.08
query42	0.09	0.06	0.06
query43	0.07	0.08	0.07
Total cold run time: 96.62 s
Total hot run time: 25.64 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 77.50% (62/80) 🎉
Increment coverage report
Complete coverage report

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

Requesting changes for one additional P1 correctness issue: exact-current-name precedence is not gated by the new scan-semantics capability, so an old-FE plan can bind different field IDs on old and new BEs during a BE-first upgrade. The existing unresolved hidden equality-key file-wide-ID thread also remains applicable; I did not duplicate it inline.

Checkpoint summary:

  • Goal and scope: reviewed all 37 changed files and traced the name-mapping/default transport from FE through Thrift into V1/V2 Parquet and ORC ordinary, position-delete, and equality-delete paths. No additional user focus was provided.
  • Compatibility: optional Thrift fields are additive and the new any-ID/default/wrapper behaviors are generally capability-gated, but the accepted P1 violates the absent-marker legacy contract. The existing hidden-key thread also remains unresolved.
  • Concurrency, lifecycle, configuration, persistence, and data writes: this patch adds no new shared-thread, resource-lifecycle, configuration, transactional, or persistence mechanism; no separate issue was found in those checkpoints.
  • Parallel paths and conditionals: V1/V2 and Parquet/ORC root, nested/container, position-delete, equality-delete, and missing-default branches were compared. Other residual hidden-key cases were deduplicated to the existing thread.
  • Tests and validation: the changed tests cover compatible-plan mixed IDs, wrappers, recursive defaults, mappings, and delete readers, but do not cover the old-FE alias collision in the inline finding. This was a static review only; the review runner contract prohibits builds and test execution.
  • Observability and performance: new failure paths retain contextual statuses/checks, and the added schema/default work is reader/planning initialization rather than a demonstrated scan hot-path regression. No additional issue was substantiated.

if (field == nullptr) {
continue;
if (field != nullptr && field->__isset.name &&
to_lower(field->name) == to_lower(column.name)) {

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] Gate exact-name precedence for old-FE plans

This exact-first pass changes field selection before iceberg_scan_semantics_version is checked. An old FE can send renamed_b#1 with alias b before a newly added current b#2, while omitting fields 9 and 34. For an all-ID file containing distinct values for both fields, the old BE's ordered lookup binds projected b to #1, but this new BE binds it to #2; the later capability check only clears defaults and cannot restore the identifier, so a BE-first rolling upgrade can return different values for one distributed scan. Please gate both the root and nested exact-first lookup on compatible-FE semantics, retain the former ordered lookup when the marker is absent, and cover the old-FE descriptor with both IDs present.

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