001package gudusoft.gsqlparser.nodes;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.hive.THiveKeyValueProperty;
005import gudusoft.gsqlparser.nodes.hive.THiveTableBuckets;
006import gudusoft.gsqlparser.nodes.hive.THiveTableFileFormat;
007import gudusoft.gsqlparser.nodes.hive.THiveTableSkewed;
008import gudusoft.gsqlparser.nodes.mysql.TMySQLIndexOption;
009import gudusoft.gsqlparser.nodes.postgresql.TPartitionBoundSpecSqlNode;
010import gudusoft.gsqlparser.nodes.mssql.TPeriodForClause;
011
012import java.util.ArrayList;
013
014/**
015 *  Type of alter table option, {@link #getOptionType()} returns the type of various option:
016 *  <br>
017 *  <p>Column</p>
018 *  <ul>
019 *      <li>{@link EAlterTableOptionType#AddColumn}, check {@link #getColumnDefinitionList()} for newly added columns</li>
020 *      <li>{@link EAlterTableOptionType#AlterColumn}, alter column option, {@link #getColumnName()} returns the column name.
021 *      <br>check {@link #getAlterColumnSubType()} for the subtype of alter column option.
022 *      <ul>
023 *          <li>{@link EAlterColumnSubType#SetDefault}, {@link #getDefaultExpr()} returns default expression</li>
024 *          <li>{@link EAlterColumnSubType#DropDefault}</li>
025 *          <li>{@link EAlterColumnSubType#DropNotNull}</li>
026 *          <li>{@link EAlterColumnSubType#SetNotNull}</li>
027 *          <li>{@link EAlterColumnSubType#SetStatistics}, {@link #getStatisticsValue} returns the statistics value</li>
028 *          <li>{@link EAlterColumnSubType#SetOptions}, {@link #getAttributeOptions} returns the set options</li>
029 *          <li>{@link EAlterColumnSubType#ResetOptions}, {@link #getAttributeOptions} returns the reset options</li>
030 *          <li>{@link EAlterColumnSubType#SetStorage}, {@link #getStorageName} retuns the storage name</li>
031 *          <li>{@link EAlterColumnSubType#SetDataType}, {@link #getNewDataType returns the data type name}</li>
032 *      </ul>
033 *      </li>
034 *      <li>{@link EAlterTableOptionType#ChangeColumn}, MySQL,Hive,Impala change column clause, {@link #getColumnName() old column name},{@link #getNewColumnDef() new column definition}</li>
035 *      <li>{@link EAlterTableOptionType#DropColumn}, check {@link #getColumnNameList()} for dropped columns. {@link #getDropRestrictType()} returns drop restrict type if any.</li>
036 *      <li>{@link EAlterTableOptionType#ModifyColumn}, check {@link #getColumnDefinitionList()} for modified columns</li>
037 *      <li>{@link EAlterTableOptionType#RenameColumn}, rename {@link #getColumnName() old name} to {@link #getNewColumnName() new name}</li>
038 *      <li>{@link EAlterTableOptionType#SetUnUsedColumn}, check {@link #getColumnNameList()} for unused column. Oracle set unused column.</li>
039 *      <li>{@link EAlterTableOptionType#DropUnUsedColumn}, Oracle drop unused columns</li>
040 *      <li>{@link EAlterTableOptionType#DropColumnsContinue}, Oracle drop columns continue</li>
041 *</ul>
042 * <p>Constraint</p>
043 * <ul>
044 *      <li>{@link EAlterTableOptionType#AddConstraint}, check {@link #getConstraintList()} for newly added table level constraints</li>
045 *      <li>{@link EAlterTableOptionType#AddConstraintPK}, {@link #getColumnNameList() primary key column list}. MySQL, {@link #getConstraintName()} returns the constraint name</li>
046 *      <li>{@link EAlterTableOptionType#AddConstraintUnique}, {@link #getColumnNameList() unique key column list}. MyQL,{@link #getConstraintName()} returns the constraint name</li>
047 *      <li>{@link EAlterTableOptionType#AddConstraintFK}, {@link #getColumnNameList() unique key column list},
048 *          {@link #getConstraintName() [constraint name]},
049 *          {@link #getReferencedObjectName() [referenced table name]},
050 *          {@link #getReferencedColumnList() [referenced column list]},MySQL</li>
051 *      <li>{@link EAlterTableOptionType#AddConstraintIndex}, check {@link #getColumnNameList() index column list},
052 *          {@link #getConstraintName() [constraint name]},{@link #getMySQLIndexStorageType() [index storage type]} MySQL add index constraint</li>
053 *      <li>{@link EAlterTableOptionType#DropConstraint}, {@link #getConstraintNameList() constraint name list}, {@link #getDropRestrictType() [drop restrict type]}, Oracle/DB2/Greenplum drop constraint. </li>
054 *      <li>{@link EAlterTableOptionType#AlterConstraintFK}, DB2 alter foreign key. </li>
055 *      <li>{@link EAlterTableOptionType#AlterConstraintCheck}, {@link #getConstraintName() check constraint name }, DB2 alter check constraint. </li>
056 *      <li>{@link EAlterTableOptionType#DropConstraintIndex}, {@link #getConstraintName() constriant name}, MySQL drop index </li>
057 *      <li>{@link EAlterTableOptionType#DropConstraintKey}, {@link #getConstraintName() constriant name}, MySQL drop index </li>
058 *      <li>{@link EAlterTableOptionType#DropConstraintPK}, Oracle/DB2/MySQL drop primary key. </li>
059 *      <li>{@link EAlterTableOptionType#DropConstraintFK},{@link #getConstraintName() [constriant name]}, DB2/MySQL drop foreign key. </li>
060 *      <li>{@link EAlterTableOptionType#DropConstraintUnique}, In Oracle, get {@link #getColumnNameList() unique column list}, In DB2, get {@link #getConstraintName() constraint name}. </li>
061 *      <li>{@link EAlterTableOptionType#DropConstraintCheck}, {@link #getConstraintName() check constraint name}, DB2 drop check constraint. </li>
062 *      <li>{@link EAlterTableOptionType#ModifyConstraint}, check {@link #getConstraintName() constraint name} </li>
063 *      <li>{@link EAlterTableOptionType#RenameConstraint}, rename {@link #getConstraintName() old name} to {@link #getNewConstraintName() new name} </li>
064 *      <li>{@link EAlterTableOptionType#ValidateConstraint},  {@link #getConstraintName() constraint name}, greenplum/postgresql</li>
065 *</ul>
066 * <p>Enable/disable</p>
067 * <ul>
068 *       <li>{@link EAlterTableOptionType#enableTrigger}, {@link #getTriggerName() trigger name}, greenplum/postgresql. </li>
069 *       <li>{@link EAlterTableOptionType#enableAlwaysTrigger}, {@link #getTriggerName() trigger name}, greenplum/postgresql. </li>
070 *       <li>{@link EAlterTableOptionType#enableReplicaTrigger}, {@link #getTriggerName() trigger name}, greenplum/postgresql. </li>
071 *       <li>{@link EAlterTableOptionType#disableTrigger}, {@link #getTriggerName() trigger name}, greenplum/postgresql. </li>
072 *       <li>{@link EAlterTableOptionType#enableRule}, {@link #getRuleName() rule name}, greenplum/postgresql. </li>
073 *       <li>{@link EAlterTableOptionType#enableAlwaysRule}, {@link #getRuleName() rule name}, greenplum/postgresql. </li>
074 *       <li>{@link EAlterTableOptionType#enableReplicaRule}, {@link #getRuleName() rule name}, greenplum/postgresql. </li>
075 *       <li>{@link EAlterTableOptionType#disableRule}, {@link #getRuleName() rule name}, greenplum. </li>
076 * </ul>
077 * <p>Others</p>
078 * <ul>
079 *       <li>{@link EAlterTableOptionType#RenameTable}, {@link #getNewTableName() new table name} </li>
080 *       <li>{@link EAlterTableOptionType#inherit}, {@link #getParentTable() parent table}, greenplum/postgresql. </li>
081 *       <li>{@link EAlterTableOptionType#noInherit}, {@link #getParentTable() parent table}, greenplum/postgresql. </li>
082 *
083 *       <li>{@link EAlterTableOptionType#ofAnyType}, {@link #getAnyTypeName() type name}, greenplum/postgresql. </li>
084 *
085 *       <li>{@link EAlterTableOptionType#ownerTo}, {@link #getNewOwnerName() owner name}, greenplum/postgresql. </li>
086 *       <li>{@link EAlterTableOptionType#setTablespace}, {@link #getNewTablespaceName() tablespace name}, greenplum/postgresql. </li>
087 *
088 *        <li>{@link EAlterTableOptionType#setSchema}, {@link #getSchemaName() schema name}, greenplum. </li>
089 *        <li>{@link EAlterTableOptionType#clusterOn}, {@link #getIndexName() index name}, postgresql. </li>
090 *
091 *  </ul>
092 */
093public class TAlterTableOption extends TParseTreeNode {
094
095    private TPeriodForClause periodForClause;
096
097    public TPeriodForClause getPeriodForClause() {
098        return periodForClause;
099    }
100
101    public void setPeriodForClause(TPeriodForClause periodForClause) {
102        this.periodForClause = periodForClause;
103    }
104
105    public static EAlterTableOptionType getAlterTableOptionTypeByToken(TSourceToken st){
106        if (st == null) return EAlterTableOptionType.RenameTable;
107        if (st.toString().equalsIgnoreCase("index")) return EAlterTableOptionType.renameIndex;
108        if (st.toString().equalsIgnoreCase("key")) return EAlterTableOptionType.renameIndex;
109
110        return EAlterTableOptionType.Unknown;
111    }
112    private TBaseTablePartition tablePartition;
113
114    public TBaseTablePartition getTablePartition() {
115        return tablePartition;
116    }
117
118    public void adjustOptionByToken(TSourceToken st){
119        if (st == null) return;
120
121        switch (getOptionType()){
122            case AddConstraintIndex:
123                if (st.tokencode == TBaseType.rrw_unique){
124                    setOptionType(EAlterTableOptionType.AddConstraintUnique);
125                }
126                break;
127        }
128    }
129    public TMySQLCreateTableOption getMySQLTableOption() {
130        return mySQLTableOption;
131    }
132
133    private  TMySQLCreateTableOption mySQLTableOption;
134
135    public void setPartitionBoundSpec(TPartitionBoundSpecSqlNode partitionBoundSpec) {
136        this.partitionBoundSpec = partitionBoundSpec;
137    }
138
139    public TPartitionBoundSpecSqlNode getPartitionBoundSpec() {
140        return partitionBoundSpec;
141    }
142
143    /**
144     * postgresql PartitionBoundSpec
145     * https://www.postgresql.org/docs/current/sql-createtable.html
146     */
147    private TPartitionBoundSpecSqlNode partitionBoundSpec;
148
149    public static final int COLUMN_POSITION_NONE = 0;
150    public static final int COLUMN_POSITION_FIRST = 1;
151    public static final int COLUMN_POSITION_AFTER = 2;
152
153    private int columnPosition = COLUMN_POSITION_NONE;
154    private TObjectName afterColumnName;
155
156    public TObjectName getAfterColumnName() {
157        return afterColumnName;
158    }
159
160    public int getColumnPosition() {
161        return columnPosition;
162    }
163
164    public void setColumnPosition(TDummy node){
165        if (node == null) return;
166        if (node.node1 != null){
167            this.columnPosition = COLUMN_POSITION_AFTER;
168            this.afterColumnName = (TObjectName)node.node1;
169        }else{
170            this.columnPosition = COLUMN_POSITION_FIRST;
171        }
172    }
173
174    private EAlterColumnSubType AlterColumnSubType = EAlterColumnSubType.unknown;
175
176    /**
177     * subtype of alter column.
178     * @return subtype of alter column.
179     */
180    public EAlterColumnSubType getAlterColumnSubType() {
181        return AlterColumnSubType;
182    }
183
184    private TPTNodeList <TMySQLIndexOption> indexOptionList;
185
186    public void setIndexOptionList(TPTNodeList<TMySQLIndexOption> indexOptionList) {
187        this.indexOptionList = indexOptionList;
188    }
189
190    /**
191     * MySQL, index options
192     * @return index options
193     */
194    public TPTNodeList<TMySQLIndexOption> getIndexOptionList() {
195
196        return indexOptionList;
197    }
198
199    private TPTNodeList <TColumnWithSortOrder > indexCols;
200
201    public void setIndexCols(TPTNodeList<TColumnWithSortOrder > indexCols) {
202        this.indexCols = indexCols;
203    }
204
205    /**
206     * MySQL, column list of foreign key
207     *
208     *
209     * @return column list of foreign key
210     */
211    public TPTNodeList<TColumnWithSortOrder > getIndexCols() {
212
213        return indexCols;
214    }
215
216    private TObjectName serdeName;
217
218    private TResultColumnList mutationUpdateList;
219
220    /**
221     * ClickHouse ALTER TABLE ... UPDATE set list.
222     * Valid when {@link #getOptionType()} is {@link EAlterTableOptionType#clickhouseUpdateMutation}.
223     * @return the SET column assignment list
224     */
225    public TResultColumnList getMutationUpdateList() {
226        return mutationUpdateList;
227    }
228
229    /**
230     * ClickHouse ALTER TABLE ... DELETE WHERE / UPDATE ... WHERE condition.
231     * Valid when {@link #getOptionType()} is {@link EAlterTableOptionType#clickhouseDeleteMutation}
232     * or {@link EAlterTableOptionType#clickhouseUpdateMutation}.
233     * @return the WHERE condition expression
234     */
235    public TExpression getMutationWhereCondition() {
236        return defaultExpr;
237    }
238
239    private TParseTreeNode partitionExpr;
240
241    /**
242     * ClickHouse ALTER TABLE partition expression.
243     * Valid when {@link #getOptionType()} is one of the clickhouse partition operations
244     * (e.g., {@link EAlterTableOptionType#clickhouseDetachPartition},
245     * {@link EAlterTableOptionType#clickhouseAttachPartition}, etc.).
246     * @return the partition expression node (integer, string, identifier, or tuple)
247     */
248    public TParseTreeNode getPartitionExpr() {
249        return partitionExpr;
250    }
251
252    private EKeyReferenceType dropRestrictType = EKeyReferenceType.no_action;
253
254    public void setDropRestrictType(TSourceToken st) {
255        if (st == null) return;
256
257        if (st.tokencode == TBaseType.rrw_cascade ){
258            this.dropRestrictType = EKeyReferenceType.cascade;
259        }else if (st.tokencode == TBaseType.rrw_restrict){
260            this.dropRestrictType = EKeyReferenceType.restrict;
261        }
262
263    }
264
265    /**
266     * drop restrict type such as: cascade, restrict
267     * @return drop restrict type such as: cascade, restrict
268     */
269    public EKeyReferenceType getDropRestrictType() {
270
271        return dropRestrictType;
272    }
273
274    /**
275     * Type of this alter table option
276     * @return Type of this alter table option
277     */
278    public EAlterTableOptionType getOptionType() {
279        return optionType;
280    }
281
282    /**
283     * referenced table in foreign key clause
284     * @return referenced table in foreign key clause
285     */
286    public TTable getReferencedTable() {
287        return referencedTable;
288    }
289
290    private TTable referencedTable = null;
291
292    private TObjectName partitionName;
293
294
295    /**
296     * partition name in PostgreSQL attached partition clause.
297     *
298     * @return partition name
299     */
300    public TObjectName getPartitionName() {
301        return partitionName;
302    }
303
304    private TColumnDefinitionList columnDefinitionList = null;
305    private TConstraintList constraintList = null;
306    private TObjectNameList columnNameList = null;
307    private TObjectName columnName = null;
308    private TObjectName newColumnName = null;
309    private TObjectName constraintName = null;
310    private TObjectName newConstraintName = null;
311    private TObjectName referencedObjectName = null;
312    private TObjectNameList referencedColumnList = null;
313    private TObjectName newTableName = null;
314    private TExpression defaultExpr = null;
315
316    /**
317     * ClickHouse, the new stored query of {@code ALTER TABLE <mv> MODIFY QUERY SELECT ...}.
318     * Valid when {@link #getOptionType()} is {@link EAlterTableOptionType#clickhouseModifyQuery}.
319     */
320    private TSelectSqlNode modifyQuerySelect = null;
321
322    /**
323     * ClickHouse, the new stored query of {@code ALTER TABLE <mv> MODIFY QUERY SELECT ...}.
324     * Valid when {@link #getOptionType()} is {@link EAlterTableOptionType#clickhouseModifyQuery}.
325     *
326     * @return the select node after MODIFY QUERY, null for other option types.
327     */
328    public TSelectSqlNode getModifyQuerySelect() {
329        return modifyQuerySelect;
330    }
331    private TConstant statisticsValue = null;
332    private ArrayList<TAttributeOption> attributeOptions;
333    private TObjectName storageName = null;
334    private TTypeName   newDataType = null;
335    private TObjectName newCollation = null;
336    private TExpression usingExpr = null;
337    private TConstraint tableConstraint = null;
338    private TObjectName indexName = null;
339    private TObjectName triggerName = null;
340    private TObjectName ruleName = null;
341    private TObjectName parentTable = null;
342    private TObjectName anyTypeName = null;
343    private TObjectName newOwnerName = null;
344    private TObjectName newTablespaceName = null;
345    private TObjectName schemaName = null;
346    private TObjectNameList constraintNameList = null;
347    private TExpression partitionExpression1 = null;
348
349    private TObjectName sourceTableName = null;
350
351    /**
352     * redshift alter table... append from source table
353     * @return redshift alter table... append from source table
354     */
355    public TObjectName getSourceTableName() {
356        return sourceTableName;
357    }
358
359    /**
360     * SQL Server, target_partition_number_expression in switch partition clause
361     * @return
362     */
363    public TExpression getPartitionExpression2() {
364        return partitionExpression2;
365    }
366
367    /**
368     * SQL Server, source_partition_number_expression in switch partition clause
369     * @return source_partition_number_expression
370     */
371    public TExpression getPartitionExpression1() {
372        return partitionExpression1;
373    }
374
375    private TExpression partitionExpression2 = null;
376
377    /**
378     * constraint name list when option type is: {@link EAlterTableOptionType#DropConstraint}
379     *
380     * @return constraint name list
381     */
382    public TObjectNameList getConstraintNameList() {
383        return constraintNameList;
384    }
385
386    /**
387     * Greenplum, Schema name when option type is {@link EAlterTableOptionType#setSchema}
388     *
389     * @return schema name
390     */
391    public TObjectName getSchemaName() {
392        return schemaName;
393    }
394
395    public void setNewTablespaceName(TObjectName newTablespaceName) {
396        this.newTablespaceName = newTablespaceName;
397    }
398
399    /**
400    * Greenplum, Postgresql, Snowflake, tablespace name when option type is {@link EAlterTableOptionType#setTablespace}
401     *
402    * @return tablespace name
403    */
404    public TObjectName getNewTablespaceName() {
405
406        return newTablespaceName;
407    }
408
409    public void setNewOwnerName(TObjectName newOwnerName) {
410        this.newOwnerName = newOwnerName;
411    }
412
413    /**
414    * owner name or roleId when option type is {@link EAlterTableOptionType#ownerTo}
415     *
416    * @return owner name or role id
417    */
418    public TObjectName getNewOwnerName() {
419
420        return newOwnerName;
421    }
422
423    public void setAnyTypeName(TObjectName anyTypeName) {
424        this.anyTypeName = anyTypeName;
425    }
426
427     /**
428     * Greenplum, Postgresql,Snowflake, any name when option type is {@link EAlterTableOptionType#ofAnyType}
429      *
430     * @return any name
431     */
432    public TObjectName getAnyTypeName() {
433
434        return anyTypeName;
435    }
436
437    public void setParentTable(TObjectName parentTable) {
438        this.parentTable = parentTable;
439    }
440
441     /**
442     * Greenplum, Postgresql,Snowflake, parent table when option type is {@link EAlterTableOptionType#inherit} or
443      * {@link EAlterTableOptionType#noInherit}
444      *
445     * @return  parent table
446     */
447    public TObjectName getParentTable() {
448
449        return parentTable;
450    }
451
452    public void setRuleName(TObjectName ruleName) {
453        this.ruleName = ruleName;
454    }
455
456    /**
457     * Greenplum, Postgresql,Snowflake, rule name when option type is {@link EAlterTableOptionType#enableRule} or
458     * {@link EAlterTableOptionType#enableAlwaysRule} or  {@link EAlterTableOptionType#enableReplicaRule} or
459     * {@link EAlterTableOptionType#disableRule}
460     *
461     * @return rule name
462     */
463    public TObjectName getRuleName() {
464
465        return ruleName;
466    }
467
468    public void setTriggerName(TObjectName triggerName) {
469        this.triggerName = triggerName;
470    }
471
472
473    /**
474     * Greenplum, Postgresql,Snowflake, trigger name when option type is {@link EAlterTableOptionType#enableTrigger} or
475     * {@link EAlterTableOptionType#enableAlwaysTrigger} or  {@link EAlterTableOptionType#enableReplicaTrigger} or
476     * {@link EAlterTableOptionType#disableTrigger}
477     *
478     * @return trigger name
479     */
480    public TObjectName getTriggerName() {
481
482        return triggerName;
483    }
484
485    public void setIndexName(TObjectName indexName) {
486        this.indexName = indexName;
487    }
488
489    /**
490     * Greenplum, Postgresql, Snowflake, index name when option type is {@link EAlterTableOptionType#clusterOn}
491     *
492     * @return index name
493     */
494    public TObjectName getIndexName() {
495
496        return indexName;
497    }
498
499    private TObjectName newIndexName;
500
501    public TObjectName getNewIndexName() {
502        return newIndexName;
503    }
504
505    public void setTableConstraint(TConstraint tableConstraint) {
506        this.tableConstraint = tableConstraint;
507    }
508
509    /**
510     * table constraint when option type is {@link EAlterTableOptionType#AddConstraint}
511     *
512     * @return table constraint
513     */
514    public TConstraint getTableConstraint() {
515
516        return tableConstraint;
517    }
518
519    public void setUsingExpr(TExpression usingExpr) {
520        this.usingExpr = usingExpr;
521    }
522
523    /**
524     * using expr when option type is {@link gudusoft.gsqlparser.EAlterTableOptionType#AlterColumn} and subtype is {@link EAlterColumnSubType#SetDataType}
525     *
526     * @return using expr
527     */
528    public TExpression getUsingExpr() {
529        return usingExpr;
530    }
531
532    public void setNewCollation(TObjectName newCollation) {
533        this.newCollation = newCollation;
534    }
535
536    /**
537     * new collation when option type is {@link gudusoft.gsqlparser.EAlterTableOptionType#AlterColumn} and subtype is {@link EAlterColumnSubType#SetDataType}
538     *
539     * @return new collation
540     */
541    public TObjectName getNewCollation() {
542
543        return newCollation;
544    }
545
546    public void setNewDataType(TTypeName newDataType) {
547        this.newDataType = newDataType;
548    }
549
550    /**
551     * new data type when option type is {@link gudusoft.gsqlparser.EAlterTableOptionType#AlterColumn} and subtype is {@link EAlterColumnSubType#SetDataType}
552     *
553     * @return new data type
554     */
555    public TTypeName getNewDataType() {
556
557        return newDataType;
558    }
559
560    public void setStorageName(TObjectName storageName) {
561        this.storageName = storageName;
562    }
563
564    /**
565     * storage name when option type is {@link gudusoft.gsqlparser.EAlterTableOptionType#AlterColumn} and subtype is {@link EAlterColumnSubType#SetStorage}
566     *
567     * @return storage name
568     */
569    public TObjectName getStorageName() {
570
571        return storageName;
572    }
573
574    public void setAttributeOptions(ArrayList<TAttributeOption> attributeOptions) {
575        this.attributeOptions = attributeOptions;
576    }
577
578    /**
579     * Greenplum,PostgreSQL,Snowflake, set/reset options when option type is {@link gudusoft.gsqlparser.EAlterTableOptionType#AlterColumn} and subtype is {@link EAlterColumnSubType#SetOptions}
580     * or {@link EAlterColumnSubType#ResetOptions}
581     *
582     * @return set/reset options
583     */
584    public ArrayList<TAttributeOption> getAttributeOptions() {
585
586        return attributeOptions;
587    }
588
589    public void setStatisticsValue(TConstant statisticsValue) {
590        this.statisticsValue = statisticsValue;
591    }
592
593    /**
594     * Greenplum,PostgreSQL,Snowflake, statistics value when option type is {@link gudusoft.gsqlparser.EAlterTableOptionType#AlterColumn} and subtype is {@link EAlterColumnSubType#SetStatistics}
595     *
596     * @return statistcs value
597     */
598    public TConstant getStatisticsValue() {
599
600        return statisticsValue;
601    }
602
603    public void setDefaultExpr(TExpression defaultExpr) {
604        this.defaultExpr = defaultExpr;
605    }
606
607    /**
608     * MySQL, PostgreSQL, expression in set default clause of alter column.
609     *
610     * @return expression in set default clause of alter column.
611     */
612    public TExpression getDefaultExpr() {
613
614        return defaultExpr;
615    }
616
617    private TMySQLIndexStorageType mySQLIndexStorageType = null;
618    private TSourceToken mySQLIndexTypeToken = null;
619
620    public void setMySQLIndexTypeToken(TSourceToken mySQLIndexTypeToken) {
621        this.mySQLIndexTypeToken = mySQLIndexTypeToken;
622
623        if (mySQLIndexTypeToken == null) return;
624
625        switch (getOptionType()){
626            case AddConstraintIndex:
627                if (mySQLIndexTypeToken.tokencode == TBaseType.rrw_unique){
628                    setOptionType(EAlterTableOptionType.AddConstraintUnique);
629                }
630                break;
631        }
632    }
633
634    /**
635     * MySQL, unique, fulltext or spatial keyword used in add key/index clause when option type is {@link EAlterTableOptionType#AddConstraintIndex}
636     *
637     * @return unique, fulltext or spatial keyword
638     */
639    public TSourceToken getMySQLIndexTypeToken() {
640
641        return mySQLIndexTypeToken;
642    }
643
644    public void setMySQLIndexStorageType(TMySQLIndexStorageType mySQLIndexStorageType) {
645        this.mySQLIndexStorageType = mySQLIndexStorageType;
646    }
647
648    /**
649     * @deprecated As of v1.7.2.4. use {@link #getIndexOptionList()} instead.
650     * @return index storage type
651     */
652    public TMySQLIndexStorageType getMySQLIndexStorageType() {
653
654        return mySQLIndexStorageType;
655    }
656
657    /**
658     * set new table name when option type is {@link EAlterTableOptionType#RenameTable }
659     *
660     * @param newTableName the new table name
661     */
662    public void setNewTableName(TObjectName newTableName) {
663        this.newTableName = newTableName;
664        this.newTableName.setDbObjectType(EDbObjectType.table);
665    }
666
667    /**
668     * new table name is valid when option type is one of the following values:
669     * <ul>
670     *     <li>{@link EAlterTableOptionType#RenameTable}, new table in rename to clause</li>
671     *     <li>{@link EAlterTableOptionType#setPrivileges}, Netezza, table name in set privileges to clause </li>
672     *     <li>{@link EAlterTableOptionType#exchangePartition},Hive, Impala, table name in exchange partition with table clause </li>
673     *     <li>{@link EAlterTableOptionType#switchPartition}, SQL Server, Openedge, table name of switch partition to target_table clause </li>
674     * </ul>
675     *
676     * @return new table name
677     */
678    public TObjectName getNewTableName() {
679
680        return newTableName;
681    }
682
683    public void setReferencedColumnList(TObjectNameList referencedColumnList) {
684        this.referencedColumnList = referencedColumnList;
685    }
686
687    public void setReferencedObjectName(TObjectName referencedObjectName) {
688        this.referencedObjectName = referencedObjectName;
689    }
690
691    public void setColumnName(TObjectName columnName) {
692        this.columnName = columnName;
693    }
694
695    /**
696     * List of {@link TConstraint} in add constraint clause, valid when {@link #getOptionType()} is {@link EAlterTableOptionType#AddConstraint}
697     *
698     * @return constraint list
699     */
700    public TConstraintList getConstraintList() {
701        return constraintList;
702    }
703
704    private TObjectNameList nameList = null;
705
706    public TObjectNameList getNameList() {
707        if (this.nameList == null){
708
709            this.nameList = new TObjectNameList();
710        }
711        return nameList;
712    }
713
714    /**
715     * List of {@link TObjectNameList}, valid when {@link #getOptionType()} is:
716     * <p>{@link EAlterTableOptionType#SetUnUsedColumn}
717     * <p>{@link EAlterTableOptionType#DropColumn}
718     * <p>{@link EAlterTableOptionType#AddConstraintIndex}, columns of an index
719     * <p>{@link EAlterTableOptionType#AddConstraintPK}, columns of primary key
720     * <p>{@link EAlterTableOptionType#AddConstraintUnique}, columns of unique key
721     * <p>{@link EAlterTableOptionType#AddConstraintFK}, columns of foreign key
722     * <p>{@link EAlterTableOptionType#DropConstraintUnique}, available in Oracle
723     * @return column name list
724     */
725    public TObjectNameList getColumnNameList() {
726        if (this.columnNameList == null){
727
728            this.columnNameList = new TObjectNameList();
729        }
730        return columnNameList;
731    }
732
733    /**
734     * List of {@link TColumnDefinitionList}, valid when {@link #getOptionType()} is:
735     * <p>{@link EAlterTableOptionType#AddColumn}
736     * <p>{@link EAlterTableOptionType#ModifyColumn}
737     *
738     * @return column definition list
739     */
740    public TColumnDefinitionList getColumnDefinitionList() {
741        return columnDefinitionList;
742    }
743
744    /**
745     * valid when {@link #getOptionType()} is:
746     * <p>{@link EAlterTableOptionType#AlterColumn}
747     * <p>{@link EAlterTableOptionType#RenameColumn}
748     * <p>{@link EAlterTableOptionType#ChangeColumn}
749     *
750     * <p>{@link EAlterTableOptionType#AddConstraintIndex}, index name, optional
751     * @return column name
752     */
753    public TObjectName getColumnName() {
754        return columnName;
755    }
756
757    /**
758     *valid when {@link #getOptionType()} is:
759     * <p>{@link EAlterTableOptionType#AddConstraintPK}, optional
760     * <p>{@link EAlterTableOptionType#AddConstraintUnique}, optional
761     * <p>{@link EAlterTableOptionType#AddConstraintFK}, optional
762     * <p>{@link EAlterTableOptionType#ModifyConstraint}
763     * <p>{@link EAlterTableOptionType#RenameConstraint}
764     * <p>{@link EAlterTableOptionType#DropConstraintFK}
765     * <p>{@link EAlterTableOptionType#DropConstraintUnique}, available in DB2
766     * <p>{@link EAlterTableOptionType#DropConstraintCheck}, available in DB2
767     * <p>{@link EAlterTableOptionType#DropConstraintIndex}, available in DB2
768     * <p>{@link EAlterTableOptionType#DropConstraintKey}, available in DB2
769     * <p>{@link EAlterTableOptionType#AlterConstraintFK}, available in DB2
770     * <p>{@link EAlterTableOptionType#AlterConstraintCheck}, available in DB2
771     * @return constraint name
772     */
773    public TObjectName getConstraintName() {
774        return constraintName;
775    }
776
777    /**
778     * new column name valid when {@link #getOptionType()} is {@link EAlterTableOptionType#RenameColumn}
779     *
780     * @return new column name
781     */
782    public TObjectName getNewColumnName() {
783        return newColumnName;
784    }
785
786    /**
787     * new constraint name valid when {@link #getOptionType()} is {@link EAlterTableOptionType#RenameConstraint}
788     *
789     * @return new constraint name
790     */
791    public TObjectName getNewConstraintName() {
792        return newConstraintName;
793    }
794
795    /**
796     * MySQL, referenced column list in foreign key clause.
797     *
798     * @return referenced column list in foreign key clause.
799     */
800    public TObjectNameList getReferencedColumnList() {
801        return referencedColumnList;
802    }
803
804    /**
805     * referenced table in foreign key clause. Please use {@link #getReferencedTable} instead.
806     *
807     * @return referenced table in foreign key clause
808     */
809    public TObjectName getReferencedObjectName() {
810        return referencedObjectName;
811    }
812
813    public void init(Object arg1){
814        this.optionType = (EAlterTableOptionType)arg1;
815    }
816
817    private TParseTreeNode clickhouseOperand1 = null, clickhouseOperand2 = null;
818
819    /**
820     * ClickHouse ALTER sub-clauses (batch 5): the primary operand — the
821     * part/partition literal, target column/index/projection name, setting
822     * list, comment constant or check-target, depending on
823     * {@link #getOptionType()}. Null when the sub-clause takes no operand.
824     */
825    public TParseTreeNode getClickhouseOperand1() {
826        return clickhouseOperand1;
827    }
828
829    /**
830     * ClickHouse ALTER sub-clauses (batch 5): the secondary operand — the
831     * WITH NAME / TO DISK / TO VOLUME constant, IN PARTITION clause,
832     * projection body or setting list, depending on
833     * {@link #getOptionType()}. Null when absent.
834     */
835    public TParseTreeNode getClickhouseOperand2() {
836        return clickhouseOperand2;
837    }
838
839    public void init(Object arg1,Object arg2){
840        init(arg1);
841        switch (optionType){
842            case dropPartitionSpecList:
843            case addPartitionSpecList:
844            case touch:
845            case archive:
846            case unArchive:
847            case setPartitionLocation:
848                this.partitionSpecList = (ArrayList<TPartitionExtensionClause>)arg2;
849                break;
850            case setTableProperties:
851            case unsetTableProperties:
852                this.tableProperties = (TPTNodeList)arg2;
853                break;
854            case setFileFormat:
855                this.fileFormat = (THiveTableFileFormat)arg2;
856                break;
857            case setLocation:
858                this.tableLocation = (TObjectName)arg2;
859                break;
860            case serde:
861                serdeName = (TObjectName)arg2;
862                break;
863            case renamePartition:
864            case addPartition:
865            case dropPartition:
866                if (arg2 instanceof TObjectNameList){
867                    nameList = (TObjectNameList) arg2;
868                }
869                else if (arg2 instanceof TPartitionExtensionClause){
870                    newPartitionSpec= (TPartitionExtensionClause)arg2;
871                }
872                else if (arg2 instanceof ArrayList){
873                    partitionDefinitionList = (ArrayList<TPartitionDefinition>)arg2;
874                }
875                else{
876                    partitionSpecList = (ArrayList<TPartitionExtensionClause>)arg2;
877                    newPartitionSpec = partitionSpecList.get(0);
878                }
879
880                break;
881            case rebuildPartition:
882            case optimizePartition:
883            case repairPartition:
884            case analyzePartition:
885            case checkPartition:
886            case discardPartition:
887            case importPartition:
888            case truncatePartition:
889                nameList = (TObjectNameList) arg2;
890                break;
891            case clickhouseModifyQuery:
892                if (arg2 instanceof TSelectSqlNode){
893                    modifyQuerySelect = (TSelectSqlNode)arg2;
894                }
895                break;
896            case dropCheck:
897                break;
898            case dropConstraint:
899                break;
900            case alterConstraint:
901                break;
902            case alterCheck:
903                break;
904            case coalescePartition:
905                break;
906            case tableBuckets:
907                numberOfBuckets = (TConstant)arg2;
908                break;
909            case skewedLocation:
910                skewedLocations = (TExpressionList)arg2;
911                break;
912            case clusteredSorted:
913                tableBuckets    = (THiveTableBuckets)arg2;
914                break;
915            case partitionColumn:
916                partitionColumnDef = (TColumnDefinition)arg2;
917                break;
918            case tableSkewed:
919                tableSkewed = (THiveTableSkewed)arg2;
920                break;
921            case setSchema:
922                schemaName = (TObjectName)arg2;
923                break;
924            case DropConstraint:
925                constraintNameList = (TObjectNameList)arg2;
926                if (constraintList != null){
927                    constraintName = constraintNameList.getObjectName(0);
928                }
929                break;
930            case CheckConstraint:
931            case NocheckConstraint:
932                constraintNameList = (TObjectNameList)arg2;
933                if (constraintNameList != null && constraintNameList.size() > 0){
934                    constraintName = constraintNameList.getObjectName(0);
935                }
936                break;
937            case modifyPrimaryKey:
938                indexName = (TObjectName)arg2;
939                break;
940            case switchPartition:
941                newTableName = (TObjectName)arg2;
942                break;
943            case AddConstraintIndex:
944            case AddConstraintPK:
945            case AddConstraintUnique:
946            case AddConstraintFK:
947                if (arg2 instanceof TPTNodeList){
948                    indexCols = (TPTNodeList)arg2;
949                }else{
950                    columnNameList = (TObjectNameList)arg2;
951                }
952                break;
953            case AddConstraintCheck:
954                defaultExpr = (TExpression)arg2;
955                break;
956            case clickhouseDeleteMutation:
957                defaultExpr = (TExpression)arg2;
958                break;
959            case clickhouseDropPartition:
960            case clickhouseDetachPartition:
961            case clickhouseAttachPartition:
962            case clickhouseFreezePartition:
963            case clickhouseUnfreezePartition:
964                partitionExpr = (TParseTreeNode)arg2;
965                break;
966            case setPrivileges:
967                newTableName = (TObjectName)arg2;
968                break;
969            case AddColumn:
970                this.columnDefinitionList = (TColumnDefinitionList)arg2;
971                break;
972            case AlterColumn:
973                this.columnName = (TObjectName)arg2;
974                this.columnName.setDbObjectType(EDbObjectType.column);
975                break;
976            case attachPartition:
977            case detachPartition:
978            case modifySubPartition:
979                partitionName = (TObjectName)arg2;
980                if (partitionName != null) partitionName.setDbObjectType(EDbObjectType.partition);
981                break;
982            case swapWith:
983                newTableName = (TObjectName)arg2;
984                break;
985            case setDataRetentionTimeInDays:
986                break;
987            case setComment:
988                break;
989            case RenameTable:
990                newTableName = (TObjectName)arg2;
991                newTableName.setDbObjectType(EDbObjectType.table);
992                break;
993            case appendFrom:
994                this.sourceTableName = (TObjectName) arg2;
995                break;
996            case AddConstraint:
997                if (arg2 instanceof TConstraint){
998                    this.tableConstraint = (TConstraint) arg2;
999                }else if (arg2 instanceof TConstraintList){
1000                    this.constraintList  = (TConstraintList) arg2;
1001                }
1002                break;
1003            case mysqlTableOption:
1004                this.mySQLTableOption = (TMySQLCreateTableOption)arg2;
1005                break;
1006            case renameIndex:
1007                this.indexName = (TObjectName)arg2;
1008                this.indexName.setDbObjectTypeDirectly(EDbObjectType.index);
1009                break;
1010            case partition:
1011                this.tablePartition = (TBaseTablePartition) arg2;
1012                break;
1013            case addPeriodForClause:
1014                this.periodForClause = (TPeriodForClause)arg2;
1015                break;
1016            case clickhouseDetachPart:
1017            case clickhouseAttachPart:
1018            case clickhouseApplyDeletedMask:
1019            case clickhouseApplyPatches:
1020            case clickhouseModifySetting:
1021            case clickhouseResetSetting:
1022            case clickhouseModifyComment:
1023            case clickhouseColumnRemoveTtl:
1024                this.clickhouseOperand1 = (TParseTreeNode)arg2;
1025                break;
1026            default:
1027                if (arg2 instanceof TColumnDefinitionList){
1028                   this.columnDefinitionList = (TColumnDefinitionList)arg2;
1029                }else if (arg2 instanceof TConstraintList){
1030                   this.constraintList = (TConstraintList)arg2;
1031                }else if (arg2 instanceof TObjectNameList) {
1032
1033                   this.columnNameList = (TObjectNameList)arg2;
1034                }else if (arg2 instanceof TDummyList) {
1035                   TDummyList dlist = (TDummyList)arg2;
1036                    TDummy dm = null;
1037                   for(int i=0;i<dlist.size();i++){
1038                       dm = dlist.getDummyItem(i);
1039                       this.getColumnNameList().addObjectName((TObjectName)dm.node1);
1040                   }
1041
1042                   if ((optionType == EAlterTableOptionType.DropColumn)&&(this.getColumnNameList().size() > 0)){
1043                       this.columnName = this.getColumnNameList().getObjectName(0);
1044                   }
1045                }
1046                break;
1047
1048        }
1049
1050     }
1051
1052
1053    private String comment;
1054
1055    public String getComment() {
1056        return comment;
1057    }
1058
1059    private TExpression commentExpr;
1060
1061    public TExpression getCommentExpr() {
1062        return commentExpr;
1063    }
1064
1065    public void setNewConstraintName(TObjectName newConstraintName) {
1066        this.newConstraintName = newConstraintName;
1067    }
1068
1069    public void setConstraintName(TDummy pName) {
1070        if (pName == null) return;
1071        if (pName.node1 == null) return;
1072        this.constraintName = (TObjectName)pName.node1;
1073    }
1074    public void setConstraintName(TObjectName constraintName) {
1075
1076        this.constraintName = constraintName;
1077    }
1078
1079    private TColumnDefinition newColumnDef;
1080
1081    /**
1082     *
1083     * @return {@link TColumnDefinition}, valid when {@link #getOptionType()} is:
1084     * <p>{@link EAlterTableOptionType#ChangeColumn}
1085     */
1086
1087    public TColumnDefinition getNewColumnDef() {
1088        return newColumnDef;
1089    }
1090
1091    /**
1092     *
1093     * valid when {@link #getOptionType()} is:
1094     * <p>{@link EAlterTableOptionType#serde}
1095     * @return serde name
1096     */
1097    public TObjectName getSerdeName() {
1098        return serdeName;
1099    }
1100
1101    public void init(Object arg1,Object arg2,Object arg3){
1102        init(arg1);
1103        switch (optionType){
1104            case AlterColumn:
1105                init(arg1,arg2);
1106                AlterColumnSubType = (EAlterColumnSubType)arg3;
1107                break;
1108            case ChangeColumn:
1109                this.columnName = (TObjectName)arg2;
1110                this.newColumnDef = (TColumnDefinition)arg3;
1111
1112                break;
1113            case serde:
1114                serdeName  = (TObjectName)arg2;
1115                tableProperties = (TPTNodeList)arg3;
1116
1117                break;
1118            case exchangePartition:
1119                if ((dbvendor == EDbVendor.dbvoracle)
1120                        ||(dbvendor == EDbVendor.dbvgaussdb)||(dbvendor == EDbVendor.dbvedb)||(dbvendor == EDbVendor.dbvgreenplum)
1121                        ||(dbvendor == EDbVendor.dbvmysql)){
1122                    partitionName = (TObjectName)arg2;
1123                    partitionName.setDbObjectType(EDbObjectType.partition);
1124                }else{
1125                    exchangePartitionSpec = (TPartitionExtensionClause)arg2;
1126                }
1127
1128                newTableName = (TObjectName)arg3;
1129                newTableName.setDbObjectType(EDbObjectType.table);
1130                break;
1131            case RenameTable:
1132                //A RENAME carrying TWO names and no INDEX/KEY keyword is a
1133                //column rename, not a table rename: the MySQL-family grammars
1134                //classify both RENAME shapes through
1135                //getAlterTableOptionTypeByToken(), which only sees the optional
1136                //INDEX/KEY token and so cannot tell "RENAME newtbl" from
1137                //"RENAME oldcol TO newcol". Left labelled RenameTable the
1138                //option held column-shaped data with a null newTableName and
1139                //doParse() threw building a TTable from it (mantis 4682).
1140                //Relabelling here makes the bare form identical to the explicit
1141                //RENAME COLUMN oldcol TO newcol form.
1142                setOptionType(EAlterTableOptionType.RenameColumn);
1143                this.columnName = (TObjectName)arg2;
1144                this.newColumnName = (TObjectName)arg3;
1145                break;
1146            case RenameColumn:
1147                this.columnName = (TObjectName)arg2;
1148                this.newColumnName = (TObjectName)arg3;
1149                break;
1150            case modifyPrimaryKey:
1151                if (arg2 !=null){
1152                    indexName = (TObjectName)arg2;
1153                }
1154                columnNameList = (TObjectNameList)arg3;
1155                break;
1156            case switchPartition:
1157                newTableName = (TObjectName)arg2;
1158                partitionExpression1 = (TExpression)arg3;
1159                break;
1160            case attachPartition:
1161                partitionName = (TObjectName)arg2;
1162                partitionBoundSpec = (TPartitionBoundSpecSqlNode) arg3;
1163                break;
1164            case reorganizePartition:
1165                nameList = (TObjectNameList) arg2;
1166                partitionDefinitionList = (ArrayList<TPartitionDefinition>)arg3;
1167                break;
1168            case renameIndex:
1169                this.indexName = (TObjectName)arg2;
1170                this.indexName.setDbObjectTypeDirectly(EDbObjectType.index);
1171                this.newIndexName  = (TObjectName)arg3;
1172                this.newIndexName.setDbObjectTypeDirectly(EDbObjectType.index);
1173                break;
1174            case clickhouseUpdateMutation:
1175                this.mutationUpdateList = (TResultColumnList)arg2;
1176                this.defaultExpr = (TExpression)arg3;
1177                break;
1178            case clickhouseFetchPartition:
1179                this.partitionExpr = (TParseTreeNode)arg2;
1180                // arg3 is the FROM path string constant
1181                break;
1182            case clickhouseMovePartition:
1183                this.partitionExpr = (TParseTreeNode)arg2;
1184                this.newTableName = (TObjectName)arg3;
1185                this.newTableName.setDbObjectType(EDbObjectType.table);
1186                break;
1187            case clickhouseReplacePartition:
1188                this.partitionExpr = (TParseTreeNode)arg2;
1189                this.sourceTableName = (TObjectName)arg3;
1190                this.sourceTableName.setDbObjectType(EDbObjectType.table);
1191                break;
1192            case clickhouseAttachPartitionFrom:
1193                this.partitionExpr = (TParseTreeNode)arg2;
1194                this.sourceTableName = (TObjectName)arg3;
1195                this.sourceTableName.setDbObjectType(EDbObjectType.table);
1196                break;
1197            case clickhouseFreezePartitionWithName:
1198            case clickhouseUnfreezePartitionWithName:
1199            case clickhouseMovePart:
1200            case clickhouseMovePartitionToStorage:
1201                this.partitionExpr = (TParseTreeNode)arg2;
1202                this.clickhouseOperand2 = (arg3 instanceof TParseTreeNode) ? (TParseTreeNode)arg3 : null;
1203                break;
1204            case clickhouseMaterializeColumn:
1205            case clickhouseMaterializeIndex:
1206            case clickhouseMaterializeProjection:
1207            case clickhouseClearColumn:
1208            case clickhouseClearIndex:
1209            case clickhouseClearProjection:
1210            case clickhouseDropProjection:
1211            case clickhouseAddProjection:
1212            case clickhouseAddIndexExpr:
1213            case clickhouseColumnModifySetting:
1214            case clickhouseColumnResetSetting:
1215                this.clickhouseOperand1 = (arg2 instanceof TParseTreeNode) ? (TParseTreeNode)arg2 : null;
1216                this.clickhouseOperand2 = (arg3 instanceof TParseTreeNode) ? (TParseTreeNode)arg3 : null;
1217                break;
1218            case clickhouseAddConstraintCheck:
1219                this.clickhouseOperand1 = (arg2 instanceof TParseTreeNode) ? (TParseTreeNode)arg2 : null;
1220                this.defaultExpr = (TExpression)arg3;
1221                break;
1222            default:
1223                this.columnName = (TObjectName)arg2;
1224                this.newColumnName = (TObjectName)arg3;
1225                break;
1226        }
1227    }
1228
1229    public void init(Object arg1,Object arg2,Object arg3,Object arg4) {
1230        init(arg1,arg2,arg3);
1231        switch (optionType) {
1232            case switchPartition:
1233                partitionExpression2 = (TExpression)arg4;
1234                break;
1235            case AlterColumn:
1236                switch (AlterColumnSubType){
1237                    case Comment:
1238                        this.comment = ((TSourceToken)arg4).toString();
1239                        break;
1240                }
1241                break;
1242            default:
1243                break;
1244        }
1245    }
1246
1247    private ArrayList<TPartitionDefinition> partitionDefinitionList;
1248
1249    public ArrayList<TPartitionDefinition> getPartitionDefinitionList() {
1250        return partitionDefinitionList;
1251    }
1252
1253    //private TPTNodeList <TPartitionExtensionClause> partitionSpecList;
1254    private ArrayList<TPartitionExtensionClause> partitionSpecList;
1255
1256    /**
1257     * Hive, Impala, partition spec list in unarchive clause when option type is {@link EAlterTableOptionType#unArchive},
1258     * {@link EAlterTableOptionType#archive}.
1259     * <br>partition spec list in touch clause when option type is {@link EAlterTableOptionType#touch},
1260     * <br>partition spec list in drop clause when option type is {@link EAlterTableOptionType#dropPartitionSpecList},
1261     * <br>partition spec list in add clause when option type is {@link EAlterTableOptionType#addPartitionSpecList},
1262     *
1263     * @return    partition spec list
1264     */
1265    public ArrayList<TPartitionExtensionClause> getPartitionSpecList() {
1266        return partitionSpecList;
1267    }
1268
1269    private TPTNodeList <THiveKeyValueProperty> tableProperties;
1270
1271    /**
1272     * Hive, Impala, table properties of SET/UNSET TBLPROPERTIES clause
1273     * when {@link #getOptionType()} is {@link EAlterTableOptionType#setTableProperties} or
1274     * {@link EAlterTableOptionType#unsetTableProperties}
1275     * <br> table properties of SET SERDE clause when {@link #getOptionType()} is {@link EAlterTableOptionType#serde}
1276     *
1277     * @return  table properties of SET/UNSET TBLPROPERTIES/SET SERDE clause.
1278     */
1279    public TPTNodeList<THiveKeyValueProperty> getTableProperties() {
1280        return tableProperties;
1281    }
1282
1283    private THiveTableFileFormat fileFormat;
1284
1285    /**
1286     * Hive,Impala,file format of SET FILEFORMAT clause valid when {@link #getOptionType()} is {@link EAlterTableOptionType#setFileFormat}
1287     *
1288     * @return      file format of SET FILEFORMAT
1289     */
1290    public THiveTableFileFormat getFileFormat() {
1291        return fileFormat;
1292    }
1293
1294    private TObjectName tableLocation;
1295
1296    /**
1297     * Hive,Impala,  file location of SET LOCATION clause valid when {@link #getOptionType()} is:
1298     * {@link EAlterTableOptionType#setLocation}
1299     *
1300     * @return   file location of SET LOCATION clause
1301     */
1302    public TObjectName getTableLocation() {
1303        return tableLocation;
1304    }
1305
1306    private TPartitionDefinition partitionDefinition;
1307
1308    public TPartitionDefinition getPartitionDefinition() {
1309        return partitionDefinition;
1310    }
1311
1312    /**
1313     * Hive, Impala, new partition spec in RENAME TO clause
1314     * valid when {@link #getOptionType()} is:
1315     * {@link EAlterTableOptionType#renamePartition}
1316     *
1317     * @return  new partition spec in RENAME TO clause
1318     */
1319    public TPartitionExtensionClause getNewPartitionSpec() {
1320        return newPartitionSpec;
1321    }
1322
1323
1324    private TPartitionExtensionClause newPartitionSpec;
1325
1326    private TConstant numberOfBuckets;
1327
1328    /**
1329     * Hive, Impala, number of buckets of INTO BUCKETS clause
1330     * valid when {@link #getOptionType()} is:
1331     * {@link EAlterTableOptionType#tableBuckets}
1332     *
1333     * @return  number of buckets of INTO BUCKETS clause
1334     */
1335    public TConstant getNumberOfBuckets() {
1336        return numberOfBuckets;
1337    }
1338
1339    private TExpressionList skewedLocations;
1340
1341    /**
1342     * Hive, Impala, skewed location of SET SKEWED LOCATION clause
1343     * valid when {@link #getOptionType()} is:
1344     * {@link EAlterTableOptionType#skewedLocation}
1345     *
1346     * @return  skewed location of SET SKEWED LOCATION clause
1347     */
1348    public TExpressionList getSkewedLocations() {
1349        return skewedLocations;
1350    }
1351
1352    private THiveTableBuckets tableBuckets;
1353
1354
1355    /**
1356     * Hive, Impala, clustered by ... [sorted by ...] into number buckets
1357     * valid when {@link #getOptionType()} is:
1358     * {@link EAlterTableOptionType#clusteredSorted}
1359     *
1360     * @return    table buckets
1361     */
1362    public THiveTableBuckets getTableBuckets() {
1363        return tableBuckets;
1364    }
1365
1366    private TColumnDefinition partitionColumnDef;
1367
1368    /**
1369     * Hive,Impala, column of  PARTITION COLUMN ( columnDef ) clause
1370     * valid when {@link #getOptionType()} is:
1371     * {@link EAlterTableOptionType#clusteredSorted}
1372     *
1373     * @return  column of  PARTITION COLUMN ( columnDef ) clause
1374     */
1375    public TColumnDefinition getPartitionColumnDef() {
1376        return partitionColumnDef;
1377    }
1378
1379    private THiveTableSkewed     tableSkewed;
1380
1381    /**
1382     * Hive, Impala,   tableSkewed clause syntax like: SKEWED BY '(' columnNameList ')' ON '(' skewedValueElement ')'
1383     * valid when {@link #getOptionType()} is:
1384     * {@link EAlterTableOptionType#tableSkewed}
1385     *
1386     * @return         tableSkewed clause
1387     */
1388    public THiveTableSkewed getTableSkewed() {
1389        return tableSkewed;
1390    }
1391
1392    /**
1393     * Hive,Impala, partition spec of EXCHANGE partitionSpec WITH TABLE tableName clause.
1394     * valid when {@link #getOptionType()} is:
1395     * {@link EAlterTableOptionType#exchangePartition}
1396     *
1397     * @return     partition spec of EXCHANGE partitionSpec WITH TABLE tableName clause.
1398     */
1399    public TPartitionExtensionClause getExchangePartitionSpec() {
1400        return exchangePartitionSpec;
1401    }
1402
1403    private TPartitionExtensionClause exchangePartitionSpec;
1404
1405    private EAlterTableOptionType optionType = EAlterTableOptionType.Unknown;
1406
1407
1408    public void doParse(TCustomSqlStatement psql, ESqlClause plocation){
1409
1410        switch (optionType){
1411            case AddColumn:
1412                getColumnDefinitionList().doParse(psql,plocation);
1413                for(int i=0;i<getColumnDefinitionList().size();i++){
1414                    TColumnDefinition cd = getColumnDefinitionList().getColumn(i);
1415
1416                    cd.getColumnName().setLocation(ESqlClause.createTable);
1417                    cd.getColumnName().setLinkedColumnDef(cd);
1418                    psql.tables.getTable(0).getLinkedColumns().addObjectName(cd.getColumnName());
1419                    cd.getColumnName().setSourceTable(psql.tables.getTable(0));
1420
1421                }
1422                break;
1423            case ModifyColumn:
1424                if (getColumnDefinitionList() != null){
1425                    getColumnDefinitionList().doParse(psql,plocation);
1426                    for(int i=0;i<getColumnDefinitionList().size();i++){
1427                        TColumnDefinition cd = getColumnDefinitionList().getColumn(i);
1428
1429                        cd.getColumnName().setLocation(ESqlClause.createTable);
1430                        cd.getColumnName().setLinkedColumnDef(cd);
1431                        psql.tables.getTable(0).getLinkedColumns().addObjectName(cd.getColumnName());
1432                        cd.getColumnName().setSourceTable(psql.tables.getTable(0));
1433
1434                    }
1435                }
1436                break;
1437            case DropColumn:
1438                for(int i=0;i<getColumnNameList().size();i++){
1439                    TObjectName dropedColumn = getColumnNameList().getObjectName(i);
1440                    psql.tables.getTable(0).getLinkedColumns().addObjectName(dropedColumn);
1441                    dropedColumn.setSourceTable(psql.tables.getTable(0));
1442                }
1443                break;
1444            case ChangeColumn:
1445                psql.tables.getTable(0).getLinkedColumns().addObjectName(getColumnName());
1446                getColumnName().setSourceTable(psql.tables.getTable(0));
1447
1448                TObjectName newColumn = newColumnDef.getColumnName();
1449                psql.tables.getTable(0).getLinkedColumns().addObjectName(newColumn);
1450                newColumn.setSourceTable(psql.tables.getTable(0));
1451
1452                break;
1453            case AddConstraintPK:
1454            case AddConstraintUnique:
1455                if (getIndexCols() != null){
1456                    for(int i=0;i<getIndexCols().size();i++){
1457                        psql.tables.getTable(0).getLinkedColumns().addObjectName(getIndexCols().getElement(i).getColumnName());
1458                        getIndexCols().getElement(i).getColumnName().setSourceTable(psql.tables.getTable(0));
1459                    }
1460                }
1461                else if (getColumnNameList().size() > 0){
1462                    for (int i=0;i<getColumnNameList().size();i++){
1463                        TObjectName columnName = getColumnNameList().getObjectName(i);
1464                        psql.tables.getTable(0).getLinkedColumns().addObjectName(columnName);
1465                        columnName.setSourceTable(psql.tables.getTable(0));
1466                    }
1467                }
1468                break;
1469            case AddConstraintFK:
1470                if (getIndexCols() != null){
1471                    for(int i=0;i<getIndexCols().size();i++){
1472                        psql.tables.getTable(0).getLinkedColumns().addObjectName(getIndexCols().getElement(i).getColumnName());
1473                        getIndexCols().getElement(i).getColumnName().setSourceTable(psql.tables.getTable(0));
1474                    }
1475                }
1476                else if (getColumnNameList().size() > 0){
1477                    for (int i=0;i<getColumnNameList().size();i++){
1478                        TObjectName columnName = getColumnNameList().getObjectName(i);
1479                        psql.tables.getTable(0).getLinkedColumns().addObjectName(columnName);
1480                        columnName.setSourceTable(psql.tables.getTable(0));
1481                    }
1482                }
1483
1484                if (referencedObjectName != null){
1485                    referencedObjectName.setDbObjectType(EDbObjectType.table);
1486                    referencedTable = psql.analyzeTablename(referencedObjectName);
1487                    if (getReferencedColumnList() != null) {
1488                        for (int i = 0; i < getReferencedColumnList().size(); i++) {
1489                            TObjectName refColumn = getReferencedColumnList().getObjectName(i);
1490                            referencedTable.getLinkedColumns().addObjectName(refColumn);
1491                            refColumn.setSourceTable(referencedTable);
1492                        }
1493                    }
1494
1495                }
1496                break;
1497            case RenameTable:
1498                //Every grammar rule that builds a RenameTable option also sets
1499                //the new name, but a missing one must not crash the parse
1500                //(mantis 4682).
1501                if (newTableName != null){
1502                    TTable lcTable = new TTable(newTableName);
1503                    lcTable.setPropertyFromObjectName(newTableName, ETableEffectType.tetAlterTableRename);
1504                    psql.addToTables(lcTable);
1505                }
1506                break;
1507            case AddConstraint:
1508                if (tableConstraint != null){
1509                    tableConstraint.doParse(psql,ESqlClause.unknown);
1510                }else if (constraintList != null){
1511                    constraintList.doParse(psql,ESqlClause.unknown);
1512                }
1513                break;
1514        }
1515
1516    }
1517
1518    private TExpression retenttionTimeInDays;
1519
1520    public TExpression getRetenttionTimeInDays() {
1521        return retenttionTimeInDays;
1522    }
1523
1524    public void accept(TParseTreeVisitor v)
1525    {
1526        v.preVisit(this);
1527        v.postVisit(this);
1528    }
1529
1530    public void acceptChildren(TParseTreeVisitor v)
1531    {
1532        v.preVisit(this);
1533        switch (optionType){
1534            case AlterColumn:
1535                columnName.acceptChildren(v);
1536                if (newDataType != null){
1537                    newDataType.acceptChildren(v);
1538                }
1539                break;
1540            case AddColumn:
1541                for(int i=0;i<getColumnDefinitionList().size();i++){
1542                    TColumnDefinition cd = getColumnDefinitionList().getColumn(i);
1543                    cd.acceptChildren(v);
1544                }
1545                break;
1546            case ModifyColumn:
1547                if (getColumnDefinitionList() != null){
1548                    for(int i=0;i<getColumnDefinitionList().size();i++){
1549                        TColumnDefinition cd = getColumnDefinitionList().getColumn(i);
1550                        cd.acceptChildren(v);
1551                    }
1552                }
1553                break;
1554            case DropColumn:
1555                for(int i=0;i<getColumnNameList().size();i++){
1556                    TObjectName dropedColumn = getColumnNameList().getObjectName(i);
1557                    dropedColumn.acceptChildren(v);
1558                }
1559                break;
1560            case ChangeColumn:
1561                break;
1562            case AddConstraintPK:
1563            case AddConstraintUnique:
1564                break;
1565            case AddConstraintFK:
1566                break;
1567            case RenameTable:
1568                break;
1569        }
1570        // ClickHouse batch-5 sub-clauses store their operands generically;
1571        // they are real AST children and must be visible to visitors. TDummy
1572        // wrappers (projection bodies, IN PARTITION clauses) have no traversal
1573        // of their own, so unwrap them here rather than change TDummy for
1574        // every vendor.
1575        visitClickhouseOperand(clickhouseOperand1, v);
1576        visitClickhouseOperand(clickhouseOperand2, v);
1577        if ((optionType == EAlterTableOptionType.clickhouseAddConstraintCheck) && (defaultExpr != null)){
1578            defaultExpr.acceptChildren(v);
1579        }
1580        v.postVisit(this);
1581    }
1582
1583    private static void visitClickhouseOperand(TParseTreeNode node, TParseTreeVisitor v){
1584        if (node == null) return;
1585        if (node instanceof TDummy){
1586            TDummy dummy = (TDummy)node;
1587            visitClickhouseOperand(dummy.node1, v);
1588            visitClickhouseOperand(dummy.node2, v);
1589            visitClickhouseOperand(dummy.node3, v);
1590            if (dummy.list1 != null) dummy.list1.acceptChildren(v);
1591            if (dummy.list2 != null) dummy.list2.acceptChildren(v);
1592        } else {
1593            node.acceptChildren(v);
1594        }
1595    }
1596
1597    public void setSerdeName(TObjectName serdeName) {
1598        this.serdeName = serdeName;
1599    }
1600
1601    public void setDropRestrictType(EKeyReferenceType dropRestrictType) {
1602        this.dropRestrictType = dropRestrictType;
1603    }
1604
1605    public void setColumnDefinitionList(TColumnDefinitionList columnDefinitionList) {
1606        this.columnDefinitionList = columnDefinitionList;
1607    }
1608
1609    public void setConstraintList(TConstraintList constraintList) {
1610        this.constraintList = constraintList;
1611    }
1612
1613    public void setColumnNameList(TObjectNameList columnNameList) {
1614        this.columnNameList = columnNameList;
1615    }
1616
1617    public void setNewColumnName(TObjectName newColumnName) {
1618        this.newColumnName = newColumnName;
1619    }
1620
1621    public void setSchemaName(TObjectName schemaName) {
1622        this.schemaName = schemaName;
1623    }
1624
1625    public void setConstraintNameList(TObjectNameList constraintNameList) {
1626        this.constraintNameList = constraintNameList;
1627    }
1628
1629    public void setPartitionExpression1(TExpression partitionExpression1) {
1630        this.partitionExpression1 = partitionExpression1;
1631    }
1632
1633    public void setPartitionExpression2(TExpression partitionExpression2) {
1634        this.partitionExpression2 = partitionExpression2;
1635    }
1636
1637    public void setNewColumnDef(TColumnDefinition newColumnDef) {
1638        this.newColumnDef = newColumnDef;
1639    }
1640
1641//    public void setPartitionSpecList(TPTNodeList<TPartitionExtensionClause> partitionSpecList) {
1642//        this.partitionSpecList = partitionSpecList;
1643//    }
1644
1645    public void setTableProperties(TPTNodeList<THiveKeyValueProperty> tableProperties) {
1646        this.tableProperties = tableProperties;
1647    }
1648
1649    public void setFileFormat(THiveTableFileFormat fileFormat) {
1650        this.fileFormat = fileFormat;
1651    }
1652
1653    public void setTableLocation(TObjectName tableLocation) {
1654        this.tableLocation = tableLocation;
1655    }
1656
1657    public void setNewPartitionSpec(TPartitionExtensionClause newPartitionSpec) {
1658        this.newPartitionSpec = newPartitionSpec;
1659    }
1660
1661    public void setNumberOfBuckets(TConstant numberOfBuckets) {
1662        this.numberOfBuckets = numberOfBuckets;
1663    }
1664
1665    public void setSkewedLocations(TExpressionList skewedLocations) {
1666        this.skewedLocations = skewedLocations;
1667    }
1668
1669    public void setTableBuckets(THiveTableBuckets tableBuckets) {
1670        this.tableBuckets = tableBuckets;
1671    }
1672
1673    public void setPartitionColumnDef(TColumnDefinition partitionColumnDef) {
1674        this.partitionColumnDef = partitionColumnDef;
1675    }
1676
1677    public void setTableSkewed(THiveTableSkewed tableSkewed) {
1678        this.tableSkewed = tableSkewed;
1679    }
1680
1681    public void setExchangePartitionSpec(TPartitionExtensionClause exchangePartitionSpec) {
1682        this.exchangePartitionSpec = exchangePartitionSpec;
1683    }
1684
1685    public void setOptionType(EAlterTableOptionType optionType) {
1686        this.optionType = optionType;
1687    }
1688}