Repository: incubator-s2graph Updated Branches: refs/heads/master 9dc39ee37 -> a07c4d2d3
add 'Contains' Claues in where parser Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/3ac20b40 Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/3ac20b40 Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/3ac20b40 Branch: refs/heads/master Commit: 3ac20b409479261dce1c26e3d489dff6f934c78a Parents: 5c85dd4 Author: daewon <[email protected]> Authored: Wed Apr 18 14:42:56 2018 +0900 Committer: daewon <[email protected]> Committed: Wed Apr 18 14:42:56 2018 +0900 ---------------------------------------------------------------------- .../s2graph/core/parsers/WhereParser.scala | 64 +++++++++----------- .../s2graph/core/rest/RequestParser.scala | 2 +- .../s2graph/core/Integrate/QueryTest.scala | 2 +- .../s2graph/core/parsers/WhereParserTest.scala | 11 +++- 4 files changed, 39 insertions(+), 40 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3ac20b40/s2core/src/main/scala/org/apache/s2graph/core/parsers/WhereParser.scala ---------------------------------------------------------------------- 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 d9e6a7b..00ef233 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 @@ -22,9 +22,8 @@ package org.apache.s2graph.core.parsers import org.apache.s2graph.core.GraphExceptions.{LabelNotExistException, WhereParserException} import org.apache.s2graph.core.mysqls.{Label, LabelMeta} import org.apache.s2graph.core.types.InnerValLike -import org.apache.s2graph.core.{GraphUtil, S2Edge, S2EdgeLike} +import org.apache.s2graph.core.{S2EdgeLike} import org.apache.s2graph.core.JSONParser._ -import org.apache.s2graph.core.utils.logger import scala.annotation.tailrec import scala.util.Try @@ -97,13 +96,15 @@ trait Clause extends ExtractValue { binOp(propValue, compValue) } } + object Where { - def apply(labelName: String, sql: String): Try[Where] = { - val label = Label.findByName(labelName).getOrElse(throw new LabelNotExistException(labelName)) - val parser = new WhereParser(label) + def apply(sql: String): Try[Where] = { + val parser = new WhereParser() + parser.parse(sql) } } + case class Where(clauses: Seq[Clause] = Seq.empty[Clause]) { def filter(edge: S2EdgeLike) = if (clauses.isEmpty) true else clauses.map(_.filter(edge)).forall(identity) @@ -121,37 +122,23 @@ case class Eq(propKey: String, value: String) extends Clause { override def filter(edge: S2EdgeLike): Boolean = binaryOp(_ == _)(propKey, value)(edge) } -case class InWithoutParent(label: Label, propKey: String, values: Set[String]) extends Clause { - lazy val innerValLikeLsOut = values.map { value => - val labelMeta = label.metaPropsInvMap.getOrElse(propKey, throw WhereParserException(s"Where clause contains not existing property name: $propKey")) - val dataType = propKey match { - case "_to" | "to" => label.tgtColumn.columnType - case "_from" | "from" => label.srcColumn.columnType - case _ => labelMeta.dataType - } - - toInnerVal(value, dataType, label.schemaVersion) - } +case class InWithoutParent(propKey: String, values: Set[String]) extends Clause { + override def filter(edge: S2EdgeLike): Boolean = { + val label = edge.innerLabel - lazy val innerValLikeLsIn = values.map { value => - val labelMeta = label.metaPropsInvMap.getOrElse(propKey, throw WhereParserException(s"Where clause contains not existing property name: $propKey")) - val dataType = propKey match { - case "_to" | "to" => label.srcColumn.columnType - case "_from" | "from" => label.tgtColumn.columnType - case _ => labelMeta.dataType + val propVal = propToInnerVal(edge, propKey) + val innerVaLs = values.map { value => + toInnerVal(value, label.metaPropsInvMap(propKey).dataType, label.schemaVersion) } - toInnerVal(value, dataType, label.schemaVersion) + innerVaLs(propVal) } +} +case class Contains(propKey: String, value: String) extends Clause { override def filter(edge: S2EdgeLike): Boolean = { - if (edge.getDir() == GraphUtil.directions("in")) { - val propVal = propToInnerVal(edge, propKey) - innerValLikeLsIn.contains(propVal) - } else { - val propVal = propToInnerVal(edge, propKey) - innerValLikeLsOut.contains(propVal) - } + val propVal = propToInnerVal(edge, propKey) + propVal.value.toString.contains(value) } } @@ -188,13 +175,10 @@ case class Or(left: Clause, right: Clause) extends Clause { object WhereParser { val success = Where() - } -case class WhereParser(label: Label) extends JavaTokenParsers { - - - override val stringLiteral = (("'" ~> "(\\\\'|[^'])*".r <~ "'" ) ^^ (_.replace("\\'", "'"))) | anyStr +case class WhereParser() extends JavaTokenParsers { + override val stringLiteral = (("'" ~> "(\\\\'|[^'])*".r <~ "'") ^^ (_.replace("\\'", "'"))) | anyStr val anyStr = "[^\\s(),']+".r @@ -206,6 +190,8 @@ case class WhereParser(label: Label) extends JavaTokenParsers { val in = "in|IN".r + val contains = "contains|CONTAINS".r + val notIn = "not in|NOT IN".r def where: Parser[Where] = rep(clause) ^^ (Where(_)) @@ -237,13 +223,17 @@ case class WhereParser(label: Label) extends JavaTokenParsers { case f ~ op ~ values => val inClause = if (f.startsWith("_parent")) IN(f, values.toSet) - else InWithoutParent(label, f, values.toSet) + else InWithoutParent(f, values.toSet) if (op.toLowerCase == "in") inClause else Not(inClause) } - def predicate = _eq | _ltGt | _between | _in + val _contains = identWithDot ~ contains ~ stringLiteral ^^ { + case f ~ op ~ value => Contains(f, value) + } + + def predicate = _eq | _ltGt | _between | _in | _contains def parse(sql: String): Try[Where] = Try { parseAll(where, sql) match { http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3ac20b40/s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala ---------------------------------------------------------------------- diff --git a/s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala b/s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala index f42d5eb..6b1ce75 100644 --- a/s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala +++ b/s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala @@ -229,7 +229,7 @@ class RequestParser(graph: S2GraphLike) { override def call(): Try[Where] = { val _where = TemplateHelper.replaceVariable(System.currentTimeMillis(), where) - WhereParser(label).parse(_where) match { + WhereParser().parse(_where) match { case s@Success(_) => s case Failure(ex) => throw BadQueryException(ex.getMessage, ex) } http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3ac20b40/s2core/src/test/scala/org/apache/s2graph/core/Integrate/QueryTest.scala ---------------------------------------------------------------------- diff --git a/s2core/src/test/scala/org/apache/s2graph/core/Integrate/QueryTest.scala b/s2core/src/test/scala/org/apache/s2graph/core/Integrate/QueryTest.scala index 87442c4..2b47666 100644 --- a/s2core/src/test/scala/org/apache/s2graph/core/Integrate/QueryTest.scala +++ b/s2core/src/test/scala/org/apache/s2graph/core/Integrate/QueryTest.scala @@ -72,7 +72,7 @@ class QueryTest extends IntegrateCommon with BeforeAndAfterEach { Query( vertices = Seq(graph.toVertex(testServiceName, testColumnName, id)), steps = Vector( - Step(Seq(QueryParam(testLabelName, where = Where(testLabelName, where)))) + Step(Seq(QueryParam(testLabelName, where = Where(where)))) ) ) http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/3ac20b40/s2core/src/test/scala/org/apache/s2graph/core/parsers/WhereParserTest.scala ---------------------------------------------------------------------- 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 66e44ec..0920a89 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 @@ -45,7 +45,7 @@ class WhereParserTest extends FunSuite with Matchers with TestCommonWithModels { println("==================") } - val whereOpt = WhereParser(label).parse(sql) + val whereOpt = WhereParser().parse(sql) if (whereOpt.isFailure) { debug(whereOpt) whereOpt.get // touch exception @@ -285,4 +285,13 @@ class WhereParserTest extends FunSuite with Matchers with TestCommonWithModels { r >= 10 && r < 30 } } + + test("check parse contains") { + val dummyLabel = ids.head._3 + + val sql = "name = 'daewon'" + val whereOpt = WhereParser().parse(sql) + println(whereOpt) + } + }
