viirya commented on code in PR #6835:
URL: https://github.com/apache/datafusion-comet/pull/6835#discussion_r4286263738


##########
spark/src/main/scala/org/apache/spark/sql/comet/operators.scala:
##########
@@ -2885,6 +2887,56 @@ trait CometHashJoin {
     val leftKeys = join.leftKeys.map(exprToProto(_, join.left.output))
     val rightKeys = join.rightKeys.map(exprToProto(_, join.right.output))
 
+    // Spark reports the streamed side's order as the join's, and drops a sort 
above the join
+    // that it satisfies. DataFusion's hash join keeps the unmatched probe 
rows of a right outer
+    // join in place only when the probe input declares an order, and 
otherwise moves them after
+    // the matched rows of each batch. Comet builds on the build side, so a 
left outer join built
+    // on the right and a right outer join built on the left both run as that 
right outer join,
+    // and an input sorted outside the native plan, a relation sorted before 
it was cached for
+    // instance, declares no order to DataFusion. Send the order so the native 
join declares it
+    // on the probe input; see SortedInputExec. Every other join type keeps 
the probe order as
+    // it is, except the null-aware anti join: Comet builds that one on its 
streamed side, so its
+    // output is not in the order Spark reports for it, and the planner 
declares no order above
+    // it.
+    //
+    // The order Spark reports can be false to begin with. A Comet join that 
may move its
+    // streamed rows reports it all the same: the null-aware anti join, a 
right outer join like
+    // this one whose probe input declared no order, and the nested loop join, 
which keeps the
+    // order of neither input. A cache reports the order of the plan that 
wrote it, so the rows
+    // of such a join can reach this one through a cache, as a JVM input that 
the native planner
+    // cannot look behind. Declaring the order there would let an operator 
above rely on it, an
+    // aggregate in sorted mode for instance, which then splits groups. So 
nothing is declared
+    // when such a join feeds the streamed side with no sort in between, or 
when a leaf reports
+    // an order that cannot be checked; see mayReportFalseOrder.
+    //
+    // Declaring any order makes DataFusion keep the probe rows in place, so 
the longest prefix
+    // of the order that Comet can express is enough. A key counts as 
expressible when the native
+    // sort accepts its type, as `supportedSortType` decides for a sort: a 
collated string is
+    // ordered by its collation in Spark but would be declared in raw byte 
order. Nothing here can
+    // tell whether an operator above relies on the order, so a join whose 
first key Comet cannot
+    // express stays in Spark.
+    val (streamed, _) = streamedSide(join.buildSide, join.left, join.right)
+    val streamedSortOrders =
+      if (runsAsRightOuterJoin(join.joinType, join.buildSide) &&
+        join.outputOrdering.nonEmpty && !mayReportFalseOrder(streamed)) {
+        val orders = join.outputOrdering.iterator
+          .takeWhile(order => supportedScalarSortElementType(order.dataType))

Review Comment:
   `supportedScalarSortElementType` rejects every array and struct, so a join 
whose streamed order starts with one now stays in Spark. Before this commit 
those keys went through `exprToProto`, which takes them: `serializeDataType` 
covers arrays and structs, and `CometSortOrder` only declines a nested key 
under a non-default null order. On `branch-1.1` the join runs natively whatever 
its streamed order. One way to hit it is `sortWithinPartitions` on an array 
column, which `supportedSortType` lets `CometSortExec` run natively, followed 
by a broadcast left outer join. The probe input then already declares the 
order, so the join needs nothing from the serde, but it now falls back.
   
   The case this check is for is the collated string. Would 
`hasNonDefaultStringCollation(order.dataType)` cover it here? That is the check 
`supportedSortType` makes, and it also catches a collated string inside a 
struct or array, while the nested null-order case stays with `CometSortOrder` 
as before. The comment on the new key-type test says struct, array and map keys 
are out of scope because `exprToProto` rejects them, which isn't the case. An 
array key in that test would pin this down.



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