001package gudusoft.gsqlparser.ir.semantic.joinanalysis; 002 003import java.util.ArrayList; 004import java.util.Collections; 005import java.util.List; 006 007/** 008 * An ordered list of {@link JoinEntity}s for one query block (GAP 1). 009 * Order follows the written join order; for a left-deep chain entity 010 * {@code n}'s {@code leftEndpoint} references the 011 * {@link JoinEndpointKind#JOIN_RESULT} produced by entity {@code n-1}. 012 * 013 * <p>Immutable. Introduced by join-analysis slice 162 (S1). 014 */ 015public final class JoinGraph { 016 017 /** Shared empty graph for blocks with no joins. */ 018 public static final JoinGraph EMPTY = new JoinGraph(Collections.<JoinEntity>emptyList()); 019 020 private final List<JoinEntity> joins; 021 022 public JoinGraph(List<JoinEntity> joins) { 023 this.joins = joins == null 024 ? Collections.<JoinEntity>emptyList() 025 : Collections.unmodifiableList(new ArrayList<JoinEntity>(joins)); 026 } 027 028 /** Never null; empty when the block has no joins. */ 029 public List<JoinEntity> getJoins() { 030 return joins; 031 } 032 033 public boolean isEmpty() { 034 return joins.isEmpty(); 035 } 036 037 @Override 038 public boolean equals(Object o) { 039 if (this == o) return true; 040 if (!(o instanceof JoinGraph)) return false; 041 return joins.equals(((JoinGraph) o).joins); 042 } 043 044 @Override 045 public int hashCode() { 046 return joins.hashCode(); 047 } 048 049 @Override 050 public String toString() { 051 return "JoinGraph" + joins; 052 } 053}