in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/resolve/ExhaustiveSearchResolver.java [407:501]
public void resolve(PatternGroup patternGroup) throws CompilationException {
// Populate our vertex / edge expression map.
for (VertexPatternExpr vertexPatternExpr : patternGroup.getVertexPatternSet()) {
VariableExpr vertexVariable = vertexPatternExpr.getVariableExpr();
canonicalExpressionsMap.putIfAbsent(vertexVariable, new ArrayList<>());
originalExpressionMap.put(vertexVariable, vertexPatternExpr);
}
for (EdgePatternExpr edgePatternExpr : patternGroup.getEdgePatternSet()) {
EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
VariableExpr edgeVariable = edgeDescriptor.getVariableExpr();
canonicalExpressionsMap.putIfAbsent(edgeVariable, new ArrayList<>());
originalExpressionMap.put(edgeVariable, edgePatternExpr);
}
// Expand the given pattern group and then prune the invalid pattern groups.
List<PatternGroup> validPatternGroups = pruneInvalidPatternGroups(expandPatternGroups(patternGroup));
for (PatternGroup validPatternGroup : validPatternGroups) {
for (AbstractExpression canonicalExpr : validPatternGroup) {
if (canonicalExpr instanceof VertexPatternExpr) {
VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) canonicalExpr;
VariableExpr vertexVariable = vertexPatternExpr.getVariableExpr();
canonicalExpressionsMap.get(vertexVariable).add(deepCopyVisitor.visit(vertexPatternExpr, null));
} else { // canonicalExpr instanceof EdgePatternExpr
EdgePatternExpr edgePatternExpr = (EdgePatternExpr) canonicalExpr;
EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
VariableExpr edgeVariable = edgeDescriptor.getVariableExpr();
canonicalExpressionsMap.get(edgeVariable).add(deepCopyVisitor.visit(edgePatternExpr, null));
// We must also visit the vertices of our edge (to find internal vertices).
VertexPatternExpr leftVertex = edgePatternExpr.getLeftVertex();
VertexPatternExpr rightVertex = edgePatternExpr.getRightVertex();
VariableExpr leftVariable = leftVertex.getVariableExpr();
VariableExpr rightVariable = rightVertex.getVariableExpr();
canonicalExpressionsMap.putIfAbsent(leftVariable, new ArrayList<>());
canonicalExpressionsMap.putIfAbsent(rightVariable, new ArrayList<>());
canonicalExpressionsMap.get(leftVariable).add(deepCopyVisitor.visit(leftVertex, null));
canonicalExpressionsMap.get(rightVariable).add(deepCopyVisitor.visit(rightVertex, null));
}
}
}
// Propagate the facts of our expression map to the original expressions.
final Function<VariableExpr, Stream<VertexPatternExpr>> canonicalVertexStreamProvider =
v -> canonicalExpressionsMap.get(v).stream().map(t -> (VertexPatternExpr) t);
final Function<VariableExpr, Stream<EdgePatternExpr>> canonicalEdgeStreamProvider =
v -> canonicalExpressionsMap.get(v).stream().map(t -> (EdgePatternExpr) t);
for (Map.Entry<VariableExpr, AbstractExpression> mapEntry : originalExpressionMap.entrySet()) {
if (canonicalExpressionsMap.get(mapEntry.getKey()).isEmpty()) {
SourceLocation sourceLocation = mapEntry.getValue().getSourceLocation();
throw new CompilationException(ErrorCode.COMPILATION_ERROR, sourceLocation,
"Encountered graph element that does not conform the queried graph schema!");
}
if (mapEntry.getValue() instanceof VertexPatternExpr) {
VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) mapEntry.getValue();
vertexPatternExpr.getLabels().clear();
Stream<VertexPatternExpr> vertexStream = canonicalVertexStreamProvider.apply(mapEntry.getKey());
vertexStream.forEach(v -> vertexPatternExpr.getLabels().addAll(v.getLabels()));
} else { // originalExpr instanceof EdgePatternExpr
EdgePatternExpr edgePatternExpr = (EdgePatternExpr) mapEntry.getValue();
EdgeDescriptor edgeDescriptor = edgePatternExpr.getEdgeDescriptor();
Integer maximumHopLength = edgeDescriptor.getMaximumHops();
// Update our edge labels.
edgeDescriptor.getEdgeLabels().clear();
Stream<EdgePatternExpr> edgeStream = canonicalEdgeStreamProvider.apply(mapEntry.getKey());
edgeStream.forEach(e -> edgeDescriptor.getEdgeLabels().addAll(e.getEdgeDescriptor().getEdgeLabels()));
// Update our direction, if we have resolved it.
Set<EdgeDirection> resolvedDirections = canonicalEdgeStreamProvider.apply(mapEntry.getKey())
.map(e -> e.getEdgeDescriptor().getEdgeDirection()).collect(Collectors.toSet());
if (resolvedDirections.size() == 1) {
edgeDescriptor.setEdgeDirection(resolvedDirections.iterator().next());
}
// Update the vertex references of our edge.
VariableExpr leftVariable = edgePatternExpr.getLeftVertex().getVariableExpr();
VariableExpr rightVariable = edgePatternExpr.getRightVertex().getVariableExpr();
edgePatternExpr.getLeftVertex().getLabels().clear();
edgePatternExpr.getRightVertex().getLabels().clear();
Stream<VertexPatternExpr> leftStream = canonicalVertexStreamProvider.apply(leftVariable);
Stream<VertexPatternExpr> rightStream = canonicalVertexStreamProvider.apply(rightVariable);
leftStream.forEach(v -> edgePatternExpr.getLeftVertex().getLabels().addAll(v.getLabels()));
rightStream.forEach(v -> edgePatternExpr.getRightVertex().getLabels().addAll(v.getLabels()));
if (edgeDescriptor.getPatternType() == EdgeDescriptor.PatternType.PATH && maximumHopLength != 1) {
VariableExpr internalVariable = edgePatternExpr.getInternalVertex().getVariableExpr();
edgePatternExpr.getInternalVertex().getLabels().clear();
Stream<VertexPatternExpr> internalStream = canonicalVertexStreamProvider.apply(internalVariable);
internalStream.forEach(v -> edgePatternExpr.getInternalVertex().getLabels().addAll(v.getLabels()));
}
}
}
}