Skip to content

[fix](iceberg) Commit every Iceberg file under the table's own location - #69392

Merged
morningman merged 12 commits into
apache:masterfrom
xylaaaaa:fix/iceberg-delete-file-commit-path
Nov 4, 2026
Merged

morningman merged 12 commits into
apache:masterfrom
xylaaaaa:fix/iceberg-delete-file-commit-path

Conversation

@xylaaaaa

@xylaaaaa xylaaaaa commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: #69082

Problem Summary:

In short. DELETE, UPDATE and MERGE on an Iceberg table recorded the delete files they write (v2 position delete files and v3 deletion vector files) under the internal s3:// address BE writes them at, instead of the table's own location (oss://, s3a://, abfss://, ...). Doris could not always read such a table back, and other engines and maintenance procedures resolved those files with the wrong file system. This PR commits delete files under the table's location. It also makes every Iceberg file Doris writes take both of its paths from one place in BE and pass one check in FE, so the next writer cannot repeat the mistake without failing.

Background

Every Iceberg sink FE sends carries two forms of the table's data location:

  • a normalized one BE can address the storage with (output_path): FE rewrites oss://, cos://, cosn://, obs://, bos://, gs://, s3a://, s3n:// and Azure abfs[s]:// / wasb[s]:// locations (except OneLake) to s3://;
  • the raw one Iceberg metadata must record: original_output_path on TIcebergTableSink, table_location on TIcebergDeleteSink, both on TIcebergMergeSink.

BE writes each file under the first form and reports it in TIcebergCommitData.file_path, which FE writes into the manifests as it is. So the reported path must be in the second form.

The problem, and what it cost

Reproduce on an Iceberg table located at oss://bucket/...:

CREATE TABLE t (id INT, v STRING) PROPERTIES ('format-version' = '2');
INSERT INTO t VALUES (1, 'a'), (2, 'b'), (3, 'c');
DELETE FROM t WHERE id = 1;
SELECT file_path FROM t$delete_files;  -- s3://bucket/.../data/delete_pos_xxx.parquet
SELECT file_path FROM t$data_files;    -- oss://bucket/.../data/...
  • Whether Doris can still read the table depends on the catalog and storage binding. In a real Azure ADLS Hadoop catalog test with explicit SharedKey, Doris SELECT failed with No storage properties found for schema: s3, and Spark failed with UnsupportedFileSystemException: No FileSystem for scheme "s3".
  • Other engines and maintenance operations such as expire_snapshots / remove_orphan_files may resolve the wrong file system from the recorded scheme, depending on the engine and FileIO. Doris's own remove_orphan_files refuses to run on such a table (Cannot determine whether listed and reachable file locations are equivalent).
  • Cause: data files were written under write_path and committed under original_write_path (VIcebergPartitionWriter), but VIcebergDeleteSink had no such split; it reported the output_path-based path it wrote.
  • Why it went unnoticed: the two writers mapped the paths in different ways, VIcebergDeleteFileWriter reported its write path by default, and FE accepted any path. CI did run on such a location: the Iceberg REST fixture's warehouse is s3a://, which FE normalizes to s3://. But the DML suites only checked that delete file paths contain /data/delete_pos_, and a stray test_iceberg_update_delete_basic.out.org in the repository records the wrong s3://warehouse/wh/... paths.

How this PR fixes it

  1. [fix](be) Commit Iceberg delete files under the table's own location, [test](be) Verify Iceberg delete file commit paths and [test](be) Initialize the Arrow memory pool in the Iceberg position delete write test: VIcebergDeleteSink writes under output_path and commits position delete files and deletion vectors under table_location. An FE unit test pins that both sinks carrying table_location name the same directory as output_path, and DataSinks.thrift documents the contract. The position delete write test sets up the Arrow memory pool the Parquet writer allocates from, so it also passes when run alone (CI review bot finding on this PR).
  2. [refactor](be) Take both paths of every Iceberg file from one output location:
    • The new IcebergOutputLocation (header-only) holds one directory in both forms and gives the write path and the commit path of a file name, and of a partition subdirectory.
    • The data writer (VIcebergTableWriter / VIcebergPartitionWriter), the delete file writer and the Puffin path all take their paths from it. VIcebergDeleteFileWriter now reports the commit path itself instead of its write path.
    • A table or delete sink without both location fields is rejected in open() / init_properties() instead of committing a write path or a relative path. The FE of every branch (3.1, 4.0, 4.1, 4.2, master) sets both fields on every Iceberg sink.
    • Directories join file names with exactly one /.
  3. [improvement](fe) Reject Iceberg commit data reported outside the sink's location:
    • planWrite registers on the transaction the raw location(s) each sink it builds carries, read back from the built sink.
    • IcebergConnectorTransaction.addCommitData, where every report from every writer enters FE, rejects a file that is not under a registered location, or has no path. FE then answers the report as not accepted, and BE deletes the files under the paths it wrote them at and cancels the query, so a wrong path fails the statement and leaves no orphan files.
    • Thrift comments state the contract, including that "the same directory" can differ in more than the scheme (Azure moves the account out of the authority). Comments only, no protocol change.
  4. [test](regression) Check that every Iceberg write records its files under the table location:
    • The new test_iceberg_write_file_locations runs INSERT, INSERT OVERWRITE PARTITION, branch INSERT, DELETE, UPDATE, MERGE and rewrite_data_files on a v2 table, and INSERT, DELETE, UPDATE and MERGE on a v3 table. After each operation every file in $all_files must start with the table's LOCATION plus /data/. A new write operation belongs in this suite too.
    • test_iceberg_update_delete_basic checks the prefix of its delete files as well, and the stray .out.org is removed.
Scenario Before After
DELETE / UPDATE / MERGE on a v2 table at oss://, s3a://, abfss://, ... position delete files recorded as s3://... recorded under the table's location
The same on a v3 table deletion vector (Puffin) files recorded as s3://... recorded under the table's location
A BE writer reports a file outside the location its sink carries committed as reported the statement fails; BE deletes the file
A sink plan without original_output_path / table_location (no supported FE sends one) data files committed as /p=1/x.parquet, delete files as s3://... rejected before any file is written
write.data.path ending with / data files at .../data//p=1/x.parquet .../data/p=1/x.parquet, as Iceberg's own location provider places them

Delete files that an older version already committed with s3:// keep that address until they are rewritten or expired.

Upgrade BE before FE, as usual. An upgraded FE rejects the s3:// delete file paths that a BE without this fix reports, so until that BE is upgraded, DELETE / UPDATE / MERGE on a table whose location FE normalizes fails instead of committing the wrong path.

Classes, and how they call each other

  • IcebergWritePlanProvider.planWrite (FE) builds the sink and registers the raw location(s) it carries with the transaction (commitLocationsOf).
  • IcebergConnectorTransaction.addCommitData (FE) accepts a reported file only under a registered location; IcebergWriterHelper then turns the fragments into DataFile / DeleteFile.
  • IcebergOutputLocation (BE, new) is one directory in its write form and its commit form.
  • VIcebergTableWriter builds the data location in open() and hands each VIcebergPartitionWriter its partition directory (WriteInfo.location). VIcebergDeleteSink writes position delete files through VIcebergDeleteFileWriter and deletion vectors into one Puffin file, both from its location. VIcebergMergeSink builds one of each.
FE planWrite ── sink: output_path + raw location ──────────────► BE
  │ addCommitLocation(raw location)                              IcebergOutputLocation(output_path, raw location)
  ▼                                                                ├─ VIcebergTableWriter ─► VIcebergPartitionWriter   data files
IcebergConnectorTransaction                                        ├─ VIcebergDeleteSink ──► VIcebergDeleteFileWriter  position deletes
  ▲ addCommitData: file_path under a registered                    │                     └─► Puffin writer             deletion vectors
  │ location, else reject the report                               └─ VIcebergMergeSink ──► both of the above
  └──────────── TIcebergCommitData.file_path = commit path ◄───────┘

