Skip to content

[fix](iceberg) Preserve nullness in partition commit values - #70214

Open
hubgeter wants to merge 1 commit into
apache:masterfrom
hubgeter:analyze/doris-29979-master
Open

hubgeter wants to merge 1 commit into
apache:masterfrom
hubgeter:analyze/doris-29979-master

Conversation

@hubgeter

@hubgeter hubgeter commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: N/A

Related PR: #68786

Problem Summary:

Writing an Iceberg STRING partition whose value is the literal 'null' can commit it as SQL NULL. For example, after inserting (1, 'null') and (2, NULL), partition pruning for p = 'null' can omit row 1. The writer routing fix in #68786 separates the files, but commit fragments still use the same textual token for both partition values.

Preserve nullable partition values through dynamic, static, and mixed partition writers, and add an optional NULL bitmap to the commit protocol. Decode it consistently when constructing data files, delete files, and identity partition conflict filters. Keep the legacy token fallback for senders without the bitmap, and preserve typed NULLs in existing JSON fragments. Reject inconsistent bitmap or partition-field counts before committing metadata.

The complete correction requires upgraded FE and BE processes. It applies to new writes and does not rewrite existing incorrect manifests. Older receivers ignore the optional field and retain their previous behavior.

Release note

Fix Iceberg writes incorrectly treating the literal STRING partition value 'null' as SQL NULL, which could cause partition-filtered queries to miss rows.

Check List (For Author)

  • Test

    • Regression test: Parquet and ORC dynamic writes, metadata partitions, static and mixed partition overwrites, empty strings, and truncate partitions; generated output and comparison both passed (28 query results).
    • Unit Test: 150 FE writer-helper and connector-transaction tests and 65 focused BE Iceberg/partition-transform tests (7 suites) passed.
    • Manual test: bash build.sh --be -j 6 (ASAN) and bash build.sh --fe -j 4 passed; formatting, header hygiene, and FE Checkstyle passed. All six changed BE source/header/test files passed clang-tidy on changed lines; both modified BE test files also passed full-file clang-tidy.
    • 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. Newly written literal 'null' and SQL NULL partitions retain distinct manifest values and conflict filters; malformed commit partition metadata is rejected.
  • 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?

@hubgeter

hubgeter commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hubgeter

hubgeter commented Nov 4, 2026

Copy link
Copy Markdown
Contributor Author

Local pipeline review — ✅ PASS

schema: doris-repo-review/v1
status: PASS
pr: apache/doris#70214
commit: 216a30a6219b7fac42d991c958baad9b8c58337a
base: b1720bdaee9c26c2b68c6955837257dd901bd736
reviewed_at: 2026-11-04T19:13+08:00
reviewer: hubgeter
model: gpt-6.1-sol
effort: max
findings: {blocker: 0, major: 0, minor: 0, nit: 0}
rounds: 1
converged: true

Notes for maintainers

  • This receipt covers static code review at the commit above. Reviewers did not execute builds, tests, mixed-version processes, or crash/failover injection; author validation is documented in the local review reports, and remote CI is separate.

Reviewed locally with the doris-repo-review pipeline. Repository policy may accept this receipt for the matching commit; it is not a human Apache approval.

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 76.65% (2101/2741)
Line Coverage 66.04% (38815/58772)
Region Coverage 53.70% (36379/67743)
Branch Coverage 57.27% (11867/20722)

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17639	5232	5066	5066
q2	2161	299	248	248
q3	10276	1412	833	833
q4	4686	470	335	335
q5	7449	795	547	547
q6	188	189	157	157
q7	752	804	607	607
q8	9267	1390	1065	1065
q9	5529	4226	4219	4219
q10	6831	1306	1036	1036
q11	457	245	231	231
q12	639	407	283	283
q13	18087	3668	3066	3066
q14	285	276	255	255
q15	q16	752	717	677	677
q17	1207	752	569	569
q18	7087	6205	6156	6156
q19	1104	970	620	620
q20	404	339	226	226
q21	5556	2456	2458	2456
q22	402	333	289	289
Total cold run time: 100758 ms
Total hot run time: 28941 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	6009	5942	6201	5942
q2	788	616	580	580
q3	5657	5821	5272	5272
q4	2024	2154	1588	1588
q5	5791	5938	5622	5622
q6	238	190	146	146
q7	2244	2053	1795	1795
q8	2980	2691	2719	2691
q9	8042	7553	7486	7486
q10	3679	3578	3134	3134
q11	577	435	381	381
q12	688	687	506	506
q13	3316	3682	3053	3053
q14	291	296	272	272
q15	q16	661	678	612	612
q17	7829	7030	6873	6873
q18	12992	12199	12878	12199
q19	912	816	804	804
q20	2172	2166	1925	1925
q21	5640	4620	4732	4620
q22	477	432	399	399
Total cold run time: 73007 ms
Total hot run time: 65900 ms

