in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/resolve/ExhaustiveSearchResolver.java [245:307]
private List<PatternGroup> expandPatternGroups(PatternGroup patternGroup) throws CompilationException {
// First pass: unify our vertex labels.
unifyVertexLabels(patternGroup);
// Second pass: collect all ambiguous graph elements.
Set<AbstractExpression> ambiguousExpressionSet = new LinkedHashSet<>();
for (AbstractExpression originalExpr : patternGroup) {
if (originalExpr instanceof VertexPatternExpr) {
VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) originalExpr;
if (vertexPatternExpr.getLabels().size() != 1
|| vertexPatternExpr.getLabels().iterator().next().isNegated()) {
ambiguousExpressionSet.add(vertexPatternExpr);
}
} else { // originalExpr instanceof EdgePatternExpr
EdgePatternExpr edgePatternExpr = (EdgePatternExpr) originalExpr;
EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
if (edgeDescriptor.getEdgeLabels().size() != 1
|| edgeDescriptor.getEdgeLabels().iterator().next().isNegated()
|| edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.PATH
|| edgeDescriptor.getEdgeDirection() == EdgeDirection.UNDIRECTED) {
ambiguousExpressionSet.add(edgePatternExpr);
}
}
}
if (ambiguousExpressionSet.isEmpty()) {
// Our list must always be mutable.
return new ArrayList<>(List.of(patternGroup));
}
// Third pass: expand the ambiguous expressions.
Deque<PatternGroup> redPatternGroups = new ArrayDeque<>();
Deque<PatternGroup> blackPatternGroups = new ArrayDeque<>();
redPatternGroups.add(patternGroup);
for (AbstractExpression ambiguousExpression : ambiguousExpressionSet) {
// Determine our read and write pattern groups.
Deque<PatternGroup> readPatternGroups, writePatternGroups;
if (redPatternGroups.isEmpty()) {
readPatternGroups = blackPatternGroups;
writePatternGroups = redPatternGroups;
} else {
readPatternGroups = redPatternGroups;
writePatternGroups = blackPatternGroups;
}
// Expand our vertex / edge patterns.
if (ambiguousExpression instanceof VertexPatternExpr) {
VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) ambiguousExpression;
expandVertexPattern(vertexPatternExpr, readPatternGroups, writePatternGroups);
} else { // ambiguousExpression instance EdgePatternExpr
EdgePatternExpr edgePatternExpr = (EdgePatternExpr) ambiguousExpression;
if (edgePatternExpr.getEdgeDescriptor().getPatternType() == EdgeDescriptor.PatternType.EDGE) {
expandEdgePattern(edgePatternExpr, readPatternGroups, writePatternGroups);
} else { // edgePatternExpr.getEdgeDescriptor().getPatternType() == EdgeDescriptor.PatternType.PATH
expandPathPattern(edgePatternExpr, readPatternGroups, writePatternGroups);
}
}
}
return new ArrayList<>(redPatternGroups.isEmpty() ? blackPatternGroups : redPatternGroups);
}