Not changed: Thrift fields (comments only), the scan side, and how FE normalizes locations.

Release note

Fix Iceberg DELETE/UPDATE/MERGE recording delete files with an s3:// path instead of the table's own location (e.g. oss://, s3a:// or abfss://), which could prevent Doris and other engines from reading the table. Iceberg data files written under a write.data.path that ends with / no longer get a double / in their path.

Check List (For Author)

  • Test:
    • Unit Test:
      • BE: run-be-ut.sh --filter='*Iceberg*:VParquetWriterTest.*': 318 tests from 35 suites pass, including every new case. The tests that write files also pass each in a process of its own: VIcebergDeleteSinkTest.TestWritePositionDeletesCommitsTableLocation (the CI review bot finding) and the new cases in VIcebergTableWriterTest, VIcebergPartitionWriterTest and VIcebergMergeSinkTest.
      • FE: all 1634 tests of fe-connector-iceberg pass (including the new cases in IcebergConnectorTransactionTest and IcebergWritePlanProviderTest); removing the registration in planWrite or the check in addCommitData makes the new cases fail.
    • Regression test: on a local cluster against the Iceberg REST docker fixture (warehouse s3a://warehouse/wh/):
      • test_iceberg_write_file_locations and test_iceberg_update_delete_basic pass. The v2 table ends with 15 data files and 3 position delete files, the v3 table with 6 data files and 3 deletion vector files, all under s3a://warehouse/wh/<db>/<table>/data/.
      • 12 related suites pass too: test_iceberg_merge_into_basic, test_iceberg_merge_into_advanced, test_iceberg_update_delete_advanced, test_iceberg_rewrite_data_files, test_iceberg_v3_row_lineage_rewrite_data_files, test_iceberg_v3_row_lineage_update_delete_merge, test_iceberg_static_partition_overwrite, test_iceberg_write_branch_dml_boundary, test_iceberg_write_overwrite_delete_files, test_iceberg_write_dml_modes_evolution, test_iceberg_write_partition_path, test_iceberg_write_transform_partitions.
      • test_iceberg_insert_overwrite, test_iceberg_write_insert and test_iceberg_write_partitions need the Hive Metastore docker and were not run locally.
    • Manual test (first commit): validated on local master with real Azure ADLS (abfss://), Hadoop catalog and explicit SharedKey: v2/v3 DELETE/UPDATE/MERGE, Spark reads and Doris expire_snapshots passed. Other cloud providers and REST-vended credentials were not tested.
  • Behavior changed: Yes. Delete files are committed under the table's location. An Iceberg write whose BE reports a file outside the location its sink carries now fails instead of committing that path, so BE must be upgraded before FE. Data files under a write.data.path ending with / no longer get a double /.
  • Does this need documentation: No

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69082

Problem Summary: DELETE, UPDATE and MERGE on an Iceberg table whose location FE normalizes for BE
(oss://, cos://, cosn://, obs://, bos://, gs://, s3a://, s3n://, and Azure abfs/abfss/wasb/wasbs
except OneLake) record the new delete files in Iceberg metadata with the internal s3:// address
instead of the table's own scheme. Both v2 position delete files (delete_pos_*.parquet) and v3
deletion vector files (delete_dv_*.puffin) are affected; data files are not.

Reproduce on an Iceberg table located at oss://bucket/...:

    CREATE TABLE t (id INT, v STRING) PROPERTIES ('format-version' = '2');
    INSERT INTO t VALUES (1, 'a'), (2, 'b'), (3, 'c');
    DELETE FROM t WHERE id = 1;
    SELECT file_path FROM t$delete_files;  -- s3://bucket/.../data/delete_pos_xxx.parquet
    SELECT file_path FROM t$data_files;    -- oss://bucket/.../data/...

Doris itself still reads the table, because it normalizes every path it reads anyway, but other
engines resolve the file system by scheme and fail: Spark or Trino reading the table, or running
expire_snapshots / remove_orphan_files, look the delete file up as s3 (e.g. OSSFileIO rejects the
s3 scheme, HadoopFileIO usually has no file system for it, ResolvingFileIO goes to AWS S3,
ADLSFileIO rejects it as an invalid ADLS URI).

Cause: data files are written under write_path (the s3:// form BE can address) and committed
under original_write_path (VIcebergPartitionWriter). VIcebergDeleteSink had no such split: it
generates delete file paths under output_path and reports exactly that path for the commit
(VIcebergDeleteFileWriter sets file_path to its output path, and the puffin path is reported
as written).

Fix: apply the same split to delete files. VIcebergDeleteSink still writes under output_path but
commits under table_location, the raw data location FE already sends, e.g. written to
s3://b/db/t/data/delete_x.parquet and committed as oss://b/db/t/data/delete_x.parquet. Every FE
version sets table_location to the raw form of output_path's directory (delete sink and merge
sink alike), so no protocol change is needed. That contract is now written on table_location in
DataSinks.thrift (comments only) and asserted by an FE unit test, since breaking it would record
delete files that do not exist without any error.

Delete files that an older version already committed with s3:// keep that address until they
are rewritten.

### Release note

Fix Iceberg DELETE/UPDATE/MERGE recording delete files with an s3:// path instead of the table's
own location (e.g. oss:// or abfss://), which made other engines fail to read the table.

### Check List (For Author)

- Test: Unit Test (VIcebergDeleteSinkTest.TestCommitPathUsesTableLocation,
  IcebergWritePlanProviderTest.planWriteDeleteAndMergeSinksKeepTableLocationInTheOutputDirectory;
  not run locally, CI runs them)
- Behavior changed: Yes. Delete files are committed under table_location.
- Does this need documentation: No
Copilot AI balanced review requested due to automatic review settings October 21, 2026 08:58
@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?

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@xylaaaaa

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage `` 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

BE UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 66.45% (31855/47939)
Line Coverage 51.23% (335593/655129)
Region Coverage 46.60% (271341/582282)
Branch Coverage 48.33% (127986/264796)

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17262	5152	5076	5076
q2	2165	309	255	255
q3	10024	1362	829	829
q4	4674	461	338	338
q5	7451	799	532	532
q6	178	184	150	150
q7	745	810	600	600
q8	9273	1307	1029	1029
q9	5375	4193	4163	4163
q10	6831	1281	1018	1018
q11	426	246	230	230
q12	652	408	287	287
q13	18048	3542	3017	3017
q14	274	262	247	247
q15	q16	705	727	649	649
q17	1165	760	589	589
q18	6962	6196	6102	6102
q19	1111	965	619	619
q20	375	333	221	221
q21	5068	2574	2559	2559
q22	374	349	261	261
Total cold run time: 99138 ms
Total hot run time: 28771 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5935	5873	5831	5831
q2	676	596	569	569
q3	5620	5735	5238	5238
q4	2040	2161	1590	1590
q5	5877	5679	5595	5595
q6	237	187	155	155
q7	2355	2020	1774	1774
q8	3012	2718	2652	2652
q9	7844	7518	7451	7451
q10	3602	3562	3108	3108
q11	596	402	383	383
q12	664	672	521	521
q13	3256	3620	3073	3073
q14	287	293	258	258
q15	q16	653	673	617	617
q17	7740	7054	6876	6876
q18	12983	12189	12854	12189
q19	889	803	798	798
q20	2129	2130	1886	1886
q21	5602	4598	4665	4598
q22	496	460	399	399
Total cold run time: 72493 ms
Total hot run time: 65561 ms

@hello-stephen

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

query5	4323	595	457	457
query6	432	212	192	192
query7	4801	440	219	219
query8	335	167	156	156
query9	8759	3084	3076	3076
query10	494	320	279	279
query11	6053	3871	3576	3576
query12	146	94	88	88
query13	1260	450	326	326
query14	6104	3882	3638	3638
query14_1	3426	3438	3462	3438
query15	205	212	182	182
query16	956	440	435	435
query17	871	645	545	545
query18	2416	417	308	308
query19	202	171	137	137
query20	85	84	84	84
query21	210	125	105	105
query22	13042	13075	12823	12823
query23	13501	12700	12478	12478
query23_1	12639	12485	12612	12485
query24	7323	827	456	456
query24_1	464	461	472	461
query25	518	400	345	345
query26	1260	258	133	133
query27	2767	433	261	261
query28	4648	1928	1919	1919
query29	1537	578	434	434
query30	300	221	180	180
query31	1024	922	826	826
query32	145	91	125	91
query33	514	294	228	228
query34	933	838	492	492
query35	739	760	645	645
query36	805	826	691	691
query37	128	96	86	86
query38	1781	1736	1669	1669
query39	790	789	747	747
query39_1	723	734	733	733
query40	215	112	90	90
query41	64	65	62	62
query42	85	83	81	81
query43	343	355	305	305
query44	1290	683	692	683
query45	179	184	162	162
query46	825	956	566	566
query47	2915	2856	2907	2856
query48	290	304	214	214
query49	593	394	292	292
query50	658	266	201	201
query51	10453	10595	10517	10517
query52	81	78	73	73
query53	181	203	147	147
query54	234	191	174	174
query55	74	64	67	64
query56	240	207	198	198
query57	1666	1626	1574	1574
query58	291	263	252	252
query59	2071	2153	1929	1929
query60	295	239	227	227
query61	151	149	147	147
query62	390	341	299	299
query63	187	157	155	155
query64	2738	929	865	865
query65	3315	3270	3268	3268
query66	1790	431	319	319
query67	19884	20180	19983	19983
query68	2952	1001	609	609
query69	391	289	257	257
query70	851	782	780	780
query71	301	255	236	236
query72	2901	2746	2441	2441
query73	509	524	293	293
query74	4602	4506	4343	4343
query75	2334	2283	1925	1925
query76	2291	1007	606	606
query77	339	376	264	264
query78	9924	9714	9177	9177
query79	988	848	521	521
query80	1208	447	344	344
query81	580	317	274	274
query82	589	135	107	107
query83	302	195	186	186
query84	303	120	101	101
query85	861	425	363	363
query86	401	234	208	208
query87	2011	1951	1803	1803
query88	3661	2685	2669	2669
query89	331	276	246	246
query90	1847	172	168	168
query91	160	167	129	129
query92	101	92	89	89
query93	1027	1013	574	574
query94	631	311	285	285
query95	575	386	308	308
query96	661	481	234	234
query97	2442	2427	2315	2315
query98	162	152	151	151
query99	782	758	636	636
Total cold run time: 234910 ms
Total hot run time: 151114 ms

@hello-stephen

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

query1	0.01	0.00	0.00
query2	0.13	0.09	0.08
query3	0.36	0.12	0.13
query4	1.60	0.15	0.13
query5	0.28	0.24	0.25
query6	1.15	0.65	0.65
query7	0.04	0.01	0.01
query8	0.09	0.08	0.07
query9	0.47	0.36	0.35
query10	0.56	0.56	0.60
query11	0.31	0.18	0.17
query12	0.31	0.19	0.18
query13	0.51	0.52	0.52
query14	0.95	0.93	0.93
query15	0.67	0.58	0.57
query16	0.34	0.36	0.36
query17	1.02	1.02	1.05
query18	0.29	0.27	0.28
query19	1.93	1.89	1.89
query20	0.02	0.02	0.02
query21	15.40	0.35	0.30
query22	4.92	0.13	0.12
query23	15.86	0.48	0.30
query24	1.96	0.63	0.38
query25	0.16	0.11	0.11
query26	0.78	0.26	0.21
query27	0.10	0.10	0.09
query28	3.67	0.74	0.38
query29	12.60	4.38	3.47
query30	0.37	0.17	0.14
query31	2.77	0.55	0.32
query32	3.25	0.58	0.48
query33	3.06	3.06	2.98
query34	15.91	4.05	3.43
query35	3.38	3.36	3.37
query36	0.55	0.51	0.48
query37	0.12	0.10	0.09
query38	0.08	0.06	0.07
query39	0.06	0.06	0.06
query40	0.20	0.16	0.16
query41	0.09	0.06	0.05
query42	0.06	0.05	0.06
query43	0.07	0.05	0.06
Total cold run time: 96.46 s
Total hot run time: 25.21 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100% (0/0) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.25% (35886/46454)
Line Coverage 62.51% (405114/648128)
Region Coverage 58.98% (342183/580183)
Branch Coverage 59.91% (158245/264151)

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 100% (0/0) 🎉
Increment coverage report
Complete coverage report

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary: A helper-only path test cannot detect missing conversion at the position-delete or deletion-vector commit sites. Write a real local Parquet position-delete file with a distinct OSS commit location and check the final commit metadata and the file's referenced data paths. Extend the shared-Puffin test with a distinct Azure commit location while retaining its physical-file and footer checks. Compute the shared Puffin commit path once before iterating over its blobs.

### Release note

None

### Check List (For Author)

- Test: Unit Test added/updated, not compiled or run locally; the user handles compilation. clang-format v16, check-format, build hygiene and git diff --check passed.
- Behavior changed: No. The existing delete-file commit path fix is preserved.
- Does this need documentation: No
@xylaaaaa

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor

Cloud UT Coverage Report

Increment line coverage 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 78.02% (2080/2666)
Line Coverage 66.24% (38335/57876)
Region Coverage 53.65% (35976/67052)
Branch Coverage 57.22% (11600/20274)

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16688	5146	5068	5068
q2	2102	310	260	260
q3	9972	1384	823	823
q4	4666	464	330	330
q5	7498	791	534	534
q6	184	179	153	153
q7	748	793	605	605
q8	9327	1347	1019	1019
q9	5518	4210	4166	4166
q10	6845	1303	1017	1017
q11	427	250	234	234
q12	646	401	294	294
q13	18103	3670	2995	2995
q14	277	272	246	246
q15	q16	750	706	673	673
q17	1220	748	578	578
q18	7032	6215	6139	6139
q19	1121	949	605	605
q20	399	345	227	227
q21	5563	2481	2459	2459
q22	370	335	288	288
Total cold run time: 99456 ms
Total hot run time: 28713 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5960	5891	6091	5891
q2	708	609	588	588
q3	5622	5737	5361	5361
q4	2032	2145	1555	1555
q5	5840	5929	5550	5550
q6	237	187	140	140
q7	2239	1999	1737	1737
q8	3051	2692	2627	2627
q9	7898	7906	7611	7611
q10	3608	3562	3160	3160
q11	578	408	396	396
q12	661	689	500	500
q13	3222	3588	3012	3012
q14	279	298	267	267
q15	q16	670	683	618	618
q17	7715	7020	6898	6898
q18	12944	12136	12950	12136
q19	915	783	793	783
q20	2146	2193	1929	1929
q21	5584	4595	4661	4595
q22	494	475	404	404
Total cold run time: 72403 ms
Total hot run time: 65758 ms

@hello-stephen

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

query5	4331	579	448	448
query6	426	208	194	194
query7	4824	442	234	234
query8	320	167	152	152
query9	8770	3068	3081	3068
query10	472	324	269	269
query11	6025	3879	3568	3568
query12	145	104	86	86
query13	1272	424	337	337
query14	6103	3937	3644	3644
query14_1	3486	3405	3350	3350
query15	202	192	182	182
query16	931	432	317	317
query17	846	633	518	518
query18	2400	420	297	297
query19	191	157	132	132
query20	84	79	80	79
query21	210	127	106	106
query22	12989	12998	12843	12843
query23	13553	12678	12443	12443
query23_1	12512	12526	12456	12456
query24	7219	794	458	458
query24_1	452	461	463	461
query25	506	403	333	333
query26	1266	253	135	135
query27	2769	434	268	268
query28	4570	1927	1928	1927
query29	1529	580	445	445
query30	296	220	190	190
query31	1020	926	817	817
query32	138	109	97	97
query33	537	300	248	248
query34	917	850	492	492
query35	731	764	632	632
query36	838	814	776	776
query37	129	98	83	83
query38	1762	1731	1683	1683
query39	795	788	752	752
query39_1	736	735	745	735
query40	226	115	113	113
query41	87	69	68	68
query42	88	83	86	83
query43	341	366	310	310
query44	1286	688	687	687
query45	182	174	164	164
query46	821	958	570	570
query47	2944	2938	2800	2800
query48	307	308	223	223
query49	574	399	301	301
query50	678	287	208	208
query51	10418	10505	10526	10505
query52	83	80	71	71
query53	190	215	153	153
query54	240	206	192	192
query55	73	70	72	70
query56	263	225	236	225
query57	1637	1619	1583	1583
query58	301	283	263	263
query59	2198	2175	2002	2002
query60	301	256	235	235
query61	170	169	162	162
query62	381	329	289	289
query63	190	157	160	157
query64	2836	1021	782	782
query65	3327	3268	3293	3268
query66	1778	437	307	307
query67	20356	20274	19983	19983
query68	3246	991	608	608
query69	400	288	247	247
query70	851	791	771	771
query71	305	217	207	207
query72	2849	2557	2374	2374
query73	520	513	293	293
query74	4658	4494	4337	4337
query75	2325	2276	1922	1922
query76	2307	997	604	604
query77	358	374	278	278
query78	9878	9712	9189	9189
query79	980	839	500	500
query80	1236	445	334	334
query81	585	326	268	268
query82	597	127	114	114
query83	301	192	201	192
query84	311	127	101	101
query85	875	427	373	373
query86	405	238	229	229
query87	1992	1966	1811	1811
query88	3605	2654	2630	2630
query89	317	286	242	242
query90	1930	171	165	165
query91	155	157	127	127
query92	100	86	82	82
query93	1003	994	588	588
query94	644	300	267	267
query95	585	331	297	297
query96	660	480	232	232
query97	2444	2429	2317	2317
query98	155	157	147	147
query99	769	771	658	658
Total cold run time: 235721 ms
Total hot run time: 150929 ms

@hello-stephen

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

query1	0.00	0.01	0.00
query2	0.09	0.06	0.05
query3	0.26	0.09	0.10
query4	1.61	0.10	0.11
query5	0.23	0.24	0.24
query6	1.17	0.68	0.68
query7	0.03	0.01	0.00
query8	0.05	0.04	0.04
query9	0.40	0.36	0.34
query10	0.58	0.58	0.60
query11	0.20	0.14	0.14
query12	0.18	0.14	0.14
query13	0.48	0.49	0.49
query14	1.02	1.02	1.01
query15	0.63	0.61	0.60
query16	0.35	0.36	0.34
query17	1.14	1.14	1.12
query18	0.21	0.19	0.18
query19	2.00	2.04	1.92
query20	0.02	0.02	0.01
query21	15.49	0.20	0.13
query22	4.81	0.05	0.06
query23	16.26	0.33	0.12
query24	3.10	0.49	0.32
query25	0.11	0.06	0.04
query26	0.81	0.21	0.14
query27	0.06	0.04	0.05
query28	3.63	0.80	0.36
query29	12.48	4.14	3.29
query30	0.28	0.13	0.12
query31	2.77	0.55	0.32
query32	3.22	0.58	0.49
query33	3.14	3.26	3.17
query34	15.33	3.97	3.43
query35	3.33	3.34	3.34
query36	0.56	0.45	0.42
query37	0.12	0.09	0.11
query38	0.05	0.04	0.04
query39	0.05	0.04	0.03
query40	0.18	0.16	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.05	0.04	0.04
Total cold run time: 96.6 s
Total hot run time: 24.26 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage `` 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 0.00% (0/5) 🎉
Increment coverage report
Complete coverage report

@morningman

Copy link
Copy Markdown
Contributor

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

The production change consistently restores the table's raw data-location URI for both position-delete files and deletion vectors. One P2 issue is reported inline: the new real-Parquet test leaves ExecEnv's Arrow memory pool uninitialized, so dictionary encoding dereferences a null pool. No P0/P1 issue was verified, and there are no existing review threads to carry forward.

Critical checkpoint conclusions:

  1. Goal and proof: the shared helper corrects commit metadata while retaining physical write paths; BE helper/v2/v3 tests and the FE directory-contract test target this behavior. The v2 write test needs the inline setup correction.
  2. Scope and reuse: one private helper serves both formats; the change is focused and follows the data writer's existing original/write-path split.
  3. Concurrency and locks: one AsyncResultWriter worker serializes open/write/close under its existing task context. Locations are initialized before use; no new shared mutation, lock order, or blocking critical section is introduced.
  4. Lifecycle and static initialization: physical-file ownership and deferred MERGE cleanup remain intact; no new static initialization or ownership cycle is added. Test environment initialization is the reported issue.
  5. Configuration: no configuration is added; existing custom data-location precedence remains intact.
  6. Compatibility and storage: no file payload format or public protocol symbol changes. Current producers derive both locations from the same captured directory; older Hadoop-Path producers are excluded by the existing coordinator ACK capability fence before writing.
  7. Thrift/protobuf: both touched sink definitions were compared on HEAD and branch-3.1/4.0/4.1/4.2. They are absent on 3.1/4.0; shared IDs, meanings, types, and optionality agree on 4.1/4.2. This patch changes comments only.
  8. Parallel paths: v2 position deletes, v3 shared Puffin output, direct DELETE, and UPDATE/MERGE forwarding were checked. Both cloud and shared-nothing use this external write path; internal MoW/version invariants do not apply.
  9. Conditions and errors: missing-location fallback matches both generators; their common base guarantees the prefix assertion. Comments explain the concrete URI failure. Existing Status propagation is preserved.
  10. Test coverage: new assertions cover raw commit URIs, unchanged referenced data-file URIs, partitions, shared-Puffin offsets/footer linkage, and trailing slashes. The FE fixture covers OSS normalization; actual Azure/cloud services and missing-output-path fallback are not newly exercised.
  11. Test results: no golden result files change. Builds and tests were not run under this static-only review contract; no author-reported execution was treated as independently verified.
  12. Observability: existing write/close logs, counters, and commit error context remain adequate for this path-string correction.
  13. Transactions, persistence, and failover: existing RowDelta publication and conflict validation remain unchanged; no new EditLog/replay state is introduced. Raw data-file identity and Puffin path-plus-offset deduplication are preserved.
  14. Writes, atomicity, and failures: write/report failure cleanup and MERGE outer-close cleanup retain the physical filesystem/path pair. The patch introduces no new crash ownership or partial-publication window; existing transaction-abort orphan behavior is unchanged.
  15. FE/BE variables: no fields are added. Direct and MERGE plans forward both existing optional locations, and future delete-file reads normalize the corrected raw URI before BE reopening.
  16. Performance and memory: only URI-sized temporaries are added per position-delete file or shared Puffin; no new bulk retention, scan, or allocation hotspot was found.
  17. Other concerns and focus: no additional user focus was supplied. URI authorities/escaping, custom directories, legacy producers, cleanup, and test dependencies received an additional sweep; no other verified defect remains.

Review coverage is complete for the supplied five-file diff and relevant static control flow. Validation limits are the prohibited runtime/build/test execution and lack of real cloud or cross-engine execution; there are no unresolved static candidates.

Review converged after 2 round(s).

it->second.rows_to_delete.add(uint32_t {10});
it->second.rows_to_delete.add(uint32_t {20});

const auto status = sink->_write_position_delete_files(file_deletions);

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.

[P2] Initialize the Arrow memory pool before the Parquet write

This new test reaches the real Parquet writer, but its fixture never initializes ExecEnv::_arrow_memory_pool: it defaults to null, and run_all_tests.cpp only calls init_mem_tracker(), which does not set it. VIcebergDeleteFileWriter enables dictionary encoding, and VParquetWriter::_parse_properties() explicitly forwards that null pool into WriterProperties. In Arrow 24, the dictionary encoder retains it in buffered_indices_; the first value's insertion reaches the STL allocator, which calls pool_->Allocate without a null fallback. Thus running this test in isolation crashes before it can verify the commit-path assertions. Save, initialize, and restore the pool as VParquetWriterTest::SetUp/TearDown already does.

…elete write test

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary: `TestWritePositionDeletesCommitsTableLocation` runs the real Parquet writer. The writer enables dictionary encoding and passes `ExecEnv::_arrow_memory_pool` to Arrow, but this fixture never initializes that pool. The test run alone therefore dereferences a null pool on the first dictionary insert. The test now sets the pool to Arrow's default pool and restores it afterwards, as `VParquetWriterTest` and `ArrowSchemaUtilTest` do.

### Release note

None

### Check List (For Author)

- Test: Unit Test (compiled and run in CI)
- Behavior changed: No
- Does this need documentation: No
@xylaaaaa

Copy link
Copy Markdown
Contributor Author

run buildall

…location

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary:

BE writes every Iceberg file under the location form it can address (output_path, e.g.
s3://b/db/t/data for an oss:// table), while Iceberg metadata must record it under the table's own
form (original_output_path or table_location, e.g. oss://b/db/t/data). The two writers did this in
two different ways:

- VIcebergTableWriter assembled both directories for every partition writer, in three copied
  branches of _create_partition_writer.
- VIcebergDeleteSink generated only the write path and rebased it into the commit form afterwards
  (_commit_path_of, added earlier in this PR), while VIcebergDeleteFileWriter still reported its
  write path as file_path and relied on the caller to overwrite it.

Nothing made a new writer, or a new kind of delete file in the delete sink, report the right form,
and getting it wrong was silent: that is how delete files came to be committed as s3://.

This commit gives both forms one owner:

- IcebergOutputLocation holds a directory in both forms and gives the write path and the commit
  path of a file name, and the same pair for a partition subdirectory. It is header-only, so no
  unity batch moves.
- The partition writer's WriteInfo carries one location instead of write_path,
  original_write_path and target_path (target_path was never read). VIcebergTableWriter builds the
  data location once in open() and takes each partition directory from it.
- VIcebergDeleteFileWriter takes the location and a file name and reports the commit path itself.
  The delete sink names its position-delete and Puffin files and takes both paths of each from its
  location, so _commit_path_of goes away.
- A table or delete sink without both location fields now fails in open() / init_properties()
  instead of committing the write path (delete sink) or a relative path such as /p=1/x.parquet
  (table sink). The FE of every branch (3.1, 4.0, 4.1, 4.2, master) sets both fields on every
  Iceberg sink, so no plan a supported FE sends is rejected.
- Directories join file names with exactly one '/'. Data files under a write.data.path ending in
  '/' were placed at .../data//p=1/x.parquet in both forms; they now go to .../data/p=1/x.parquet,
  as Iceberg's own location provider places them. Delete files already joined this way.

### Release note

Iceberg data files written under a write.data.path that ends with '/' no longer get a double '/'
in their path.

### Check List (For Author)

- Test: Unit Test
    - New IcebergOutputLocationTest; new cases in VIcebergPartitionWriterTest,
      VIcebergTableWriterTest, VIcebergDeleteSinkTest and VIcebergMergeSinkTest (data files and
      the merge sink's inner sinks write under output_path and commit under the table's form; plans
      without both location fields are rejected).
    - run-be-ut.sh --filter='*Iceberg*:VParquetWriterTest.*': 318 tests from 35 suites pass,
      including every new case. The tests that write files also pass each in a process of its own:
      VIcebergDeleteSinkTest.TestWritePositionDeletesCommitsTableLocation and the new cases in
      VIcebergTableWriterTest, VIcebergPartitionWriterTest and VIcebergMergeSinkTest.
- Behavior changed: Yes. A sink plan without both location fields is rejected (no supported FE
  sends one). Data files under a write.data.path ending in '/' no longer get a double '/'.
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…k's location

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary:

FE took every file path BE reported for an Iceberg write as it was: IcebergWriterHelper wrote
commitData.getFilePath() into the DataFile / DeleteFile, and rollback() deleted that path through
the table's FileIO. Nothing checked that the path was in the table's own location form. A writer
that reported the address BE wrote the file at (the s3:// form FE normalizes oss://, cos://,
cosn://, obs://, bos://, gs://, s3a://, s3n:// and Azure locations to) committed files that other
engines could not open, and no test noticed. The Iceberg REST fixture's warehouse is s3a://, which
is normalized to s3://, so the DML suites ran into exactly this case; the
test_iceberg_update_delete_basic.out.org left in the repository records delete files as
s3://warehouse/wh/... for tables located at s3a://warehouse/wh/....

Fix:

- planWrite registers on the transaction the raw location every sink it builds carries:
  TIcebergTableSink.original_output_path, TIcebergDeleteSink.table_location, and both fields of
  TIcebergMergeSink. commitLocationsOf reads them back from the built sink, so the registered value
  is exactly what BE receives.
- IcebergConnectorTransaction.addCommitData rejects a fragment whose file_path is not under one of
  them, or that has no path. This is where every report from every writer, current or future,
  enters FE.
- Rejecting the report fails the statement cleanly: FE answers the report as not accepted
  (QeProcessorImpl), and BE deletes the files under the paths it wrote them at and cancels the
  query. A check at commit time instead would leave rollback() deleting the wrong path, i.e. orphan
  files.
- DataSinks.thrift comments on original_output_path, table_location and TIcebergCommitData.file_path
  state the contract, including that "the same directory" can differ in more than the scheme
  (Azure moves the account out of the authority). Comments only, no protocol change.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - IcebergConnectorTransactionTest: files under every registered location are accepted; the
      normalized s3:// address, a sibling directory sharing the prefix, a fragment without a path
      and a fragment before any sink registered a location are rejected and not accumulated.
    - IcebergWritePlanProviderTest: INSERT, REWRITE, DELETE and UPDATE plans each register their
      sink's location, so a file under the oss:// data location is accepted and the s3:// form is
      rejected.
    - All 1634 tests of fe-connector-iceberg pass (5 skipped: live connectivity checks). Removing
      the registration in planWrite, or the check in addCommitData, makes the new cases fail.
- Behavior changed: Yes. An Iceberg write whose BE reports a file outside the location its sink
  carries now fails instead of committing that path. Upgrade BE before FE: an upgraded FE rejects
  the s3:// delete file paths that a BE without the fix in this PR reports, so DELETE / UPDATE /
  MERGE on a table whose location FE normalizes fails until that BE is upgraded.
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…port

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary: When FE rejects a final external-file report (for example the
Iceberg commit-location check finds a file outside the sink's commit location),
QeProcessorImpl only answered BE with external_file_commit_data_accepted=false.
The fragment was never marked done and the coordinator status was never set.
BE treats the rejection as terminal: it removes the files and never resends the
report. The coordinator join therefore kept waiting on the fragment latch until
insert_timeout (4 hours by default), and the user saw a timeout instead of the
real reason.

Now QeProcessorImpl cancels the coordinator with the rejection reason before it
answers BE. Both coordinators' cancel release the fragment latch, so the INSERT
fails immediately with the validation error and the transaction is aborted.

### Release note

None

### Check List (For Author)

- Test: Unit Test (QeProcessorImplReportAckTest, run by CI)
- Behavior changed: Yes. A rejected final external-file report now fails the statement immediately instead of waiting until timeout.
- Does this need documentation: No
@xylaaaaa
xylaaaaa requested a review from morrySnow as a code owner October 31, 2026 17:09
@xylaaaaa

Copy link
Copy Markdown
Contributor Author

run buildall

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	16626	5097	5033	5033
q2	2119	304	250	250
q3	9921	1372	812	812
q4	4606	456	331	331
q5	7427	812	530	530
q6	176	181	152	152
q7	753	789	590	590
q8	9369	1330	1055	1055
q9	5456	4163	4153	4153
q10	6811	1273	1021	1021
q11	425	234	221	221
q12	636	397	278	278
q13	18119	3662	2996	2996
q14	275	276	246	246
q15	q16	707	714	662	662
q17	1204	739	581	581
q18	6911	6198	6157	6157
q19	1098	950	599	599
q20	402	336	225	225
q21	5195	2100	2243	2100
q22	344	293	254	254
Total cold run time: 98580 ms
Total hot run time: 28246 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5552	5547	5579	5547
q2	674	557	538	538
q3	5229	5382	4992	4992
q4	1963	2115	1548	1548
q5	5242	5143	5130	5130
q6	243	259	228	228
q7	2425	2025	1856	1856
q8	2950	2680	2631	2631
q9	8069	7965	7904	7904
q10	3743	3756	3242	3242
q11	605	447	440	440
q12	684	709	523	523
q13	3541	3829	3338	3338
q14	326	312	308	308
q15	q16	700	731	632	632
q17	8214	6992	6878	6878
q18	12963	12199	12861	12199
q19	915	822	817	817
q20	2141	2152	1942	1942
q21	5535	4568	4625	4568
q22	495	458	403	403
Total cold run time: 72209 ms
Total hot run time: 65664 ms

@hello-stephen

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

query5	4311	576	453	453
query6	419	202	186	186
query7	4800	431	222	222
query8	323	186	147	147
query9	8764	3221	3198	3198
query10	476	307	252	252
query11	6023	3844	3559	3559
query12	157	92	86	86
query13	1263	440	324	324
query14	6085	3916	3672	3672
query14_1	3395	3367	3399	3367
query15	201	198	178	178
query16	936	433	410	410
query17	839	644	515	515
query18	2410	404	296	296
query19	185	160	124	124
query20	81	83	79	79
query21	206	125	102	102
query22	12906	12983	12774	12774
query23	13335	12851	12412	12412
query23_1	12534	12429	12445	12429
query24	7176	840	467	467
query24_1	500	469	478	469
query25	535	428	367	367
query26	1249	261	140	140
query27	2759	436	272	272
query28	4560	2024	2003	2003
query29	1537	617	450	450
query30	298	210	182	182
query31	1014	936	820	820
query32	141	95	93	93
query33	530	313	267	267
query34	912	856	508	508
query35	723	763	641	641
query36	881	803	726	726
query37	126	98	90	90
query38	1782	1770	1656	1656
query39	806	794	745	745
query39_1	732	728	743	728
query40	222	121	99	99
query41	72	69	69	69
query42	94	84	82	82
query43	378	370	316	316
query44	1329	708	709	708
query45	174	183	170	170
query46	822	959	557	557
query47	2881	2941	2672	2672
query48	319	305	221	221
query49	588	403	304	304
query50	701	275	226	226
query51	10525	10472	10587	10472
query52	82	80	80	80
query53	187	208	158	158
query54	268	205	184	184
query55	70	67	66	66
query56	256	224	237	224
query57	1645	1619	1549	1549
query58	297	269	282	269
query59	2147	2216	1974	1974
query60	309	265	229	229
query61	177	161	171	161
query62	395	337	296	296
query63	191	164	160	160
query64	2843	940	756	756
query65	3344	3257	3247	3247
query66	1761	408	313	313
query67	20279	20044	20090	20044
query68	2988	1018	607	607
query69	394	279	256	256
query70	849	767	772	767
query71	302	225	203	203
query72	2683	2567	2332	2332
query73	513	540	289	289
query74	4644	4529	4328	4328
query75	2314	2275	1924	1924
query76	2186	1011	636	636
query77	349	360	269	269
query78	9955	9755	9157	9157
query79	999	858	524	524
query80	1246	406	346	346
query81	601	318	278	278
query82	566	133	109	109
query83	310	196	178	178
query84	313	118	100	100
query85	891	446	371	371
query86	413	234	234	234
query87	2032	1916	1818	1818
query88	3849	2795	2782	2782
query89	333	286	243	243
query90	1937	164	166	164
query91	158	145	123	123
query92	95	86	89	86
query93	1010	991	571	571
query94	636	302	273	273
query95	569	332	360	332
query96	712	501	244	244
query97	2459	2451	2313	2313
query98	177	157	145	145
query99	764	759	642	642
Total cold run time: 235274 ms
Total hot run time: 151011 ms

@hello-stephen

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

query1	0.01	0.01	0.01
query2	0.13	0.08	0.08
query3	0.35	0.13	0.13
query4	1.61	0.13	0.13
query5	0.27	0.24	0.25
query6	1.15	0.64	0.65
query7	0.04	0.01	0.01
query8	0.08	0.07	0.07
query9	0.46	0.35	0.37
query10	0.59	0.61	0.57
query11	0.31	0.19	0.17
query12	0.31	0.20	0.21
query13	0.52	0.51	0.54
query14	0.94	0.92	0.91
query15	0.65	0.58	0.58
query16	0.34	0.36	0.35
query17	1.00	1.01	1.00
query18	0.28	0.27	0.27
query19	1.96	1.87	1.88
query20	0.02	0.01	0.01
query21	15.39	0.34	0.30
query22	4.95	0.12	0.12
query23	15.84	0.49	0.29
query24	2.18	0.51	0.40
query25	0.16	0.11	0.10
query26	0.76	0.27	0.20
query27	0.10	0.10	0.09
query28	3.51	0.84	0.38
query29	12.62	4.32	3.36
query30	0.34	0.17	0.14
query31	2.75	0.57	0.32
query32	3.23	0.60	0.49
query33	3.06	2.99	2.94
query34	15.90	4.11	3.46
query35	3.37	3.37	3.38
query36	0.61	0.51	0.52
query37	0.11	0.10	0.09
query38	0.06	0.06	0.06
query39	0.06	0.06	0.06
query40	0.19	0.17	0.16
query41	0.11	0.06	0.05
query42	0.06	0.06	0.05
query43	0.06	0.06	0.07
Total cold run time: 96.44 s
Total hot run time: 25.1 s

@xylaaaaa

xylaaaaa commented Nov 3, 2026

Copy link
Copy Markdown
Contributor Author

run buildall

@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.08% (38838/58772)
Region Coverage 53.87% (36495/67743)
Branch Coverage 57.34% (11882/20722)

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17598	5178	5043	5043
q2	2116	336	247	247
q3	10220	1408	823	823
q4	4677	471	342	342
q5	7452	805	531	531
q6	180	186	155	155
q7	750	794	600	600
q8	9258	1324	1036	1036
q9	5475	4220	4191	4191
q10	6819	1308	1043	1043
q11	430	250	227	227
q12	632	398	282	282
q13	18084	3639	3113	3113
q14	275	273	255	255
q15	q16	735	707	655	655
q17	1209	746	571	571
q18	7071	6215	6164	6164
q19	1120	971	613	613
q20	405	342	224	224
q21	4809	2129	2300	2129
q22	357	301	261	261
Total cold run time: 99672 ms
Total hot run time: 28505 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	5661	5576	5568	5568
q2	697	570	541	541
q3	5232	5416	4927	4927
q4	2027	2180	1601	1601
q5	5268	5167	5606	5167
q6	270	212	159	159
q7	2340	2148	1924	1924
q8	3163	2989	2830	2830
q9	7987	8013	8060	8013
q10	3818	3720	3286	3286
q11	618	456	437	437
q12	717	728	539	539
q13	3674	4114	3281	3281
q14	324	328	302	302
q15	q16	698	719	646	646
q17	8363	7647	7285	7285
q18	12970	12162	12970	12162
q19	936	809	807	807
q20	2136	2210	1944	1944
q21	5874	4718	4830	4718
q22	502	494	402	402
Total cold run time: 73275 ms
Total hot run time: 66539 ms

@hello-stephen

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

query5	4323	608	461	461
query6	438	203	190	190
query7	4799	449	231	231
query8	323	174	182	174
query9	8739	3232	3223	3223
query10	483	303	260	260
query11	5806	3902	3608	3608
query12	147	96	88	88
query13	1245	456	325	325
query14	6141	3972	3667	3667
query14_1	3465	3428	3530	3428
query15	214	204	182	182
query16	945	424	410	410
query17	897	651	543	543
query18	2421	425	326	326
query19	208	177	141	141
query20	86	97	85	85
query21	214	131	110	110
query22	12994	13074	12760	12760
query23	13588	12961	12428	12428
query23_1	12591	12611	12619	12611
query24	7378	827	481	481
query24_1	492	498	491	491
query25	555	432	376	376
query26	1267	256	144	144
query27	2774	448	282	282
query28	4607	2061	2053	2053
query29	1564	601	466	466
query30	320	228	185	185
query31	1019	939	836	836
query32	157	96	97	96
query33	522	311	250	250
query34	917	858	516	516
query35	746	770	649	649
query36	825	808	738	738
query37	126	99	86	86
query38	1793	1728	1684	1684
query39	797	799	739	739
query39_1	742	726	751	726
query40	233	121	99	99
query41	72	71	68	68
query42	89	80	81	80
query43	350	361	317	317
query44	1342	717	717	717
query45	188	182	167	167
query46	851	978	567	567
query47	3032	2981	2660	2660
query48	313	322	249	249
query49	565	427	289	289
query50	679	288	209	209
query51	10490	10513	10791	10513
query52	80	76	66	66
query53	182	215	148	148
query54	253	195	189	189
query55	70	67	66	66
query56	236	225	213	213
query57	1675	1646	1579	1579
query58	285	262	251	251
query59	2113	2233	1987	1987
query60	293	239	220	220
query61	149	150	146	146
query62	381	340	282	282
query63	190	157	157	157
query64	2823	949	813	813
query65	3359	3273	3305	3273
query66	1788	413	304	304
query67	20168	20385	20132	20132
query68	3280	990	652	652
query69	400	284	251	251
query70	860	796	793	793
query71	291	250	209	209
query72	2830	2621	2352	2352
query73	528	529	301	301
query74	4646	4508	4359	4359
query75	2390	2298	1906	1906
query76	2392	1012	597	597
query77	358	357	269	269
query78	9970	9847	9200	9200
query79	986	860	547	547
query80	818	472	344	344
query81	588	314	267	267
query82	580	131	104	104
query83	306	207	188	188
query84	312	129	100	100
query85	906	426	395	395
query86	349	240	229	229
query87	1991	1934	1829	1829
query88	3840	2813	2799	2799
query89	337	282	246	246
query90	1807	170	160	160
query91	165	153	131	131
query92	98	90	91	90
query93	1009	1020	592	592
query94	548	314	265	265
query95	582	407	303	303
query96	696	497	238	238
query97	2449	2424	2302	2302
query98	162	152	166	152
query99	787	763	650	650
Total cold run time: 236007 ms
Total hot run time: 152067 ms

@hello-stephen

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

query1	0.00	0.00	0.01
query2	0.14	0.09	0.09
query3	0.35	0.13	0.12
query4	1.60	0.13	0.14
query5	0.27	0.25	0.24
query6	1.16	0.64	0.64
query7	0.04	0.01	0.00
query8	0.09	0.07	0.07
query9	0.45	0.36	0.36
query10	0.59	0.57	0.62
query11	0.32	0.18	0.19
query12	0.31	0.19	0.19
query13	0.54	0.53	0.52
query14	0.95	0.93	0.93
query15	0.68	0.58	0.58
query16	0.36	0.36	0.36
query17	0.97	1.02	1.03
query18	0.29	0.28	0.27
query19	1.92	1.84	1.88
query20	0.02	0.02	0.02
query21	15.41	0.34	0.30
query22	4.91	0.13	0.13
query23	15.89	0.48	0.30
query24	2.40	0.52	0.41
query25	0.15	0.10	0.10
query26	0.77	0.26	0.21
query27	0.10	0.10	0.09
query28	3.40	0.83	0.39
query29	12.60	4.44	3.44
query30	0.34	0.17	0.13
query31	2.76	0.62	0.33
query32	3.23	0.62	0.49
query33	2.95	3.00	3.05
query34	15.86	4.12	3.46
query35	3.38	3.39	3.40
query36	0.58	0.48	0.49
query37	0.12	0.09	0.10
query38	0.07	0.06	0.07
query39	0.06	0.06	0.05
query40	0.20	0.17	0.16
query41	0.12	0.05	0.05
query42	0.07	0.05	0.05
query43	0.06	0.06	0.05
Total cold run time: 96.48 s
Total hot run time: 25.29 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

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

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (23/23) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 77.70% (35878/46176)
Line Coverage 62.94% (402859/640113)
Region Coverage 59.51% (340960/572963)
Branch Coverage 60.59% (157742/260325)

@morningman

Copy link
Copy Markdown
Contributor

/review

@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

Codex automated review failed and did not complete.

Error: Selected model is at capacity. Please try a different model.
Workflow run: https://github.com/apache/doris/actions/runs/41616249670

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

@morningman

Copy link
Copy Markdown
Contributor

Local pipeline review — ✅ PASS

schema: doris-repo-review/v1
status: PASS
pr: apache/doris#69392
commit: c8d917291673e51cea99c571dd329aab21e2bf25
base: 8e10b235cf030d486b6840cfd64b6218ab515e6d
reviewed_at: 2026-11-04T08:40+08:00
reviewer: morningman
model: claude-opus-5-5
effort: max
findings: {blocker: 0, major: 0, minor: 2, nit: 5}
rounds: 1
converged: true

Notes for maintainers

  • F-01 (wording, undeclared behaviour change) fe/fe-core/src/main/java/org/apache/doris/qe/QeProcessorImpl.java:361-365: since c8d9172, FE cancels the coordinator whenever it rejects a final external-file report. This applies to Hive, Iceberg, MaxCompute and Paimon alike. A statement that used to hang until insert_timeout now fails at once and carries the reason. The change is correct, and no statement that would have succeeded can fail because of it. But the PR body does not declare it, and its line 47 still credits BE's cancel. Worth fixing before the squash merge.
  • Backport (dev/4.1.x, dev/4.2.x): only the BE half picks as is. branch-4.1/4.2 plan Iceberg writes through fe-core IcebergTransaction and the legacy planner/Iceberg*Sink. Neither branch has the fe-connector-iceberg write path or the rejectedExternalFileReport ack handling in QeProcessorImpl. So the FE commit-location gate (fe/fe-connector/fe-connector-iceberg/src/main/java/org/apache/doris/connector/iceberg/IcebergConnectorTransaction.java:660-671) and the cancel have to be re-done there.
  • Not verified by this review: nothing was built or run. CI at this head passed every new BE/FE case and test_iceberg_write_file_locations. The red check_coverage_fe is the exit-4 infra failure seen across PRs. No real OSS or Azure storage was exercised.

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.

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

Iceberg files must be written through normalized storage locations while metadata retains the table's original URI. This PR centralizes both paths, registers each sink's original directory, validates incoming commit fragments, and cancels the statement when FE rejects a report.

Static review of c8d9172 against 8e10b23 found no blocking issues in the FE changes and necessary BE path/report/cleanup contracts. Sink coverage, directory boundaries, synchronization and failure propagation are consistent. Both previous inline findings are fixed.

APPROVE within this scope. No builds or tests were run. The supplied snapshot shows successful P0, compilation, FE/BE unit tests and external regression, but FE coverage failed and required-check rules were not supplied. This is not a full BE review or merge-readiness certification.

Automated FE-focused static review (gpt-6.1-sol, high). No build or tests were run.

@morningman
morningman merged commit b78c656 into apache:master Nov 4, 2026
34 of 36 checks passed
xylaaaaa pushed a commit to xylaaaaa/doris that referenced this pull request Nov 4, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary: The backported file-location regression was missing from the
Iceberg P0 coverage matrix. Add risk R19, case W20, and the suite mapping from
upstream so the matrix includes all supported write operations.

### Release note

None

### Check List (For Author)

- Test: Manual test; verified the coverage mapping against the backported regression and upstream PR. git diff --check passed.
- Behavior changed: No
- Does this need documentation: Yes; update the requested existing coverage matrix in this commit.
xylaaaaa pushed a commit to xylaaaaa/doris that referenced this pull request Nov 4, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392

Problem Summary: The 4.2 coverage fixture bypasses planning and constructs
Iceberg transactions directly. It never registers a raw sink location, so the
backported validation rejects its s3://bucket/events files before the existing
transaction assertions run. Ten of eleven transaction coverage tests failed.
Register the matching table, delete, or merge sink in beginWrite, adapting
upstream 52c04ac to the release branch. Also add risk R19, case W20, and
the file-location suite to the existing P0 coverage matrix.

### Release note

None

### Check List (For Author)

- Test: Unit Test; run-fe-ut.sh executed 117 tests across 15 classes, with 111 passing, 6 pre-existing disabled tests skipped, and no failures or errors. The transaction coverage class passed all 11 tests; all 4 known-bug cases remain disabled. Maven Checkstyle and git diff --check passed.
- Behavior changed: No
- Does this need documentation: Yes; update the requested existing coverage matrix in this commit.
csun5285 added a commit to csun5285/doris that referenced this pull request Nov 4, 2026
…eKeyIterator

### What problem does this PR solve?

Issue Number: None

Related PR: apache#69515

Problem Summary:

SameKeyIterator had two behaviors switched by MergeDecision::drop_older_versions: for
merge-on-read UNIQUE_KEYS it kept the first, newest, row of every key and dropped the others,
and for AGG_KEYS, a sequence map and changelog scans it flagged the rows of one key for the fold
above. One class with two modes needed a DORIS_CHECK to stop the flagging call in the dropping
mode, and its name only described the second one.

After the rebase onto master, UniqueKeyBlockIterator did nothing on its own either: the older
versions were dropped below it, and master's row TTL change (apache#65858) moved the delete-sign filter
of the compaction and checksum reads into BlockReader::next_block_with_aggregation. It was a
second DirectBlockIterator.

Now:

- UniqueKeyIterator (unique_key_iterator.h) keeps only the newest row of every key and counts the
  others in merged_rows(). BlockReader and BetaRowsetReader::new_iterator (schema change, TopN)
  put it above the merge when the read's drop_older_versions is set.
- SameKeyIterator only flags the rows of one key; it takes the key ordinals, not the decision.
- Both share SameKeyFlags, as the key group of a vertical compaction does.
- UniqueKeyBlockIterator is removed: a merge-on-read UNIQUE_KEYS read is a DirectBlockIterator
  over the UniqueKeyIterator, with the delete sign filtered in BlockReader as before.

So a merge-on-read UNIQUE_KEYS read is: VHeapMergeIterator sorts, UniqueKeyIterator keeps the
newest row of every key, DirectBlockIterator hands the Blocks out.

### Release note

None

### Check List (For Author)

- Test: Unit Test
    - BlockReaderUniqueKeysTest checks the DirectBlockIterator over a UniqueKeyIterator;
      VGenericIteratorsTest and BlockReaderChangelogMergeTest build the merge the way the readers do
    - 363 tests of the iterator, compaction, rowid conversion, tablet reader, schema change and
      row TTL suites pass (built with format/transformer/vparquet_writer_test.cpp set aside: it
      does not compile on master since apache#69392 changed VIcebergPartitionWriter's WriteInfo)
- Behavior changed: No
- Does this need documentation: No

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
morningman added a commit that referenced this pull request Nov 4, 2026
…berg WriteInfo (#70209)

### What problem does this PR solve?

Issue Number: None

Related PR: #69392, #69971

Problem Summary:

**In short.** `doris_be_test` does not compile on master since #69971
was merged, so the BE UT of every PR fails with `BE BUILD FAIL`. This
fixes the one test case that breaks it.

**The problem.** #69392 replaced the `write_path`, `original_write_path`
and `target_path` fields of `IPartitionWriterBase::WriteInfo` with one
`IcebergOutputLocation location`, and updated the callers it knew about.
#69971, merged after it, added
`VParquetWriterTest.HiveAndIcebergParquetPageIndexOptions`, which still
sets the old fields:

```
be/test/format/transformer/vparquet_writer_test.cpp:380:41: error: no matching constructor for initialization of 'VIcebergPartitionWriter'
```

Each PR built alone, so both were green. TeamCity's BE UT has failed
this way for PRs merged with master `0eb5131db62` (for example build
1092024 of #69605).

**How this PR fixes it.** The case builds its `WriteInfo` as the other
Iceberg case in the same file does, `.location =
IcebergOutputLocation(".", ".")`. Nothing else changes.
hubgeter added a commit to hubgeter/doris that referenced this pull request Nov 5, 2026
### Background

Iceberg writers carry separate physical and metadata directory forms in
IcebergOutputLocation. Their WriteInfo aggregate requires this location to be
initialized before a writer can be constructed.

### What problem does this PR solve?

Issue Number: None
Related PR: apache#69376 (follow-up), apache#69392 (output-location interface change)
PR Type: Test

Problem Summary: The unsupported-Parquet-codec test still default-constructed
WriteInfo and assigned its removed write_path field. After merging current
master this prevents the BE unit-test target from compiling. Initialize the
physical and metadata directories explicitly while retaining the existing
zero-file-creation regression assertions.

### Details

- Failure: BE UT compilation reports a deleted WriteInfo default constructor
  and a nonexistent write_path member in the new codec-rejection test.
- Cause: the output-location refactor changed WriteInfo after the PR branched.
- Stability evidence: use the same aggregate pattern as current master tests,
  with both local directory forms set to '.', FILE_LOCAL, and no brokers.
  Keep the unique filename, SyncPoint callback and all assertions unchanged.

### Testing

- clang-format 16 on the four PR files, build hygiene, and git diff --check passed.
- git range-diff confirmed the four original patches are preserved by rebase.
- ASAN run-be-ut.sh --run
  --filter=VIcebergPartitionWriterTest.UnsupportedParquetCodecDoesNotCreateFile
  -j 2 was attempted locally, but stopped during dependency preparation before
  compilation. Required submodules were incomplete and the mandatory
  libgoogle_cloud_cpp_oauth2.a is absent. No local runtime test pass is claimed.

### Release note

None

### Check List (For Author)

- Test: static checks passed; local unit-test execution remains unverified.
- Behavior changed: No.
- Does this need documentation: No.
- Pre-submission status: Partially verified: BE UT compilation and execution
  need verification on the prepared CI environment.

### AI Disclosure

- Tool: Codex.
- Generated: test initialization and this commit message.
- Human review: Not performed in this automated session.
xylaaaaa pushed a commit to xylaaaaa/doris that referenced this pull request Nov 7, 2026
### What problem does this PR solve?

Issue Number: None

Related PR: apache#69392, apache#70173, apache#69841, apache#70185

Problem Summary: Merge the latest branch-4.2 into the Iceberg file-location
backport. Preserve the session partition-overwrite mode together with bound-sink
location registration. Adapt the newly added Parquet writer test to
IcebergOutputLocation, and update overwrite fixtures for explicit modes, retained
snapshots, and registered commit locations. Check path acceptance and rejection
for both static and dynamic overwrite modes.

### Release note

None

### Check List (For Author)

- Test: Unit Test via run-fe-ut.sh --run (16 related FE classes; 122 passed,
  6 pre-existing disabled cases skipped, zero failures or errors); Java
  Checkstyle; clang-format 16; Parquet test translation-unit syntax check via
  clang-tidy and the existing ASAN compilation database. BE unit tests and
  external regressions are delegated to CI.
- Behavior changed: No; preserve both the release branch's overwrite behavior
  and this PR's file-location validation.
- Does this need documentation: No
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants