001package gudusoft.gsqlparser.resolver2.expansion;
002
003import gudusoft.gsqlparser.nodes.TResultColumn;
004import gudusoft.gsqlparser.resolver2.model.ColumnSource;
005
006/**
007 * Represents a column expanded from a star (*) column.
008 *
009 * <p>When SELECT * is expanded, each column from the source tables
010 * becomes an ExpandedColumn. This class tracks:
011 * - The column name
012 * - The original star column it came from
013 * - The source (which table/namespace)
014 * - Whether to include table qualifier
015 *
016 * <p>Example:
017 * <pre>
018 * SELECT * FROM employees
019 * -- Expands to:
020 * ExpandedColumn("id", employees.id, *, true)
021 * ExpandedColumn("name", employees.name, *, true)
022 * ExpandedColumn("salary", employees.salary, *, true)
023 * </pre>
024 */
025public class ExpandedColumn {
026
027    /** The column name */
028    private final String columnName;
029
030    /** The source of this column (which table/namespace) */
031    private final ColumnSource columnSource;
032
033    /** The original star column this was expanded from */
034    private final TResultColumn originalStarColumn;
035
036    /** The table qualifier (if qualified star like t1.*) */
037    private final String tableQualifier;
038
039    /** Whether to include table qualifier in the expanded name */
040    private final boolean includeQualifier;
041
042    /**
043     * Create an expanded column from an unqualified star.
044     *
045     * @param columnName the column name
046     * @param columnSource the column source
047     * @param originalStarColumn the original star column
048     * @param includeQualifier whether to include table qualifier
049     */
050    public ExpandedColumn(
051            String columnName,
052            ColumnSource columnSource,
053            TResultColumn originalStarColumn,
054            boolean includeQualifier) {
055        this.columnName = columnName;
056        this.columnSource = columnSource;
057        this.originalStarColumn = originalStarColumn;
058        this.tableQualifier = null;
059        this.includeQualifier = includeQualifier;
060    }
061
062    /**
063     * Create an expanded column from a qualified star (e.g., t1.*).
064     *
065     * @param columnName the column name
066     * @param columnSource the column source
067     * @param originalStarColumn the original star column
068     * @param tableQualifier the table qualifier (e.g., "t1")
069     * @param includeQualifier whether to include table qualifier
070     */
071    public ExpandedColumn(
072            String columnName,
073            ColumnSource columnSource,
074            TResultColumn originalStarColumn,
075            String tableQualifier,
076            boolean includeQualifier) {
077        this.columnName = columnName;
078        this.columnSource = columnSource;
079        this.originalStarColumn = originalStarColumn;
080        this.tableQualifier = tableQualifier;
081        this.includeQualifier = includeQualifier;
082    }
083
084    public String getColumnName() {
085        return columnName;
086    }
087
088    public ColumnSource getColumnSource() {
089        return columnSource;
090    }
091
092    public TResultColumn getOriginalStarColumn() {
093        return originalStarColumn;
094    }
095
096    public String getTableQualifier() {
097        return tableQualifier;
098    }
099
100    public boolean isQualified() {
101        return tableQualifier != null;
102    }
103
104    /**
105     * Get the fully qualified column name (e.g., "t1.id").
106     *
107     * @return qualified name if qualifier is set, otherwise just column name
108     */
109    public String getQualifiedName() {
110        if (includeQualifier && tableQualifier != null && !tableQualifier.isEmpty()) {
111            return tableQualifier + "." + columnName;
112        } else if (includeQualifier && columnSource != null &&
113                   columnSource.getFinalTable() != null) {
114            String tableName = columnSource.getFinalTable().getAliasName();
115            if (tableName == null || tableName.isEmpty()) {
116                tableName = columnSource.getFinalTable().getName();
117            }
118            if (tableName != null && !tableName.isEmpty()) {
119                return tableName + "." + columnName;
120            }
121            // Try getting table name from TTable.getTableName()
122            gudusoft.gsqlparser.nodes.TObjectName tableNameObj = columnSource.getFinalTable().getTableName();
123            if (tableNameObj != null) {
124                String tableStr = tableNameObj.getTableString();
125                if (tableStr != null && !tableStr.isEmpty()) {
126                    return tableStr + "." + columnName;
127                }
128            }
129        }
130        return columnName;
131    }
132
133    /**
134     * Get the column name without qualifier.
135     *
136     * @return unqualified column name
137     */
138    public String getUnqualifiedName() {
139        return columnName;
140    }
141
142    /**
143     * Get the confidence score for this expanded column.
144     *
145     * @return confidence [0.0, 1.0], or 1.0 if no source available
146     */
147    public double getConfidence() {
148        return columnSource != null ? columnSource.getConfidence() : 1.0;
149    }
150
151    @Override
152    public String toString() {
153        return getQualifiedName();
154    }
155
156    @Override
157    public boolean equals(Object obj) {
158        if (this == obj) return true;
159        if (!(obj instanceof ExpandedColumn)) return false;
160        ExpandedColumn other = (ExpandedColumn) obj;
161        return getQualifiedName().equals(other.getQualifiedName());
162    }
163
164    @Override
165    public int hashCode() {
166        return getQualifiedName().hashCode();
167    }
168}