Skip to content

[bug](iceberg) use split file format for iceberg scan#65760

Open
zhangstar333 wants to merge 4 commits into
apache:masterfrom
zhangstar333:format_type
Open

[bug](iceberg) use split file format for iceberg scan#65760
zhangstar333 wants to merge 4 commits into
apache:masterfrom
zhangstar333:format_type

Conversation

@zhangstar333

@zhangstar333 zhangstar333 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Problem Summary:
A table maybe contain mixed parquet and orc files.
before used the table-level format for every split files, it's should use from data file.
and when table properties were absent, maybe trigger full planFiles() call for every splits, this cause mush times.

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

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

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@morningman morningman added usercase Important user case type label dev/4.0.x dev/4.1.x labels Jul 17, 2026
@zhangstar333

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: the Iceberg per-split format path is largely sound, but the shared range-construction reorder breaks Hudi JNI scans, and the current head also fails the required FE style gate.

Critical checkpoint conclusions:

  • Goal and end-to-end behavior: Ordinary Iceberg eager, lazy/batch, rewrite-context, and table-level-count splits all carry each DataFile.format() into the range, while system-table and delete-file paths retain their dedicated formats. V1 and V2 BE readers honor the per-range value, so the intended mixed Parquet/ORC dispatch is present. Defaulting a property-less Iceberg table to Parquet avoids the extra manifest planning pass and matches Iceberg's default.
  • Scope and parallel paths: The Iceberg-specific pieces are focused, but changing the shared FileQueryScanNode hook ordering is not isolated. Hudi consumes the inherited range format while building THudiFileDesc; the resulting JNI/native mismatch is the blocking issue described inline.
  • Concurrency and lifecycle: No new lock ordering or concurrent mutation was introduced. The split format is assigned before eager use or publication to the existing lazy split queue, and every production data-split path preserves it.
  • Compatibility and error handling: No Thrift schema or persisted format changed; current BE code already supports the optional per-range override with scan-level fallback. Unsupported Iceberg formats fail explicitly. The Hudi descriptor mismatch nevertheless violates the existing FE/BE contract and makes MOR/forced-JNI scans fail.
  • Configuration, persistence, transactions, and data writes: No configuration, EditLog, transaction, or storage-format change is introduced by this PR.
  • Tests and validation: The new unit tests verify property lookup and a manually initialized ORC split, but do not exercise a real mixed-format eager/lazy range pipeline or the shared Hudi hook. No builds were run in this review-only environment. The live CheckStyle job fails on the now-unused DdlException import in IcebergScanNode.java and the lexicographic position of the new TFileFormatType import in IcebergScanNodeTest.java; both must be fixed and the gate rerun.
  • Performance and observability: Removing the property-less planFiles() fallback avoids redundant manifest planning. Existing scan/profile/error paths are sufficient for this change; no additional metrics are required.

No additional user-provided focus was supplied. The full changed-file set, shared-base connector paths, tests, and current CI result were reviewed.

Comment thread fe/fe-core/src/main/java/org/apache/doris/datasource/FileQueryScanNode.java Outdated
@zhangstar333

Copy link
Copy Markdown
Contributor Author

/review

@zhangstar333

Copy link
Copy Markdown
Contributor Author

run buildall

@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 actionable test issues: the mixed-format bootstrap fixture is not repeatable against retained Iceberg state, and the property-absent unit test does not exercise the populated-table branch that previously planned files. Please address the inline comments.

