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}