aboutsummaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorWenchen Fan <cloud0fan@outlook.com>2015-10-20 13:36:03 -0700
committerDavies Liu <davies.liu@gmail.com>2015-10-20 13:38:25 -0700
commit478c7ce8628c05ebce2972e631d76317accebe9c (patch)
treecb4154abc51ae79fefede5468112d4a6df0e6dae /sql
parent2f6dd634c169a34811738a3c230cce4462612748 (diff)
downloadspark-478c7ce8628c05ebce2972e631d76317accebe9c.tar.gz
spark-478c7ce8628c05ebce2972e631d76317accebe9c.tar.bz2
spark-478c7ce8628c05ebce2972e631d76317accebe9c.zip
[SPARK-6740] [SQL] correctly parse NOT operator with comparison operations
We can't parse `NOT` operator with comparison operations like `SELECT NOT TRUE > TRUE`, this PR fixed it. Takes over https://github.com/apache/spark/pull/6326. Author: Wenchen Fan <cloud0fan@outlook.com> Closes #8617 from cloud-fan/not.
Diffstat (limited to 'sql')
-rw-r--r--sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala6
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/SqlParserSuite.scala21
-rw-r--r--sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/PlanTest.scala2
3 files changed, 21 insertions, 8 deletions
diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
index 2595e1f90c..08ca325b21 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/SqlParser.scala
@@ -218,7 +218,10 @@ object SqlParser extends AbstractSparkSQLParser with DataTypeParser {
andExpression * (OR ^^^ { (e1: Expression, e2: Expression) => Or(e1, e2) })
protected lazy val andExpression: Parser[Expression] =
- comparisonExpression * (AND ^^^ { (e1: Expression, e2: Expression) => And(e1, e2) })
+ notExpression * (AND ^^^ { (e1: Expression, e2: Expression) => And(e1, e2) })
+
+ protected lazy val notExpression: Parser[Expression] =
+ NOT.? ~ comparisonExpression ^^ { case maybeNot ~ e => maybeNot.map(_ => Not(e)).getOrElse(e) }
protected lazy val comparisonExpression: Parser[Expression] =
( termExpression ~ ("=" ~> termExpression) ^^ { case e1 ~ e2 => EqualTo(e1, e2) }
@@ -246,7 +249,6 @@ object SqlParser extends AbstractSparkSQLParser with DataTypeParser {
}
| termExpression <~ IS ~ NULL ^^ { case e => IsNull(e) }
| termExpression <~ IS ~ NOT ~ NULL ^^ { case e => IsNotNull(e) }
- | NOT ~> termExpression ^^ {e => Not(e)}
| termExpression
)
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/SqlParserSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/SqlParserSuite.scala
index b93a3abc6e..79b4846cb9 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/SqlParserSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/SqlParserSuite.scala
@@ -17,10 +17,10 @@
package org.apache.spark.sql.catalyst
-import org.apache.spark.SparkFunSuite
-import org.apache.spark.sql.catalyst.expressions.Attribute
-import org.apache.spark.sql.catalyst.plans.logical.LogicalPlan
-import org.apache.spark.sql.catalyst.plans.logical.Command
+import org.apache.spark.sql.catalyst.analysis.UnresolvedAlias
+import org.apache.spark.sql.catalyst.expressions.{Literal, GreaterThan, Not, Attribute}
+import org.apache.spark.sql.catalyst.plans.PlanTest
+import org.apache.spark.sql.catalyst.plans.logical.{OneRowRelation, Project, LogicalPlan, Command}
private[sql] case class TestCommand(cmd: String) extends LogicalPlan with Command {
override def output: Seq[Attribute] = Seq.empty
@@ -49,7 +49,7 @@ private[sql] class CaseInsensitiveTestParser extends AbstractSparkSQLParser {
}
}
-class SqlParserSuite extends SparkFunSuite {
+class SqlParserSuite extends PlanTest {
test("test long keyword") {
val parser = new SuperLongKeywordTestParser
@@ -63,4 +63,15 @@ class SqlParserSuite extends SparkFunSuite {
assert(TestCommand("NotRealCommand") === parser.parse("execute NotRealCommand"))
assert(TestCommand("NotRealCommand") === parser.parse("exEcute NotRealCommand"))
}
+
+ test("test NOT operator with comparison operations") {
+ val parsed = SqlParser.parse("SELECT NOT TRUE > TRUE")
+ val expected = Project(
+ UnresolvedAlias(
+ Not(
+ GreaterThan(Literal(true), Literal(true)))
+ ) :: Nil,
+ OneRowRelation)
+ comparePlans(parsed, expected)
+ }
}
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/PlanTest.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/PlanTest.scala
index f76a903dcc..2efee1fc54 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/PlanTest.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/plans/PlanTest.scala
@@ -25,7 +25,7 @@ import org.apache.spark.sql.catalyst.util._
/**
* Provides helper methods for comparing plans.
*/
-class PlanTest extends SparkFunSuite {
+abstract class PlanTest extends SparkFunSuite {
/**
* Since attribute references are given globally unique ids during analysis,
* we must normalize them to check if two different queries are identical.