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}