001package gudusoft.gsqlparser.ir.semantic;
002
003import java.util.Objects;
004
005/**
006 * In-statement reference to a column. Holds the FROM-clause alias and the
007 * column name as they appear in the SQL — <i>not</i> the final physical
008 * table. Physical/provenance information lives on {@link RelationSource}'s
009 * {@link gudusoft.gsqlparser.ir.semantic.binding.RelationBinding} so that
010 * later CTE/subquery slices can describe provenance separately without
011 * mutating this shape.
012 */
013public final class ColumnRef {
014
015    private final String relationAlias;
016    private final String columnName;
017
018    public ColumnRef(String relationAlias, String columnName) {
019        if (relationAlias == null || relationAlias.isEmpty()) {
020            throw new IllegalArgumentException("relationAlias must be non-empty");
021        }
022        if (columnName == null || columnName.isEmpty()) {
023            throw new IllegalArgumentException("columnName must be non-empty");
024        }
025        this.relationAlias = relationAlias;
026        this.columnName = columnName;
027    }
028
029    public String getRelationAlias() {
030        return relationAlias;
031    }
032
033    public String getColumnName() {
034        return columnName;
035    }
036
037    @Override
038    public boolean equals(Object o) {
039        if (this == o) return true;
040        if (!(o instanceof ColumnRef)) return false;
041        ColumnRef other = (ColumnRef) o;
042        return relationAlias.equals(other.relationAlias) && columnName.equals(other.columnName);
043    }
044
045    @Override
046    public int hashCode() {
047        return Objects.hash(relationAlias, columnName);
048    }
049
050    @Override
051    public String toString() {
052        return relationAlias + "." + columnName;
053    }
054}