Skip to content

Commit 7b3101e

Browse files
committed
fix(cypher): restore cartesian where pattern OR/XOR fail-fast (#1391)
1 parent bbe469f commit 7b3101e

2 files changed

Lines changed: 22 additions & 0 deletions

File tree

graphistry/compute/gfql/cypher/lowering.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6231,6 +6231,9 @@ def lower_match_query(
62316231
row_where: Optional[ExpressionText] = None
62326232
row_where_predicates: List[str] = list(dynamic_row_where_predicates)
62336233
if query.where is not None:
6234+
where_expr_upper = boolean_expr_to_text(query.where.expr_tree).upper() if query.where.expr_tree is not None else ""
6235+
if _cartesian_node_only_patterns(merged_match) is not None and query.where.expr_tree is not None and _where_expr_tree_pattern_predicates(query.where.expr_tree) and (" OR " in where_expr_upper or " XOR " in where_expr_upper):
6236+
raise _unsupported_at_span("Cypher WHERE pattern predicates mixed with OR/XOR are not yet supported for cartesian MATCH patterns", field="where", value=where_expr_upper, span=query.where.span)
62346237
where_expr, where_pattern_row_filters = _rewrite_where_expr_patterns_to_markers(
62356238
where=query.where,
62366239
alias_targets=alias_targets,

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1555,6 +1555,25 @@ def test_string_cypher_supports_cartesian_node_only_row_filter_between_aliases()
15551555
]
15561556

15571557

1558+
def test_string_cypher_rejects_cartesian_where_pattern_predicates_mixed_with_or() -> None:
1559+
graph = _mk_graph(
1560+
pd.DataFrame(
1561+
{
1562+
"id": [0, 1, 2],
1563+
"label__TheLabel": [False, True, False],
1564+
"label__MissingLabel": [False, False, False],
1565+
}
1566+
),
1567+
pd.DataFrame({"s": [0, 0, 1], "d": [1, 2, 2], "type": ["T", "X", "T"]}),
1568+
)
1569+
with pytest.raises(GFQLValidationError, match="OR/XOR"):
1570+
graph.gfql(
1571+
"MATCH (a), (b) "
1572+
"WHERE a.id = 0 AND (a)-[:T]->(b:TheLabel) OR (a)-[:T*]->(b:MissingLabel) "
1573+
"RETURN DISTINCT b"
1574+
)
1575+
1576+
15581577
def test_string_cypher_supports_cartesian_dynamic_pattern_property_projection() -> None:
15591578
graph = _mk_cartesian_dynamic_pattern_graph()
15601579

0 commit comments

Comments
 (0)