Critical checkpoint conclusions:

  • Goal and data correctness: The production change carries each Iceberg DataFile.format() into its split/range, so mixed Parquet/ORC snapshots dispatch the correct reader. Property-absent tables use Iceberg's Parquet write default without planning data files.
  • Scope and clarity: The production change is focused on split-level format propagation and removal of the repeated planning side effect. The two scope-local defects are confined to fixture repeatability and the strength of the new regression guard.
  • Parallel paths: Eager, lazy/batch, manifest-cache, table-level count, rewrite-context, ordinary system-table, position-delete, and independent delete-file-format paths were checked. All non-system data paths use createIcebergSplit; system paths bypass the nullable field safely.
  • Concurrency and lifecycle: The new split field is populated before the split is published through SplitAssignment; no new shared mutable lifecycle, lock ordering, static initialization, or cleanup hazard was introduced.
  • Compatibility and FE/BE transport: The existing optional range-level thrift field is reused. Both legacy and V2 BE scanners prefer the range format with scan-level fallback. The existing Hudi P1 is fixed at the current head by seeding the scan default before connector-specific setup and is not duplicated here.
  • Configuration, persistence, and transactions: No configuration, EditLog, Doris transaction, or storage-serialization contract is added. The Iceberg sink, commit, metrics, and compression callers were traced and consistently use the property-derived write default, while physical reads use each split's actual format.
  • Tests and expected results: The split-format unit test and ordered regression output are internally consistent, but run31.sql violates the drop-before-use fixture rule and breaks repeated Iceberg stack initialization. The property-absent lookup test also leaves currentSnapshot() null, so it passes the removed empty-table shortcut and does not guard elimination of planFiles() for populated tables. Per the review contract, this was a static review; no builds or tests were run.
  • Performance and observability: Removing planFiles() from format lookup avoids repeated full planning, and no new hot-path copy, logging, metric, or observability issue was found.
  • User focus and completeness: No additional user focus was provided. The whole changed-file list, existing review thread, accepted/dismissed candidates, and upstream/downstream paths were swept; after three normal/risk convergence rounds, no unresolved point remains beyond the two inline test issues.

@zhangstar333

Copy link
Copy Markdown
Contributor Author

/review

@zhangstar333

Copy link
Copy Markdown
Contributor Author

run buildall

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

Approval opinion: no new blocking issues found on 2eda0b5de745e1bc32e3ec4383abca99bb5c5b4b.

Critical checkpoint conclusions:

  • Goal and proof: The PR now carries DataFile.format() into each ordinary Iceberg range, so one active snapshot can read Parquet and ORC files with their respective readers. It also removes data-file planning from table-default format resolution. The propertyless-table unit test, split-format unit test, and ordered external mixed-format regression are each sensitive to the corresponding base behavior.
  • Scope and clarity: The production change is limited to scan-level default seeding, split-level Iceberg format propagation, and property-default resolution; the fixture and tests directly cover those behaviors.
  • Concurrency: The only concurrency-adjacent path is lazy split production. params.format_type is initialized before SplitAssignment starts, and each IcebergSplit receives its immutable enum before queue publication. No new lock, lock ordering, or shared mutable format state is introduced.
  • Lifecycle: Ordinary eager, lazy, count-pushdown, rewrite, and manifest-cache paths all construct splits through createIcebergSplit. System-table factories take early branches before the nullable data-file format is read. Both BE scanner generations reset reader/split state between ranges.
  • Configuration: No configuration item is added or changed.
  • Compatibility: No thrift field, enum, symbol, or persisted storage format changes. The existing optional range-level format is preferred by both legacy and V2 scanners, with the scan-level value retained as the compatibility fallback when the range field is absent.
  • Parallel paths: Hudi again sees the initialized scan default before its hook; Paimon and Iceberg can still override the range per split; Hive, MaxCompute, LakeSoul, Trino, TVF, plugin, and Remote Doris paths retain their previous behavior.
  • Special conditions and error handling: Ordinary split formats are always populated in production, system-table formats remain specialized, and unsupported data formats fail loudly instead of silently selecting a reader.
  • Test coverage: The bootstrap is rerun-safe, proves three records in each physical format, and the ordered data query exercises normal mixed-format planning. The unit tests cover the populated propertyless-table optimization and direct range override. Negative unsupported-format behavior remains fail-fast.
  • Test results: Per the automated-review contract, I did not build or run tests. This checkout lacks .worktree_initialized and thirdparty/installed/bin/protoc; conclusions are static. GitHub CheckStyle is passing at submission time, while compile and FE UT checks are still pending.
  • Observability: Existing reader-format diagnostics and unsupported-format exceptions are sufficient for this focused change; no new metric or log is required.
  • Transactions, persistence, and writes: No transaction protocol, EditLog, failover, or persistence boundary changes. Propertyless future writes now follow Iceberg's Parquet default, while existing files are read using each file's own format.
  • FE-BE propagation: The existing TFileRangeDesc.format_type carries the per-split value on every ordinary Iceberg path; delete-file formats remain independently propagated.
  • Performance: Format resolution no longer calls planFiles(), and per-split overhead is only an enum mapping. No new repeated scan, copy, or allocation was found.
  • Other issues: The three existing inline concerns (Hudi hook ordering, repeatable bootstrap, and the propertyless-table mock) are fixed on the current head and were not duplicated. No additional user focus was provided.

