Skip to content

Commit

Permalink
Merge pull request #4752 from opsmill/dga-20241026-query
Browse files Browse the repository at this point in the history
Avoid using WHERE $node_kind IN LABELS(n) in query,
  • Loading branch information
dgarros authored Oct 28, 2024
2 parents 9c88eeb + 4c2f3bc commit 3002117
Show file tree
Hide file tree
Showing 15 changed files with 66 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,18 @@ def __init__(self, **kwargs: Any):
def render_match(self) -> str:
query = """
// Find all the active nodes
MATCH (node:Node)
WHERE ( "Profile%(node_kind)s" IN LABELS(node) OR "%(node_kind)s" IN LABELS(node) )
AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
AND NOT exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $new_attr.name }))
CALL {
MATCH (node:%(node_kind)s)
WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
AND NOT exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $new_attr.name }))
RETURN node
UNION
MATCH (node:Profile%(node_kind)s)
WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
AND NOT exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $new_attr.name }))
RETURN node
}
WITH node
""" % {"node_kind": self.previous_attr.node_kind}

return query
Expand Down
13 changes: 10 additions & 3 deletions backend/infrahub/core/migrations/query/attribute_rename.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,16 @@ def __init__(
def render_match(self) -> str:
query = """
// Find all the active nodes
MATCH (node:Node)
WHERE ( "Profile%(node_kind)s" IN LABELS(node) OR "%(node_kind)s" IN LABELS(node) )
AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
CALL {
MATCH (node:%(node_kind)s)
WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
RETURN node
UNION
MATCH (node:Profile%(node_kind)s)
WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $prev_attr.name }))
RETURN node
}
WITH node
""" % {"node_kind": self.previous_attr.node_kind}

return query
Expand Down
10 changes: 7 additions & 3 deletions backend/infrahub/core/migrations/schema/node_attribute_remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ def render_sub_query_per_rel_type(rel_type: str, rel_def: FieldInfo) -> str:

query = """
// Find all the active nodes
MATCH (node:Node)
WHERE $node_kind IN LABELS(node) AND exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name }))
MATCH (node:%(node_kind)s)
WHERE exists((node)-[:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name }))
CALL {
WITH node
MATCH (root:Root)<-[r:IS_PART_OF]-(node)
Expand Down Expand Up @@ -102,7 +102,11 @@ def render_sub_query_per_rel_type(rel_type: str, rel_def: FieldInfo) -> str:
SET rb.to = $current_time
)
RETURN DISTINCT active_attr
""" % {"branch_filter": branch_filter, "sub_query_all": sub_query_all}
""" % {
"branch_filter": branch_filter,
"sub_query_all": sub_query_all,
"node_kind": self.migration.new_schema.kind,
}
self.add_to_query(query)


Expand Down
10 changes: 6 additions & 4 deletions backend/infrahub/core/migrations/schema/node_remove.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.migration.previous_schema.kind
self.params["current_time"] = self.at.to_string()
self.params["branch_name"] = self.branch.name

Expand All @@ -52,8 +51,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
# ruff: noqa: E501
query = """
// Find all the active nodes
MATCH (node:Node)
WHERE $node_kind IN LABELS(node)
MATCH (node:%(node_kind)s)
CALL {
WITH node
MATCH (root:Root)<-[r:IS_PART_OF]-(node)
Expand All @@ -66,7 +64,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WHERE rb.status = "active"
%(node_remove_query)s
RETURN DISTINCT active_node
""" % {"branch_filter": branch_filter, "node_remove_query": node_remove_query}
""" % {
"branch_filter": branch_filter,
"node_remove_query": node_remove_query,
"node_kind": self.migration.previous_schema.kind,
}
self.add_to_query(query)

def get_nbr_migrations_executed(self) -> int:
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/query/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,6 @@ def _get_tracked_variables(self) -> list[str]:

async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
self.order_by = []
self.params["node_kind"] = self.schema.kind

self.return_labels = ["n.uuid", "rb.branch", f"{db.get_id_function_name()}(rb) as rb_id"]
where_clause_elements = []
Expand All @@ -803,8 +802,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
self.params.update(branch_params)

query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH (root:Root)<-[r:IS_PART_OF]-(n)
Expand All @@ -815,7 +813,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: Any) -> None:
}
WITH n, r as rb
WHERE rb.status = "active"
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.schema.kind}
self.add_to_query(query)
use_simple = False
if self.filters and "id" in self.filters:
Expand Down
8 changes: 3 additions & 5 deletions backend/infrahub/core/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,10 @@ async def count_relationships(db: InfrahubDatabase, label: Optional[str] = None)
async def get_nodes(db: InfrahubDatabase, label: str) -> list[Neo4jNode]:
"""Return theall nodes of a given label in the database."""
query = """
MATCH (node)
WHERE $label IN LABELS(node)
MATCH (node:%(node_kind)s)
RETURN node
"""
params: dict = {"label": label}
results = await db.execute_query(query=query, params=params, name="get_nodes")
""" % {"node_kind": label}
results = await db.execute_query(query=query, name="get_nodes")
return [result[0] for result in results]


Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/attribute/choices.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["attr_name"] = self.attribute_schema.name
self.params["allowed_values"] = [choice.name for choice in self.attribute_schema.choices]
self.params["null_value"] = NULL_VALUE

query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH p = (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue)
Expand All @@ -50,7 +48,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
AND attribute_value IS NOT NULL
AND attribute_value <> $null_value
AND NOT (attribute_value IN $allowed_values)
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["node.uuid", "attribute_value", "value_relationship"]
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/attribute/enum.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["attr_name"] = self.attribute_schema.name
self.params["allowed_values"] = self.attribute_schema.enum
self.params["null_value"] = NULL_VALUE
query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue)
Expand All @@ -49,7 +47,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
AND attribute_value IS NOT NULL
AND attribute_value <> $null_value
AND NOT (attribute_value IN $allowed_values)
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["node.uuid", "attribute_value", "value_relationship"]
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/attribute/kind.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["attr_name"] = self.attribute_schema.name
self.params["null_value"] = NULL_VALUE

query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH p = (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue)
Expand All @@ -55,7 +53,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WHERE all(r in relationships(full_path) WHERE r.status = "active")
AND attribute_value IS NOT NULL
AND attribute_value <> $null_value
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["node.uuid", "attribute_value", "value_relationship.branch as value_branch"]
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/attribute/length.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["attr_name"] = self.attribute_schema.name
self.params["min_length"] = self.attribute_schema.min_length
self.params["max_length"] = self.attribute_schema.max_length

query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue)
Expand All @@ -48,7 +46,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
(toInteger($min_length) IS NOT NULL AND size(attribute_value) < toInteger($min_length))
OR (toInteger($max_length) IS NOT NULL AND size(attribute_value) > toInteger($max_length))
)
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["node.uuid", "value_relationship", "attribute_value"]
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/attribute/optional.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["attr_name"] = self.attribute_schema.name
self.params["null_value"] = NULL_VALUE

query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue)
Expand All @@ -44,7 +42,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WITH full_path, node, attribute_value, value_relationship
WHERE all(r in relationships(full_path) WHERE r.status = "active")
AND (attribute_value IS NULL OR attribute_value = $null_value)
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["node.uuid", "value_relationship"]
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/attribute/regex.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string())
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["attr_name"] = self.attribute_schema.name
self.params["attr_value_regex"] = self.attribute_schema.regex
self.params["null_value"] = NULL_VALUE
query = """
MATCH p = (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH p = (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rr:IS_PART_OF]-(n)-[ra:HAS_ATTRIBUTE]-(:Attribute { name: $attr_name } )-[rv:HAS_VALUE]-(av:AttributeValue)
Expand All @@ -45,7 +43,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WHERE all(r in relationships(full_path) WHERE r.status = "active")
AND attribute_value <> $null_value
AND NOT attribute_value =~ $attr_value_regex
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["node.uuid", "attribute_value", "value_relationship"]
Expand Down
11 changes: 7 additions & 4 deletions backend/infrahub/core/validators/node/hierarchy.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
if hierarchy := getattr(self.node_schema, "hierarchy", None):
self.params["hierarchy_kind"] = hierarchy
else:
Expand All @@ -61,8 +60,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No

# ruff: noqa: E501
query = """
MATCH (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rroot:IS_PART_OF]-(n)
Expand Down Expand Up @@ -117,7 +115,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
any(r in relationships(current_path) WHERE r.hierarchy <> $hierarchy_kind)
OR NOT ($peer_kind IN labels(current_peer))
)
""" % {"branch_filter": branch_filter, "to_children": to_children, "to_parent": to_parent}
""" % {
"branch_filter": branch_filter,
"to_children": to_children,
"to_parent": to_parent,
"node_kind": self.node_schema.kind,
}

self.add_to_query(query)
self.return_labels = ["start_node.uuid", "branch_name", "current_peer.uuid"]
Expand Down
14 changes: 5 additions & 9 deletions backend/infrahub/core/validators/relationship/optional.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["relationship_id"] = self.relationship_schema.identifier

query = """
// Query all Active Nodes of type
// and store their UUID in uuids_active_node
MATCH (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH (root:Root)<-[r:IS_PART_OF]-(n)
Expand All @@ -45,8 +43,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WITH COLLECT(active_node.uuid) AS uuids_active_node
// identifier all nodes with at least one active member for this relationship
// and store their UUID in uuids_with_rel
MATCH (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n, uuids_active_node
MATCH path = (n)-[r:IS_RELATED]-(:Relationship { name: $relationship_id })
Expand All @@ -58,12 +55,11 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WITH n1 as node_with_rel, r1 as r, uuids_active_node
WHERE r.status = "active"
WITH COLLECT(node_with_rel.uuid) AS uuids_with_rel, uuids_active_node
MATCH (n:Node)-[r:IS_PART_OF]->(:Root)
WHERE $node_kind IN LABELS(n)
AND n.uuid IN uuids_active_node
MATCH (n:%(node_kind)s)-[r:IS_PART_OF]->(:Root)
WHERE n.uuid IN uuids_active_node
AND not n.uuid IN uuids_with_rel
AND NOT exists((n)-[:IS_RELATED]-(:Relationship { name: $relationship_id }))
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["n.uuid", "r as root_relationship"]
Expand Down
6 changes: 2 additions & 4 deletions backend/infrahub/core/validators/relationship/peer.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,12 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
branch_filter, branch_params = self.branch.get_query_filter_path(at=self.at.to_string(), is_isolated=False)
self.params.update(branch_params)

self.params["node_kind"] = self.node_schema.kind
self.params["relationship_id"] = self.relationship_schema.identifier
self.params["allowed_peer_kinds"] = allowed_peer_kinds

# ruff: noqa: E501
query = """
MATCH (n:Node)
WHERE $node_kind IN LABELS(n)
MATCH (n:%(node_kind)s)
CALL {
WITH n
MATCH path = (root:Root)<-[rroot:IS_PART_OF]-(n)
Expand Down Expand Up @@ -85,7 +83,7 @@ async def query_init(self, db: InfrahubDatabase, **kwargs: dict[str, Any]) -> No
WITH start_node, current_peer, branch_name, current_path
WHERE all(r in relationships(current_path) WHERE r.status = "active")
AND NOT any(label IN LABELS(current_peer) WHERE label IN $allowed_peer_kinds)
""" % {"branch_filter": branch_filter}
""" % {"branch_filter": branch_filter, "node_kind": self.node_schema.kind}

self.add_to_query(query)
self.return_labels = ["start_node.uuid", "branch_name", "current_peer.uuid"]
Expand Down

0 comments on commit 3002117

Please sign in to comment.