001package gudusoft.gsqlparser.nodes.redshift;
002
003import gudusoft.gsqlparser.EDbVendor;
004import gudusoft.gsqlparser.nodes.TObjectNameList;
005import gudusoft.gsqlparser.nodes.TParseTreeNode;
006import gudusoft.gsqlparser.nodes.TObjectName;
007import gudusoft.gsqlparser.nodes.TParseTreeVisitor;
008
009import java.util.ArrayList;
010import java.util.List;
011
012/**
013 * Represents the table_attributes for Redshift materialized views
014 * Based on: https://docs.aws.amazon.com/redshift/latest/dg/materialized-view-create-sql-command.html
015 */ 
016public class TRedshiftTableAttributes extends TParseTreeNode {
017
018    /**
019     * Possible distribution styles for Redshift materialized views
020     */
021    public enum EDistStyle {
022        EVEN, // Distribute data evenly across the nodes (default)
023        ALL,  // Distribute entire copy of data to each node
024        KEY   // Distribute according to the values in DISTKEY column
025    }
026    
027    // The type of table attribute (distribution style, distribution key, sort key)
028    private ETableAttributeType attributeType = ETableAttributeType.ttUnknown;
029    
030    // Distribution style
031    private EDistStyle distStyle = EDistStyle.EVEN; // Default is EVEN
032    
033    // Distribution key column identifier
034    private TObjectName distKey;
035    
036    // Sort key columns
037    private TObjectNameList sortKeyColumns ;
038    
039    /**
040     * Default constructor
041     */
042    public TRedshiftTableAttributes() {
043        this.dbvendor = EDbVendor.dbvredshift;
044    }
045    
046    /**
047     * Constructor with distribution style
048     * @param distStyle The distribution style to use
049     */
050    public TRedshiftTableAttributes(EDistStyle distStyle) {
051        this();
052        this.distStyle = distStyle;
053        this.attributeType = ETableAttributeType.ttDistStyle;
054    }
055    
056
057    public void init(Object arg1) {
058        this.attributeType = (ETableAttributeType)arg1;
059    }
060
061    public void init(Object arg1, Object arg2) {
062        this.attributeType = (ETableAttributeType)arg1;
063        switch (attributeType) {
064            case ttDistStyle:
065                this.distStyle = (EDistStyle)arg2;
066                break;
067            case ttDistKey:
068                this.distKey = (TObjectName)arg2;
069                break;
070            case ttSortKey:
071                this.sortKeyColumns = (TObjectNameList)arg2;
072                break;
073            default:
074                break;
075        }
076    }
077
078    /**
079     * Constructor with distribution style and key
080     * @param distStyle The distribution style to use
081     * @param distKey The distribution key column
082     */
083    public TRedshiftTableAttributes(EDistStyle distStyle, TObjectName distKey) {
084        this(distStyle);
085        this.distKey = distKey;
086        if (distStyle == EDistStyle.KEY) {
087            this.attributeType = ETableAttributeType.ttDistKey;
088        }
089    }
090    
091    /**
092     * Get the attribute type
093     * @return The type of table attribute
094     */
095    public ETableAttributeType getAttributeType() {
096        return attributeType;
097    }
098    
099    /**
100     * Set the attribute type
101     * @param attributeType The type of table attribute
102     */
103    public void setAttributeType(ETableAttributeType attributeType) {
104        this.attributeType = attributeType;
105    }
106    
107    /**
108     * Get the distribution style
109     * @return The distribution style
110     */
111    public EDistStyle getDistStyle() {
112        return distStyle;
113    }
114    
115    /**
116     * Set the distribution style
117     * @param distStyle The distribution style
118     * @return this object for method chaining
119     */
120    public TRedshiftTableAttributes setDistStyle(EDistStyle distStyle) {
121        this.distStyle = distStyle;
122        this.attributeType = ETableAttributeType.ttDistStyle;
123        return this;
124    }
125    
126    /**
127     * Get the distribution key
128     * @return The distribution key column identifier
129     */
130    public TObjectName getDistKey() {
131        return distKey;
132    }
133    
134    /**
135     * Set the distribution key
136     * @param distKey The column identifier to use as distribution key
137     * @return this object for method chaining
138     */
139    public TRedshiftTableAttributes setDistKey(TObjectName distKey) {
140        this.distKey = distKey;
141        if (this.distStyle == EDistStyle.KEY) {
142            this.attributeType = ETableAttributeType.ttDistKey;
143        }
144        return this;
145    }
146    
147    /**
148     * Get the sort key columns
149     * @return List of sort key columns
150     */
151    public TObjectNameList getSortKeyColumns() {
152        return sortKeyColumns;
153    }
154    
155
156   
157    /**
158     * Generate the SQL fragment for table_attributes
159     * @return SQL string representing the table attributes
160     */
161    public String toSql() {
162        StringBuilder sql = new StringBuilder();
163        
164        // Add distribution style
165        if (this.attributeType == ETableAttributeType.ttDistStyle || 
166            this.attributeType == ETableAttributeType.ttDistKey) {
167            sql.append("DISTSTYLE ").append(distStyle.name());
168        }
169        
170        // Add distribution key if specified and style is KEY
171        if (this.attributeType == ETableAttributeType.ttDistKey && 
172            distStyle == EDistStyle.KEY && 
173            distKey != null) {
174            sql.append(" DISTKEY (").append(distKey).append(")");
175        }
176        
177        // Add sort key if columns are specified
178        if (this.attributeType == ETableAttributeType.ttSortKey && sortKeyColumns != null && sortKeyColumns.size() > 0) {
179            if (sql.length() > 0) {
180                sql.append(" ");
181            }
182            sql.append("SORTKEY (");
183            sql.append(String.join(", ", sortKeyColumns.toString()));
184            sql.append(")");
185        }
186        
187        return sql.toString();
188    }
189    
190    @Override
191    public String toString() {
192        return toSql();
193    }
194
195    public void accept(TParseTreeVisitor v)
196    {
197        v.preVisit(this);
198        v.postVisit(this);
199    }
200
201    public void acceptChildren(TParseTreeVisitor v) {
202        v.preVisit(this);
203        v.postVisit(this);
204    }    
205}