Review completion: two normal full-review passes and one separate risk-focused pass all returned NO_NEW_VALUABLE_FINDINGS in Round 1. Main-agent verification resolved every risk item and found no unresolved candidate or inline comment to submit.

@hello-stephen

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

------ Round 1 ----------------------------------
============================================
q1	17723	4250	4096	4096
q2	2005	320	205	205
q3	10289	1384	822	822
q4	4681	469	344	344
q5	7597	893	572	572
q6	192	177	140	140
q7	749	818	617	617
q8	9388	1508	1496	1496
q9	5558	4388	4356	4356
q10	6782	1761	1480	1480
q11	503	349	341	341
q12	745	592	454	454
q13	18123	3392	2793	2793
q14	265	269	250	250
q15	q16	815	777	716	716
q17	1053	961	948	948
q18	7020	5998	5629	5629
q19	1319	1373	1001	1001
q20	808	676	610	610
q21	6190	2596	2424	2424
q22	438	360	296	296
Total cold run time: 102243 ms
Total hot run time: 29590 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4408	4304	4352	4304
q2	291	318	219	219
q3	4624	4942	4439	4439
q4	2091	2179	1360	1360
q5	4446	4292	4280	4280
q6	242	175	130	130
q7	1740	2243	1750	1750
q8	2569	2196	2181	2181
q9	8071	8179	7853	7853
q10	4760	4671	4255	4255
q11	567	461	381	381
q12	795	769	542	542
q13	3268	3644	2867	2867
q14	310	329	301	301
q15	q16	705	736	638	638
q17	1340	1322	1453	1322
q18	7810	7544	7228	7228
q19	1176	1098	1076	1076
q20	2208	2200	1942	1942
q21	5272	4647	4533	4533
q22	518	463	399	399
Total cold run time: 57211 ms
Total hot run time: 52000 ms

@hello-stephen

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

