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        AUTO  // Automatic distribution style (Redshift chooses best)
026    }
027
028    /**
029     * Possible auto refresh options for Redshift materialized views
030     */
031    public enum EAutoRefresh {
032        YES,  // Enable auto refresh
033        NO    // Disable auto refresh
034    }
035    
036    // The type of table attribute (distribution style, distribution key, sort key)
037    private ETableAttributeType attributeType = ETableAttributeType.ttUnknown;
038    
039    // Distribution style
040    private EDistStyle distStyle = EDistStyle.EVEN; // Default is EVEN
041    
042    // Distribution key column identifier
043    private TObjectName distKey;
044    
045    // Sort key columns
046    private TObjectNameList sortKeyColumns ;
047
048    // Auto refresh setting
049    private EAutoRefresh autoRefresh;
050
051    /**
052     * Default constructor
053     */
054    public TRedshiftTableAttributes() {
055        this.dbvendor = EDbVendor.dbvredshift;
056    }
057    
058    /**
059     * Constructor with distribution style
060     * @param distStyle The distribution style to use
061     */
062    public TRedshiftTableAttributes(EDistStyle distStyle) {
063        this();
064        this.distStyle = distStyle;
065        this.attributeType = ETableAttributeType.ttDistStyle;
066    }
067    
068
069    public void init(Object arg1) {
070        this.attributeType = (ETableAttributeType)arg1;
071    }
072
073    public void init(Object arg1, Object arg2) {
074        this.attributeType = (ETableAttributeType)arg1;
075        switch (attributeType) {
076            case ttDistStyle:
077                this.distStyle = (EDistStyle)arg2;
078                break;
079            case ttDistKey:
080                this.distKey = (TObjectName)arg2;
081                break;
082            case ttSortKey:
083                this.sortKeyColumns = (TObjectNameList)arg2;
084                break;
085            case ttAutoRefresh:
086                this.autoRefresh = (EAutoRefresh)arg2;
087                break;
088            default:
089                break;
090        }
091    }
092
093    /**
094     * Constructor with distribution style and key
095     * @param distStyle The distribution style to use
096     * @param distKey The distribution key column
097     */
098    public TRedshiftTableAttributes(EDistStyle distStyle, TObjectName distKey) {
099        this(distStyle);
100        this.distKey = distKey;
101        if (distStyle == EDistStyle.KEY) {
102            this.attributeType = ETableAttributeType.ttDistKey;
103        }
104    }
105    
106    /**
107     * Get the attribute type
108     * @return The type of table attribute
109     */
110    public ETableAttributeType getAttributeType() {
111        return attributeType;
112    }
113    
114    /**
115     * Set the attribute type
116     * @param attributeType The type of table attribute
117     */
118    public void setAttributeType(ETableAttributeType attributeType) {
119        this.attributeType = attributeType;
120    }
121    
122    /**
123     * Get the distribution style
124     * @return The distribution style
125     */
126    public EDistStyle getDistStyle() {
127        return distStyle;
128    }
129    
130    /**
131     * Set the distribution style
132     * @param distStyle The distribution style
133     * @return this object for method chaining
134     */
135    public TRedshiftTableAttributes setDistStyle(EDistStyle distStyle) {
136        this.distStyle = distStyle;
137        this.attributeType = ETableAttributeType.ttDistStyle;
138        return this;
139    }
140    
141    /**
142     * Get the distribution key
143     * @return The distribution key column identifier
144     */
145    public TObjectName getDistKey() {
146        return distKey;
147    }
148    
149    /**
150     * Set the distribution key
151     * @param distKey The column identifier to use as distribution key
152     * @return this object for method chaining
153     */
154    public TRedshiftTableAttributes setDistKey(TObjectName distKey) {
155        this.distKey = distKey;
156        if (this.distStyle == EDistStyle.KEY) {
157            this.attributeType = ETableAttributeType.ttDistKey;
158        }
159        return this;
160    }
161    
162    /**
163     * Get the sort key columns
164     * @return List of sort key columns
165     */
166    public TObjectNameList getSortKeyColumns() {
167        return sortKeyColumns;
168    }
169
170    /**
171     * Get the auto refresh setting
172     * @return The auto refresh setting (YES or NO), or null if not set
173     */
174    public EAutoRefresh getAutoRefresh() {
175        return autoRefresh;
176    }
177
178    /**
179     * Set the auto refresh setting
180     * @param autoRefresh The auto refresh setting (YES or NO)
181     * @return this object for method chaining
182     */
183    public TRedshiftTableAttributes setAutoRefresh(EAutoRefresh autoRefresh) {
184        this.autoRefresh = autoRefresh;
185        this.attributeType = ETableAttributeType.ttAutoRefresh;
186        return this;
187    }
188
189    /**
190     * Generate the SQL fragment for table_attributes
191     * @return SQL string representing the table attributes
192     */
193    public String toSql() {
194        StringBuilder sql = new StringBuilder();
195        
196        // Add distribution style
197        if (this.attributeType == ETableAttributeType.ttDistStyle || 
198            this.attributeType == ETableAttributeType.ttDistKey) {
199            sql.append("DISTSTYLE ").append(distStyle.name());
200        }
201        
202        // Add distribution key if specified and style is KEY
203        if (this.attributeType == ETableAttributeType.ttDistKey && 
204            distStyle == EDistStyle.KEY && 
205            distKey != null) {
206            sql.append(" DISTKEY (").append(distKey).append(")");
207        }
208        
209        // Add sort key if columns are specified
210        if (this.attributeType == ETableAttributeType.ttSortKey && sortKeyColumns != null && sortKeyColumns.size() > 0) {
211            if (sql.length() > 0) {
212                sql.append(" ");
213            }
214            sql.append("SORTKEY (");
215            sql.append(String.join(", ", sortKeyColumns.toString()));
216            sql.append(")");
217        }
218
219        // Add auto refresh if specified
220        if (this.attributeType == ETableAttributeType.ttAutoRefresh && autoRefresh != null) {
221            if (sql.length() > 0) {
222                sql.append(" ");
223            }
224            sql.append("AUTO REFRESH ").append(autoRefresh.name());
225        }
226
227        return sql.toString();
228    }
229    
230    @Override
231    public String toString() {
232        return toSql();
233    }
234
235    public void accept(TParseTreeVisitor v)
236    {
237        v.preVisit(this);
238        v.postVisit(this);
239    }
240
241    public void acceptChildren(TParseTreeVisitor v) {
242        v.preVisit(this);
243        v.postVisit(this);
244    }    
245}