@hello-stephen

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

query5	4310	614	461	461
query6	430	213	193	193
query7	4794	451	236	236
query8	335	173	155	155
query9	8768	3210	3224	3210
query10	517	311	254	254
query11	6007	3879	3577	3577
query12	150	92	89	89
query13	1249	455	335	335
query14	6108	3950	3631	3631
query14_1	3419	3416	3436	3416
query15	210	196	181	181
query16	984	407	411	407
query17	832	638	523	523
query18	2408	413	300	300
query19	189	157	128	128
query20	82	84	82	82
query21	208	135	106	106
query22	13037	13021	12846	12846
query23	13490	12883	12480	12480
query23_1	12538	12438	12489	12438
query24	7334	828	467	467
query24_1	476	468	477	468
query25	514	395	335	335
query26	1258	259	136	136
query27	2767	439	271	271
query28	4668	2035	2032	2032
query29	1549	594	453	453
query30	292	228	184	184
query31	1016	930	812	812
query32	151	92	91	91
query33	516	298	242	242
query34	954	860	504	504
query35	739	756	650	650
query36	840	832	728	728
query37	134	102	84	84
query38	1776	1725	1672	1672
query39	784	791	736	736
query39_1	740	736	734	734
query40	222	120	100	100
query41	72	70	67	67
query42	87	87	84	84
query43	348	364	311	311
query44	1410	715	715	715
query45	183	183	166	166
query46	853	989	576	576
query47	2956	3008	2758	2758
query48	308	330	226	226
query49	581	402	310	310
query50	710	294	234	234
query51	10723	10621	10722	10621
query52	82	84	74	74
query53	199	216	155	155
query54	241	205	199	199
query55	80	69	65	65
query56	238	239	229	229
query57	1703	1616	1563	1563
query58	298	256	265	256
query59	2198	2213	1967	1967
query60	306	254	240	240
query61	171	171	162	162
query62	404	342	291	291
query63	196	165	168	165
query64	2853	1109	780	780
query65	3387	3288	3269	3269
query66	1770	429	305	305
query67	20404	20159	20047	20047
query68	2929	1045	622	622
query69	373	287	250	250
query70	855	767	775	767
query71	293	244	217	217
query72	2728	2575	2331	2331
query73	526	550	312	312
query74	4649	4536	4377	4377
query75	2340	2308	1927	1927
query76	2324	1044	629	629
query77	355	386	268	268
query78	9891	9825	9259	9259
query79	1040	886	548	548
query80	811	460	352	352
query81	580	320	280	280
query82	575	143	109	109
query83	299	205	199	199
query84	317	128	105	105
query85	897	428	368	368
query86	356	242	231	231
query87	1993	1938	1827	1827
query88	3817	2796	2834	2796
query89	345	291	243	243
query90	1843	181	170	170
query91	171	161	136	136
query92	104	95	109	95
query93	1094	1083	599	599
query94	515	315	282	282
query95	584	411	328	328
query96	726	532	253	253
query97	2510	2497	2383	2383
query98	164	171	153	153
query99	767	772	678	678
Total cold run time: 236071 ms
Total hot run time: 152007 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.10	0.05	0.06
query3	0.27	0.10	0.09
query4	1.61	0.10	0.10
query5	0.22	0.24	0.24
query6	1.20	0.69	0.68
query7	0.04	0.01	0.01
query8	0.06	0.03	0.04
query9	0.40	0.35	0.34
query10	0.58	0.59	0.56
query11	0.20	0.14	0.14
query12	0.19	0.14	0.15
query13	0.49	0.50	0.49
query14	1.03	1.03	1.01
query15	0.63	0.61	0.60
query16	0.34	0.35	0.34
query17	1.12	1.14	1.17
query18	0.20	0.20	0.19
query19	2.13	1.99	2.01
query20	0.01	0.02	0.01
query21	15.50	0.19	0.13
query22	4.96	0.06	0.05
query23	16.26	0.33	0.12
query24	3.14	0.55	0.47
query25	0.12	0.06	0.04
query26	0.92	0.22	0.15
query27	0.04	0.05	0.05
query28	3.15	0.76	0.39
query29	12.50	4.17	3.25
query30	0.28	0.13	0.10
query31	2.77	0.55	0.32
query32	3.23	0.60	0.50
query33	3.14	3.25	3.17
query34	15.51	3.97	3.36
query35	3.33	3.32	3.32
query36	0.54	0.47	0.63
query37	0.10	0.08	0.08
query38	0.05	0.05	0.04
query39	0.04	0.03	0.03
query40	0.17	0.15	0.14
query41	0.09	0.03	0.03
query42	0.03	0.02	0.02
query43	0.04	0.03	0.04
Total cold run time: 96.73 s
Total hot run time: 24.41 s

