Skip to content

Commit 0a79847

Browse files
committed
test(cypher): harden two-MATCH reentry varlen wrong-row coverage (#1001)
1 parent f8449bc commit 0a79847

1 file changed

Lines changed: 61 additions & 7 deletions

File tree

graphistry/tests/compute/gfql/cypher/test_lowering.py

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5168,24 +5168,78 @@ def test_string_cypher_supports_unused_named_path_alias_for_endpoint_projection(
51685168

51695169

51705170
@pytest.mark.parametrize(
5171-
"query",
5171+
"query,expected_names",
51725172
[
5173-
"MATCH (a:A) MATCH (a)-[:LIKES*1]->()-[:LIKES]->(c) RETURN c.name",
5174-
"MATCH (a:A) MATCH (a)-[:LIKES*2]->()-[:LIKES]->(c) RETURN c.name",
5175-
"MATCH (a:A) MATCH (a)-[:LIKES]->()-[:LIKES*3]->(c) RETURN c.name",
5176-
"MATCH (a:A) MATCH (a)<-[:LIKES]-()-[:LIKES*3]->(c) RETURN c.name",
5173+
("MATCH (a:A) MATCH (a)-[:LIKES*1]->()-[:LIKES]->(c) RETURN c.name AS name", ["C"]),
5174+
("MATCH (a:A) MATCH (a)-[:LIKES*2]->()-[:LIKES]->(c) RETURN c.name AS name", ["D"]),
5175+
("MATCH (a:A) MATCH (a)-[:LIKES]->()-[:LIKES*3]->(c) RETURN c.name AS name", []),
5176+
("MATCH (a:A) MATCH (a)<-[:LIKES]-()-[:LIKES*3]->(c) RETURN c.name AS name", []),
51775177
],
51785178
)
51795179
def test_string_cypher_accepts_nonterminal_variable_length_relationship_patterns(
51805180
query: str,
5181+
expected_names: List[str],
51815182
) -> None:
5182-
"""Connected patterns with non-terminal variable-length relationships are now supported."""
5183+
"""Connected reentry forms with varlen rels return expected rows."""
51835184
graph = _mk_graph(
51845185
pd.DataFrame({"id": ["a", "b", "c", "d"], "label__A": [True, False, False, False], "name": ["A", "B", "C", "D"]}),
51855186
pd.DataFrame({"s": ["a", "b", "c"], "d": ["b", "c", "d"], "type": ["LIKES", "LIKES", "LIKES"]}),
51865187
)
51875188
result = graph.gfql(query)
5188-
assert result._nodes is not None
5189+
got_names = _to_pandas_df(result._nodes)["name"].tolist()
5190+
assert got_names == expected_names
5191+
5192+
5193+
def test_string_cypher_two_match_reentry_varlen_forward_matches_connected_shape() -> None:
5194+
"""Regression for #1001: split MATCH form should match connected form rows."""
5195+
nodes = []
5196+
edges = []
5197+
for level in range(5):
5198+
for idx in range(2 ** level):
5199+
node_id = f"n{level}_{idx}"
5200+
nodes.append({"id": node_id, "label__A": level == 0, "name": node_id})
5201+
if level > 0:
5202+
parent = f"n{level - 1}_{idx // 2}"
5203+
edges.append({"s": parent, "d": node_id, "type": "LIKES"})
5204+
5205+
graph = _mk_graph(pd.DataFrame(nodes), pd.DataFrame(edges))
5206+
split_query = "MATCH (a:A) MATCH (a)-[:LIKES]->()-[:LIKES*3]->(c) RETURN c.name AS name ORDER BY name"
5207+
connected_query = "MATCH (a:A)-[:LIKES]->()-[:LIKES*3]->(c) RETURN c.name AS name ORDER BY name"
5208+
5209+
split_rows = graph.gfql(split_query)._nodes.to_dict(orient="records")
5210+
connected_rows = graph.gfql(connected_query)._nodes.to_dict(orient="records")
5211+
5212+
assert split_rows == connected_rows
5213+
assert split_rows == [{"name": name} for name in sorted(f"n4_{i}" for i in range(16))]
5214+
5215+
5216+
def test_string_cypher_two_match_reentry_varlen_reverse_matches_connected_shape() -> None:
5217+
"""Regression for #1001 reverse direction shape from TCK-style query."""
5218+
graph = _mk_graph(
5219+
pd.DataFrame(
5220+
{
5221+
"id": ["a", "x", "y1", "y2", "c1", "c2"],
5222+
"label__A": [True, False, False, False, False, False],
5223+
"name": ["a", "x", "y1", "y2", "c1", "c2"],
5224+
}
5225+
),
5226+
pd.DataFrame(
5227+
{
5228+
"s": ["x", "x", "y1", "y2", "y2"],
5229+
"d": ["a", "y1", "y2", "c1", "c2"],
5230+
"type": ["LIKES", "LIKES", "LIKES", "LIKES", "LIKES"],
5231+
}
5232+
),
5233+
)
5234+
5235+
split_query = "MATCH (a:A) MATCH (a)<-[:LIKES]-()-[:LIKES*3]->(c) RETURN c.name AS name ORDER BY name"
5236+
connected_query = "MATCH (a:A)<-[:LIKES]-()-[:LIKES*3]->(c) RETURN c.name AS name ORDER BY name"
5237+
5238+
split_rows = graph.gfql(split_query)._nodes.to_dict(orient="records")
5239+
connected_rows = graph.gfql(connected_query)._nodes.to_dict(orient="records")
5240+
5241+
assert split_rows == connected_rows
5242+
assert split_rows == [{"name": "c1"}, {"name": "c2"}]
51895243

51905244

51915245
def _mk_chain_graph():

0 commit comments

Comments
 (0)