001package gudusoft.gsqlparser.nodes.teradata;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.*;
005
006public class TTDUnpivot extends TParseTreeNode {
007
008    private TFromTable onTableRef;
009    private TConstantList valueColumnsInString;
010    private TConstantList unpivotColumnsInString;
011    private TConstantList columnListInString;
012    private TConstantList columnAliasListInString;
013
014    private TTable unPivotTable;
015
016    // The TTable representing the TD_UNPIVOT output (where VALUE_COLUMNS and UNPIVOT_COLUMN are linked)
017    private TTable tdUnpivotOutputTable;
018
019    private TObjectNameList valueColumns = new TObjectNameList();
020    private TObjectNameList unpivotColumns = new TObjectNameList();
021    private TObjectNameList columnList = new TObjectNameList();
022
023    public TObjectNameList getColumnList() {
024        return columnList;
025    }
026
027    public TObjectNameList getUnpivotColumns() {
028        return unpivotColumns;
029    }
030
031    public TObjectNameList getValueColumns() {
032        return valueColumns;
033    }
034
035    public TTable getUnPivotTable() {
036        return unPivotTable;
037    }
038
039    /**
040     * Set the TD_UNPIVOT output table. This is the TTable that represents the TD_UNPIVOT
041     * table function output. VALUE_COLUMNS and UNPIVOT_COLUMN are linked to this table.
042     */
043    public void setTdUnpivotOutputTable(TTable table) {
044        this.tdUnpivotOutputTable = table;
045    }
046
047    public TTable getTdUnpivotOutputTable() {
048        return tdUnpivotOutputTable;
049    }
050
051    public TConstantList getColumnAliasListInString() {
052        return columnAliasListInString;
053    }
054
055    public TConstantList getColumnListInString() {
056        return columnListInString;
057    }
058
059    public TConstantList getUnpivotColumnsInString() {
060        return unpivotColumnsInString;
061    }
062
063    public TConstantList getValueColumnsInString() {
064        return valueColumnsInString;
065    }
066
067    /**
068     * Strip leading and trailing single quotes from a column name string.
069     * In TD_UNPIVOT, column names are specified as string literals ('column_name'),
070     * but when resolved they should be treated as identifiers without quotes.
071     */
072    private String stripQuotes(String name) {
073        if (name != null && name.length() >= 2 && name.startsWith("'") && name.endsWith("'")) {
074            return name.substring(1, name.length() - 1);
075        }
076        return name;
077    }
078
079    /**
080     * Create a TObjectName from a constant, stripping single quotes from the column name.
081     */
082    private TObjectName createColumnFromConstant(TConstant c) {
083        TSourceToken token = c.getValueToken();
084        String originalName = token.toString();
085        String strippedName = stripQuotes(originalName);
086
087        // Create a new source token with the stripped name for display purposes
088        TSourceToken newToken = new TSourceToken(strippedName);
089        newToken.lineNo = token.lineNo;
090        newToken.columnNo = token.columnNo;
091        newToken.offset = token.offset;
092
093        return TObjectName.createObjectName(EDbVendor.dbvteradata, EDbObjectType.column, newToken);
094    }
095
096    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
097        unPivotTable = psql.analyzeFromTable(onTableRef,true);
098        TTable refTable = unPivotTable;
099        if (unPivotTable.getTableType() == ETableSource.subquery){
100            refTable = unPivotTable.getSubquery().getTables().getTable(0);
101        }
102
103        // Determine the output table for VALUE_COLUMNS and UNPIVOT_COLUMN
104        // These are output columns of the TD_UNPIVOT function, not columns from the source table
105        TTable outputTable = (tdUnpivotOutputTable != null) ? tdUnpivotOutputTable : refTable;
106
107        // VALUE_COLUMNS: These are the output value columns of TD_UNPIVOT
108        // They should be linked to the TD_UNPIVOT output table
109        for(int i=0;i<valueColumnsInString.size();i++){
110            TConstant c = valueColumnsInString.getConstant(i);
111            TObjectName nc = createColumnFromConstant(c);
112            valueColumns.addObjectName(nc);
113            outputTable.getLinkedColumns().addObjectName(nc);
114            nc.setSourceTable(outputTable);
115        }
116
117        // UNPIVOT_COLUMN: This is the output "label" column of TD_UNPIVOT (contains original column names)
118        // It should be linked to the TD_UNPIVOT output table
119        for(int i=0;i<unpivotColumnsInString.size();i++){
120            TConstant c = unpivotColumnsInString.getConstant(i);
121            TObjectName nc = createColumnFromConstant(c);
122            unpivotColumns.addObjectName(nc);
123            outputTable.getLinkedColumns().addObjectName(nc);
124            nc.setSourceTable(outputTable);
125        }
126
127        // COLUMN_LIST: These are the source columns being unpivoted
128        // They should be linked to the source table (refTable)
129        for(int i=0;i<columnListInString.size();i++){
130            TConstant c = columnListInString.getConstant(i);
131            TObjectName nc = createColumnFromConstant(c);
132            columnList.addObjectName(nc);
133            refTable.getLinkedColumns().addObjectName(nc);
134            nc.setSourceTable(refTable);
135        }
136    }
137
138    public void init(Object arg1,Object arg2,Object arg3,Object arg4){
139        onTableRef = (TFromTable)arg1;
140        valueColumnsInString = (TConstantList)arg2;
141        unpivotColumnsInString = (TConstantList)arg3;
142        columnListInString = (TConstantList)arg4;
143    }
144
145    public void init(Object arg1,Object arg2,Object arg3,Object arg4,Object arg5){
146        init(arg1,arg2,arg3,arg4);
147        columnAliasListInString = (TConstantList)arg5;
148    }
149
150    public void accept(TParseTreeVisitor v){
151        v.preVisit(this);
152        v.postVisit(this);
153    }
154
155    public void acceptChildren(TParseTreeVisitor v){
156        v.preVisit(this);
157        v.postVisit(this);
158    }
159}