@hubgeter
hubgeter force-pushed the analyze/doris-29979-master branch from 216a30a to d332f85 Compare November 5, 2026 07:01
@hubgeter

hubgeter commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17638	5130	5054	5054
q2	2157	312	249	249
q3	10238	1393	827	827
q4	4689	465	340	340
q5	7441	807	541	541
q6	181	188	155	155
q7	753	832	609	609
q8	9244	1325	1096	1096
q9	5432	4204	4185	4185
q10	6827	1287	1025	1025
q11	428	254	240	240
q12	639	399	285	285
q13	18094	3602	3040	3040
q14	277	269	257	257
q15	q16	729	717	682	682
q17	1209	742	580	580
q18	6972	6208	6146	6146
q19	1099	948	579	579
q20	389	343	230	230
q21	5939	2578	2494	2494
q22	384	337	288	288
Total cold run time: 100759 ms
Total hot run time: 28902 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5907	5884	6095	5884
q2	765	598	568	568
q3	5768	5870	5399	5399
q4	2034	2121	1549	1549
q5	5751	5807	5603	5603
q6	240	181	147	147
q7	2249	2010	1770	1770
q8	2975	2723	2667	2667
q9	7964	7508	7549	7508
q10	3641	3568	3124	3124
q11	583	403	378	378
q12	677	674	502	502
q13	3270	3648	3056	3056
q14	289	287	260	260
q15	q16	656	679	616	616
q17	7775	7051	6874	6874
q18	12962	12231	12959	12231
q19	903	770	756	756
q20	2142	2216	1933	1933
q21	5553	4642	4851	4642
q22	496	435	398	398
Total cold run time: 72600 ms
Total hot run time: 65865 ms

@hello-stephen

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

