vranes commented on code in PR #58827:
URL: https://github.com/apache/spark/pull/58827#discussion_r4047651597


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala:
##########
@@ -17,6 +17,7 @@
 

Review Comment:
   1. PR description doesn't describe the array < struct > behaviour before vs 
now. Its behaviour is changed in a different way than arrays with basic element 
types, it should be properly documented.
   2. We should fix the bare structs in the same way (ASOF validation accepts 
different field names with different types, but it fails in a later validation 
stage). 



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala:
##########
@@ -2768,16 +2769,27 @@ object AsOfJoin {
     def usesArrayOrderExpression(leftType: DataType, rightType: DataType): 
Boolean =
       (leftType, rightType) match {
         case (ArrayType(leftElem, _), ArrayType(rightElem, _)) =>
-          areArrayElementsCompatible(leftElem, rightElem)
+          // MATCH_CONDITION compares the two arrays with `>=`, which widens 
array elements only
+          // through findTightestCommonType (no string promotion, no decimal 
widening). Accept
+          // exactly what that comparison can compare: orderable elements that 
are already
+          // structurally equal (BinaryComparison ignores struct field names 
and nullability) or
+          // have a tightest common type. Otherwise the type check would pass 
but the `>=` would
+          // fail to resolve.
+          isValidOperandType(leftElem) && isValidOperandType(rightElem) &&
+            (DataType.equalsStructurally(leftElem, rightElem, 
ignoreNullability = true) ||
+              arrayElementCommonType(leftElem, rightElem).isDefined)
         case _ => false
       }
 
-    private def areArrayElementsCompatible(leftElem: DataType, rightElem: 
DataType): Boolean = {
-      if (DataTypeUtils.sameType(leftElem, rightElem)) {
-        RowOrdering.isOrderable(leftElem)
-      } else {
-        arePositionalStructsCompatible(leftElem, rightElem)
-      }
+    /**
+     * The element type the `>=` comparison coerces two array operands to, if 
any. Binary

Review Comment:
   This reads as if this is only about that specific comparison operator (>=). 
Replace with "binary comparison" and simplify the comment. Perhaps add an 
example also to make it clear.



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/plans/logical/basicLogicalOperators.scala:
##########
@@ -2988,8 +3000,30 @@ object AsOfJoin {
   private def buildArrayOrderExpression(
       leftOperand: Expression,
       rightOperand: Expression,
-      elementType: DataType,
       operator: MatchComparisonOperator): Expression = {
+    val leftElementType = 
leftOperand.dataType.asInstanceOf[ArrayType].elementType
+    val rightElementType = 
rightOperand.dataType.asInstanceOf[ArrayType].elementType
+    // The ZipWith lambda variables and both array inputs must share the 
element type the `>=`
+    // comparison coerces to. Coercible elements (e.g. INT vs BIGINT, or INT 
vs FLOAT which widens
+    // to DOUBLE under ANSI) widen to their tightest common type and both 
arrays are cast to it.
+    // Structurally equal elements (BinaryComparison ignores struct field 
names) need no cast and
+    // compare element-wise by ordinal.
+    val elementsStructurallyEqual =
+      DataType.equalsStructurally(leftElementType, rightElementType, 
ignoreNullability = true)
+    val (leftArray, rightArray, elementType) =
+      if (elementsStructurallyEqual) {
+        (leftOperand, rightOperand, leftElementType)
+      } else {
+        MatchConditionTypes.arrayElementCommonType(leftElementType, 
rightElementType) match {
+          case Some(widerElementType) =>
+            (castArrayElementType(leftOperand, widerElementType),
+              castArrayElementType(rightOperand, widerElementType),
+              widerElementType)
+          case None =>
+            // Unreachable: usesArrayOrderExpression already required a common 
element type here.
+            throw SparkException.internalError("MATCH_CONDITION array elements 
have no common type")

Review Comment:
   `usesArrayOrderExpression` and `buildArrayOrderExpression` both decide the 
array element type the same way. Consider a shared `MatchConditionTypes` helper 
returning `Option[DataType]` so the two can't drift.



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