Flatten nested and/or queries

This commit is contained in:
Eike Kettner 2021-03-07 12:36:13 +01:00
parent 63d146c2de
commit 7638dc5111
3 changed files with 42 additions and 5 deletions

View File

@ -1,5 +1,7 @@
package docspell.query.internal
import cats.data.{NonEmptyList => Nel}
import docspell.query.ItemQuery.Expr._
import docspell.query.ItemQuery._
@ -11,12 +13,14 @@ object ExprUtil {
def reduce(expr: Expr): Expr =
expr match {
case AndExpr(inner) =>
if (inner.tail.isEmpty) reduce(inner.head)
else AndExpr(inner.map(reduce))
val nodes = spliceAnd(inner)
if (nodes.tail.isEmpty) reduce(nodes.head)
else AndExpr(nodes.map(reduce))
case OrExpr(inner) =>
if (inner.tail.isEmpty) reduce(inner.head)
else OrExpr(inner.map(reduce))
val nodes = spliceOr(inner)
if (nodes.tail.isEmpty) reduce(nodes.head)
else OrExpr(nodes.map(reduce))
case NotExpr(inner) =>
inner match {
@ -62,4 +66,19 @@ object ExprUtil {
case CustomFieldIdMatch(_, _, _) =>
expr
}
private def spliceAnd(nodes: Nel[Expr]): Nel[Expr] =
nodes.flatMap {
case Expr.AndExpr(inner) =>
spliceAnd(inner)
case node =>
Nel.of(node)
}
private def spliceOr(nodes: Nel[Expr]): Nel[Expr] =
nodes.flatMap {
case Expr.OrExpr(inner) =>
spliceOr(inner)
case node =>
Nel.of(node)
}
}

View File

@ -52,6 +52,6 @@ class FulltextExtractTest extends FunSuite {
test("wrong fulltext search position") {
assertFts("name:test (| date:2021-02 content:yes)", Result.UnsupportedPosition)
assertFts("name:test (& date:2021-02 content:yes)", Result.UnsupportedPosition) //TODO
assertFtsSuccess("name:test (& date:2021-02 content:yes)", "yes".some)
}
}

View File

@ -1,5 +1,7 @@
package docspell.query.internal
import cats.implicits._
import munit._
import docspell.query.ItemQueryParser
import docspell.query.ItemQuery
@ -40,4 +42,20 @@ class ItemQueryParserTest extends FunSuite {
val q = ItemQueryParser.parseUnsafe("")
assertEquals(ItemQuery.all, q)
}
test("splice inner and nodes") {
val raw = "(& name:hello (& date:2021-02 name:world) (& name:hello) )"
val q = ItemQueryParser.parseUnsafe(raw)
val expect =
ItemQueryParser.parseUnsafe("name:hello date:2021-02 name:world name:hello")
assertEquals(expect.copy(raw = raw.some), q)
}
test("splice inner or nodes") {
val raw = "(| name:hello (| date:2021-02 name:world) (| name:hello) )"
val q = ItemQueryParser.parseUnsafe(raw)
val expect =
ItemQueryParser.parseUnsafe("(| name:hello date:2021-02 name:world name:hello )")
assertEquals(expect.copy(raw = raw.some), q)
}
}