Skip to content

Commit cd6129e

Browse files
committed
Inject subqueries before WITH statements in generated query.
1 parent bbf7a68 commit cd6129e

File tree

2 files changed

+58
-56
lines changed

2 files changed

+58
-56
lines changed

neomodel/async_/match.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,34 @@ def build_query(self) -> str:
962962
query += self._ast.with_clause
963963

964964
returned_items: list[str] = []
965+
if hasattr(self.node_set, "_subqueries"):
966+
for subquery in self.node_set._subqueries:
967+
query += " CALL {"
968+
if subquery["initial_context"]:
969+
query += " WITH "
970+
context: list[str] = []
971+
for var in subquery["initial_context"]:
972+
if isinstance(var, (NodeNameResolver, RelationNameResolver)):
973+
context.append(var.resolve(self))
974+
else:
975+
context.append(var)
976+
query += ",".join(context)
977+
978+
query += f"{subquery['query']} }} "
979+
self._query_params.update(subquery["query_params"])
980+
for varname in subquery["return_set"]:
981+
# We declare the returned variables as "virtual" relations of the
982+
# root node class to make sure they will be translated by a call to
983+
# resolve_subgraph() (otherwise, they will be lost).
984+
# This is probably a temporary solution until we find something better...
985+
self._ast.subgraph[varname] = {
986+
"target": None, # We don't need target class in this use case
987+
"children": {},
988+
"variable_name": varname,
989+
"rel_variable_name": varname,
990+
}
991+
returned_items += subquery["return_set"]
992+
965993
if hasattr(self.node_set, "_intermediate_transforms"):
966994
for transform in self.node_set._intermediate_transforms:
967995
query += " WITH "
@@ -970,6 +998,7 @@ def build_query(self) -> str:
970998
# Reset return list since we'll probably invalidate most variables
971999
self._ast.return_clause = ""
9721000
self._ast.additional_return = []
1001+
returned_items = []
9731002
for name, varprops in transform["vars"].items():
9741003
source = varprops["source"]
9751004
if isinstance(source, (NodeNameResolver, RelationNameResolver)):
@@ -997,34 +1026,6 @@ def build_query(self) -> str:
9971026
ordering.append(item)
9981027
query += ",".join(ordering)
9991028

1000-
if hasattr(self.node_set, "_subqueries"):
1001-
for subquery in self.node_set._subqueries:
1002-
query += " CALL {"
1003-
if subquery["initial_context"]:
1004-
query += " WITH "
1005-
context: list[str] = []
1006-
for var in subquery["initial_context"]:
1007-
if isinstance(var, (NodeNameResolver, RelationNameResolver)):
1008-
context.append(var.resolve(self))
1009-
else:
1010-
context.append(var)
1011-
query += ",".join(context)
1012-
1013-
query += f"{subquery['query']} }} "
1014-
self._query_params.update(subquery["query_params"])
1015-
for varname in subquery["return_set"]:
1016-
# We declare the returned variables as "virtual" relations of the
1017-
# root node class to make sure they will be translated by a call to
1018-
# resolve_subgraph() (otherwise, they will be lost).
1019-
# This is probably a temporary solution until we find something better...
1020-
self._ast.subgraph[varname] = {
1021-
"target": None, # We don't need target class in this use case
1022-
"children": {},
1023-
"variable_name": varname,
1024-
"rel_variable_name": varname,
1025-
}
1026-
returned_items += subquery["return_set"]
1027-
10281029
query += " RETURN "
10291030
if self._ast.return_clause and not self._subquery_namespace:
10301031
returned_items.append(self._ast.return_clause)

neomodel/sync_/match.py

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -960,6 +960,34 @@ def build_query(self) -> str:
960960
query += self._ast.with_clause
961961

962962
returned_items: list[str] = []
963+
if hasattr(self.node_set, "_subqueries"):
964+
for subquery in self.node_set._subqueries:
965+
query += " CALL {"
966+
if subquery["initial_context"]:
967+
query += " WITH "
968+
context: list[str] = []
969+
for var in subquery["initial_context"]:
970+
if isinstance(var, (NodeNameResolver, RelationNameResolver)):
971+
context.append(var.resolve(self))
972+
else:
973+
context.append(var)
974+
query += ",".join(context)
975+
976+
query += f"{subquery['query']} }} "
977+
self._query_params.update(subquery["query_params"])
978+
for varname in subquery["return_set"]:
979+
# We declare the returned variables as "virtual" relations of the
980+
# root node class to make sure they will be translated by a call to
981+
# resolve_subgraph() (otherwise, they will be lost).
982+
# This is probably a temporary solution until we find something better...
983+
self._ast.subgraph[varname] = {
984+
"target": None, # We don't need target class in this use case
985+
"children": {},
986+
"variable_name": varname,
987+
"rel_variable_name": varname,
988+
}
989+
returned_items += subquery["return_set"]
990+
963991
if hasattr(self.node_set, "_intermediate_transforms"):
964992
for transform in self.node_set._intermediate_transforms:
965993
query += " WITH "
@@ -968,6 +996,7 @@ def build_query(self) -> str:
968996
# Reset return list since we'll probably invalidate most variables
969997
self._ast.return_clause = ""
970998
self._ast.additional_return = []
999+
returned_items = []
9711000
for name, varprops in transform["vars"].items():
9721001
source = varprops["source"]
9731002
if isinstance(source, (NodeNameResolver, RelationNameResolver)):
@@ -995,34 +1024,6 @@ def build_query(self) -> str:
9951024
ordering.append(item)
9961025
query += ",".join(ordering)
9971026

998-
if hasattr(self.node_set, "_subqueries"):
999-
for subquery in self.node_set._subqueries:
1000-
query += " CALL {"
1001-
if subquery["initial_context"]:
1002-
query += " WITH "
1003-
context: list[str] = []
1004-
for var in subquery["initial_context"]:
1005-
if isinstance(var, (NodeNameResolver, RelationNameResolver)):
1006-
context.append(var.resolve(self))
1007-
else:
1008-
context.append(var)
1009-
query += ",".join(context)
1010-
1011-
query += f"{subquery['query']} }} "
1012-
self._query_params.update(subquery["query_params"])
1013-
for varname in subquery["return_set"]:
1014-
# We declare the returned variables as "virtual" relations of the
1015-
# root node class to make sure they will be translated by a call to
1016-
# resolve_subgraph() (otherwise, they will be lost).
1017-
# This is probably a temporary solution until we find something better...
1018-
self._ast.subgraph[varname] = {
1019-
"target": None, # We don't need target class in this use case
1020-
"children": {},
1021-
"variable_name": varname,
1022-
"rel_variable_name": varname,
1023-
}
1024-
returned_items += subquery["return_set"]
1025-
10261027
query += " RETURN "
10271028
if self._ast.return_clause and not self._subquery_namespace:
10281029
returned_items.append(self._ast.return_clause)

0 commit comments

Comments
 (0)