in asterix-graphix/src/main/java/org/apache/asterix/graphix/lang/rewrite/resolve/ExhaustiveSearchResolver.java [329:404]
private void unifyVertexLabels(PatternGroup patternGroup) {
// Pass #1: Collect all vertex variables and their labels.
Map<VariableExpr, Set<ElementLabel>> vertexVariableMap = new HashMap<>();
for (AbstractExpression abstractExpression : patternGroup) {
if (abstractExpression instanceof VertexPatternExpr) {
VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) abstractExpression;
VariableExpr vertexVariable = vertexPatternExpr.getVariableExpr();
vertexVariableMap.putIfAbsent(vertexVariable, new HashSet<>());
vertexVariableMap.get(vertexVariable).addAll(vertexPatternExpr.getLabels());
SubqueryVertexJoinAnnotation hint = vertexPatternExpr.findHint(SubqueryVertexJoinAnnotation.class);
if (hint != null) {
VariableExpr sourceVertexVariable = hint.getSourceVertexVariable();
vertexVariableMap.putIfAbsent(sourceVertexVariable, new HashSet<>());
vertexVariableMap.get(sourceVertexVariable).addAll(vertexPatternExpr.getLabels());
}
} else { // abstractExpression instanceof EdgePatternExpr
EdgePatternExpr edgePatternExpr = (EdgePatternExpr) abstractExpression;
VertexPatternExpr leftVertexExpr = edgePatternExpr.getLeftVertex();
VertexPatternExpr rightVertexExpr = edgePatternExpr.getRightVertex();
VariableExpr leftVariable = leftVertexExpr.getVariableExpr();
VariableExpr rightVariable = rightVertexExpr.getVariableExpr();
// Visit the vertices of our edges and their labels as well.
vertexVariableMap.putIfAbsent(leftVariable, new HashSet<>());
vertexVariableMap.putIfAbsent(rightVariable, new HashSet<>());
vertexVariableMap.get(leftVariable).addAll(leftVertexExpr.getLabels());
vertexVariableMap.get(rightVariable).addAll(rightVertexExpr.getLabels());
SubqueryVertexJoinAnnotation leftHint = leftVertexExpr.findHint(SubqueryVertexJoinAnnotation.class);
SubqueryVertexJoinAnnotation rightHint = rightVertexExpr.findHint(SubqueryVertexJoinAnnotation.class);
if (leftHint != null) {
VariableExpr sourceVertexVariable = leftHint.getSourceVertexVariable();
vertexVariableMap.putIfAbsent(sourceVertexVariable, new HashSet<>());
vertexVariableMap.get(sourceVertexVariable).addAll(leftVertexExpr.getLabels());
}
if (rightHint != null) {
VariableExpr sourceVertexVariable = rightHint.getSourceVertexVariable();
vertexVariableMap.putIfAbsent(sourceVertexVariable, new HashSet<>());
vertexVariableMap.get(sourceVertexVariable).addAll(rightVertexExpr.getLabels());
}
}
}
// Pass #2: Copy the vertex label sets to all vertices of the same variable.
for (AbstractExpression abstractExpression : patternGroup) {
if (abstractExpression instanceof VertexPatternExpr) {
VertexPatternExpr vertexPatternExpr = (VertexPatternExpr) abstractExpression;
VariableExpr vertexVariable = vertexPatternExpr.getVariableExpr();
vertexPatternExpr.getLabels().addAll(vertexVariableMap.get(vertexVariable));
SubqueryVertexJoinAnnotation hint = vertexPatternExpr.findHint(SubqueryVertexJoinAnnotation.class);
if (hint != null) {
vertexPatternExpr.getLabels().addAll(vertexVariableMap.get(hint.getSourceVertexVariable()));
}
} else { // abstractExpression instanceof EdgePatternExpr
EdgePatternExpr edgePatternExpr = (EdgePatternExpr) abstractExpression;
VertexPatternExpr leftVertexExpr = edgePatternExpr.getLeftVertex();
VertexPatternExpr rightVertexExpr = edgePatternExpr.getRightVertex();
// Visit the vertices of our edge as well.
VariableExpr leftVariable = leftVertexExpr.getVariableExpr();
VariableExpr rightVariable = rightVertexExpr.getVariableExpr();
leftVertexExpr.getLabels().addAll(vertexVariableMap.get(leftVariable));
rightVertexExpr.getLabels().addAll(vertexVariableMap.get(rightVariable));
SubqueryVertexJoinAnnotation leftHint = leftVertexExpr.findHint(SubqueryVertexJoinAnnotation.class);
SubqueryVertexJoinAnnotation rightHint = rightVertexExpr.findHint(SubqueryVertexJoinAnnotation.class);
if (leftHint != null) {
leftVertexExpr.getLabels().addAll(vertexVariableMap.get(leftHint.getSourceVertexVariable()));
}
if (rightHint != null) {
rightVertexExpr.getLabels().addAll(vertexVariableMap.get(rightHint.getSourceVertexVariable()));
}
}
}
}