Skip to content

Commit

Permalink
Merge pull request #10214 from OliviaYtterbrink/3.2-empty-properties-…
Browse files Browse the repository at this point in the history
…filter

Properly handle filtering with empty properties map
  • Loading branch information
fickludd committed Nov 2, 2017
2 parents fe453ec + 0036916 commit c849489
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,30 @@ class MatchPredicateNormalizerTest extends CypherFunSuite with RewriteTest {
"MATCH (n)-[r:Foo]->() WHERE n.foo = 'bar' AND n.bar = 4 AND r.foo = 1 AND r.bar = 'baz' RETURN n")
}

test("remove empty predicate from node") {
assertRewrite(
"MATCH (n { }) RETURN n",
"MATCH (n) RETURN n")
}

test("remove empty predicate from rel") {
assertRewrite(
"MATCH (n)-[r:Foo { }]->() RETURN n",
"MATCH (n)-[r:Foo]->() RETURN n")
}

test("remove empty predicates") {
assertRewrite(
"MATCH (n { })-[r:Foo { }]->() RETURN n",
"MATCH (n)-[r:Foo]->() RETURN n")
}

test("remove empty predicates and keep existing WHERE") {
assertRewrite(
"MATCH (n { })-[r:Foo { }]->() WHERE n.baz = true OR r.baz = false RETURN n",
"MATCH (n)-[r:Foo]->() WHERE n.baz = true OR r.baz = false RETURN n")
}

test("prepend predicates to existing WHERE") {
assertRewrite(
"MATCH (n {foo: 'bar', bar: 4})-[r:Foo {foo: 1, bar: 'baz'}]->() WHERE n.baz = true OR r.baz = false RETURN n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,24 @@ abstract class MatchPredicateNormalization(normalizer: MatchPredicateNormalizer)
case _ => identity
}

if (predicates.isEmpty)
m.copy(where = m.where.map(w => {
val pos: InputPosition = where.fold(m.position)(_.position)
w.copy( expression = w.expression.endoRewrite(whereRewriter))(pos)
}))(m.position)
else {
val rewrittenPredicates: List[Expression] = (predicates ++ where.map(_.expression)).toList

val predOpt: Option[Expression] = rewrittenPredicates match {
case Nil => None
case exp :: Nil => Some(exp)
case list => Some(list.reduce(And(_, _)(m.position)))
}
val rewrittenPredicates: List[Expression] = (predicates ++ where.map(_.expression)).toList

val newWhere: Option[Where] = predOpt.map {
exp =>
val pos: InputPosition = where.fold(m.position)(_.position)
Where(exp.endoRewrite(whereRewriter))(pos)
}
val predOpt: Option[Expression] = rewrittenPredicates match {
case Nil => None
case exp :: Nil => Some(exp)
case list => Some(list.reduce(And(_, _)(m.position)))
}

m.copy(
pattern = pattern.endoRewrite(topDown(Rewriter.lift(normalizer.replace))),
where = newWhere
)(m.position)
val newWhere: Option[Where] = predOpt.map {
exp =>
val pos: InputPosition = where.fold(m.position)(_.position)
Where(exp.endoRewrite(whereRewriter))(pos)
}

m.copy(
pattern = pattern.endoRewrite(topDown(Rewriter.lift(normalizer.replace))),
where = newWhere
)(m.position)
}

private def whereRewriter: Rewriter = Rewriter.lift {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,4 +149,21 @@ Feature: MatchAcceptance
| a |
| (:A:B) |
| (:A:C) |

Scenario: Handle filtering with empty properties map
Given an empty graph
And having executed:
"""
CREATE ({foo: 1})-[:R {bar: 1}]->({foo: 2}),
({foo: 3})-[:R {bar: 2}]->({foo: 4}),
({foo: 5})-[:R {bar: 3}]->({foo: 6})
"""
When executing query:
"""
MATCH (a { })-[r:R { }]->(b { }) WHERE a.foo = 3 AND b.foo = 4
RETURN r.bar
"""
Then the result should be:
| r.bar |
| 2 |
And no side effects

0 comments on commit c849489

Please sign in to comment.