Skip to content

Commit 604d246

Browse files
committed
Improved query planner to use CountOp
1 parent faab43b commit 604d246

1 file changed

Lines changed: 8 additions & 16 deletions

File tree

engine/src/main/java/com/arcadedb/query/opencypher/planner/CypherExecutionPlanner.java

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,9 @@ private boolean shouldUseOptimizer() {
189189
if (match.isOptional())
190190
return false; // Not yet supported in optimizer
191191

192-
// Multiple path patterns in a single MATCH (e.g., MATCH (a:T1), (b:T2))
193-
// require Cartesian product which the optimizer doesn't support yet
194-
if (match.hasPathPatterns() && match.getPathPatterns().size() > 1)
195-
return false;
192+
// Multiple path patterns in a single MATCH (e.g., MATCH (a:X)-[:E1]->(b:Y), (a)<-[:E2]-(c:Z))
193+
// are supported when the patterns share variables (the optimizer handles them via join planning).
194+
// Disconnected patterns with no shared variables fall through to step-by-step interpretation.
196195

197196
// Check if all nodes have labels, no named path variables, and no unsupported property constraints
198197
if (match.hasPathPatterns()) {
@@ -272,18 +271,11 @@ private boolean shouldUseOptimizer() {
272271

273272
// Aggregation queries: the optimizer doesn't enforce Cypher's relationship uniqueness
274273
// constraint (each edge matched at most once per MATCH clause). Edge uniqueness is scoped
275-
// to each individual MATCH clause, NOT across clauses. So we check disjointness within
276-
// each clause independently — overlapping types across different MATCHes are fine.
277-
if (statement.getReturnClause() != null && statement.getReturnClause().hasAggregations()) {
278-
for (final MatchClause match : statement.getMatchClauses()) {
279-
if (match.hasPathPatterns()) {
280-
for (final PathPattern path : match.getPathPatterns()) {
281-
if (!allEdgeTypesDisjoint(path))
282-
return false;
283-
}
284-
}
285-
}
286-
}
274+
// to each individual MATCH clause, NOT across clauses. The CountOp detectors
275+
// (PropagateChainOp, AntiJoinChainOp, PairHashJoinOp) handle duplicate edge types
276+
// correctly — they count tuples, not distinct edges. So we allow duplicate edge types
277+
// through to the optimizer; the CountOp fast paths and the GAVFusedChainOperator
278+
// both produce correct results regardless of edge type overlap.
287279

288280
return true;
289281
}

0 commit comments

Comments
 (0)