From fa8359ae2b0b4f025582e033a3338d1492642c90 Mon Sep 17 00:00:00 2001 From: Reynold Xin Date: Fri, 20 Jun 2014 14:10:55 -0700 Subject: [PATCH] [SPARK-2225] Turn HAVING without GROUP BY into WHERE. --- .../org/apache/spark/sql/hive/HiveQl.scala | 15 ++++----------- .../sql/hive/execution/HiveQuerySuite.scala | 19 +++++++------------ 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala index c69e3dba6b467..b073dc3895f05 100644 --- a/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala +++ b/sql/hive/src/main/scala/org/apache/spark/sql/hive/HiveQl.scala @@ -563,7 +563,6 @@ private[hive] object HiveQl { withWhere) }.getOrElse(withWhere) - // The projection of the query can either be a normal projection, an aggregation // (if there is a group by) or a script transformation. val withProject = transformation.getOrElse { @@ -581,16 +580,10 @@ private[hive] object HiveQl { val withDistinct = if (selectDistinctClause.isDefined) Distinct(withProject) else withProject - val withHaving = havingClause.map { h => - - if (groupByClause == None) { - throw new SemanticException("HAVING specified without GROUP BY") - } - - val havingExpr = h.getChildren.toSeq match { - case Seq(hexpr) => nodeToExpr(hexpr) - } - + val withHaving = havingClause.map { h => + val havingExpr = h.getChildren.toSeq match { case Seq(hexpr) => nodeToExpr(hexpr) } + // Note that we added a cast to boolean. If the expression itself is already boolean, + // the optimizer will get rid of the unnecessary cast. Filter(Cast(havingExpr, BooleanType), withDistinct) }.getOrElse(withDistinct) diff --git a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala index 80185098bf24f..d855310253bf3 100644 --- a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala +++ b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala @@ -227,27 +227,22 @@ class HiveQuerySuite extends HiveComparisonTest { test("SPARK-2180: HAVING support in GROUP BY clauses (positive)") { val fixture = List(("foo", 2), ("bar", 1), ("foo", 4), ("bar", 3)) .zipWithIndex.map {case Pair(Pair(value, attr), key) => HavingRow(key, value, attr)} - TestHive.sparkContext.parallelize(fixture).registerAsTable("having_test") - val results = hql("SELECT value, max(attr) AS attr FROM having_test GROUP BY value HAVING attr > 3") .collect() .map(x => Pair(x.getString(0), x.getInt(1))) - + assert(results === Array(Pair("foo", 4))) - TestHive.reset() } - - test("SPARK-2180: HAVING without GROUP BY raises exception") { - intercept[Exception] { - hql("SELECT value, attr FROM having_test HAVING attr > 3") - } - } - test("SPARK-2180: HAVING with non-boolean clause raises no exceptions") { - val results = hql("select key, count(*) c from src group by key having c").collect() + test("SPARK-2180: HAVING with non-boolean clause raises no exceptions") { + hql("select key, count(*) c from src group by key having c").collect() + } + + test("SPARK-2225: turn HAVING without GROUP BY into a simple filter") { + assert(hql("select key from src having key > 490").collect().size < 100) } test("Query Hive native command execution result") {