add Not logical operator on WhereParser.
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala b/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
index 75e9657..d6e176b 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala
@@ -198,10 +198,14 @@
def paren: Parser[Clause] = "(" ~> clause <~ ")"
- def clause: Parser[Clause] = (predicate | paren) * (and ^^^ { (a: Clause, b: Clause) => And(a, b) } | or ^^^ { (a: Clause, b: Clause) => Or(a, b) })
+ def clause: Parser[Clause] = (_not | predicate | paren) * (and ^^^ { (a: Clause, b: Clause) => And(a, b) } | or ^^^ { (a: Clause, b: Clause) => Or(a, b) })
def identWithDot: Parser[String] = repsep(ident, ".") ^^ { case values => values.mkString(".") }
+ val _not = "not|NOT".r ~ (predicate | paren) ^^ {
+ case op ~ p => Not(p)
+ }
+
val _eq = identWithDot ~ ("!=" | "=") ~ stringLiteral ^^ {
case f ~ op ~ s => if (op == "=") Eq(f, s) else Not(Eq(f, s))
}
@@ -219,14 +223,10 @@
case f ~ minV ~ maxV => Between(f, minV, maxV)
}
- val _in = identWithDot ~ (notIn | in) ~ ("(" ~> repsep(stringLiteral, ",") <~ ")") ^^ {
+ val _in = identWithDot ~ (in) ~ ("(" ~> repsep(stringLiteral, ",") <~ ")") ^^ {
case f ~ op ~ values =>
- val inClause =
- if (f.startsWith("_parent")) IN(f, values.toSet)
- else InWithoutParent(f, values.toSet)
-
- if (op.toLowerCase == "in") inClause
- else Not(inClause)
+ if (f.startsWith("_parent")) IN(f, values.toSet)
+ else InWithoutParent(f, values.toSet)
}
val _contains = identWithDot ~ contains ~ stringLiteral ^^ {
diff --git a/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala b/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
index 342d9c6..0ff4db1 100644
--- a/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
+++ b/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala
@@ -46,6 +46,7 @@
}
val whereOpt = WhereParser().parse(sql)
+
if (whereOpt.isFailure) {
debug(whereOpt)
whereOpt.get // touch exception
@@ -138,6 +139,7 @@
f("time > 2")(true)
f("time <= 3")(true)
f("time < 2")(false)
+ f("NOT time >= 3")(false)
f("(time in (1, 2, 3) and is_blocked = true) or is_hidden = false")(false)
f("(time in (1, 2, 3) or is_blocked = true) or is_hidden = false")(true)
@@ -169,6 +171,8 @@
f(s"_from = ${tgtVertex.innerId.value} and _to = 102934")(false)
f(s"_from = -1")(false)
f(s"_from in (-1, -0.1)")(false)
+ f(s"NOT (_from = -1)")(true)
+ f(s"NOT _from contains 'a'")(true)
}
}