001
002package gudusoft.gsqlparser.dlineage.dataflow.model;
003
004import gudusoft.gsqlparser.EDbVendor;
005import gudusoft.gsqlparser.ETableKind;
006import gudusoft.gsqlparser.ETableSource;
007import gudusoft.gsqlparser.TCustomSqlStatement;
008import gudusoft.gsqlparser.TSourceToken;
009import gudusoft.gsqlparser.dlineage.util.DlineageUtil;
010import gudusoft.gsqlparser.dlineage.util.Pair3;
011import gudusoft.gsqlparser.nodes.TFunctionCall;
012import gudusoft.gsqlparser.nodes.TObjectName;
013import gudusoft.gsqlparser.nodes.TTable;
014import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
015import gudusoft.gsqlparser.sqlenv.TSQLCatalog;
016import gudusoft.gsqlparser.sqlenv.TSQLColumn;
017import gudusoft.gsqlparser.sqlenv.TSQLEnv;
018import gudusoft.gsqlparser.sqlenv.TSQLSchema;
019import gudusoft.gsqlparser.sqlenv.TSQLTable;
020import gudusoft.gsqlparser.stmt.TCreateTableSqlStatement;
021import gudusoft.gsqlparser.stmt.TCreateViewSqlStatement;
022import gudusoft.gsqlparser.util.Logger;
023import gudusoft.gsqlparser.util.LoggerFactory;
024import gudusoft.gsqlparser.util.SQLUtil;
025
026import java.io.ByteArrayInputStream;
027import java.io.IOException;
028import java.util.*;
029
030public class Table {
031
032        private static final Logger logger = LoggerFactory.getLogger(Table.class);
033
034        private long id;
035        protected String server;
036        protected String database;
037        protected String schema;
038        protected String name;
039        protected String displayName;
040        protected String fullName;
041        protected Set<String> alias = new LinkedHashSet<String>();
042        protected String parent;
043        protected Pair3<Long, Long, String> startPosition;
044        protected Pair3<Long, Long, String> endPosition;
045        private List<TableColumn> columns = new ArrayList<TableColumn>();
046        private boolean subquery = false;
047
048        private TTable tableObject;
049        private TObjectName viewName;
050        private boolean isCreateTable;
051        private boolean isView;
052        private boolean isPseudo;
053        private boolean isExternal;
054        private boolean isStage;
055        private boolean isSequence;
056        private boolean isPath;
057        private boolean isStream;
058        private boolean isVariable;
059        private boolean isConstant;
060        private boolean isDatabase;
061        private boolean isSchema;
062        private boolean isDataSource;
063        private String location;
064        private String fileType;
065        private String fileFormat;
066        private List<Process> processes;
067        private SubType subType;
068        private String starStmt;
069        private boolean hasSQLEnv = false;
070        private String currentAlias;
071    private boolean isDetermined;
072
073        private boolean fromDDL;
074
075        private TableRelationRows relationRows = new TableRelationRows(this);
076
077        private TCustomSqlStatement stmt;
078
079        public Table(TCustomSqlStatement stmt, TObjectName viewName) {
080                this(viewName);
081                this.stmt = stmt;
082                if (stmt != null) {
083                        TSourceToken startToken = stmt.getStartToken();
084                        TSourceToken endToken = stmt.getEndToken();
085                        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
086                                        ModelBindingManager.getGlobalHash());
087                        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
088                                        endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
089                }
090        }
091
092        public TCustomSqlStatement getSqlStatement() {
093                return stmt;
094        }
095        
096        public Table(TTable table, String tableName) {
097                if (table == null) {
098                        throw new IllegalArgumentException("Table arguments can't be null.");
099                }
100
101                id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
102
103                this.tableObject = table;
104
105                TSourceToken startToken = table.getStartToken();
106                TSourceToken endToken = table.getEndToken();
107                if (startToken == null && table.getSubquery() != null) {
108                        startToken = table.getSubquery().getStartToken();
109                        endToken = table.getSubquery().getEndToken();
110                }
111                this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
112                                ModelBindingManager.getGlobalHash());
113                this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(),
114                                ModelBindingManager.getGlobalHash());
115
116
117                this.name = tableName;
118                this.fullName = tableName;
119                setAlias(table.getAliasName());
120                setCurrentAlias(table.getAliasName());
121                
122                if (name.startsWith("`") && name.endsWith("`") && name.indexOf(".") != -1
123                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
124                        this.name = SQLUtil.trimColumnStringQuote(name);
125                        this.fullName = SQLUtil.trimColumnStringQuote(fullName);
126                }
127
128                if (table.getSubquery() != null) {
129                        subquery = true;
130                }
131
132                EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
133                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
134                boolean supportSchema = TSQLEnv.supportSchema(vendor);
135
136                if (table.getTableName().getDblink() == null) {
137                        this.server = DlineageUtil.getTableServer(table.getTableName().toString());
138                        this.database = DlineageUtil.getTableDatabase(table.getTableName().toString());
139                        this.schema = DlineageUtil.getTableSchema(table.getTableName().toString());
140                }
141                else {
142                        if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
143                                this.server = getDefaultServer();
144                        }
145                        this.database = SQLUtil.normalizeIdentifier(vendor, ESQLDataObjectType.dotDblink, table.getTableName().getDblink().toString());
146                        if (!SQLUtil.isEmpty(table.getTableName().getSchemaString())) {
147                                this.schema = table.getTableName().getSchemaString();
148                        }
149                        this.subType = SubType.dblink;
150                        this.name = this.name.replace(table.getTableName().getDblink().toString(), this.database);
151                        ModelBindingManager.get().appendDblinkTable(this.name);
152                        return;
153                }
154
155                fillSchemaInfo();
156
157                if (SQLUtil.isEmpty(this.database)) {
158                        this.database = DlineageUtil.getTableDatabase(table.getTableName().toString());
159                        if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema()
160                                        && !SQLUtil.isEmpty(table.getTableName().getImplictDatabaseString())) {
161                                this.database = table.getTableName().getImplictDatabaseString();
162                        }
163                }
164
165                if (SQLUtil.isEmpty(this.schema)) {
166                        this.schema = DlineageUtil.getTableSchema(table.getTableName().toString());
167                        if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema()
168                                        && !SQLUtil.isEmpty(table.getTableName().getImplictSchemaString())) {
169                                this.schema = table.getTableName().getImplictSchemaString();
170                        }
171                }
172
173                if (!SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) {
174                        if (!SQLUtil.isEmpty(table.getTableName().getImplictSchemaString())) {
175                                this.schema = table.getTableName().getImplictSchemaString();
176                        }
177                }
178
179                if (table.getTableType() == ETableSource.function) {
180                        subType = SubType.function;
181                }
182
183                if (!supportCatalog) {
184                        this.database = null;
185                } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
186                        this.database = getDefaultDatabase();
187                }
188
189                if (!supportSchema) {
190                        this.schema = null;
191                } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
192                        this.schema = getDefaultSchema();
193                }
194
195                updateTableName(supportCatalog, supportSchema);
196
197                if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
198                        this.server = getDefaultServer();
199                }
200        }
201
202        public Table(TTable table) {
203                if (table == null) {
204                        throw new IllegalArgumentException("Table arguments can't be null.");
205                }
206
207                id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
208
209                this.tableObject = table;
210
211                TSourceToken startToken = table.getStartToken();
212                TSourceToken endToken = table.getEndToken();
213                if (startToken == null && table.getSubquery() != null) {
214                        startToken = table.getSubquery().getStartToken();
215                        endToken = table.getSubquery().getEndToken();
216                }
217                this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
218                                ModelBindingManager.getGlobalHash());
219                this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(),
220                                ModelBindingManager.getGlobalHash());
221
222                if (table.getLinkTable() != null) {
223                        this.fullName = table.getLinkTable().getFullName();
224                        this.name = table.getLinkTable().getName();
225                        setAlias(table.getName());
226                        setCurrentAlias(table.getName());
227                } else if (table.getTableType() == ETableSource.function && table.getFuncCall() != null) {
228                        TFunctionCall function = table.getFuncCall();
229                        this.fullName = function.getFunctionName().toString();
230                        this.name = function.getFunctionName().toString();
231                        setAlias(table.getAliasName());
232                        setCurrentAlias(table.getAliasName());
233                } else {
234                        if (table.getSubquery() != null && table.getAliasClause() != null) {
235                                this.name = table.getAliasClause().getAliasName().toString();
236                                this.subType = SubType.alias_table;
237                        } else if (table.getTableName() != null) {
238                                this.name = table.getTableName().toString();
239                        } else {
240                                this.name = table.getName();
241                        }
242
243                        this.fullName = table.getFullName();
244                        if (this.fullName == null) {
245                                this.fullName = this.name;
246                        }
247
248                        setAlias(table.getAliasName());
249                        setCurrentAlias(table.getAliasName());
250                }
251
252                if (name.startsWith("`") && name.endsWith("`") && name.indexOf(".") != -1
253                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
254                        this.name = SQLUtil.trimColumnStringQuote(name);
255                        this.fullName = SQLUtil.trimColumnStringQuote(fullName);
256                }
257
258                if (table.getSubquery() != null) {
259                        subquery = true;
260                }
261
262                EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
263                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
264                boolean supportSchema = TSQLEnv.supportSchema(vendor);
265
266                if (table.getTableName().getDblink() == null) {
267                        this.server = DlineageUtil.getTableServer(table.getTableName().toString());
268                        this.database = DlineageUtil.getTableDatabase(table.getTableName().toString());
269                        this.schema = DlineageUtil.getTableSchema(table.getTableName().toString());
270                }
271                else {
272                        if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
273                                this.server = getDefaultServer();
274                        }
275                        this.database = SQLUtil.normalizeIdentifier(vendor, ESQLDataObjectType.dotDblink, table.getTableName().getDblink().toString());
276                        if (!SQLUtil.isEmpty(table.getTableName().getSchemaString())) {
277                                this.schema = table.getTableName().getSchemaString();
278                        }
279                        this.subType = SubType.dblink;
280                        this.name = this.name.replace(table.getTableName().getDblink().toString(), this.database);
281                        ModelBindingManager.get().appendDblinkTable(this.name);
282                        return;
283                }
284
285                fillSchemaInfo();
286
287                if (SQLUtil.isEmpty(this.database)) {
288                        this.database = DlineageUtil.getTableDatabase(table.getTableName().toString());
289                        if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema()
290                                        && !SQLUtil.isEmpty(table.getTableName().getImplictDatabaseString())) {
291                                this.database = table.getTableName().getImplictDatabaseString();
292                        }
293                }
294
295                if (SQLUtil.isEmpty(this.schema)) {
296                        this.schema = DlineageUtil.getTableSchema(table.getTableName().toString());
297                        if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema()
298                                        && !SQLUtil.isEmpty(table.getTableName().getImplictSchemaString())) {
299                                this.schema = table.getTableName().getImplictSchemaString();
300                        }
301                }
302
303                if (!SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) {
304                        if (!SQLUtil.isEmpty(table.getTableName().getImplictSchemaString())) {
305                                this.schema = table.getTableName().getImplictSchemaString();
306                        }
307                }
308
309                if (table.getTableType() == ETableSource.function) {
310                        subType = SubType.function;
311                }
312
313                if (!supportCatalog) {
314                        this.database = null;
315                } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
316                        this.database = getDefaultDatabase();
317                }
318
319                if (!supportSchema) {
320                        this.schema = null;
321                } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
322                        this.schema = getDefaultSchema();
323                }
324
325                updateTableName(supportCatalog, supportSchema);
326
327                if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
328                        this.server = getDefaultServer();
329                }
330        }
331
332        public void addColumnsFromSQLEnv(){
333                TSQLEnv sqlEnv = ModelBindingManager.getGlobalSQLEnv();
334                if (sqlEnv == null) {
335                        return;
336                }
337                TSQLTable tsqlTable = sqlEnv.searchTable(ModelFactory.getQualifiedTableName(this));
338                if (tsqlTable != null && tsqlTable.getColumnList()!=null) {
339                        for(TSQLColumn tsqlColumn: tsqlTable.getColumnList()){
340                                TObjectName columnName = new TObjectName();
341                                columnName.setString(tsqlColumn.getName());
342                                new TableColumn(this, columnName);
343                        }
344                        this.setCreateTable(true);
345                        this.setHasSQLEnv(true);
346                }
347        }
348
349        private void fillSchemaInfo() {
350                TCustomSqlStatement currentStmt = ModelBindingManager.getGlobalStmtStack().peek();
351                TCustomSqlStatement stmt = DlineageUtil.getTopStmt(ModelBindingManager.getGlobalStmtStack().peek());
352                
353                String sqlComment = null;
354                try {
355                        sqlComment = stmt.getCommentBeforeNode();
356                } catch (Exception e) {
357                }
358                if (!SQLUtil.isEmpty(sqlComment) && (sqlComment.indexOf("db") != -1 || sqlComment.indexOf("schema") != -1)) {
359                        Properties properties = new Properties();
360                        try {
361                                properties.load(
362                                                new ByteArrayInputStream(sqlComment.replace("--", "").trim().replace(",", "\n").getBytes()));
363                                if (SQLUtil.isEmpty(this.server) && properties.containsKey("db-instance")) {
364                                        this.server = properties.getProperty("db-instance");
365                                }
366                                if (SQLUtil.isEmpty(this.database) && properties.containsKey("db")) {
367                                        this.database = properties.getProperty("db");
368                                        if(this.database.indexOf(".")!=-1) {
369                                                String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
370                                                this.database = delimitedChar + SQLUtil.trimColumnStringQuote(this.database) + delimitedChar;
371                                        }
372                                }
373                                if (SQLUtil.isEmpty(this.schema) && properties.containsKey("schema")) {
374                                        this.schema = properties.getProperty("schema");
375                                        if(this.schema.indexOf(".")!=-1) {
376                                                String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
377                                                this.schema = delimitedChar + SQLUtil.trimColumnStringQuote(this.schema) + delimitedChar;
378                                        }
379                                }
380                        } catch (IOException e) {
381                                logger.error("load sql comment properties failed.", e);
382                        }
383                }
384                
385                if(stmt instanceof TCreateTableSqlStatement) {
386                        TCreateTableSqlStatement createTableStmt = (TCreateTableSqlStatement)stmt;
387                        if (createTableStmt.getTableKinds() != null 
388                                        && (createTableStmt.getTableKinds().contains(ETableKind.etkTemporary) 
389                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkTemp)
390                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkLocalTemporary)
391                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkLocalTemp)
392                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkGlobalTemporary)
393                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkGlobalTemp))) {
394                                if (this.tableObject == createTableStmt.getTargetTable()) {
395                                        setSubType(SubType.temp_table);
396                                        return;
397                                }
398                        }
399                }
400                
401                if(currentStmt instanceof TCreateTableSqlStatement) {
402                        TCreateTableSqlStatement createTableStmt = (TCreateTableSqlStatement)currentStmt;
403                        if (createTableStmt.getTableKinds() != null 
404                                        && (createTableStmt.getTableKinds().contains(ETableKind.etkTemporary) 
405                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkTemp)
406                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkLocalTemporary)
407                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkLocalTemp)
408                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkGlobalTemporary)
409                                                        || createTableStmt.getTableKinds().contains(ETableKind.etkGlobalTemp))) {
410                                if (this.tableObject == createTableStmt.getTargetTable()) {
411                                        setSubType(SubType.temp_table);
412                                        return;
413                                }
414                        }
415                }
416                
417                if(stmt instanceof TCreateViewSqlStatement) {
418                        TCreateViewSqlStatement createViewStmt = (TCreateViewSqlStatement)stmt;
419                        if (createViewStmt.getTableKind() != null 
420                                        && (createViewStmt.getTableKind() == (ETableKind.etkTemporary) 
421                                                        || createViewStmt.getTableKind() == (ETableKind.etkTemp)
422                                                        || createViewStmt.getTableKind() == (ETableKind.etkLocalTemporary)
423                                                        || createViewStmt.getTableKind() == (ETableKind.etkLocalTemp)
424                                                        || createViewStmt.getTableKind() == (ETableKind.etkGlobalTemporary)
425                                                        || createViewStmt.getTableKind() == (ETableKind.etkGlobalTemp))) {
426                                if (this.viewName == createViewStmt.getViewName()) {
427                                        setSubType(SubType.temp_table);
428                                        return;
429                                }
430                        }
431                }
432                
433                if(currentStmt instanceof TCreateViewSqlStatement) {
434                        TCreateViewSqlStatement createViewStmt = (TCreateViewSqlStatement)currentStmt;
435                        if (createViewStmt.getTableKind() != null 
436                                        && (createViewStmt.getTableKind() == (ETableKind.etkTemporary) 
437                                                        || createViewStmt.getTableKind() == (ETableKind.etkTemp)
438                                                        || createViewStmt.getTableKind() == (ETableKind.etkLocalTemporary)
439                                                        || createViewStmt.getTableKind() == (ETableKind.etkLocalTemp)
440                                                        || createViewStmt.getTableKind() == (ETableKind.etkGlobalTemporary)
441                                                        || createViewStmt.getTableKind() == (ETableKind.etkGlobalTemp))) {
442                                if (this.viewName == createViewStmt.getViewName()) {
443                                        setSubType(SubType.temp_table);
444                                        return;
445                                }
446                        }
447                }
448                
449
450                if (SQLUtil.isEmpty(this.database) || this.database.equals(ModelBindingManager.getGlobalDatabase())) {
451                        TSQLEnv sqlEnv = ModelBindingManager.getGlobalSQLEnv();
452                        if (sqlEnv == null) {
453                                return;
454                        }
455                        int occurrence = 0;
456                        int maxPriority = -1;
457                        String tableDatabase = null;
458                        String tableSchema = null;
459                        Map<Integer, List<String>> databaseSchemasMap = new HashMap<Integer, List<String>>();
460                        for (TSQLCatalog catalog : sqlEnv.getCatalogList()) {
461                                if (SQLUtil.isEmpty(schema) || this.schema.equals(ModelBindingManager.getGlobalSchema())) {
462                                        for (TSQLSchema schema : catalog.getSchemaList()) {
463                                                TSQLTable tsqlTable = schema.findTable(DlineageUtil.getSimpleTableName(this.name));
464                                                if (tsqlTable != null) {
465                                                        occurrence += 1;
466                                                        if (tsqlTable.getPriority() > maxPriority
467                                                                        || (maxPriority > 0 && tsqlTable.getPriority() == maxPriority)) {
468                                                                tableDatabase = catalog.getName();
469                                                                if(tableDatabase.indexOf(".")!=-1) {
470                                                                        String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
471                                                                        tableDatabase = delimitedChar + SQLUtil.trimColumnStringQuote(tableDatabase) + delimitedChar;
472                                                                }
473                                                                tableSchema = schema.getName();
474                                                                if(tableSchema.indexOf(".")!=-1) {
475                                                                        String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
476                                                                        tableSchema = delimitedChar + SQLUtil.trimColumnStringQuote(tableSchema) + delimitedChar;
477                                                                }
478                                                                maxPriority = tsqlTable.getPriority();
479                                                                if(!databaseSchemasMap.containsKey(maxPriority)) {
480                                                                        databaseSchemasMap.put(maxPriority, new ArrayList<String>());
481                                                                }
482                                                                databaseSchemasMap.get(maxPriority).add(tableDatabase + "___" + tableSchema);
483                                                        }
484                                                }
485                                        }
486//                                      if (occurrence > 1) {
487//                                              break;
488//                                      }
489                                } else {
490                                        TSQLSchema schema = catalog.getSchema(this.schema, false);
491                                        if (schema != null) {
492                                                TSQLTable tsqlTable = schema.findTable(DlineageUtil.getSimpleTableName(this.name));
493                                                if (tsqlTable != null) {
494                                                        occurrence += 1;
495                                                        if (tsqlTable.getPriority() > maxPriority
496                                                                        || (maxPriority > 0 && tsqlTable.getPriority() == maxPriority)) {
497                                                                tableDatabase = catalog.getName();
498                                                                if(tableDatabase.indexOf(".")!=-1) {
499                                                                        String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
500                                                                        tableDatabase = delimitedChar + SQLUtil.trimColumnStringQuote(tableDatabase) + delimitedChar;
501                                                                }
502                                                                tableSchema = schema.getName();
503                                                                if(tableSchema.indexOf(".")!=-1) {
504                                                                        String delimitedChar = TSQLEnv.delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
505                                                                        tableSchema = delimitedChar + SQLUtil.trimColumnStringQuote(tableSchema) + delimitedChar;
506                                                                }
507                                                                maxPriority = tsqlTable.getPriority();
508                                                                if(!databaseSchemasMap.containsKey(maxPriority)) {
509                                                                        databaseSchemasMap.put(maxPriority, new ArrayList<String>());
510                                                                }
511                                                                databaseSchemasMap.get(maxPriority).add(tableDatabase + "___" + tableSchema);
512                                                        }
513                                                }
514                                        }
515                                }
516                        }
517                        if (occurrence == 1 || (maxPriority > 0 && databaseSchemasMap.get(maxPriority).size() == 1)) {
518                                if (tableDatabase != null && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(tableDatabase)) {
519                                        this.database = tableDatabase;
520                                }
521                                if (tableSchema != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(tableSchema)) {
522                                        this.schema = tableSchema;
523                                }
524                        }
525                } else if (SQLUtil.isEmpty(this.schema) || this.schema.equals(ModelBindingManager.getGlobalSchema())) {
526                        TSQLEnv sqlEnv = ModelBindingManager.getGlobalSQLEnv();
527                        if (sqlEnv == null) {
528                                return;
529                        }
530                        int occurrence = 0;
531                        int maxPriority = -1;
532                        String tableDatabase = null;
533                        String tableSchema = null;
534                        Map<Integer, List<String>> databaseSchemasMap = new HashMap<Integer, List<String>>();
535                        TSQLCatalog catalog = sqlEnv.searchCatalog(this.database);
536                        if (catalog != null) {
537                                for (TSQLSchema schema : catalog.getSchemaList()) {
538                                        TSQLTable tsqlTable = schema.findTable(DlineageUtil.getSimpleTableName(this.name));
539                                        if (tsqlTable != null) {
540                                                occurrence += 1;
541                                                if (tsqlTable.getPriority() > maxPriority
542                                                                || (maxPriority > 0 && tsqlTable.getPriority() == maxPriority)) {
543                                                        tableDatabase = catalog.getName();
544                                                        if (tableDatabase.indexOf(".") != -1) {
545                                                                String delimitedChar = TSQLEnv
546                                                                                .delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
547                                                                tableDatabase = delimitedChar + SQLUtil.trimColumnStringQuote(tableDatabase)
548                                                                                + delimitedChar;
549                                                        }
550                                                        tableSchema = schema.getName();
551                                                        if (tableSchema.indexOf(".") != -1) {
552                                                                String delimitedChar = TSQLEnv
553                                                                                .delimitedChar(ModelBindingManager.getGlobalOption().getVendor());
554                                                                tableSchema = delimitedChar + SQLUtil.trimColumnStringQuote(tableSchema)
555                                                                                + delimitedChar;
556                                                        }
557                                                        maxPriority = tsqlTable.getPriority();
558                                                        if(!databaseSchemasMap.containsKey(maxPriority)) {
559                                                                databaseSchemasMap.put(maxPriority, new ArrayList<String>());
560                                                        }
561                                                        databaseSchemasMap.get(maxPriority).add(tableDatabase + "___" + tableSchema);
562                                                }
563                                        }
564                                }
565                        }
566
567                        if (occurrence == 1 || (maxPriority > 0 && databaseSchemasMap.get(maxPriority).size() == 1)) {
568                                if (tableDatabase != null && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(tableDatabase)) {
569                                        this.database = tableDatabase;
570                                }
571                                if (tableSchema != null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(tableSchema)) {
572                                        this.schema = tableSchema;
573                                }
574                        }
575
576                        if (SQLUtil.isEmpty(this.schema) && !SQLUtil.isEmpty(this.database)) {
577                                this.schema = getDefaultSchema();
578                        }
579                }
580        }
581
582        public Table(TObjectName tableName) {
583                if (tableName == null) {
584                        throw new IllegalArgumentException("Table arguments can't be null.");
585                }
586
587                id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
588                
589                this.viewName = tableName;
590
591                TSourceToken startToken = tableName.getStartToken();
592                TSourceToken endToken = tableName.getEndToken();
593                this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
594                                ModelBindingManager.getGlobalHash());
595                this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo, endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(),
596                                ModelBindingManager.getGlobalHash());
597
598                this.fullName = tableName.toString();
599                this.name = tableName.toString();
600                if (SQLUtil.isEmpty(name)) {
601                        name = tableName.toString();
602                }
603
604                if (name.startsWith("`") && name.endsWith("`") && name.indexOf(".") != -1
605                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
606                        this.name = SQLUtil.trimColumnStringQuote(name);
607                        this.fullName = SQLUtil.trimColumnStringQuote(fullName);
608                }
609
610                this.server = DlineageUtil.getTableServer(tableName.toString());
611                this.database = DlineageUtil.getTableDatabase(tableName.toString());
612                this.schema = DlineageUtil.getTableSchema(tableName.toString());
613
614                fillSchemaInfo();
615
616                EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
617                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
618                boolean supportSchema = TSQLEnv.supportSchema(vendor);
619
620                if (supportCatalog && SQLUtil.isEmpty(this.database)) {
621                        this.database = DlineageUtil.getTableDatabase(tableName.toString());
622                        if (SQLUtil.isEmpty(this.database) && ModelBindingManager.getGlobalOption().isShowImplicitSchema()
623                                        && !SQLUtil.isEmpty(tableName.getImplictDatabaseString())) {
624                                this.database = tableName.getImplictDatabaseString();
625                        }
626                }
627
628                if (supportSchema && SQLUtil.isEmpty(this.schema)) {
629                        this.schema = DlineageUtil.getTableSchema(tableName.toString());
630                        if (SQLUtil.isEmpty(this.schema) && ModelBindingManager.getGlobalOption().isShowImplicitSchema()
631                                        && !SQLUtil.isEmpty(tableName.getImplictSchemaString())) {
632                                this.schema = tableName.getImplictSchemaString();
633                        }
634                }
635
636                if (supportSchema && !SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) {
637                        if (!SQLUtil.isEmpty(tableName.getImplictSchemaString())) {
638                                this.schema = tableName.getImplictSchemaString();
639                        } else {
640                                this.schema = getDefaultSchema();
641                        }
642                }
643
644                if (!supportCatalog) {
645                        this.database = null;
646                } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
647                        this.database = getDefaultDatabase();
648                }
649
650                if (!supportSchema) {
651                        this.schema = null;
652                } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
653                        this.schema = getDefaultSchema();
654                }
655
656                updateTableName(supportCatalog, supportSchema);
657
658                if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
659                        this.server = getDefaultServer();
660                }
661        }
662
663        protected String getDefaultServer() {
664                String defaultServer = null;
665                if (ModelBindingManager.getGlobalSQLEnv() != null) {
666                        defaultServer = ModelBindingManager.getGlobalSQLEnv().getDefaultServerName();
667                }
668                if (!SQLUtil.isEmpty(defaultServer))
669                        return defaultServer;
670                return TSQLEnv.DEFAULT_SERVER_NAME;
671        }
672
673        protected String getDefaultSchema() {
674                String defaultSchema = null;
675                if (ModelBindingManager.getGlobalSQLEnv() != null) {
676                        defaultSchema = ModelBindingManager.getGlobalSQLEnv().getDefaultSchemaName();
677                }
678                if (!SQLUtil.isEmpty(defaultSchema))
679                        return defaultSchema;
680                return TSQLEnv.DEFAULT_SCHEMA_NAME;
681        }
682
683        protected String getDefaultDatabase() {
684                String defaultDatabase = null;
685                if (ModelBindingManager.getGlobalSQLEnv() != null) {
686                        defaultDatabase = ModelBindingManager.getGlobalSQLEnv().getDefaultCatalogName();
687                }
688                if (!SQLUtil.isEmpty(defaultDatabase))
689                        return defaultDatabase;
690                return TSQLEnv.DEFAULT_DB_NAME;
691        }
692
693        public Table(String tableName) {
694                if (tableName == null) {
695                        throw new IllegalArgumentException("Table arguments can't be null.");
696                }
697
698                id = ++ModelBindingManager.get().TABLE_COLUMN_ID;
699
700                this.startPosition = new Pair3<Long, Long, String>(-1L, -1L, ModelBindingManager.getGlobalHash());
701                this.endPosition = new Pair3<Long, Long, String>(-1L, -1L, ModelBindingManager.getGlobalHash());
702
703                this.fullName = tableName;
704                this.name = tableName;
705                if (SQLUtil.isEmpty(name)) {
706                        name = tableName;
707                }
708
709                if (name.startsWith("`") && name.endsWith("`") && name.indexOf(".") != -1
710                                && ModelBindingManager.getGlobalOption().getVendor() == EDbVendor.dbvbigquery) {
711                        this.name = SQLUtil.trimColumnStringQuote(name);
712                        this.fullName = SQLUtil.trimColumnStringQuote(fullName);
713                }
714
715                EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
716                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
717                boolean supportSchema = TSQLEnv.supportSchema(vendor);
718
719                fillSchemaInfo();
720
721                this.server = DlineageUtil.getTableServer(tableName);
722
723                if (supportCatalog && SQLUtil.isEmpty(this.database)) {
724                        this.database = DlineageUtil.getTableDatabase(tableName);
725                }
726                if (supportSchema && SQLUtil.isEmpty(this.schema)) {
727                        this.schema = DlineageUtil.getTableSchema(tableName);
728                }
729                if (supportSchema && !SQLUtil.isEmpty(this.database) && SQLUtil.isEmpty(this.schema)) {
730                        this.schema = getDefaultSchema();
731                }
732
733                if (!supportCatalog) {
734                        this.database = null;
735                } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
736                        this.database = getDefaultDatabase();
737                }
738
739                if (!supportSchema) {
740                        this.schema = null;
741                } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
742                        this.schema = getDefaultSchema();
743                }
744
745                updateTableName(supportCatalog, supportSchema);
746
747                if (this.server == null && !TSQLEnv.DEFAULT_SERVER_NAME.equals(getDefaultServer())) {
748                        this.server = getDefaultServer();
749                }
750        }
751
752        protected void updateTableName(boolean supportCatalog, boolean supportSchema) {
753                List<String> segments = SQLUtil.parseNames(this.name);
754                this.name = segments.get(segments.size() - 1);
755                if (supportCatalog && supportSchema) {
756                        StringBuilder builder = new StringBuilder();
757                        if (segments.size() > 2) {
758                                builder.append(segments.get(segments.size() - 3)).append(".");
759                        } else {
760                                if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) {
761                                        builder.append(this.database).append(".");
762                                }
763                        }
764                        if (segments.size() > 1) {
765                                builder.append(segments.get(segments.size() - 2)).append(".");
766                        } else {
767                                if (builder.length() > 0) {
768                                        if (this.schema == null) {
769                                                if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
770                                                        this.schema = "dbo";
771                                                } else {
772                                                        this.schema = getDefaultSchema();
773                                                }
774                                        }
775                                        else if (TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)
776                                                        && ModelBindingManager.getGlobalVendor() == EDbVendor.dbvmssql) {
777                                                this.schema = "dbo";
778                                        }
779                                        builder.append(this.schema).append(".");
780                                } else {
781                                        if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) {
782                                                builder.append(this.schema).append(".");
783                                        }
784                                }
785                        }
786                        builder.append(this.name);
787                        this.name = builder.toString();
788                } else if (supportCatalog) {
789                        if (segments.size() > 1) {
790                                this.name = segments.get(segments.size() - 2) + "." + this.name;
791                        }
792                        else {
793                                if (!SQLUtil.isEmpty(this.database) && !TSQLEnv.DEFAULT_DB_NAME.equalsIgnoreCase(this.database)) {
794                                        this.name = this.database + "." + this.name;
795                                }
796                        }
797                } else if (supportSchema) {
798                        if (segments.size() > 1) {
799                                this.name = segments.get(segments.size() - 2) + "." + this.name;
800                        } else {
801                                if (!SQLUtil.isEmpty(this.schema) && !TSQLEnv.DEFAULT_SCHEMA_NAME.equalsIgnoreCase(this.schema)) {
802                                        this.name = this.schema + "." + this.name;
803                                }
804                        }
805                }
806
807                if (this.server != null && !this.server.equals(getDefaultServer())) {
808                        this.name = this.server + "." + this.name;
809                }
810        }
811
812        public long getId() {
813                return id;
814        }
815
816        public String getName() {
817                return name;
818        }
819
820        public void setName(String name) {
821                EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
822                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
823                boolean supportSchema = TSQLEnv.supportSchema(vendor);
824                if (!supportCatalog) {
825                        this.database = null;
826                } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
827                        this.database = getDefaultDatabase();
828                }
829
830                if (!supportSchema) {
831                        this.schema = null;
832                } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
833                        this.schema = getDefaultSchema();
834                }
835                
836                this.name = name;
837                
838                updateTableName(supportCatalog, supportSchema);
839        }
840
841        public Pair3<Long, Long, String> getStartPosition() {
842                return startPosition;
843        }
844
845        public Pair3<Long, Long, String> getEndPosition() {
846                return endPosition;
847        }
848
849        public List<TableColumn> getColumns() {
850                return columns;
851        }
852
853        public void addColumn(TableColumn column) {
854                if (column != null && !this.columns.contains(column)) {
855                        this.columns.add(column);
856                }
857        }
858
859        public TTable getTableObject() {
860                return tableObject;
861        }
862
863        public String getAlias() {
864                String aliasString = Arrays.toString(this.alias.toArray(new String[0]));
865                return aliasString.substring(1, aliasString.length() - 1);
866        }
867
868        public void setAlias(String alias) {
869                if (!SQLUtil.isEmpty(alias)) {
870                        this.alias.add(alias);
871                }
872        }
873
874        public String getFullName() {
875                return fullName;
876        }
877
878        public boolean hasSubquery() {
879                return subquery;
880        }
881
882        public String getParent() {
883                return parent;
884        }
885
886        public void setParent(String parent) {
887                this.parent = parent;
888        }
889
890//      public TObjectName getTableName() {
891//              return tableName;
892//      }
893
894        public String getDatabase() {
895                return database;
896        }
897
898        public String getSchema() {
899                return schema;
900        }
901
902        public TableRelationRows getRelationRows() {
903                return relationRows;
904        }
905
906        public boolean isCreateTable() {
907                return isCreateTable;
908        }
909
910        public void setCreateTable(boolean isCreateTable, boolean fromDDL) {
911                this.isCreateTable = isCreateTable;
912                if (isCreateTable) {
913                        for (TableColumn column : columns) {
914                                column.setShowStar(false);
915                        }
916                        setDetermined(true);
917                        if (fromDDL) {
918                                setFromDDL(true);
919                                TCustomSqlStatement stmt = ModelBindingManager.getGlobalStmtStack().peek();
920                                if (stmt!=null && stmt.getClass().getSimpleName().startsWith("TCreate")) {
921                                        TSourceToken startToken = stmt.getStartToken();
922                                        TSourceToken endToken = stmt.getEndToken();
923                                        this.startPosition = new Pair3<Long, Long, String>(startToken.lineNo, startToken.columnNo,
924                                                        ModelBindingManager.getGlobalHash());
925                                        this.endPosition = new Pair3<Long, Long, String>(endToken.lineNo,
926                                                        endToken.columnNo + SQLUtil.endTrim(endToken.astext).length(), ModelBindingManager.getGlobalHash());
927                                }
928                        }
929                }
930        }
931        
932        public void setCreateTable(boolean isCreateTable) {
933                setCreateTable(isCreateTable, false);
934        }
935
936        public boolean isView() {
937                return isView;
938        }
939
940        public void setView(boolean isView) {
941                this.isView = isView;
942        }
943
944        public boolean isPseudo() {
945                return isPseudo;
946        }
947
948        public void setPseudo(boolean isPseudo) {
949                this.isPseudo = isPseudo;
950        }
951
952        public boolean isExternal() {
953                return isExternal;
954        }
955
956        public void setExternal(boolean isExternal) {
957                this.isExternal = isExternal;
958        }
959
960        public boolean isStage() {
961                return isStage;
962        }
963
964        public void setStage(boolean isStage) {
965                this.isStage = isStage;
966        }
967
968        public boolean isSequence() {
969                return isSequence;
970        }
971
972        public void setSequence(boolean sequence) {
973                isSequence = sequence;
974        }
975
976        public boolean isVariable() {
977                return isVariable;
978        }
979
980        public void setVariable(boolean isVariable) {
981                this.isVariable = isVariable;
982        }
983
984        public boolean isConstant() {
985                return isConstant;
986        }
987
988        public void setConstant(boolean isConstant) {
989                this.isConstant = isConstant;
990        }
991
992        public boolean isPath() {
993                return isPath;
994        }
995
996        public void setPath(boolean isPath) {
997                this.isPath = isPath;
998                if(isPath) {
999                        String filePathDatabase = ModelBindingManager.getGlobalOption().getFilePathDatabase();
1000                        String filePathSchema = ModelBindingManager.getGlobalOption().getFilePathSchema();
1001                        if(SQLUtil.isEmpty(filePathDatabase)) {
1002                                this.database = null;
1003                        }
1004                        else {
1005                                this.database = filePathDatabase;
1006                        }
1007                        if(SQLUtil.isEmpty(filePathSchema)) {
1008                                this.schema = null;
1009                        }
1010                        else {
1011                                this.schema = filePathSchema;
1012                        }
1013
1014                        EDbVendor vendor = ModelBindingManager.getGlobalOption().getVendor();
1015                        boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
1016                        boolean supportSchema = TSQLEnv.supportSchema(vendor);
1017                        if (!supportCatalog) {
1018                                this.database = null;
1019                        } else if (this.database == null && !TSQLEnv.DEFAULT_DB_NAME.equals(getDefaultDatabase())) {
1020                                this.database = getDefaultDatabase();
1021                        }
1022
1023                        if (!supportSchema) {
1024                                this.schema = null;
1025                        } else if (this.schema == null && !TSQLEnv.DEFAULT_SCHEMA_NAME.equals(getDefaultSchema())) {
1026                                this.schema = getDefaultSchema();
1027                        }
1028
1029                        updateTableName(supportCatalog, supportSchema);
1030                }
1031        }
1032
1033        public boolean isCursor() {
1034                return isVariable && getSubType() == SubType.cursor;
1035        }
1036
1037        public String getLocation() {
1038                return location;
1039        }
1040
1041        public void setLocation(String location) {
1042                this.location = location;
1043        }
1044
1045        public String getFileType() {
1046                return fileType;
1047        }
1048
1049        public void setFileType(String fileType) {
1050                this.fileType = fileType;
1051        }
1052
1053        public String getDisplayName() {
1054                return displayName;
1055        }
1056
1057        public void setDisplayName(String displayName) {
1058                this.displayName = displayName;
1059        }
1060
1061        public String getFileFormat() {
1062                return fileFormat;
1063        }
1064
1065        public void setFileFormat(String fileFormat) {
1066                this.fileFormat = fileFormat;
1067        }
1068
1069        public List<Process> getProcesses() {
1070                return processes;
1071        }
1072
1073        public void addProcess(Process process) {
1074                if (processes == null) {
1075                        processes = new ArrayList<Process>();
1076                }
1077                if (process != null && !processes.contains(process)) {
1078                        processes.add(process);
1079                }
1080        }
1081        
1082        public void removeProcess(Process process) {
1083                if (processes == null) {
1084                        processes = new ArrayList<Process>();
1085                }
1086                if (process != null && processes.contains(process)) {
1087                        processes.remove(process);
1088                }
1089        }
1090
1091        public void setSubType(SubType subType) {
1092                if (this.subType == null || subType == SubType.record_type) {
1093                        this.subType = subType;
1094                }
1095        }
1096
1097        public SubType getSubType() {
1098                return subType;
1099        }
1100
1101        public boolean isStream() {
1102                return isStream;
1103        }
1104
1105        public void setStream(boolean isStream) {
1106                this.isStream = isStream;
1107        }
1108
1109        public boolean isSchema() {
1110                return isSchema;
1111        }
1112
1113        public void setSchema(boolean isSchema) {
1114                this.isSchema = isSchema;
1115        }
1116
1117        public void setDatabase(String database) {
1118                this.database = database;
1119        }
1120
1121        public boolean isDatabase() {
1122                return isDatabase;
1123        }
1124
1125        public void setDatabase(boolean isDatabase) {
1126                this.isDatabase = isDatabase;
1127        }
1128
1129        public boolean isDataSource() {
1130                return isDataSource;
1131        }
1132
1133        public void setDataSource(boolean dataSource) {
1134                isDataSource = dataSource;
1135        }
1136
1137        public String getStarStmt() {
1138                return starStmt;
1139        }
1140
1141        public void setStarStmt(String starStmt) {
1142                this.starStmt = starStmt;
1143        }
1144
1145        public void setHasSQLEnv(boolean hasSQLEnv) {
1146                this.hasSQLEnv = hasSQLEnv;
1147        }
1148
1149        public boolean hasSQLEnv() {
1150                return hasSQLEnv;
1151        }
1152
1153        public String getCurrentAlias() {
1154                return currentAlias;
1155        }
1156
1157        public void setCurrentAlias(String currentAlias) {
1158                if (SQLUtil.isEmpty(currentAlias)) {
1159                        this.currentAlias = null;
1160                } else
1161                        this.currentAlias = currentAlias;
1162        }
1163
1164        public Set<String> getAliasList() {
1165                return alias;
1166        }
1167
1168        public String getServer() {
1169                return server;
1170        }
1171
1172        public boolean isDetermined() {
1173                return isDetermined;
1174        }
1175
1176        public void setDetermined(boolean isDetermined) {
1177                this.isDetermined = isDetermined;
1178        }
1179
1180        public boolean isFromDDL() {
1181                return fromDDL;
1182        }
1183
1184        public void setFromDDL(boolean fromDDL) {
1185                this.fromDDL = fromDDL;
1186        }
1187}