query5	4312	591	457	457
query6	440	205	187	187
query7	4800	441	229	229
query8	321	162	151	151
query9	8770	3186	3125	3125
query10	481	300	262	262
query11	6048	3841	3588	3588
query12	148	100	92	92
query13	1247	421	314	314
query14	6176	3900	3614	3614
query14_1	3314	3411	3404	3404
query15	205	201	193	193
query16	959	421	394	394
query17	837	624	509	509
query18	2394	402	297	297
query19	199	160	129	129
query20	85	84	81	81
query21	204	123	105	105
query22	12950	12985	12776	12776
query23	13580	12792	12501	12501
query23_1	12548	12649	12594	12594
query24	7378	820	464	464
query24_1	470	477	474	474
query25	510	422	362	362
query26	1260	259	148	148
query27	2772	434	274	274
query28	4652	2036	2041	2036
query29	1562	609	475	475
query30	300	222	190	190
query31	1011	942	817	817
query32	142	97	94	94
query33	532	308	244	244
query34	989	839	508	508
query35	753	754	647	647
query36	827	808	699	699
query37	124	97	88	88
query38	1757	1750	1645	1645
query39	804	822	743	743
query39_1	728	744	746	744
query40	221	136	97	97
query41	72	68	67	67
query42	87	82	81	81
query43	347	356	313	313
query44	1313	704	702	702
query45	175	189	162	162
query46	825	964	571	571
query47	2931	2452	2884	2452
query48	299	318	225	225
query49	584	394	300	300
query50	669	274	207	207
query51	10528	10530	10584	10530
query52	79	80	73	73
query53	189	232	155	155
query54	261	206	211	206
query55	75	71	66	66
query56	236	222	245	222
query57	1674	1610	1606	1606
query58	296	276	251	251
query59	2176	2170	2042	2042
query60	291	252	234	234
query61	169	170	168	168
query62	392	336	294	294
query63	189	170	164	164
query64	2889	960	776	776
query65	3357	3287	3270	3270
query66	1758	415	314	314
query67	22649	22595	22586	22586
query68	3312	1005	620	620
query69	386	294	253	253
query70	838	776	755	755
query71	302	239	222	222
query72	2809	2642	2303	2303
query73	528	528	291	291
query74	4609	4547	4376	4376
query75	2346	2279	1895	1895
query76	2377	1010	587	587
query77	356	369	315	315
query78	9981	9710	9111	9111
query79	986	868	552	552
query80	1228	413	342	342
query81	583	319	268	268
query82	575	135	103	103
query83	303	192	182	182
query84	309	120	97	97
query85	896	427	374	374
query86	405	245	234	234
query87	1971	1973	1815	1815
query88	3845	2793	2774	2774
query89	336	287	239	239
query90	1871	173	166	166
query91	159	157	126	126
query92	102	89	88	88
query93	1131	991	588	588
query94	643	311	296	296
query95	584	314	352	314
query96	673	487	236	236
query97	2471	2431	2372	2372
query98	162	157	149	149
query99	785	768	651	651
Total cold run time: 238914 ms
Total hot run time: 153829 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.15	0.09	0.08
query3	0.34	0.12	0.12
query4	1.60	0.13	0.13
query5	0.25	0.26	0.25
query6	1.16	0.65	0.65
query7	0.04	0.00	0.00
query8	0.10	0.08	0.07
query9	0.44	0.36	0.35
query10	0.56	0.59	0.58
query11	0.32	0.17	0.17
query12	0.32	0.18	0.18
query13	0.52	0.51	0.52
query14	0.95	0.92	0.93
query15	0.65	0.58	0.58
query16	0.36	0.37	0.36
query17	1.00	0.98	1.03
query18	0.29	0.27	0.27
query19	1.97	1.83	1.87
query20	0.02	0.01	0.01
query21	15.40	0.35	0.31
query22	4.93	0.13	0.12
query23	15.86	0.47	0.29
query24	1.99	0.61	0.40
query25	0.14	0.11	0.10
query26	0.79	0.27	0.21
query27	0.10	0.10	0.10
query28	3.35	0.84	0.39
query29	12.57	4.28	3.38
query30	0.33	0.16	0.14
query31	2.75	0.60	0.32
query32	3.22	0.60	0.47
query33	2.91	2.98	3.05
query34	15.88	4.04	3.42
query35	3.37	3.40	3.36
query36	0.61	0.50	0.69
query37	0.14	0.11	0.10
query38	0.08	0.06	0.07
query39	0.06	0.07	0.06
query40	0.18	0.18	0.17
query41	0.11	0.05	0.06
query42	0.06	0.05	0.05
query43	0.07	0.06	0.06
Total cold run time: 95.95 s
Total hot run time: 25.09 s

@hubgeter
hubgeter marked this pull request as ready for review November 9, 2026 09:52
### What problem does this PR solve?

Issue Number: N/A

Related PR: apache#68786

Problem Summary: Iceberg STRING partition values equal to the literal 'null' and SQL NULL share the same legacy commit token. Even with distinct partition writers, the FE can commit the literal value as a null partition, so partition pruning misses matching rows. Preserve nullable values through dynamic, static, and mixed BE writers, transmit an optional NULL bitmap, and share decoding across data-file metadata, delete-file metadata, and identity-partition conflict filters. Retain legacy sender behavior and typed JSON nulls, and reject inconsistent commit partition metadata.

### Release note

Fix Iceberg writes incorrectly treating literal STRING partition values equal to 'null' as SQL NULL. The complete correction requires upgraded FE and BE processes and applies to newly committed files.

### Check List (For Author)

- Test: Unit Test / Regression test / Manual test
    - 150 FE writer-helper and connector-transaction unit tests passed.
    - BE focused unit tests are building; not yet executed.
    - Parquet/ORC regression output generation and comparison passed (28 query results).
    - ASAN BE build, FE build, formatting, header hygiene, and FE Checkstyle passed.
    - Both modified BE test files passed full-file clang-tidy; the final changed-line scan is in progress.
- Behavior changed: Yes. New literal 'null' partitions retain non-null manifest values and conflict filters; malformed partition metadata fails before commit.
- Does this need documentation: No
@hubgeter
hubgeter force-pushed the analyze/doris-29979-master branch from d332f85 to 62104bf Compare November 9, 2026 09:53
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