diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala index 4a979fd214aba..10bff5e6e59a2 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/CheckAnalysis.scala @@ -537,6 +537,19 @@ trait CheckAnalysis extends PredicateHelper with LookupCatalog with QueryErrorsB } } + case Window(_, partitionSpec, _, _) => + // Both `partitionSpec` and `orderSpec` must be orderable. We only need an extra check + // for `partitionSpec` here because `orderSpec` has the type check itself. + partitionSpec.foreach { p => + if (!RowOrdering.isOrderable(p.dataType)) { + p.failAnalysis( + errorClass = "EXPRESSION_TYPE_IS_NOT_ORDERABLE", + messageParameters = Map( + "expr" -> toSQLExpr(p), + "exprType" -> toSQLType(p.dataType))) + } + } + case GlobalLimit(limitExpr, _) => checkLimitLikeClause("limit", limitExpr) case LocalLimit(limitExpr, child) => diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala index 5a30081872710..f12d224096917 100644 --- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala +++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/analysis/AnalysisErrorSuite.scala @@ -1316,4 +1316,18 @@ class AnalysisErrorSuite extends AnalysisTest with DataTypeErrorsBase { ) } } + + errorClassTest( + "SPARK-47572: Enforce Window partitionSpec is orderable", + testRelation2.select( + WindowExpression( + new Rank(), + WindowSpecDefinition( + CreateMap(Literal("key") :: UnresolvedAttribute("a") :: Nil) :: Nil, + SortOrder(UnresolvedAttribute("b"), Ascending) :: Nil, + UnspecifiedFrame)).as("window")), + errorClass = "EXPRESSION_TYPE_IS_NOT_ORDERABLE", + messageParameters = Map( + "expr" -> "\"_w0\"", + "exprType" -> "\"MAP\"")) }