Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for using partial_match queries with array variables #4201

Merged
merged 1 commit into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions backend/infrahub/core/query/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -1055,9 +1055,16 @@ def _add_final_filter(self, field_attribute_requirements: list[FieldAttributeReq
var_name = f"final_attr_value{far.index}"
self.params[var_name] = far.field_attr_comparison_value
if self.partial_match:
where_parts.append(
f"toLower(toString({far.final_value_query_variable})) CONTAINS toLower(toString(${var_name}))"
)
if isinstance(far.field_attr_comparison_value, list):
# If the any filter is an array/list
var_array = f"{var_name}_array"
where_parts.append(
f"any({var_array} IN ${var_name} WHERE toLower(toString({far.final_value_query_variable})) CONTAINS toLower({var_array}))"
)
else:
where_parts.append(
f"toLower(toString({far.final_value_query_variable})) CONTAINS toLower(toString(${var_name}))"
)
continue

where_parts.append(f"{far.final_value_query_variable} {far.comparison_operator} ${var_name}")
Expand Down
41 changes: 41 additions & 0 deletions backend/tests/unit/graphql/test_graphql_partial_match.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,44 @@ async def test_query_filter_relationships_with_generic_filter_mutliple_partial_m
assert result.data
assert len(result.data["TestCar"]["edges"]) == 1
assert result.data["TestCar"]["edges"][0]["node"]["id"] == smolt_car.id


async def test_query_filter_local_attrs_partial_match_values(
db: InfrahubDatabase, default_branch: Branch, criticality_schema
) -> None:
"""Ensure that query partial_match filtering works when using arrays/lists as part of the query input."""
obj1 = await Node.init(db=db, schema=criticality_schema)
await obj1.new(db=db, name="red", level=1)
await obj1.save(db=db)
obj2 = await Node.init(db=db, schema=criticality_schema)
await obj2.new(db=db, name="green", level=2)
await obj2.save(db=db)
obj3 = await Node.init(db=db, schema=criticality_schema)
await obj3.new(db=db, name="blue", level=3)
await obj3.save(db=db)
obj4 = await Node.init(db=db, schema=criticality_schema)
await obj4.new(db=db, name="grey", level=4)
await obj4.save(db=db)

query = """
query {
TestCriticality(name__values: ["red", "green", "grey"], any__value: "gr", partial_match: true) {
edges {
node {
name {
value
}
}
}
}
}
"""

result = await graphql_query(query=query, db=db, branch=default_branch)

assert result.errors is None
assert result.data
assert len(result.data["TestCriticality"]["edges"]) == 2
assert ["green", "grey"] == sorted(
[node["node"]["name"]["value"] for node in result.data["TestCriticality"]["edges"]]
)
Loading