001package gudusoft.gsqlparser.stmt;
002
003import gudusoft.gsqlparser.*;
004import gudusoft.gsqlparser.nodes.*;
005import gudusoft.gsqlparser.nodes.flink.TFlinkWatermarkClause;
006import gudusoft.gsqlparser.nodes.flink.TFlinkWithClause;
007import gudusoft.gsqlparser.nodes.hive.*;
008import gudusoft.gsqlparser.nodes.netezza.TExternalTableOption;
009import gudusoft.gsqlparser.nodes.oracle.TPhysicalProperties;
010import gudusoft.gsqlparser.nodes.postgresql.TInheritsClause;
011import gudusoft.gsqlparser.nodes.postgresql.TPartitionBoundSpecSqlNode;
012import gudusoft.gsqlparser.nodes.teradata.TIndexDefinition;
013import gudusoft.gsqlparser.nodes.teradata.TTeradataPeriodForClause;
014
015import java.util.*;
016
017/**
018 * SQL create table statement.
019 * <br>
020 * {@link #getTargetTable} returns the created table. {@link #getColumnList()} returns columns created in the table.
021 * <br> {@link #getTableConstraints()} returns table level constraints if any.
022 * <br> {@link #getSubQuery()} returns select statement that generate data for this table.
023 * <br><br>Example:
024 * <pre>
025 *     CREATE TABLE dbo.Employee (EmployeeID int PRIMARY KEY CLUSTERED);
026 * </pre>
027 * Table:dbo.Employee can be fetched from {@link #getTargetTable} or the first element of {@link #tables}
028 * <br> column definitions: can be fetched from {@link #getColumnList}
029 * <br>
030 * table constraints: {@link #getTableConstraints}
031 *
032 */
033public class TCreateTableSqlStatement extends TCustomSqlStatement {
034
035
036    public TInheritsClause getInheritsClause() {
037        return inheritsClause;
038    }
039
040    private TInheritsClause inheritsClause;
041
042    private TBaseTablePartition tablePartition;
043
044
045    public TBaseTablePartition getTablePartition() {
046        return tablePartition;
047    }
048
049    public void setPartitionBoundSpec(TPartitionBoundSpecSqlNode partitionBoundSpec) {
050        this.partitionBoundSpec = partitionBoundSpec;
051    }
052
053    public TPartitionBoundSpecSqlNode getPartitionBoundSpec() {
054        return partitionBoundSpec;
055    }
056
057    /**
058     * postgresql PartitionBoundSpec
059     * https://www.postgresql.org/docs/current/sql-createtable.html
060     */
061    private TPartitionBoundSpecSqlNode partitionBoundSpec;
062
063    public TTableProperties getTableProperties() {
064        return tableProperties;
065    }
066
067    public void setTableProperties(TTableProperties tableProperties) {
068        this.tableProperties = tableProperties;
069    }
070
071    private TTableProperties tableProperties;
072
073    public enum TableSourceType  {normal,subquery,like,clone,copy,partitionOf,forExchangeWith,usingTemplate,refreshUsing};
074    private TableSourceType tableSourceType = TableSourceType.normal;
075
076    private List<String> externalTableOptionList = null;
077
078    /**
079     * sql server create external table with options
080     * @return
081     */
082    public  List<String> getExternalTableOptionNames(){
083        return  TBaseType.getOptionNames(externalTableOptionList);
084    }
085
086    /**
087     * sql server create external table with option.
088     *
089     * @param optionName
090     * @return
091     */
092    public String getExternalTableOption(String optionName){
093        return TBaseType.getOption(externalTableOptionList,optionName);
094    }
095
096    public TableSourceType getTableSourceType() {
097        return tableSourceType;
098    }
099
100    private TObjectName cloneSourceTable = null;
101
102    public TObjectName getCloneSourceTable() {
103        return cloneSourceTable;
104    }
105
106    private TExternalTableOption externalTableOption = null;
107
108    public TExternalTableOption getExternalTableOption() {
109        return externalTableOption;
110    }
111
112    private TExpression partitionByExpr;
113
114    public void setPartitionByExpr(TExpression partitionByExpr) {
115        this.partitionByExpr = partitionByExpr;
116    }
117
118    /**
119     * Bigquery partition by expr
120     *
121     * @return expr
122     */
123    public TExpression getPartitionByExpr() {
124        return partitionByExpr;
125    }
126
127    private String awsSnsTopic = null;
128
129    public void setAwsSnsTopic(String awsSnsTopic) {
130        this.awsSnsTopic = awsSnsTopic;
131    }
132
133    public String getAwsSnsTopic() {
134        return awsSnsTopic;
135    }
136
137    private TObjectNameList partitionColumnList;
138
139    public void setPartitionColumnList(TObjectNameList partitionColumnList) {
140        this.partitionColumnList = partitionColumnList;
141    }
142
143    public TObjectNameList getPartitionColumnList() {
144        return partitionColumnList;
145    }
146
147    public void setFileFormatName(String fileFormatName) {
148        this.fileFormatName = fileFormatName;
149    }
150
151    public void setFileFormatType(String fileFormatType) {
152        this.fileFormatType = fileFormatType;
153    }
154
155    public String getFileFormatName() {
156        return fileFormatName;
157    }
158
159    public String getFileFormatType() {
160        return fileFormatType;
161    }
162
163    private String fileFormatName = null;
164    private String fileFormatType = null;
165
166    private String regex_pattern;
167
168    public void setRegex_pattern(String regex_pattern) {
169        this.regex_pattern = regex_pattern;
170    }
171
172    public String getRegex_pattern() {
173        return regex_pattern;
174    }
175
176    private TStageLocation stageLocation;
177
178    public void setStageLocation(TStageLocation stageLocation) {
179        this.stageLocation = stageLocation;
180    }
181
182    public TStageLocation getStageLocation() {
183        return stageLocation;
184    }
185
186    public void setTableOptions(ArrayList<TCreateTableOption> tableOptions) {
187        this.tableOptions = tableOptions;
188    }
189
190    public ArrayList<TCreateTableOption> getTableOptions() {
191        return tableOptions;
192    }
193
194    private ArrayList<TCreateTableOption> tableOptions;
195
196    public void setOnFilegroup(TDummy onFilegroup) {
197        this.onFilegroup = onFilegroup;
198    }
199
200    public TDummy getOnFilegroup() {
201        return onFilegroup;
202    }
203
204    private TDummy onFilegroup = null;
205
206    /**
207     * Oracle physical properties
208     * @return Oracle physical properties
209     */
210    public TPhysicalProperties getPhysicalProperties() {
211        return physicalProperties;
212    }
213
214    private TPhysicalProperties physicalProperties;
215
216    private EnumSet<ETableKind> tableKinds = EnumSet.noneOf(ETableKind.class);
217
218    public void setTableKinds(EnumSet<ETableKind> tableKinds) {
219        this.tableKinds = tableKinds;
220    }
221
222    /**
223     * Type of this table
224     * @return Type of this table
225     */
226    public EnumSet<ETableKind> getTableKinds() {
227        return tableKinds;
228    }
229
230    private TTable asTable;
231
232    /**
233     * Netezza, Teradata, as table name.
234     * @return as table name
235     */
236    public TTable getAsTable() {
237        return asTable;
238    }
239
240    private boolean externalTable;
241
242    /**
243     * @deprecated As of v1.9.7.2 , replace by {@link #isExternal}
244     * <br>
245     * Netezza, whether it is a external table
246     * @return true if it's netezza create external table
247     */
248    public boolean isExternalTable() {
249        return externalTable;
250    }
251
252    private ArrayList <TIndexDefinition> indexDefinitions;
253
254    /**
255     * Teradata index definition
256     *
257     * <pre>UNIQUE PRIMARY INDEX (storeid, productid, salesdate)</pre>
258     * @return  list of index definition
259     */
260    public ArrayList<TIndexDefinition> getIndexDefinitions() {
261        return indexDefinitions;
262    }
263
264    /**
265     * Teradata PERIOD FOR clauses that define derived temporal columns.
266     * A table can have multiple PERIOD FOR clauses (e.g., one for VALIDTIME and one for TRANSACTIONTIME).
267     */
268    private ArrayList<TTeradataPeriodForClause> periodForClauses;
269
270    /**
271     * Returns the list of Teradata PERIOD FOR clauses in this CREATE TABLE statement.
272     * PERIOD FOR clauses define derived columns that represent time periods from two date/timestamp columns.
273     *
274     * @return list of PERIOD FOR clauses, may be null or empty if none are defined
275     */
276    public ArrayList<TTeradataPeriodForClause> getPeriodForClauses() {
277        return periodForClauses;
278    }
279
280    /**
281     * Flink WATERMARK clauses that define event-time processing.
282     * A table typically has at most one WATERMARK clause.
283     */
284    private ArrayList<TFlinkWatermarkClause> watermarkClauses;
285
286    /**
287     * Returns the list of Flink WATERMARK clauses in this CREATE TABLE statement.
288     * WATERMARK clauses define how watermarks are generated for event-time processing.
289     *
290     * @return list of WATERMARK clauses, may be null or empty if none are defined
291     */
292    public ArrayList<TFlinkWatermarkClause> getWatermarkClauses() {
293        return watermarkClauses;
294    }
295
296    /**
297     * Returns the first Flink WATERMARK clause in this CREATE TABLE statement.
298     * Typically only one WATERMARK clause is defined per table.
299     *
300     * @return the first WATERMARK clause, or null if none are defined
301     */
302    public TFlinkWatermarkClause getWatermarkClause() {
303        return (watermarkClauses != null && !watermarkClauses.isEmpty())
304            ? watermarkClauses.get(0)
305            : null;
306    }
307
308    private boolean external;
309    private boolean usingTemplate;
310    private boolean ifNotExists;
311    private TObjectName tableLocation;
312    private TObjectName tableComment;
313    private THiveTableProperties hiveTableProperties;
314    private THiveTablePartition hiveTablePartition;
315    private THiveTableBuckets hiveTableBuckets;
316    private THiveTableSkewed hiveTableSkewed;
317    private THiveRowFormat hiveRowFormat;
318    private THiveTableFileFormat hiveTableFileFormat;
319    private TObjectName likeTableName;
320
321    /**
322     * Flink WITH clause containing connector properties.
323     */
324    private TFlinkWithClause flinkWithClause;
325
326    /**
327     * Get the Flink WITH clause containing connector properties.
328     *
329     * <p>Flink SQL uses the WITH clause to specify connector properties:</p>
330     * <pre>
331     * CREATE TABLE my_table (
332     *   id BIGINT,
333     *   name STRING
334     * ) WITH (
335     *   'connector' = 'kafka',
336     *   'topic' = 'my-topic',
337     *   'properties.bootstrap.servers' = 'localhost:9092',
338     *   'format' = 'json'
339     * );
340     * </pre>
341     *
342     * @return the Flink WITH clause, or null if not present
343     */
344    public TFlinkWithClause getFlinkWithClause() {
345        return flinkWithClause;
346    }
347
348    /**
349     * Set the Flink WITH clause.
350     * @param flinkWithClause the Flink WITH clause
351     */
352    public void setFlinkWithClause(TFlinkWithClause flinkWithClause) {
353        this.flinkWithClause = flinkWithClause;
354    }
355
356    /**
357     * Hive, Impala,Netezza,snowflake whether it is an external table
358     * @return whether it is an external table
359     */
360    public boolean isExternal() {
361        return external;
362    }
363
364    /**
365     * Snowflake: whether this table is created with
366     * {@code CREATE TABLE ... USING TEMPLATE <query>}, where the query result
367     * (typically over INFER_SCHEMA) derives the column definitions.
368     *
369     * @return true if created via USING TEMPLATE
370     */
371    public boolean isUsingTemplate() {
372        return usingTemplate;
373    }
374
375    /**
376     * Hive, impala table row format
377     * @return table row format
378     */
379    public THiveRowFormat getHiveRowFormat() {
380        return hiveRowFormat;
381    }
382
383    /**
384     * Hive, Impala table buckets
385     * @return table buckets
386     */
387    public THiveTableBuckets getHiveTableBuckets() {
388        return hiveTableBuckets;
389    }
390
391    /**
392     * Hive, Impala table file format
393     * @return table file format
394     */
395    public THiveTableFileFormat getHiveTableFileFormat() {
396        return hiveTableFileFormat;
397    }
398
399    /**
400     * Hive, Impala table partition
401     * @return table partition
402     */
403    public THiveTablePartition getHiveTablePartition() {
404        return hiveTablePartition;
405    }
406
407    /**
408     * Hive, Impala table properties
409     * @return table properties
410     */
411    public THiveTableProperties getHiveTableProperties() {
412        return hiveTableProperties;
413    }
414
415    /**
416     * Hive, Impala skewed by clause.
417     * @return skewed by clause.
418     */
419    public THiveTableSkewed getHiveTableSkewed() {
420        return hiveTableSkewed;
421    }
422
423    /**
424     * Hive, Impala, if not exists clause
425     * @return true if not exists clause is used in create table statement
426     */
427    public boolean isIfNotExists() {
428        return ifNotExists;
429    }
430
431    /**
432     * Greenplum, table used in like clause.
433     * <br>Hive, Impala, table used in like clause.
434     * @return table used in like clause.
435     */
436    public TObjectName getLikeTableName() {
437        return likeTableName;
438    }
439
440    /**
441     * Hive, Impala, comment of the table.
442     * @return comment of the table.
443     */
444    public TObjectName getTableComment() {
445        return tableComment;
446    }
447
448    /**
449     * Hive, Impala, location of the table.
450     * @return location of the table.
451     */
452    public TObjectName getTableLocation() {
453        return tableLocation;
454    }
455
456    private TObjectName rowTypeName;
457    private TObjectName superTableName;
458
459    /**
460     * Informix, typename used in of type clause.
461     *
462     * @return row type name
463     */
464    public TObjectName getRowTypeName() {
465        return rowTypeName;
466    }
467
468    /**
469     * Informix, table name used in the under clause.
470     * @return table name used in the under clause.
471     */
472    public TObjectName getSuperTableName() {
473        return superTableName;
474    }
475
476    /**
477     * Data of the created table is derived from this select statement.
478     *
479     * @return {@link gudusoft.gsqlparser.stmt.TSelectSqlStatement} used in create table.
480     */
481    public TSelectSqlStatement getSubQuery() {
482        return subQuery;
483    }
484
485    private TSelectSqlStatement subQuery = null;
486    private TCustomSqlStatement refreshUsingStatement = null;
487    private TExecuteSqlStatement executePreparedStatement = null;//greenplum
488
489    /**
490     * Snowflake custom incremental dynamic-table refresh logic.
491     *
492     * @return the MERGE or INSERT statement inside REFRESH USING, or null
493     */
494    public TCustomSqlStatement getRefreshUsingStatement() {
495        return refreshUsingStatement;
496    }
497
498    public TExecuteSqlStatement getExecutePreparedStatement() {
499        return executePreparedStatement;
500    }
501
502
503
504    private TPTNodeList <TMySQLCreateTableOption> mySQLTableOptionList;
505
506    /**
507     * MySQL, option used in create table such as engine, auto_increment and etc.
508     * @return option used in create table such as engine, auto_increment and etc.
509     */
510    public TPTNodeList<TMySQLCreateTableOption> getMySQLTableOptionList() {
511        return mySQLTableOptionList;
512    }
513
514    public TCreateTableSqlStatement(EDbVendor dbvendor) {
515        super(dbvendor);
516        sqlstatementtype = ESqlStatementType.sstcreatetable;
517    }
518
519    void buildsql() {
520    }
521
522    void clear() {
523    }
524
525    String getasprettytext() {
526        return "";
527    }
528
529    void iterate(TVisitorAbs pvisitor) {
530    }
531
532    private TObjectName tableName = null;
533
534    /**
535     * The first table in {@link #tables}, this is the same table as {@link #getTargetTable}
536     *
537     * @return The first table in {@link #tables}, or null when the statement was
538     *         only partially parsed and no table was recorded (e.g. a syntax
539     *         error before the table name). Callers treat a missing table name
540     *         as optional, so returning null is preferred over throwing.
541     */
542    public TObjectName getTableName() {
543        if (tables == null || tables.size() == 0 || tables.getTable(0) == null) {
544            return null;
545        }
546        return tables.getTable(0).getTableName();
547    }
548
549    private boolean webTable = false;
550
551    public boolean isWebTable() {
552        return webTable;
553    }
554
555
556    private boolean readable;
557
558    public boolean isReadable() {
559        return readable;
560    }
561
562    public boolean isWritable() {
563        return writable;
564    }
565
566    private boolean writable;
567
568    private TConstant executeCmd;
569
570
571    public TConstant getExecuteCmd() {
572        return executeCmd;
573    }
574
575
576    private ArrayList<TConstant> locationFiles;
577
578    public void setLocationFiles(ArrayList<TConstant> locationFiles) {
579        this.locationFiles = locationFiles;
580    }
581
582    public ArrayList<TConstant> getLocationFiles() {
583        return locationFiles;
584    }
585
586    public int doParseStatement(TCustomSqlStatement psql) {
587       if (rootNode == null) return -1;
588       TCreateTableSqlNode createTableNode = (TCreateTableSqlNode)rootNode;
589       super.doParseStatement(psql);
590       this.tableKinds = createTableNode.getTableKinds();
591       this.tableSourceType = createTableNode.getTableSourceType();
592       this.setTargetTable(createTableNode.getTable());
593
594
595       // move to TMetadataCollector
596
597//       TSQLTable sqlTable = null;
598//        if (getSqlEnv() != null)  {
599//            if (createTableNode.getTable() != null){
600//                sqlTable = getSqlEnv().addTable(createTableNode.getTable().getFullName(),true);
601//            }
602//
603//            if (getSqlEnv().getDefaultCatalogName() != null){
604//                if (createTableNode.getTable().getTableName().getDatabaseToken() == null){
605//                    createTableNode.getTable().getTableName().setDatabaseToken(new TSourceToken(getSqlEnv().getDefaultCatalogName()),true);
606//                }
607//            }
608//
609//            createTableNode.getTable().getTableName().setSqlEnv(getSqlEnv());
610//        }
611
612        // end of move to TMetadataCollector
613
614       externalTable = createTableNode.isExternalTable();
615       physicalProperties = createTableNode.getPhysicalProperties();
616       tableProperties = createTableNode.getTableProperties();
617       this.tablePartition = createTableNode.getTablePartition();
618
619       if (createTableNode.getNetezzaExternalTableOption() != null){
620           this.externalTableOption = new TExternalTableOption(createTableNode.getNetezzaExternalTableOption().toString());
621       }
622
623       mySQLTableOptionList = createTableNode.getMySQLTableOptionList();
624       tableOptions = createTableNode.getTableOptions();
625       if (tableOptions != null){
626           for(int i=0;i<tableOptions.size();i++){
627               tableOptions.get(i).doParse(this,ESqlClause.unknown);
628           }
629       }
630
631       superTableName = createTableNode.getSuperTableName();
632       rowTypeName = createTableNode.getRowTypeName();
633       onFilegroup = createTableNode.getOnFilegroup();
634       cloneSourceTable = createTableNode.getCloneSourceTable();
635       if (cloneSourceTable != null){
636           cloneSourceTable.setDbObjectType(this.dbvendor,EDbObjectType.table);
637       }
638       likeTableName = createTableNode.getLikeTableName();
639       if (likeTableName != null){
640           likeTableName.setDbObjectType(this.dbvendor,EDbObjectType.table);
641       }
642       partitionBoundSpec = createTableNode.getPartitionBoundSpec();
643
644       tables.addTable(createTableNode.getTable());
645       asTable = createTableNode.getAsTable();
646        if (asTable != null) tables.addTable(asTable);
647       if ((createTableNode.getTableElementList() != null)&&(createTableNode.getTableElementList().size() >0 )){
648           TTableElement te;
649           TColumnDefinition cd;
650           Set<String> columnNames = new LinkedHashSet<String>();
651           for(int i=0; i<createTableNode.getTableElementList().size();i++){
652              te = createTableNode.getTableElementList().getTableElement(i);
653               if (te.getType() == TTableElement.type_column_def) {
654                   cd = te.getColumnDefinition();
655                   this.getColumnList().addColumn(cd);
656
657                   cd.doParse(this, ESqlClause.createTable);
658                   this.getTargetTable().getObjectNameReferences().addObjectName(cd.getColumnName());
659                   cd.getColumnName().setLocation(ESqlClause.createTable);
660                   cd.getColumnName().setLinkedColumnDef(cd);
661                   getTargetTable().getLinkedColumns().addObjectName(cd.getColumnName());
662                   cd.getColumnName().setSourceTable(getTargetTable());
663                   // move to TMetadataCollector
664//                   if (sqlTable != null){
665//                       sqlTable.addColumn(cd.getColumnName().toString(),cd.getDatatype());
666//                       //getTargetTable().setSqlTable(sqlTable);
667//                   }
668                   if (!columnNames.add(cd.getColumnName().toString())){
669                       // find duplicate colum name
670                       TSourceToken st = cd.getColumnName().getStartToken();
671                       this.parseerrormessagehandle(new TSyntaxError(st.getAstext(), st.lineNo, st.columnNo
672                               ,"duplicate column name", EErrorType.spfatalerror
673                               , TBaseType.MSG_ERROR_DUPLICATED_COLUMN_NAME,this,st.posinlist));
674
675                   }
676               }
677               else  if (te.getType() == TTableElement.type_table_like){
678                   likeTableName = te.getParentTable();
679               }else  if (te.getType() == TTableElement.type_supplemental_logging){
680
681               }else  if (te.getType() == TTableElement.type_period_for_clause){
682                   // Teradata PERIOD FOR clause - derived temporal column
683                   if (periodForClauses == null) {
684                       periodForClauses = new ArrayList<TTeradataPeriodForClause>();
685                   }
686                   periodForClauses.add(te.getPeriodForClause());
687               }else  if (te.getType() == TTableElement.type_flink_watermark){
688                   // Flink WATERMARK clause for event-time processing
689                   if (watermarkClauses == null) {
690                       watermarkClauses = new ArrayList<TFlinkWatermarkClause>();
691                   }
692                   watermarkClauses.add(te.getFlinkWatermarkClause());
693               }else{
694                   te.getConstraint().doParse(this,ESqlClause.unknown);
695                   this.getTableConstraints().addConstraint(te.getConstraint());
696               }
697           }
698       }
699
700       // column name list used when create table using a subquery.
701       TColumnDefinition t = null;
702       if ((createTableNode.getColumnList() != null)&&(createTableNode.getColumnList().size() > 0)){
703           for(int i=0;i<createTableNode.getColumnList().size();i++){
704               t = new TColumnDefinition(createTableNode.getColumnList().getObjectName(i));
705               t.setStartToken(t.getColumnName().getStartToken());
706               t.setEndToken(t.getColumnName().getEndToken());
707               this.getColumnList().addColumn(t);
708               this.getTargetTable().getObjectNameReferences().addObjectName(createTableNode.getColumnList().getObjectName(i));
709               getTargetTable().getLinkedColumns().addObjectName(createTableNode.getColumnList().getObjectName(i));
710               createTableNode.getColumnList().getObjectName(i).setSourceTable(getTargetTable());
711               // move to TMetadataCollector
712//               if (sqlTable != null){
713//                   sqlTable.addColumn(createTableNode.getColumnList().getObjectName(i).toString());
714//               }
715           }
716       }
717
718       if((subQuery == null) && (createTableNode.getSubQueryNode() != null) && (createTableNode.getSubQueryNode().getRelationExpr() == null)){
719           subQuery = new TSelectSqlStatement(this.dbvendor);
720           subQuery.rootNode = createTableNode.getSubQueryNode();
721           subQuery.doParseStatement(this);
722
723
724           // link column alias in subquery to table in create statement if columnList is not specified.
725           // Skipped for Snowflake USING TEMPLATE: the template query (e.g. ARRAY_AGG over
726           // INFER_SCHEMA) only infers the schema, so its select-list columns must NOT become
727           // columns of the target table the way a CREATE TABLE AS SELECT would.
728           if (createTableNode.getColumnList() == null && !createTableNode.isUsingTemplate()){
729               TSelectSqlStatement viewQuery = subQuery;
730               if (subQuery.isCombinedQuery()){
731                   viewQuery = subQuery.getRightStmt();
732               }
733
734                        if (viewQuery.getResultColumnList() != null) {
735               for(int i=0;i<viewQuery.getResultColumnList().size();i++){
736                   TResultColumn resultColumn = viewQuery.getResultColumnList().getResultColumn(i);
737                   TObjectName aliasName = null;
738                   if (resultColumn.getAliasClause() != null){
739                       if (resultColumn.getAliasClause().getColumns() != null){
740                           // select explode(str_to_map(regexp_replace(regexp_replace(regexp_replace(lower(t.input), '', ''), '',''), '', ''), '', '')) as (`key`, `value`) from B t1
741                            for (int j=0;j<resultColumn.getAliasClause().getColumns().size();j++){
742                                TObjectName aliasName1 =  resultColumn.getAliasClause().getColumns().getObjectName(j);
743                                aliasName1.setLocation(ESqlClause.columnAlias);
744                                resultColumn.getAliasNameList().add(aliasName1);
745                            }
746                       }else {
747                           aliasName = TObjectName.createObjectName (this.dbvendor, EDbObjectType.column,resultColumn.getAliasClause().getAliasName().getStartToken());
748                           aliasName.getReferencedObjects().addObjectName(resultColumn.getAliasClause().getAliasName());
749                           aliasName.setLocation(resultColumn.getAliasClause().getAliasName().getLocation());
750                       }
751                   }else{
752                       if (resultColumn.getExpr().getObjectOperand() != null){
753                           aliasName =  TObjectName.createObjectName (this.dbvendor, EDbObjectType.column,resultColumn.getExpr().getObjectOperand().getPartToken());
754                           aliasName.getReferencedObjects().addObjectName(resultColumn.getExpr().getObjectOperand());
755                           aliasName.setLocation(resultColumn.getExpr().getObjectOperand().getLocation());
756                       }
757                   }
758
759                   if (aliasName != null){
760                       if (aliasName.getLocation() == ESqlClause.unknown){
761                           aliasName.setLocation(ESqlClause.columnAlias);
762                       }
763                       getTargetTable().getLinkedColumns().addObjectName(aliasName);
764                       aliasName.setSourceTable(getTargetTable());
765                       resultColumn.setAliasName(aliasName.toString());
766
767                       // move to TMetadataCollector
768//                       if (sqlTable != null){
769//                           sqlTable.addColumn(TSQLEnv.getObjectName(aliasName.toString()));
770//                       }
771                   }
772               }
773                        }
774           }
775       }else if ((createTableNode.getSubQueryNode() != null) && (createTableNode.getSubQueryNode().getRelationExpr() != null)){
776            // CREATE TABLE a AS TABLE b
777           asTable = new TTable(createTableNode.getSubQueryNode().getRelationExpr().getRelationName());
778           tables.addTable(asTable);
779       }
780
781       if (createTableNode.getRefreshUsingStatementNode() != null) {
782           createTableNode.getRefreshUsingStatementNode().doParse(
783                   this, ESqlClause.unknown);
784           refreshUsingStatement = createTableNode
785                   .getRefreshUsingStatementNode().getStmt();
786       }
787
788       if (createTableNode.getExecuteSqlNode() != null){
789           executePreparedStatement = new TExecuteSqlStatement(this.dbvendor);
790           executePreparedStatement.rootNode = createTableNode.getExecuteSqlNode();
791           executePreparedStatement.doParseStatement(this);
792       }
793
794        external = createTableNode.isExternal();
795        usingTemplate = createTableNode.isUsingTemplate();
796       if (!external && tableKinds.contains(ETableKind.etkExternal)){
797           external = true;
798       }
799       if (external){
800           if (createTableNode.getOptionStartParenthesis() != null){
801               externalTableOptionList = TBaseType.getArrayListBetweenTokens(createTableNode.getOptionStartParenthesis(),createTableNode.getOptionEndParenthesis(),false);
802           }
803       }
804        ifNotExists = createTableNode.isIfNotExists();
805        if (createTableNode.getTableComment() != null){
806            tableComment = createTableNode.getTableComment();
807        }
808
809        locationFiles = createTableNode.getLocationFiles();
810        readable = createTableNode.isReadable();
811        writable = createTableNode.isWritable();
812        executeCmd = createTableNode.getExecuteCmd();
813        webTable = createTableNode.isWebTable();
814
815        tableLocation = createTableNode.getTableLocation();
816        hiveTableProperties = createTableNode.getHiveTableProperties();
817        hiveTablePartition = createTableNode.getHiveTablePartition();
818        hiveTableBuckets = createTableNode.getHiveTableBuckets();
819        hiveRowFormat = createTableNode.getHiveRowFormat();
820        hiveTableSkewed = createTableNode.getHiveTableSkewed();
821        hiveTableFileFormat = createTableNode.getHiveTableFileFormat();
822        flinkWithClause = createTableNode.getFlinkWithClause();
823        if (likeTableName == null){
824            likeTableName = createTableNode.getLikeTableName();
825        }
826        indexDefinitions = createTableNode.getIndexDefinitions();
827        if (indexDefinitions != null){
828            for(int i=0;i<indexDefinitions.size();i++){
829                indexDefinitions.get(i).doParse(this,ESqlClause.tableIndexOption);
830            }
831        }
832
833        inheritsClause = createTableNode.getInheritsClause();
834        if (inheritsClause != null) {
835            for(int i=0;i<inheritsClause.getParentTables().size();i++){
836                inheritsClause.getParentTables().getObjectName(i).setDbObjectType(this.dbvendor, EDbObjectType.table);
837            }
838        }
839        return 0;
840    }
841
842    /**
843     * table level constraints.
844     * @return List of table constraints of this table.
845     */
846    public TConstraintList getTableConstraints() {
847        if (this.tableConstraints == null){
848            this.tableConstraints = new TConstraintList();
849
850        }
851        
852        return tableConstraints;
853    }
854
855    /**
856     *  columns created in create table statement.
857     *
858     * @return List of column definitions of this table.
859     */
860    public TColumnDefinitionList getColumnList() {
861        if (this.columnList == null){
862            this.columnList = new TColumnDefinitionList();
863
864        }
865        return columnList;
866    }
867
868    private TColumnDefinitionList columnList = null;
869    private TConstraintList tableConstraints = null;
870
871    public void accept(TParseTreeVisitor v){
872        v.preVisit(this);
873        v.postVisit(this);
874    }
875
876    public void acceptChildren(TParseTreeVisitor v){
877        v.preVisit(this);
878        //tables.acceptChildren(v);
879        if (getTargetTable() != null) {
880            getTargetTable().acceptChildren(v);
881        }
882        this.getColumnList().acceptChildren(v);
883        if ((this.getTableConstraints() != null)&&(this.getTableConstraints().size()>0)){
884            this.getTableConstraints().acceptChildren(v);
885        }
886        if (this.getSubQuery() != null){
887            this.getSubQuery().acceptChildren(v);
888        }
889        if (this.getRefreshUsingStatement() != null){
890            this.getRefreshUsingStatement().acceptChildren(v);
891        }
892        if (getHiveTablePartition() != null){
893            getHiveTablePartition().acceptChildren(v);
894        }
895        v.postVisit(this);
896    }
897
898    public void setColumnList(TColumnDefinitionList columnList) {
899        this.columnList = columnList;
900    }
901
902    public void setAsTable(TTable asTable) {
903        this.asTable = asTable;
904    }
905
906    public void setExternalTable(boolean externalTable) {
907        this.externalTable = externalTable;
908    }
909
910    public void setIndexDefinitions(ArrayList<TIndexDefinition> indexDefinitions) {
911        this.indexDefinitions = indexDefinitions;
912    }
913
914    public void setExternal(boolean external) {
915        this.external = external;
916    }
917
918    public void setIfNotExists(boolean ifNotExists) {
919        this.ifNotExists = ifNotExists;
920    }
921
922    public void setTableLocation(TObjectName tableLocation) {
923        this.tableLocation = tableLocation;
924    }
925
926    public void setTableComment(TObjectName tableComment) {
927        this.tableComment = tableComment;
928    }
929
930    public void setHiveTableProperties(THiveTableProperties hiveTableProperties) {
931        this.hiveTableProperties = hiveTableProperties;
932    }
933
934    public void setHiveTablePartition(THiveTablePartition hiveTablePartition) {
935        this.hiveTablePartition = hiveTablePartition;
936    }
937
938    public void setHiveTableBuckets(THiveTableBuckets hiveTableBuckets) {
939        this.hiveTableBuckets = hiveTableBuckets;
940    }
941
942    public void setHiveTableSkewed(THiveTableSkewed hiveTableSkewed) {
943        this.hiveTableSkewed = hiveTableSkewed;
944    }
945
946    public void setHiveRowFormat(THiveRowFormat hiveRowFormat) {
947        this.hiveRowFormat = hiveRowFormat;
948    }
949
950    public void setHiveTableFileFormat(THiveTableFileFormat hiveTableFileFormat) {
951        this.hiveTableFileFormat = hiveTableFileFormat;
952    }
953
954    public void setLikeTableName(TObjectName likeTableName) {
955        this.likeTableName = likeTableName;
956    }
957
958    public void setRowTypeName(TObjectName rowTypeName) {
959        this.rowTypeName = rowTypeName;
960    }
961
962    public void setSuperTableName(TObjectName superTableName) {
963        this.superTableName = superTableName;
964    }
965
966    public void setSubQuery(TSelectSqlStatement subQuery) {
967        this.subQuery = subQuery;
968    }
969
970    public void setExecutePreparedStatement(TExecuteSqlStatement executePreparedStatement) {
971        this.executePreparedStatement = executePreparedStatement;
972    }
973
974    public void setMySQLTableOptionList(TPTNodeList<TMySQLCreateTableOption> mySQLTableOptionList) {
975        this.mySQLTableOptionList = mySQLTableOptionList;
976    }
977
978    public void setTableName(TObjectName tableName) {
979        this.tableName = tableName;
980    }
981
982    public void setTableConstraints(TConstraintList tableConstraints) {
983        this.tableConstraints = tableConstraints;
984    }
985}