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};
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 TExecuteSqlStatement executePreparedStatement = null;//greenplum
487
488    public TExecuteSqlStatement getExecutePreparedStatement() {
489        return executePreparedStatement;
490    }
491
492
493
494    private TPTNodeList <TMySQLCreateTableOption> mySQLTableOptionList;
495
496    /**
497     * MySQL, option used in create table such as engine, auto_increment and etc.
498     * @return option used in create table such as engine, auto_increment and etc.
499     */
500    public TPTNodeList<TMySQLCreateTableOption> getMySQLTableOptionList() {
501        return mySQLTableOptionList;
502    }
503
504    public TCreateTableSqlStatement(EDbVendor dbvendor) {
505        super(dbvendor);
506        sqlstatementtype = ESqlStatementType.sstcreatetable;
507    }
508
509    void buildsql() {
510    }
511
512    void clear() {
513    }
514
515    String getasprettytext() {
516        return "";
517    }
518
519    void iterate(TVisitorAbs pvisitor) {
520    }
521
522    private TObjectName tableName = null;
523
524    /**
525     * The first table in {@link #tables}, this is the same table as {@link #getTargetTable}
526     *
527     * @return The first table in {@link #tables}
528     */
529    public TObjectName getTableName() {
530        return tables.getTable(0).getTableName();
531    }
532
533    private boolean webTable = false;
534
535    public boolean isWebTable() {
536        return webTable;
537    }
538
539
540    private boolean readable;
541
542    public boolean isReadable() {
543        return readable;
544    }
545
546    public boolean isWritable() {
547        return writable;
548    }
549
550    private boolean writable;
551
552    private TConstant executeCmd;
553
554
555    public TConstant getExecuteCmd() {
556        return executeCmd;
557    }
558
559
560    private ArrayList<TConstant> locationFiles;
561
562    public void setLocationFiles(ArrayList<TConstant> locationFiles) {
563        this.locationFiles = locationFiles;
564    }
565
566    public ArrayList<TConstant> getLocationFiles() {
567        return locationFiles;
568    }
569
570    public int doParseStatement(TCustomSqlStatement psql) {
571       if (rootNode == null) return -1;
572       TCreateTableSqlNode createTableNode = (TCreateTableSqlNode)rootNode;
573       super.doParseStatement(psql);
574       this.tableKinds = createTableNode.getTableKinds();
575       this.tableSourceType = createTableNode.getTableSourceType();
576       this.setTargetTable(createTableNode.getTable());
577
578
579       // move to TMetadataCollector
580
581//       TSQLTable sqlTable = null;
582//        if (getSqlEnv() != null)  {
583//            if (createTableNode.getTable() != null){
584//                sqlTable = getSqlEnv().addTable(createTableNode.getTable().getFullName(),true);
585//            }
586//
587//            if (getSqlEnv().getDefaultCatalogName() != null){
588//                if (createTableNode.getTable().getTableName().getDatabaseToken() == null){
589//                    createTableNode.getTable().getTableName().setDatabaseToken(new TSourceToken(getSqlEnv().getDefaultCatalogName()),true);
590//                }
591//            }
592//
593//            createTableNode.getTable().getTableName().setSqlEnv(getSqlEnv());
594//        }
595
596        // end of move to TMetadataCollector
597
598       externalTable = createTableNode.isExternalTable();
599       physicalProperties = createTableNode.getPhysicalProperties();
600       tableProperties = createTableNode.getTableProperties();
601       this.tablePartition = createTableNode.getTablePartition();
602
603       if (createTableNode.getNetezzaExternalTableOption() != null){
604           this.externalTableOption = new TExternalTableOption(createTableNode.getNetezzaExternalTableOption().toString());
605       }
606
607       mySQLTableOptionList = createTableNode.getMySQLTableOptionList();
608       tableOptions = createTableNode.getTableOptions();
609       if (tableOptions != null){
610           for(int i=0;i<tableOptions.size();i++){
611               tableOptions.get(i).doParse(this,ESqlClause.unknown);
612           }
613       }
614
615       superTableName = createTableNode.getSuperTableName();
616       rowTypeName = createTableNode.getRowTypeName();
617       onFilegroup = createTableNode.getOnFilegroup();
618       cloneSourceTable = createTableNode.getCloneSourceTable();
619       if (cloneSourceTable != null){
620           cloneSourceTable.setDbObjectType(this.dbvendor,EDbObjectType.table);
621       }
622       likeTableName = createTableNode.getLikeTableName();
623       if (likeTableName != null){
624           likeTableName.setDbObjectType(this.dbvendor,EDbObjectType.table);
625       }
626       partitionBoundSpec = createTableNode.getPartitionBoundSpec();
627
628       tables.addTable(createTableNode.getTable());
629       asTable = createTableNode.getAsTable();
630        if (asTable != null) tables.addTable(asTable);
631       if ((createTableNode.getTableElementList() != null)&&(createTableNode.getTableElementList().size() >0 )){
632           TTableElement te;
633           TColumnDefinition cd;
634           Set<String> columnNames = new LinkedHashSet<String>();
635           for(int i=0; i<createTableNode.getTableElementList().size();i++){
636              te = createTableNode.getTableElementList().getTableElement(i);
637               if (te.getType() == TTableElement.type_column_def) {
638                   cd = te.getColumnDefinition();
639                   this.getColumnList().addColumn(cd);
640
641                   cd.doParse(this, ESqlClause.createTable);
642                   this.getTargetTable().getObjectNameReferences().addObjectName(cd.getColumnName());
643                   cd.getColumnName().setLocation(ESqlClause.createTable);
644                   cd.getColumnName().setLinkedColumnDef(cd);
645                   getTargetTable().getLinkedColumns().addObjectName(cd.getColumnName());
646                   cd.getColumnName().setSourceTable(getTargetTable());
647                   // move to TMetadataCollector
648//                   if (sqlTable != null){
649//                       sqlTable.addColumn(cd.getColumnName().toString(),cd.getDatatype());
650//                       //getTargetTable().setSqlTable(sqlTable);
651//                   }
652                   if (!columnNames.add(cd.getColumnName().toString())){
653                       // find duplicate colum name
654                       TSourceToken st = cd.getColumnName().getStartToken();
655                       this.parseerrormessagehandle(new TSyntaxError(st.getAstext(), st.lineNo, st.columnNo
656                               ,"duplicate column name", EErrorType.spfatalerror
657                               , TBaseType.MSG_ERROR_DUPLICATED_COLUMN_NAME,this,st.posinlist));
658
659                   }
660               }
661               else  if (te.getType() == TTableElement.type_table_like){
662                   likeTableName = te.getParentTable();
663               }else  if (te.getType() == TTableElement.type_supplemental_logging){
664
665               }else  if (te.getType() == TTableElement.type_period_for_clause){
666                   // Teradata PERIOD FOR clause - derived temporal column
667                   if (periodForClauses == null) {
668                       periodForClauses = new ArrayList<TTeradataPeriodForClause>();
669                   }
670                   periodForClauses.add(te.getPeriodForClause());
671               }else  if (te.getType() == TTableElement.type_flink_watermark){
672                   // Flink WATERMARK clause for event-time processing
673                   if (watermarkClauses == null) {
674                       watermarkClauses = new ArrayList<TFlinkWatermarkClause>();
675                   }
676                   watermarkClauses.add(te.getFlinkWatermarkClause());
677               }else{
678                   te.getConstraint().doParse(this,ESqlClause.unknown);
679                   this.getTableConstraints().addConstraint(te.getConstraint());
680               }
681           }
682       }
683
684       // column name list used when create table using a subquery.
685       TColumnDefinition t = null;
686       if ((createTableNode.getColumnList() != null)&&(createTableNode.getColumnList().size() > 0)){
687           for(int i=0;i<createTableNode.getColumnList().size();i++){
688               t = new TColumnDefinition(createTableNode.getColumnList().getObjectName(i));
689               t.setStartToken(t.getColumnName().getStartToken());
690               t.setEndToken(t.getColumnName().getEndToken());
691               this.getColumnList().addColumn(t);
692               this.getTargetTable().getObjectNameReferences().addObjectName(createTableNode.getColumnList().getObjectName(i));
693               getTargetTable().getLinkedColumns().addObjectName(createTableNode.getColumnList().getObjectName(i));
694               createTableNode.getColumnList().getObjectName(i).setSourceTable(getTargetTable());
695               // move to TMetadataCollector
696//               if (sqlTable != null){
697//                   sqlTable.addColumn(createTableNode.getColumnList().getObjectName(i).toString());
698//               }
699           }
700       }
701
702       if((subQuery == null) && (createTableNode.getSubQueryNode() != null) && (createTableNode.getSubQueryNode().getRelationExpr() == null)){
703           subQuery = new TSelectSqlStatement(this.dbvendor);
704           subQuery.rootNode = createTableNode.getSubQueryNode();
705           subQuery.doParseStatement(this);
706
707
708           // link column alias in subquery to table in create statement if columnList is not specified.
709           // Skipped for Snowflake USING TEMPLATE: the template query (e.g. ARRAY_AGG over
710           // INFER_SCHEMA) only infers the schema, so its select-list columns must NOT become
711           // columns of the target table the way a CREATE TABLE AS SELECT would.
712           if (createTableNode.getColumnList() == null && !createTableNode.isUsingTemplate()){
713               TSelectSqlStatement viewQuery = subQuery;
714               if (subQuery.isCombinedQuery()){
715                   viewQuery = subQuery.getRightStmt();
716               }
717
718                        if (viewQuery.getResultColumnList() != null) {
719               for(int i=0;i<viewQuery.getResultColumnList().size();i++){
720                   TResultColumn resultColumn = viewQuery.getResultColumnList().getResultColumn(i);
721                   TObjectName aliasName = null;
722                   if (resultColumn.getAliasClause() != null){
723                       if (resultColumn.getAliasClause().getColumns() != null){
724                           // select explode(str_to_map(regexp_replace(regexp_replace(regexp_replace(lower(t.input), '', ''), '',''), '', ''), '', '')) as (`key`, `value`) from B t1
725                            for (int j=0;j<resultColumn.getAliasClause().getColumns().size();j++){
726                                TObjectName aliasName1 =  resultColumn.getAliasClause().getColumns().getObjectName(j);
727                                aliasName1.setLocation(ESqlClause.columnAlias);
728                                resultColumn.getAliasNameList().add(aliasName1);
729                            }
730                       }else {
731                           aliasName = TObjectName.createObjectName (this.dbvendor, EDbObjectType.column,resultColumn.getAliasClause().getAliasName().getStartToken());
732                           aliasName.getReferencedObjects().addObjectName(resultColumn.getAliasClause().getAliasName());
733                           aliasName.setLocation(resultColumn.getAliasClause().getAliasName().getLocation());
734                       }
735                   }else{
736                       if (resultColumn.getExpr().getObjectOperand() != null){
737                           aliasName =  TObjectName.createObjectName (this.dbvendor, EDbObjectType.column,resultColumn.getExpr().getObjectOperand().getPartToken());
738                           aliasName.getReferencedObjects().addObjectName(resultColumn.getExpr().getObjectOperand());
739                           aliasName.setLocation(resultColumn.getExpr().getObjectOperand().getLocation());
740                       }
741                   }
742
743                   if (aliasName != null){
744                       if (aliasName.getLocation() == ESqlClause.unknown){
745                           aliasName.setLocation(ESqlClause.columnAlias);
746                       }
747                       getTargetTable().getLinkedColumns().addObjectName(aliasName);
748                       aliasName.setSourceTable(getTargetTable());
749                       resultColumn.setAliasName(aliasName.toString());
750
751                       // move to TMetadataCollector
752//                       if (sqlTable != null){
753//                           sqlTable.addColumn(TSQLEnv.getObjectName(aliasName.toString()));
754//                       }
755                   }
756               }
757                        }
758           }
759       }else if ((createTableNode.getSubQueryNode() != null) && (createTableNode.getSubQueryNode().getRelationExpr() != null)){
760            // CREATE TABLE a AS TABLE b
761           asTable = new TTable(createTableNode.getSubQueryNode().getRelationExpr().getRelationName());
762           tables.addTable(asTable);
763       }
764
765       if (createTableNode.getExecuteSqlNode() != null){
766           executePreparedStatement = new TExecuteSqlStatement(this.dbvendor);
767           executePreparedStatement.rootNode = createTableNode.getExecuteSqlNode();
768           executePreparedStatement.doParseStatement(this);
769       }
770
771        external = createTableNode.isExternal();
772        usingTemplate = createTableNode.isUsingTemplate();
773       if (!external && tableKinds.contains(ETableKind.etkExternal)){
774           external = true;
775       }
776       if (external){
777           if (createTableNode.getOptionStartParenthesis() != null){
778               externalTableOptionList = TBaseType.getArrayListBetweenTokens(createTableNode.getOptionStartParenthesis(),createTableNode.getOptionEndParenthesis(),false);
779           }
780       }
781        ifNotExists = createTableNode.isIfNotExists();
782        if (createTableNode.getTableComment() != null){
783            tableComment = createTableNode.getTableComment();
784        }
785
786        locationFiles = createTableNode.getLocationFiles();
787        readable = createTableNode.isReadable();
788        writable = createTableNode.isWritable();
789        executeCmd = createTableNode.getExecuteCmd();
790        webTable = createTableNode.isWebTable();
791
792        tableLocation = createTableNode.getTableLocation();
793        hiveTableProperties = createTableNode.getHiveTableProperties();
794        hiveTablePartition = createTableNode.getHiveTablePartition();
795        hiveTableBuckets = createTableNode.getHiveTableBuckets();
796        hiveRowFormat = createTableNode.getHiveRowFormat();
797        hiveTableSkewed = createTableNode.getHiveTableSkewed();
798        hiveTableFileFormat = createTableNode.getHiveTableFileFormat();
799        flinkWithClause = createTableNode.getFlinkWithClause();
800        if (likeTableName == null){
801            likeTableName = createTableNode.getLikeTableName();
802        }
803        indexDefinitions = createTableNode.getIndexDefinitions();
804        if (indexDefinitions != null){
805            for(int i=0;i<indexDefinitions.size();i++){
806                indexDefinitions.get(i).doParse(this,ESqlClause.tableIndexOption);
807            }
808        }
809
810        inheritsClause = createTableNode.getInheritsClause();
811        if (inheritsClause != null) {
812            for(int i=0;i<inheritsClause.getParentTables().size();i++){
813                inheritsClause.getParentTables().getObjectName(i).setDbObjectType(this.dbvendor, EDbObjectType.table);
814            }
815        }
816        return 0;
817    }
818
819    /**
820     * table level constraints.
821     * @return List of table constraints of this table.
822     */
823    public TConstraintList getTableConstraints() {
824        if (this.tableConstraints == null){
825            this.tableConstraints = new TConstraintList();
826
827        }
828        
829        return tableConstraints;
830    }
831
832    /**
833     *  columns created in create table statement.
834     *
835     * @return List of column definitions of this table.
836     */
837    public TColumnDefinitionList getColumnList() {
838        if (this.columnList == null){
839            this.columnList = new TColumnDefinitionList();
840
841        }
842        return columnList;
843    }
844
845    private TColumnDefinitionList columnList = null;
846    private TConstraintList tableConstraints = null;
847
848    public void accept(TParseTreeVisitor v){
849        v.preVisit(this);
850        v.postVisit(this);
851    }
852
853    public void acceptChildren(TParseTreeVisitor v){
854        v.preVisit(this);
855        //tables.acceptChildren(v);
856        if (getTargetTable() != null) {
857            getTargetTable().acceptChildren(v);
858        }
859        this.getColumnList().acceptChildren(v);
860        if ((this.getTableConstraints() != null)&&(this.getTableConstraints().size()>0)){
861            this.getTableConstraints().acceptChildren(v);
862        }
863        if (this.getSubQuery() != null){
864            this.getSubQuery().acceptChildren(v);
865        }
866        if (getHiveTablePartition() != null){
867            getHiveTablePartition().acceptChildren(v);
868        }
869        v.postVisit(this);
870    }
871
872    public void setColumnList(TColumnDefinitionList columnList) {
873        this.columnList = columnList;
874    }
875
876    public void setAsTable(TTable asTable) {
877        this.asTable = asTable;
878    }
879
880    public void setExternalTable(boolean externalTable) {
881        this.externalTable = externalTable;
882    }
883
884    public void setIndexDefinitions(ArrayList<TIndexDefinition> indexDefinitions) {
885        this.indexDefinitions = indexDefinitions;
886    }
887
888    public void setExternal(boolean external) {
889        this.external = external;
890    }
891
892    public void setIfNotExists(boolean ifNotExists) {
893        this.ifNotExists = ifNotExists;
894    }
895
896    public void setTableLocation(TObjectName tableLocation) {
897        this.tableLocation = tableLocation;
898    }
899
900    public void setTableComment(TObjectName tableComment) {
901        this.tableComment = tableComment;
902    }
903
904    public void setHiveTableProperties(THiveTableProperties hiveTableProperties) {
905        this.hiveTableProperties = hiveTableProperties;
906    }
907
908    public void setHiveTablePartition(THiveTablePartition hiveTablePartition) {
909        this.hiveTablePartition = hiveTablePartition;
910    }
911
912    public void setHiveTableBuckets(THiveTableBuckets hiveTableBuckets) {
913        this.hiveTableBuckets = hiveTableBuckets;
914    }
915
916    public void setHiveTableSkewed(THiveTableSkewed hiveTableSkewed) {
917        this.hiveTableSkewed = hiveTableSkewed;
918    }
919
920    public void setHiveRowFormat(THiveRowFormat hiveRowFormat) {
921        this.hiveRowFormat = hiveRowFormat;
922    }
923
924    public void setHiveTableFileFormat(THiveTableFileFormat hiveTableFileFormat) {
925        this.hiveTableFileFormat = hiveTableFileFormat;
926    }
927
928    public void setLikeTableName(TObjectName likeTableName) {
929        this.likeTableName = likeTableName;
930    }
931
932    public void setRowTypeName(TObjectName rowTypeName) {
933        this.rowTypeName = rowTypeName;
934    }
935
936    public void setSuperTableName(TObjectName superTableName) {
937        this.superTableName = superTableName;
938    }
939
940    public void setSubQuery(TSelectSqlStatement subQuery) {
941        this.subQuery = subQuery;
942    }
943
944    public void setExecutePreparedStatement(TExecuteSqlStatement executePreparedStatement) {
945        this.executePreparedStatement = executePreparedStatement;
946    }
947
948    public void setMySQLTableOptionList(TPTNodeList<TMySQLCreateTableOption> mySQLTableOptionList) {
949        this.mySQLTableOptionList = mySQLTableOptionList;
950    }
951
952    public void setTableName(TObjectName tableName) {
953        this.tableName = tableName;
954    }
955
956    public void setTableConstraints(TConstraintList tableConstraints) {
957        this.tableConstraints = tableConstraints;
958    }
959}