parthchandra commented on code in PR #5331:
URL: https://github.com/apache/datafusion-comet/pull/5331#discussion_r3834501153


##########
spark/src/main/scala/org/apache/comet/serde/operator/CometIcebergNativeScan.scala:
##########
@@ -859,6 +859,49 @@ object CometIcebergNativeScan extends 
CometOperatorSerde[CometBatchScanExec] wit
     Some(builder.setIcebergScan(icebergScanBuilder).build())
   }
 
+  /**
+   * The part of an Iceberg-reported sort order that the native per-partition 
merge can honour, or
+   * Nil when the merge must stay off. Two callers use this one gate: the 
proto serialization
+   * (which turns on the native SortPreservingMergeExec) and
+   * CometIcebergNativeScanExec.outputOrdering (which tells Spark the scan is 
sorted). Sharing the
+   * gate means the two always agree.
+   *
+   * v1 accepts only identity sort fields on top-level columns that are in the 
projection. Each
+   * SortOrder child must be an AttributeReference in `output`, and must 
serialize to proto.
+   * Transform sort fields (bucket/truncate/...) are not AttributeReferences, 
so they fall through
+   * to Nil and we read unordered. Checking exprToProto here, not just in the 
proto path, keeps
+   * the two callers in step: outputOrdering never advertises an order the 
proto path would drop.
+   *
+   * We trust Iceberg on file-level sortedness. If it reports an ordering, 
SortOrderAnalyzer has
+   * already checked each file's sort_order_id matches the table order, so 
every file is sorted.
+   *
+   * We read scanExec.ordering (the raw reported order), not 
scanExec.outputOrdering. Spark blanks
+   * outputOrdering when a partition holds more than one file -- the case this 
merge handles.

Review Comment:
   Made more one change. Added a check to fall back to spark if iceberg reports 
ordering and native cannot support it (without that we will silently get wrong 
results because Spark would have removed the sort already). 



##########
native/core/src/execution/operators/iceberg_scan.rs:
##########
@@ -86,6 +86,24 @@ pub struct IcebergScanExec {
     tasks: Vec<FileScanTask>,
     /// Number of data files to read concurrently
     data_file_concurrency_limit: usize,
+    /// FileIO (and, for S3, the JVM credential bridge behind it) built once 
at plan time and shared
+    /// across partitions. FileIO is cheap to clone (Arc-backed), so each 
`execute` clones this
+    /// rather than rebuilding the storage factory + credential bridge. This 
matters in the ordered
+    /// path, where the scan is one partition per file and `execute` is called 
once per file.
+    file_io: FileIO,
+    /// Table sort order Iceberg reported, translated against `output_schema`. 
`Some` makes this a
+    /// multi-partition scan: one sorted stream per task, which a 
SortPreservingMergeExec above
+    /// merges back into one sorted partition. It is also advertised in 
`plan_properties`. `None`
+    /// keeps the old single-partition unordered read (all tasks streamed 
together).
+    ///
+    /// Concurrency note: in the ordered path each partition reads exactly one 
task, so
+    /// `data_file_concurrency_limit` no longer bounds cross-file concurrency; 
instead the wrapping
+    /// SortPreservingMergeExec drives one reader per file to merge them. That 
fan-out (files per
+    /// Spark partition) is intrinsic to a k-way merge of per-file sorted 
streams -- the files must

Review Comment:
   Agreed, and added the fix recommended by @andygrove to limit max files per 
partition with a change. We cannot fallback to unordered because by this time 
Spark planning would have removed the downstream sort and not producing ordered 
results will produce wrong results. So now, beyond the threshold, we will fall 
back to a spillable `SortExec` so we always produce correct results



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to