diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala index 7ace11efe52fb..0d2b5f3fdfbab 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/parser/AstBuilder.scala @@ -1740,7 +1740,19 @@ class AstBuilder extends SqlBaseBaseVisitor[AnyRef] with SQLConfHelper with Logg override def visitWindowDef(ctx: WindowDefContext): WindowSpecDefinition = withOrigin(ctx) { // CLUSTER BY ... | PARTITION BY ... ORDER BY ... val partition = ctx.partition.asScala.map(expression) - val order = ctx.sortItem.asScala.map(visitSortItem) + val order = if (ctx.sortItem.asScala.nonEmpty) { + ctx.sortItem.asScala.map(visitSortItem) + } else if (ctx.windowFrame != null && + ctx.windowFrame().frameType.getType == SqlBaseParser.RANGE) { + // for RANGE window frame, we won't add default order spec + ctx.sortItem.asScala.map(visitSortItem) + } else { + // Same default behaviors like hive, when order spec is null + // set partition spec expression as order spec + ctx.partition.asScala.map { expr => + SortOrder(expression(expr), Ascending, Ascending.defaultNullOrdering, Seq.empty) + } + } // RANGE/ROWS BETWEEN ... val frameSpecOption = Option(ctx.windowFrame).map { frame =>