feat: Sort-aware Iceberg reads in Comet via a per-partition streaming merge - #5331
Draft
parthchandra wants to merge 3 commits into
Draft
feat: Sort-aware Iceberg reads in Comet via a per-partition streaming merge#5331parthchandra wants to merge 3 commits into
parthchandra wants to merge 3 commits into
Conversation
Contributor
Author
|
This PR has some followups -
|
Contributor
Author
|
@anuragmantri, @peter-toth , you might be interested in looking at this. k-way merge to maintain the ordered property of sorted Iceberg tables. Feedback, especially about test coverage, would be highly appreciated. |
parthchandra
force-pushed
the
stream-merge
branch
from
August 11, 2026 23:18
90efceb to
312356d
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Which issue does this PR close?
Closes #5323.
Rationale for this change
Currently when Comet reads a sorted Iceberg table, the scan throws away the ordering to achieve parallelism. As a result Spark can't tell the data is already sorted, and it re-sorts on every read — in joins, aggregates, windows, and order-by queries — even though the work was already done at write time.
This PR modifies the native scan to preserve and report that ordering, so Spark can drop the redundant sorts. It builds on Iceberg's own
SupportsReportOrdering(apache/iceberg#14948): when Iceberg reports a sortorder, merge the sorted files per partition, and tell Spark the result is sorted.
The scan also reports Iceberg's key-group partitioning. (For Spark to eliminate shuffle in SMJ, the scan must also report how the data is grouped by the join key (storage-partitioned join)).
What changes are included in this PR?
For every Spark partition, the scan now reads each sorted file as its own stream and k-way-merges them into one sorted stream using DataFusion's
SortPreservingMergeExec.Summary of changes -
table_sort_ordersfield onIcebergScanCommoncarries the reported sort order to the native side.actually in the projection. Anything else (transforms, a sort key that isn't selected) falls back to today's unordered read and reports nothing, so it's always correct.
IcebergScanExecbecomes multi-partition when an ordering is present (one sorted stream per file), and the planner wraps it inSortPreservingMergeExec. No changes to iceberg-rust — we justcall its existing reader once per file instead of once for the whole batch.
The PR also adds two config flags for the Iceberg scan:
spark.comet.scan.icebergNative.sortMerge.enabled(default on) — report the sort order and do the per-partition merge. Only does anything when Iceberg'sspark.sql.iceberg.planning.preserve-data-orderingison (off by default).
spark.comet.scan.icebergNative.reportPartitioning.enabled(default off) — report key-grouped partitioning for storage-partitioned joins. Off by default while we build out coverage for the adaptive-executionpartition-pushdown path.
Note: A global
ORDER BYstill keeps its final sort — a per-partition merge isn't a cluster-wide order — so that case is unchanged.How are these changes tested?
iceberg_scan.rs: multi-partition with a reported ordering, single-partition without one.CometIcebergSortMergeReadSuiteover real Iceberg tables (local Hadoop catalog, sort order set via the Iceberg Java API, one file per insert).