anuragmantri commented on code in PR #5331:
URL: https://github.com/apache/datafusion-comet/pull/5331#discussion_r3777421395
##########
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.
+ */
+ def reportableOrdering(
+ ordering: Option[Seq[SortOrder]],
+ output: Seq[Attribute]): Seq[SortOrder] = {
+ if (!CometConf.COMET_ICEBERG_SORT_MERGE_ENABLED.get()) {
+ Nil
+ } else {
+ ordering match {
+ case Some(orders) if orders.nonEmpty && orders.forall(isReportable(_,
output)) =>
+ orders
+ case _ =>
+ Nil
+ }
+ }
+ }
+
+ private def isReportable(order: SortOrder, output: Seq[Attribute]): Boolean =
+ isIdentityProjected(order, output) && exprToProto(order, output).isDefined
+
Review Comment:
As identified in the [Iceberg
PR](https://github.com/apache/iceberg/pull/14948#pullrequestreview-4932308014)
and the design doc https://github.com/apache/datafusion-comet/issues/5323, UUID
orders differently in Iceberg than in Spark's comparator, and the identity case
for UUID needs to follow Iceberg's byte ordering specifically. This gate
doesn't check the sort column's type at all. I believe we could rely on
upstream https://github.com/apache/iceberg/pull/16750 to not report ordering on
UUID. Is my understanding correct?
--
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]