Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package org.apache.spark.sql.execution.aggregate

import org.apache.spark.sql.catalyst.expressions._
import org.apache.spark.sql.catalyst.expressions.aggregate._
import org.apache.spark.sql.catalyst.optimizer.NormalizeFloatingNumbers
Comment thread
HyukjinKwon marked this conversation as resolved.
Outdated
import org.apache.spark.sql.execution.SparkPlan
import org.apache.spark.sql.execution.streaming.{StateStoreRestoreExec, StateStoreSaveExec}

Expand Down Expand Up @@ -144,11 +145,16 @@ object AggUtils {
// [COUNT(DISTINCT foo), MAX(DISTINCT foo)], but [COUNT(DISTINCT bar), COUNT(DISTINCT foo)] is
// disallowed because those two distinct aggregates have different column expressions.
val distinctExpressions = functionsWithDistinct.head.aggregateFunction.children
val namedDistinctExpressions = distinctExpressions.map {
case ne: NamedExpression => ne
case other => Alias(other, other.toString)()
val normalizedNamedDistinctExpressions = distinctExpressions.map { e =>
Comment thread
HyukjinKwon marked this conversation as resolved.
Outdated
// Ideally this should be done in `NormalizeFloatingNumbers`, but we do it here because
// `groupingExpressions` is not extracted during logical phase.
Comment thread
viirya marked this conversation as resolved.
Outdated
NormalizeFloatingNumbers.normalize(e) match {
case ne: NamedExpression => ne
case other => Alias(other, other.toString)()
Comment thread
HyukjinKwon marked this conversation as resolved.
Outdated
}
}
val distinctAttributes = namedDistinctExpressions.map(_.toAttribute)

val distinctAttributes = normalizedNamedDistinctExpressions.map(_.toAttribute)
val groupingAttributes = groupingExpressions.map(_.toAttribute)

// 1. Create an Aggregate Operator for partial aggregations.
Expand All @@ -159,7 +165,7 @@ object AggUtils {
// DISTINCT column. For example, for AVG(DISTINCT value) GROUP BY key, the grouping
// expressions will be [key, value].
createAggregate(
groupingExpressions = groupingExpressions ++ namedDistinctExpressions,
groupingExpressions = groupingExpressions ++ normalizedNamedDistinctExpressions,
aggregateExpressions = aggregateExpressions,
aggregateAttributes = aggregateAttributes,
resultExpressions = groupingAttributes ++ distinctAttributes ++
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1012,4 +1012,20 @@ class DataFrameAggregateSuite extends QueryTest
}
}
}

test("SPARK-32038: NormalizeFloatingNumbers should work on distinct aggregate") {
withTempView("view") {
val nan1 = java.lang.Float.intBitsToFloat(0x7f800001)
val nan2 = java.lang.Float.intBitsToFloat(0x7fffffff)

Seq(("mithunr", Float.NaN),
("mithunr", nan1),
("mithunr", nan2),
("abellina", 1.0f),
("abellina", 2.0f)).toDF("uid", "score").createOrReplaceTempView("view")

val df = spark.sql("select uid, count(distinct score) from view group by 1 order by 1 asc")
checkAnswer(df, Row("abellina", 2) :: Row("mithunr", 1) :: Nil)
}
}
}