query5	4325	625	489	489
query6	470	231	214	214
query7	4850	635	351	351
query8	347	200	181	181
query9	8794	4145	4135	4135
query10	476	361	304	304
query11	5909	2328	2194	2194
query12	164	105	101	101
query13	1265	611	428	428
query14	6246	5214	4908	4908
query14_1	4242	4236	4227	4227
query15	214	201	179	179
query16	1008	486	454	454
query17	954	744	588	588
query18	2440	476	354	354
query19	212	201	151	151
query20	114	108	110	108
query21	238	168	136	136
query22	13579	13573	13387	13387
query23	17346	16623	16146	16146
query23_1	16209	16221	16357	16221
query24	7595	1792	1296	1296
query24_1	1284	1291	1295	1291
query25	579	469	390	390
query26	1346	378	227	227
query27	2554	604	390	390
query28	4505	1995	2008	1995
query29	1081	617	497	497
query30	347	273	242	242
query31	1114	1096	990	990
query32	102	64	63	63
query33	555	325	262	262
query34	1166	1113	660	660
query35	772	783	701	701
query36	1182	1159	1060	1060
query37	154	104	91	91
query38	1866	1696	1652	1652
query39	866	887	871	871
query39_1	826	846	825	825
query40	245	163	142	142
query41	66	64	64	64
query42	102	93	94	93
query43	320	324	284	284
query44	1412	764	760	760
query45	198	184	174	174
query46	1097	1167	718	718
query47	2151	2138	2018	2018
query48	409	436	297	297
query49	574	421	299	299
query50	1105	428	330	330
query51	10539	10763	10628	10628
query52	87	88	74	74
query53	260	289	210	210
query54	272	235	216	216
query55	74	71	66	66
query56	298	299	282	282
query57	1291	1285	1204	1204
query58	296	264	254	254
query59	1580	1610	1422	1422
query60	299	270	253	253
query61	152	149	149	149
query62	535	493	440	440
query63	255	196	207	196
query64	2812	1088	865	865
query65	4745	4634	4660	4634
query66	1851	495	384	384
query67	29405	29329	29142	29142
query68	3317	1460	979	979
query69	417	352	274	274
query70	1111	952	944	944
query71	383	353	320	320
query72	3064	2707	2342	2342
query73	853	823	458	458
query74	5034	4950	4709	4709
query75	2556	2513	2136	2136
query76	2294	1174	772	772
query77	370	369	283	283
query78	11886	11797	11217	11217
query79	1378	1181	715	715
query80	1284	550	448	448
query81	526	338	297	297
query82	576	162	124	124
query83	367	318	292	292
query84	328	162	131	131
query85	987	627	523	523
query86	416	297	278	278
query87	1820	1838	1751	1751
query88	3742	2777	2746	2746
query89	434	385	339	339
query90	1948	204	198	198
query91	206	189	158	158
query92	64	62	58	58
query93	1533	1633	1008	1008
query94	713	364	316	316
query95	799	606	474	474
query96	1044	775	341	341
query97	2662	2614	2498	2498
query98	211	214	200	200
query99	1096	1116	976	976
Total cold run time: 263372 ms
Total hot run time: 177880 ms

@hello-stephen

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

query1	0.00	0.00	0.00
query2	0.10	0.05	0.05
query3	0.25	0.14	0.14
query4	1.61	0.18	0.14
query5	0.24	0.23	0.23
query6	1.22	1.08	1.08
query7	0.03	0.01	0.00
query8	0.06	0.04	0.03
query9	0.40	0.33	0.32
query10	0.59	0.62	0.55
query11	0.19	0.14	0.14
query12	0.19	0.14	0.15
query13	0.48	0.48	0.48
query14	1.04	1.01	1.04
query15	0.64	0.60	0.60
query16	0.33	0.33	0.32
query17	1.09	1.11	1.11
query18	0.23	0.21	0.21
query19	2.06	1.86	1.94
query20	0.01	0.01	0.01
query21	15.44	0.20	0.13
query22	5.01	0.05	0.05
query23	16.14	0.33	0.12
query24	2.95	0.46	0.31
query25	0.10	0.05	0.05
query26	0.74	0.21	0.16
query27	0.04	0.03	0.04
query28	3.57	0.95	0.55
query29	12.49	4.12	3.28
query30	0.27	0.16	0.15
query31	2.77	0.60	0.31
query32	3.22	0.59	0.49
query33	3.23	3.18	3.29
query34	15.51	4.25	3.54
query35	3.56	3.52	3.59
query36	0.56	0.46	0.44
query37	0.09	0.06	0.07
query38	0.05	0.04	0.04
query39	0.04	0.04	0.03
query40	0.18	0.16	0.17
query41	0.09	0.03	0.04
query42	0.04	0.03	0.03
query43	0.04	0.03	0.04
Total cold run time: 96.89 s
Total hot run time: 25.11 s

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

Labels

dev/4.0.x dev/4.1.x usercase Important user case type label

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants