Skip to content

Commit

Permalink
fix: Fix scoping issue with existential subquery (#1151)
Browse files Browse the repository at this point in the history
Remove elements from scope cache when leaving existential subquery.

Closes #1147
  • Loading branch information
meistermeier authored Dec 18, 2024
1 parent 3b52925 commit 4ff3dd5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -728,4 +728,46 @@ static boolean areSemanticallyEquivalent(Statement statement1, Map<String, Objec

return true;
}

@Test // GH-1147
void shouldNotRecognizeLocallyScopedElementsFromExistentialSubqueries() {
var cypher = """
MATCH (this:Series)
WHERE ((EXISTS {
MATCH (this)-[edge:MANUFACTURER]->(this0:Manufacturer)
WHERE (this0.name = $param0 AND edge.current = $param1)
}
OR EXISTS {
MATCH (this)-[edge:MANUFACTURER]->(this1:Manufacturer)
WHERE (this1.name = $param2 AND edge.current = $param3)
})
AND EXISTS {
MATCH (this)-[edge:BRAND]->(this2:Brand)
WHERE (this2.name = $param4 AND edge.current = $param5)
})
RETURN this""";
var renderer = Renderer.getRenderer(Configuration.newConfig()
.withPrettyPrint(true)
.withGeneratedNames(true)
.build());
var normalized = renderer.render(CypherParser.parse(cypher));
assertThat(normalized).isEqualTo("""
MATCH (v0:Series)
WHERE ((EXISTS {
MATCH (v0)-[v1:MANUFACTURER]->(v2:Manufacturer)
WHERE (v2.name = $p0
AND v1.current = $p1)
}
OR EXISTS {
MATCH (v0)-[v1:MANUFACTURER]->(v2:Manufacturer)
WHERE (v2.name = $p2
AND v1.current = $p3)
})
AND EXISTS {
MATCH (v0)-[v1:BRAND]->(v2:Brand)
WHERE (v2.name = $p4
AND v1.current = $p5)
})
RETURN v0""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.neo4j.cypherdsl.core.AliasedExpression;
import org.neo4j.cypherdsl.core.Asterisk;
import org.neo4j.cypherdsl.core.Cypher;
import org.neo4j.cypherdsl.core.ExistentialSubquery;
import org.neo4j.cypherdsl.core.Expression;
import org.neo4j.cypherdsl.core.Foreach;
import org.neo4j.cypherdsl.core.FunctionInvocation;
Expand Down Expand Up @@ -259,7 +260,10 @@ public void doLeave(Visitable visitable) {
leaveStatement(visitable);
} else if (hasLocalScope(visitable)) {
notify = true;
this.dequeOfVisitedNamed.pop();
Set<IdentifiableElement> lastVisitedNames = this.dequeOfVisitedNamed.pop();
if (visitable instanceof ExistentialSubquery) {
this.afterStatement.retainAll(lastVisitedNames);
}
} else {
clearPreviouslyVisitedNamed(visitable);
}
Expand Down

0 comments on commit 4ff3dd5

Please sign in to comment.