Skip to content

Commit 651e009

Browse files
committed
Limit the use cases where WITH * is automatically injected.
1 parent 96a8cbc commit 651e009

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

neomodel/async_/match.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ def __init__(
436436
)
437437
self.is_count = is_count
438438
self.subgraph: dict = {}
439+
self.mixed_filters: bool = False
439440

440441

441442
class AsyncQueryBuilder:
@@ -833,6 +834,7 @@ def add_to_target(statement: str, connector: Q, optional: bool) -> None:
833834
# everything into the one applied after OPTIONAL MATCH statements...
834835
opt_match_filters += match_filters
835836
match_filters = []
837+
self._ast.mixed_filters = True
836838

837839
ret = f" {q.connector} ".join(match_filters)
838840
if ret and q.negated:
@@ -949,8 +951,9 @@ def build_query(self) -> str:
949951
query += " OPTIONAL MATCH ".join(i for i in self._ast.optional_match)
950952

951953
if self._ast.optional_where:
952-
# Make sure filtering works as expected with optional match, even if it's not performant...
953-
query += " WITH *"
954+
if self._ast.mixed_filters:
955+
# Make sure filtering works as expected with optional match, even if it's not performant...
956+
query += " WITH *"
954957
query += " WHERE "
955958
query += " AND ".join(self._ast.optional_where)
956959

neomodel/sync_/match.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ def __init__(
434434
)
435435
self.is_count = is_count
436436
self.subgraph: dict = {}
437+
self.mixed_filters: bool = False
437438

438439

439440
class QueryBuilder:
@@ -831,6 +832,7 @@ def add_to_target(statement: str, connector: Q, optional: bool) -> None:
831832
# everything into the one applied after OPTIONAL MATCH statements...
832833
opt_match_filters += match_filters
833834
match_filters = []
835+
self._ast.mixed_filters = True
834836

835837
ret = f" {q.connector} ".join(match_filters)
836838
if ret and q.negated:
@@ -947,8 +949,9 @@ def build_query(self) -> str:
947949
query += " OPTIONAL MATCH ".join(i for i in self._ast.optional_match)
948950

949951
if self._ast.optional_where:
950-
# Make sure filtering works as expected with optional match, even if it's not performant...
951-
query += " WITH *"
952+
if self._ast.mixed_filters:
953+
# Make sure filtering works as expected with optional match, even if it's not performant...
954+
query += " WITH *"
952955
query += " WHERE "
953956
query += " AND ".join(self._ast.optional_where)
954957

test/async_/test_match_api.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,17 @@ async def test_q_filters():
553553
)
554554
assert len(latte_or_robusta_coffee) == 2
555555

556+
robusta_coffee = (
557+
await Coffee.nodes.fetch_relations(Optional("species"))
558+
.filter(species__name="Robusta")
559+
.all()
560+
)
561+
# Since we first do a MATCH on Coffee, the filter which is applied after the
562+
# OPTIONAL MATCH is useless because we don't inject any WITH * statement in this
563+
# case.
564+
# So, that's the result we expect...
565+
assert len(robusta_coffee) == 6
566+
556567
class QQ:
557568
pass
558569

test/sync_/test_match_api.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,17 @@ def test_q_filters():
549549
)
550550
assert len(latte_or_robusta_coffee) == 2
551551

552+
robusta_coffee = (
553+
Coffee.nodes.fetch_relations(Optional("species"))
554+
.filter(species__name="Robusta")
555+
.all()
556+
)
557+
# Since we first do a MATCH on Coffee, the filter which is applied after the
558+
# OPTIONAL MATCH is useless because we don't inject any WITH * statement in this
559+
# case.
560+
# So, that's the result we expect...
561+
assert len(robusta_coffee) == 6
562+
552563
class QQ:
553564
pass
554565

0 commit comments

Comments
 (0)