// initialize a relation set
HashMap<String, RelationNode> relationMap = Maps.newHashMap();
// Remain relation set to be joined
Set<String> remainRelNames = new HashSet<String>();
for (RelationNode relation : block.getRelations()) {
RelationNode rel = relation;
relationMap.put(rel.getCanonicalName(), rel);
remainRelNames.add(rel.getCanonicalName());
}
// A set of already-joined relations
Set<String> alreadyJoinedRelNames = new HashSet<String>();
// Get candidates from all relations to be joined
List<RelationNode> candidates = getSmallerRelations(relationMap, remainRelNames);
LogicalNode lastOne = candidates.get(0); // Get the first candidate relation (i.e., smallest)
remainRelNames.remove(((RelationNode)lastOne).getCanonicalName()); // Remove the first candidate relation
// Add the first candidate to the set of joined relations
alreadyJoinedRelNames.add(((RelationNode)lastOne).getCanonicalName());
List<CandidateJoinNode> orderedJoins;
CandidateJoinNode chosen = null;
while(true) {
// Get a set of relations that can be joined to the composite relation.
Set<CandidateJoin> joinCandidates = new HashSet<CandidateJoin>();
for (String currentRel : alreadyJoinedRelNames) {
// find all relations that can be joined to this relation
Collection<JoinEdge> edges = joinGraph.getJoinsWith(currentRel);
if (edges.size() > 0) { // if there are available join quals
for (JoinEdge edge : edges) {
if (alreadyJoinedRelNames.contains(edge.getLeftRelation())
&& currentRel.contains(edge.getRightRelation())) { // if two relations are already joined
continue;
}
if (!alreadyJoinedRelNames.contains(edge.getLeftRelation())) {
joinCandidates.add(new CandidateJoin(edge.getLeftRelation(), edge)) ;
}
if (!alreadyJoinedRelNames.contains(edge.getRightRelation())) {
joinCandidates.add(new CandidateJoin(edge.getRightRelation(), edge));
}
}
} else {
for (RelationNode rel : block.getRelations()) {
// Add all relations except for itself to join candidates
if (!currentRel.equals(rel.getCanonicalName())) {
joinCandidates.add(new CandidateJoin(rel.getCanonicalName(),
new JoinEdge(JoinType.CROSS, currentRel, rel.getCanonicalName())));
}
}
}
}