001
002package gudusoft.gsqlparser.dlineage;
003
004import gudusoft.gsqlparser.*;
005import gudusoft.gsqlparser.dlineage.dataflow.listener.DataFlowHandleListener;
006import gudusoft.gsqlparser.dlineage.dataflow.metadata.MetadataReader;
007import gudusoft.gsqlparser.dlineage.dataflow.metadata.grabit.GrabitMetadataAnalyzer;
008import gudusoft.gsqlparser.dlineage.dataflow.metadata.sqldep.SQLDepMetadataAnalyzer;
009import gudusoft.gsqlparser.dlineage.dataflow.metadata.sqlflow.SqlflowMetadataAnalyzer;
010import gudusoft.gsqlparser.dlineage.dataflow.model.*;
011import gudusoft.gsqlparser.dlineage.dataflow.model.Process;
012import gudusoft.gsqlparser.dlineage.dataflow.model.JoinRelationship.JoinClauseType;
013import gudusoft.gsqlparser.dlineage.dataflow.model.json.Coordinate;
014import gudusoft.gsqlparser.dlineage.dataflow.model.json.Dataflow;
015import gudusoft.gsqlparser.dlineage.dataflow.model.json.Error;
016import gudusoft.gsqlparser.dlineage.dataflow.model.xml.*;
017import gudusoft.gsqlparser.dlineage.dataflow.sqlenv.SQLEnvParser;
018import gudusoft.gsqlparser.dlineage.metadata.MetadataUtil;
019import gudusoft.gsqlparser.dlineage.metadata.Sqlflow;
020import gudusoft.gsqlparser.dlineage.util.*;
021import gudusoft.gsqlparser.nodes.TTable;
022import gudusoft.gsqlparser.nodes.*;
023import gudusoft.gsqlparser.nodes.couchbase.TObjectConstruct;
024import gudusoft.gsqlparser.nodes.couchbase.TPair;
025import gudusoft.gsqlparser.nodes.functions.TJsonObjectFunction;
026import gudusoft.gsqlparser.nodes.hive.THiveTransformClause;
027import gudusoft.gsqlparser.nodes.hive.THiveTransformClause.ETransformType;
028import gudusoft.gsqlparser.resolver2.ScopeBuildResult;
029import gudusoft.gsqlparser.resolver2.TSQLResolver2;
030import gudusoft.gsqlparser.sqlenv.ESQLDataObjectType;
031import gudusoft.gsqlparser.sqlenv.TSQLEnv;
032import gudusoft.gsqlparser.sqlenv.TSQLSchema;
033import gudusoft.gsqlparser.sqlenv.TSQLTable;
034import gudusoft.gsqlparser.sqlenv.parser.TJSONSQLEnvParser;
035import gudusoft.gsqlparser.stmt.*;
036import gudusoft.gsqlparser.stmt.db2.TDb2ReturnStmt;
037import gudusoft.gsqlparser.stmt.db2.TDb2SqlVariableDeclaration;
038import gudusoft.gsqlparser.stmt.hive.THiveLoad;
039import gudusoft.gsqlparser.stmt.mssql.*;
040import gudusoft.gsqlparser.stmt.mysql.TLoadDataStmt;
041import gudusoft.gsqlparser.stmt.oracle.*;
042import gudusoft.gsqlparser.stmt.redshift.TRedshiftCopy;
043import gudusoft.gsqlparser.stmt.redshift.TRedshiftDeclare;
044import gudusoft.gsqlparser.stmt.snowflake.*;
045import gudusoft.gsqlparser.stmt.teradata.TTeradataCreateProcedure;
046import gudusoft.gsqlparser.util.*;
047import gudusoft.gsqlparser.util.json.JSON;
048
049import javax.script.ScriptEngine;
050import javax.script.ScriptEngineManager;
051import javax.script.ScriptException;
052import java.io.*;
053import java.util.*;
054import java.util.concurrent.atomic.AtomicInteger;
055import java.util.regex.Matcher;
056import java.util.regex.Pattern;
057import java.util.stream.Collectors;
058
059import static gudusoft.gsqlparser.EJoinType.right;
060
061@SuppressWarnings("rawtypes")
062public class DataFlowAnalyzer implements IDataFlowAnalyzer {
063
064        private static final Logger logger = LoggerFactory.getLogger(DataFlowAnalyzer.class);
065
066        private static final List<String> TERADATA_BUILTIN_FUNCTIONS = Arrays
067                        .asList(new String[] { "ACCOUNT", "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP",
068                                        "CURRENT_USER", "DATABASE", "DATE", "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", });
069
070        private static final List<String> CONSTANT_BUILTIN_FUNCTIONS = Arrays.asList(new String[] { "ACCOUNT",
071                        "CURRENT_DATE", "CURRENT_ROLE", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_USER", "DATABASE", "DATE",
072                        "PROFILE", "ROLE", "SESSION", "TIME", "USER", "SYSDATE", "GETDATE" });
073
074        private Stack<TCustomSqlStatement> stmtStack = new Stack<TCustomSqlStatement>();
075        private List<ResultSet> appendResultSets = new ArrayList<ResultSet>();
076        private Set<TCustomSqlStatement> accessedStatements = new HashSet<TCustomSqlStatement>();
077        private Set<TSelectSqlStatement> accessedSubqueries = new HashSet<TSelectSqlStatement>();
078        private Map<String, TCustomSqlStatement> viewDDLMap = new HashMap<String, TCustomSqlStatement>();
079        private Map<String, TCustomSqlStatement> procedureDDLMap = new HashMap<String, TCustomSqlStatement>();
080        private Map<TTable, TObjectNameList> structObjectMap = new HashMap<TTable, TObjectNameList>();
081
082        private SqlInfo[] sqlInfos;
083        private List<ErrorInfo> errorInfos = new ArrayList<ErrorInfo>();
084        private IndexedLinkedHashMap<String, List<SqlInfo>> sqlInfoMap = new IndexedLinkedHashMap<String, List<SqlInfo>>();
085        private TSQLEnv sqlenv = null;
086        private ModelBindingManager modelManager = new ModelBindingManager();
087        private ModelFactory modelFactory = new ModelFactory(modelManager);
088        private List<Long> tableIds = new ArrayList<Long>();
089        private TTableList hiveFromTables;
090        private dataflow dataflow;
091        private String dataflowString;
092        private Option option = new Option();
093
094        {
095                modelManager.TABLE_COLUMN_ID = option.getStartId();
096                modelManager.RELATION_ID = option.getStartId();
097                ModelBindingManager.set(modelManager);
098                ModelBindingManager.setGlobalStmtStack(stmtStack);
099                ModelBindingManager.setGlobalOption(option);
100                ModelBindingManager.setGlobalSqlInfo(sqlInfoMap);
101        }
102
103        public DataFlowAnalyzer(String sqlContent, Option option) {
104                SqlInfo[] sqlInfos = new SqlInfo[1];
105                SqlInfo info = new SqlInfo();
106                info.setSql(sqlContent);
107                info.setOriginIndex(0);
108                sqlInfos[0] = info;
109                this.option = option;
110                ModelBindingManager.setGlobalOption(this.option);
111                this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
112        }
113
114        public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput, String defaultServer,
115                        String defaultDatabase, String defaltSchema) {
116                SqlInfo[] sqlInfos = new SqlInfo[1];
117                SqlInfo info = new SqlInfo();
118                info.setSql(sqlContent);
119                info.setOriginIndex(0);
120                sqlInfos[0] = info;
121                option.setVendor(dbVendor);
122                option.setSimpleOutput(simpleOutput);
123                option.setDefaultServer(defaultServer);
124                option.setDefaultDatabase(defaultDatabase);
125                option.setDefaultSchema(defaltSchema);
126                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
127        }
128
129        public DataFlowAnalyzer(String sqlContent, EDbVendor dbVendor, boolean simpleOutput) {
130                SqlInfo[] sqlInfos = new SqlInfo[1];
131                SqlInfo info = new SqlInfo();
132                info.setSql(sqlContent);
133                info.setOriginIndex(0);
134                sqlInfos[0] = info;
135                option.setVendor(dbVendor);
136                option.setSimpleOutput(simpleOutput);
137                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
138        }
139
140        public DataFlowAnalyzer(String[] sqlContents, Option option) {
141                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
142                for (int i = 0; i < sqlContents.length; i++) {
143                        SqlInfo info = new SqlInfo();
144                        info.setSql(sqlContents[i]);
145                        info.setOriginIndex(0);
146                        sqlInfos[i] = info;
147                }
148                this.option = option;
149                ModelBindingManager.setGlobalOption(this.option);
150                this.sqlInfos = convertSQL(option.getVendor(), JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
151        }
152
153        public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput, String defaultServer,
154                        String defaultDatabase, String defaltSchema) {
155                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
156                for (int i = 0; i < sqlContents.length; i++) {
157                        SqlInfo info = new SqlInfo();
158                        info.setSql(sqlContents[i]);
159                        info.setOriginIndex(0);
160                        sqlInfos[i] = info;
161                }
162                option.setVendor(dbVendor);
163                option.setSimpleOutput(simpleOutput);
164                option.setDefaultServer(defaultServer);
165                option.setDefaultDatabase(defaultDatabase);
166                option.setDefaultSchema(defaltSchema);
167                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
168        }
169
170        public DataFlowAnalyzer(String[] sqlContents, EDbVendor dbVendor, boolean simpleOutput) {
171                SqlInfo[] sqlInfos = new SqlInfo[sqlContents.length];
172                for (int i = 0; i < sqlContents.length; i++) {
173                        SqlInfo info = new SqlInfo();
174                        info.setSql(sqlContents[i]);
175                        info.setOriginIndex(0);
176                        sqlInfos[i] = info;
177                }
178                option.setVendor(dbVendor);
179                option.setSimpleOutput(simpleOutput);
180                this.sqlInfos = convertSQL(dbVendor, JSON.toJSONString(sqlInfos)).toArray(new SqlInfo[0]);
181        }
182
183        public DataFlowAnalyzer(SqlInfo[] sqlInfos, Option option) {
184                this.sqlInfos = sqlInfos;
185                this.option = option;
186                ModelBindingManager.setGlobalOption(this.option);
187        }
188
189        public DataFlowAnalyzer(SqlInfo[] sqlInfos, EDbVendor dbVendor, boolean simpleOutput) {
190                this.sqlInfos = sqlInfos;
191                option.setVendor(dbVendor);
192                option.setSimpleOutput(simpleOutput);
193        }
194
195        public DataFlowAnalyzer(File[] sqlFiles, Option option) {
196                SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length];
197                for (int i = 0; i < sqlFiles.length; i++) {
198                        SqlInfo info = new SqlInfo();
199                        info.setSql(SQLUtil.getFileContent(sqlFiles[i]));
200                        info.setFileName(sqlFiles[i].getName());
201                        info.setFilePath(sqlFiles[i].getAbsolutePath());
202                        info.setOriginIndex(0);
203                        sqlInfos[i] = info;
204                }
205                this.sqlInfos = sqlInfos;
206                this.option = option;
207                ModelBindingManager.setGlobalOption(this.option);
208        }
209
210        public DataFlowAnalyzer(File[] sqlFiles, EDbVendor dbVendor, boolean simpleOutput) {
211                SqlInfo[] sqlInfos = new SqlInfo[sqlFiles.length];
212                for (int i = 0; i < sqlFiles.length; i++) {
213                        SqlInfo info = new SqlInfo();
214                        info.setSql(SQLUtil.getFileContent(sqlFiles[i]));
215                        info.setFileName(sqlFiles[i].getName());
216                        info.setFilePath(sqlFiles[i].getAbsolutePath());
217                        info.setOriginIndex(0);
218                        sqlInfos[i] = info;
219                }
220                this.sqlInfos = sqlInfos;
221                option.setVendor(dbVendor);
222                option.setSimpleOutput(simpleOutput);
223        }
224
225        public DataFlowAnalyzer(File sqlFile, Option option) {
226                File[] children = SQLUtil.listFiles(sqlFile);
227                SqlInfo[] sqlInfos = new SqlInfo[children.length];
228                for (int i = 0; i < children.length; i++) {
229                        SqlInfo info = new SqlInfo();
230                        info.setSql(SQLUtil.getFileContent(children[i]));
231                        info.setFileName(children[i].getName());
232                        info.setFilePath(children[i].getAbsolutePath());
233                        info.setOriginIndex(0);
234                        sqlInfos[i] = info;
235                }
236                this.sqlInfos = sqlInfos;
237                this.option = option;
238                ModelBindingManager.setGlobalOption(this.option);
239        }
240
241        public DataFlowAnalyzer(File sqlFile, EDbVendor dbVendor, boolean simpleOutput) {
242                File[] children = SQLUtil.listFiles(sqlFile);
243                SqlInfo[] sqlInfos = new SqlInfo[children.length];
244                for (int i = 0; i < children.length; i++) {
245                        SqlInfo info = new SqlInfo();
246                        info.setSql(SQLUtil.getFileContent(children[i]));
247                        info.setFileName(children[i].getName());
248                        info.setFilePath(children[i].getAbsolutePath());
249                        info.setOriginIndex(0);
250                        sqlInfos[i] = info;
251                }
252                this.sqlInfos = sqlInfos;
253                option.setVendor(dbVendor);
254                option.setSimpleOutput(simpleOutput);
255        }
256
257        public boolean isIgnoreRecordSet() {
258                return option.isIgnoreRecordSet();
259        }
260
261        public void setIgnoreRecordSet(boolean ignoreRecordSet) {
262                option.setIgnoreRecordSet(ignoreRecordSet);
263        }
264
265        public boolean isSimpleShowTopSelectResultSet() {
266                return option.isSimpleShowTopSelectResultSet();
267        }
268
269        public void setSimpleShowTopSelectResultSet(boolean simpleShowTopSelectResultSet) {
270                option.setSimpleShowTopSelectResultSet(simpleShowTopSelectResultSet);
271        }
272
273        public boolean isSimpleShowFunction() {
274                return option.isSimpleShowFunction();
275        }
276
277        public void setSimpleShowFunction(boolean simpleShowFunction) {
278                option.setSimpleShowFunction(simpleShowFunction);
279        }
280
281        public boolean isShowJoin() {
282                return option.isShowJoin();
283        }
284
285        public void setShowJoin(boolean showJoin) {
286                option.setShowJoin(showJoin);
287        }
288
289        public void setShowCallRelation(boolean showCallRelation) {
290                option.setShowCallRelation(showCallRelation);
291        }
292
293        public boolean isShowCallRelation() {
294                return option.isShowCallRelation();
295        }
296
297        public boolean isShowImplicitSchema() {
298                return option.isShowImplicitSchema();
299        }
300
301        public void setShowImplicitSchema(boolean showImplicitSchema) {
302                option.setShowImplicitSchema(showImplicitSchema);
303        }
304
305        public boolean isShowConstantTable() {
306                return option.isShowConstantTable();
307        }
308
309        public void setShowConstantTable(boolean showConstantTable) {
310                option.setShowConstantTable(showConstantTable);
311        }
312
313        public boolean isShowCountTableColumn() {
314                return option.isShowCountTableColumn();
315        }
316
317        public void setShowCountTableColumn(boolean showCountTableColumn) {
318                option.setShowCountTableColumn(showCountTableColumn);
319        }
320
321        public boolean isTransform() {
322                return option.isTransform();
323        }
324
325        public void setTransform(boolean transform) {
326                option.setTransform(transform);
327                if (option.isTransformCoordinate()) {
328                        option.setTransform(true);
329                }
330        }
331
332        public boolean isTransformCoordinate() {
333                return option.isTransformCoordinate();
334        }
335
336        public void setTransformCoordinate(boolean transformCoordinate) {
337                option.setTransformCoordinate(transformCoordinate);
338                if (transformCoordinate) {
339                        option.setTransform(true);
340                }
341        }
342
343        public boolean isLinkOrphanColumnToFirstTable() {
344                return option.isLinkOrphanColumnToFirstTable();
345        }
346
347        public void setLinkOrphanColumnToFirstTable(boolean linkOrphanColumnToFirstTable) {
348                option.setLinkOrphanColumnToFirstTable(linkOrphanColumnToFirstTable);
349        }
350
351        public boolean isIgnoreTemporaryTable() {
352                return option.isIgnoreTemporaryTable();
353        }
354
355        public void setIgnoreTemporaryTable(boolean ignoreTemporaryTable) {
356                option.setIgnoreTemporaryTable(ignoreTemporaryTable);
357        }
358        
359        public boolean isIgnoreCoordinate() {
360                return option.isIgnoreCoordinate();
361        }
362
363        public void setIgnoreCoordinate(boolean ignoreCoordinate) {
364                option.setIgnoreCoordinate(ignoreCoordinate);
365        }
366
367        public void setHandleListener(DataFlowHandleListener listener) {
368                option.setHandleListener(listener);
369        }
370
371        public void setSqlEnv(TSQLEnv sqlenv) {
372                this.sqlenv = sqlenv;
373        }
374
375        public void setOption(Option option) {
376                this.option = option;
377                ModelBindingManager.setGlobalOption(this.option);
378        }
379
380        public Option getOption() {
381                return option;
382        }
383
384        public synchronized String chechSyntax() {
385                StringBuilder builder = new StringBuilder();
386                if (sqlInfos != null) {
387                        for (SqlInfo sqlInfo : sqlInfos) {
388                                String content = sqlInfo.getSql();
389                                if (content != null && content.indexOf("<dlineage") != -1) {
390                                        try {
391                                                XML2Model.loadXML(dataflow.class, content);
392                                                continue;
393                                        } catch (Exception e) {
394                                                builder.append("Parsing dataflow ").append("occurs errors.\n").append(e.getMessage())
395                                                                .append("\n");
396                                        }
397                                }
398                                if (content != null && content.trim().startsWith("{")) {
399                                        Map queryObject = (Map) JSON.parseObject(content);
400                                        content = (String) queryObject.get("sourceCode");
401                                }
402                                if (MetadataReader.isMetadata(content)) {
403                                        continue;
404                                }
405                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
406                                sqlparser.sqltext = content;
407                                int result = sqlparser.parse();
408                                if (result != 0) {
409                                        builder.append("Parsing sql ").append("occurs errors.\n").append(sqlparser.getErrormessage())
410                                                        .append("\n");
411                                }
412                        }
413                }
414                return builder.toString();
415        }
416
417        public synchronized String generateDataFlow(boolean withExtraInfo) {
418                if (ModelBindingManager.get() == null) {
419                        ModelBindingManager.set(modelManager);
420                }
421
422                dataflow = analyzeSqlScript();
423
424                if (dataflow != null && !withExtraInfo && dataflow.getResultsets() != null) {
425                        for (table t : dataflow.getResultsets()) {
426                                t.setIsTarget(null);
427                                if (t.getColumns() != null) {
428                                        for (column t1 : t.getColumns()) {
429                                                t1.setIsFunction(null);
430                                        }
431                                }
432                        }
433                }
434                
435                if(dataflow!=null && dataflow.getRelationships()!=null && option.getFilterRelationTypes()!=null && !option.getFilterRelationTypes().isEmpty()) {
436                        List<relationship> relationships = new ArrayList<relationship>();
437                        for(relationship relationship: dataflow.getRelationships()) {
438                                if(option.getFilterRelationTypes().contains(relationship.getType())) {
439                                        relationships.add(relationship);
440                                }
441                        }
442                        dataflow.setRelationships(relationships);
443                }
444
445                if (option.getHandleListener() != null) {
446                        option.getHandleListener().endAnalyze(dataflow);
447                }
448
449                if (option.isOutput()) {
450                        if (option.getHandleListener() != null) {
451                                option.getHandleListener().startOutputDataFlowXML();
452                        }
453                        if (dataflow != null) {
454                                if (option.isTextFormat()) {
455                                        dataflowString = getTextOutput(dataflow);
456                                } else {
457                                        try {
458                                                dataflowString = XML2Model.saveXML(dataflow);
459                                        }catch (Exception e){
460                                                logger.error("Output dataflow to xml failed.", e);
461                                                dataflowString = null;
462                                        }
463                                }
464                        }
465                        if (option.getHandleListener() != null) {
466                                option.getHandleListener().endOutputDataFlowXML(dataflowString == null ? 0 : dataflowString.length());
467                        }
468                }
469
470                return dataflowString;
471        }
472
473        private dataflow removeDuplicateColumns(dataflow dataflow) {
474                List<table> tables = new ArrayList<table>();
475                if (dataflow.getTables() != null) {
476                        tables.addAll(dataflow.getTables());
477                }
478                if (dataflow.getViews() != null) {
479                        tables.addAll(dataflow.getViews());
480                }
481                if (dataflow.getStages() != null) {
482                        tables.addAll(dataflow.getStages());
483                }
484                if (dataflow.getDatasources() != null) {
485                        tables.addAll(dataflow.getDatasources());
486                }
487                if (dataflow.getStreams() != null) {
488                        tables.addAll(dataflow.getStreams());
489                }
490                if (dataflow.getPaths() != null) {
491                        tables.addAll(dataflow.getPaths());
492                }
493                if (dataflow.getVariables() != null) {
494                        tables.addAll(dataflow.getVariables());
495                }
496                if (dataflow.getResultsets() != null) {
497                        tables.addAll(dataflow.getResultsets());
498                }
499                for (table table : tables) {
500                        if (table.getColumns() == null) {
501                                continue;
502                        }
503                        Set<String> columnIds = new HashSet<String>();
504                        Iterator<column> iter = table.getColumns().iterator();
505                        while(iter.hasNext()) {
506                                column column = iter.next();
507                                String id = column.getId();
508                                if (columnIds.contains(id)) {
509                                        iter.remove();
510                                } else {
511                                        columnIds.add(id);
512                                }
513                        }
514                }
515                return dataflow;
516        }
517
518        public synchronized String generateDataFlow() {
519                return generateDataFlow(false);
520        }
521
522        public synchronized String generateSqlInfos() {
523                return JSON.toJSONString(sqlInfoMap);
524        }
525
526        public Map<String, List<SqlInfo>> getSqlInfos() {
527                return sqlInfoMap;
528        }
529
530        public Map getHashSQLMap() {
531                return modelManager.getHashSQLMap();
532        }
533        
534        public Map getDynamicSQLMap() {
535                return modelManager.getDynamicSQLMap();
536        }
537
538        /**
539         * @deprecated please use SqlInfoHelper.getSelectedDbObjectInfo
540         */
541        public DbObjectPosition getSelectedDbObjectInfo(Coordinate start, Coordinate end) {
542                if (start == null || end == null) {
543                        throw new IllegalArgumentException("Coordinate can't be null.");
544                }
545
546                String hashCode = start.getHashCode();
547
548                if (hashCode == null) {
549                        throw new IllegalArgumentException("Coordinate hashcode can't be null.");
550                }
551
552                int dbObjectStartLine = (int) start.getX() - 1;
553                int dbObjectStarColumn = (int) start.getY() - 1;
554                int dbObjectEndLine = (int) end.getX() - 1;
555                int dbObjectEndColumn = (int) end.getY() - 1;
556                List<SqlInfo> sqlInfoList;
557                if (hashCode.matches("\\d+")) {
558                        sqlInfoList = sqlInfoMap.getValueAtIndex(Integer.valueOf(hashCode));
559                } else {
560                        sqlInfoList = sqlInfoMap.get(hashCode);
561                }
562                for (int j = 0; j < sqlInfoList.size(); j++) {
563                        SqlInfo sqlInfo = sqlInfoList.get(j);
564                        int startLine = sqlInfo.getLineStart();
565                        int endLine = sqlInfo.getLineEnd();
566                        if (dbObjectStartLine >= startLine && dbObjectStartLine <= endLine) {
567                                DbObjectPosition position = new DbObjectPosition();
568                                position.setFile(sqlInfo.getFileName());
569                                position.setFilePath(sqlInfo.getFilePath());
570                                position.setSql(sqlInfo.getSql());
571                                position.setIndex(sqlInfo.getOriginIndex());
572                                List<Pair<Integer, Integer>> positions = position.getPositions();
573                                positions.add(new Pair<Integer, Integer>(
574                                                dbObjectStartLine - startLine + sqlInfo.getOriginLineStart() + 1, dbObjectStarColumn + 1));
575                                positions.add(new Pair<Integer, Integer>(dbObjectEndLine - startLine + sqlInfo.getOriginLineStart() + 1,
576                                                dbObjectEndColumn + 1));
577                                return position;
578                        }
579                }
580                return null;
581        }
582
583        public static dataflow mergeTables(dataflow dataflow, Long startId) {
584                return mergeTables(dataflow, startId, new Option());
585        }
586
587        public static dataflow mergeTables(dataflow dataflow, Long startId, Option option) {
588                List<table> tableCopy = new ArrayList<table>();
589                List<table> viewCopy = new ArrayList<table>();
590                List<table> databaseCopy = new ArrayList<table>();
591                List<table> schemaCopy = new ArrayList<table>();
592                List<table> stageCopy = new ArrayList<table>();
593                List<table> dataSourceCopy = new ArrayList<table>();
594                List<table> streamCopy = new ArrayList<table>();
595                List<table> fileCopy = new ArrayList<table>();
596                List<table> variableCopy = new ArrayList<table>();
597                List<table> cursorCopy = new ArrayList<table>();
598                List<table> resultSetCopy = new ArrayList<table>();
599                if (dataflow.getTables() != null) {
600                        tableCopy.addAll(dataflow.getTables());
601                }
602                dataflow.setTables(tableCopy);
603                if (dataflow.getViews() != null) {
604                        viewCopy.addAll(dataflow.getViews());
605                }
606                dataflow.setViews(viewCopy);
607                if (dataflow.getDatabases() != null) {
608                        databaseCopy.addAll(dataflow.getDatabases());
609                }
610                dataflow.setDatabases(databaseCopy);
611                if (dataflow.getSchemas() != null) {
612                        schemaCopy.addAll(dataflow.getSchemas());
613                }
614                dataflow.setSchemas(schemaCopy);
615                if (dataflow.getStages() != null) {
616                        stageCopy.addAll(dataflow.getStages());
617                }
618                dataflow.setStages(stageCopy);
619                if (dataflow.getDatasources() != null) {
620                        dataSourceCopy.addAll(dataflow.getDatasources());
621                }
622                dataflow.setDatasources(dataSourceCopy);
623                if (dataflow.getStreams() != null) {
624                        streamCopy.addAll(dataflow.getStreams());
625                }
626                dataflow.setStreams(streamCopy);
627                if (dataflow.getPaths() != null) {
628                        fileCopy.addAll(dataflow.getPaths());
629                }
630                dataflow.setPaths(fileCopy);
631                if (dataflow.getVariables() != null) {
632                        variableCopy.addAll(dataflow.getVariables());
633                }
634                dataflow.setVariables(variableCopy);
635                if (dataflow.getResultsets() != null) {
636                        resultSetCopy.addAll(dataflow.getResultsets());
637                }
638                dataflow.setResultsets(resultSetCopy);
639
640                Map<String, List<table>> tableMap = new HashMap<String, List<table>>();
641                Map<String, String> tableTypeMap = new HashMap<String, String>();
642                Map<String, TMssqlCreateType> mssqlTypeMap = new HashMap<String, TMssqlCreateType>();
643                Map<String, String> tableIdMap = new HashMap<String, String>();
644
645                Map<String, List<column>> columnMap = new HashMap<String, List<column>>();
646                Map<String, Set<String>> tableColumnMap = new HashMap<String, Set<String>>();
647                Map<String, String> columnIdMap = new HashMap<String, String>();
648                Map<String, column> columnMergeIdMap = new HashMap<String, column>();
649
650                List<table> tables = new ArrayList<table>();
651                tables.addAll(dataflow.getTables());
652                tables.addAll(dataflow.getViews());
653                tables.addAll(dataflow.getDatabases());
654                tables.addAll(dataflow.getSchemas());
655                tables.addAll(dataflow.getStages());
656                tables.addAll(dataflow.getDatasources());
657                tables.addAll(dataflow.getStreams());
658                tables.addAll(dataflow.getPaths());
659                tables.addAll(dataflow.getResultsets());
660                tables.addAll(dataflow.getVariables());
661                
662                Set<String> columnIds = new HashSet<String>();
663
664                for (table table : tables) {
665                        String qualifiedTableName = DlineageUtil.getQualifiedTableName(table);
666                        String tableFullName = DlineageUtil.getIdentifierNormalTableName(qualifiedTableName);
667
668                        if (!tableMap.containsKey(tableFullName)) {
669                                tableMap.put(tableFullName, new ArrayList<table>());
670                        }
671
672                        tableMap.get(tableFullName).add(table);
673
674                        if (!tableTypeMap.containsKey(tableFullName)) {
675                                tableTypeMap.put(tableFullName, table.getType());
676                        } else if ("view".equals(table.getSubType())) {
677                                tableTypeMap.put(tableFullName, table.getType());
678                        } else if ("database".equals(table.getSubType())) {
679                                tableTypeMap.put(tableFullName, table.getType());
680                        } else if ("schema".equals(table.getSubType())) {
681                                tableTypeMap.put(tableFullName, table.getType());
682                        } else if ("stage".equals(table.getSubType())) {
683                                tableTypeMap.put(tableFullName, table.getType());
684                        } else if ("sequence".equals(table.getSubType())) {
685                                tableTypeMap.put(tableFullName, table.getType());
686                        } else if ("datasource".equals(table.getSubType())) {
687                                tableTypeMap.put(tableFullName, table.getType());
688                        } else if ("stream".equals(table.getSubType())) {
689                                tableTypeMap.put(tableFullName, table.getType());
690                        } else if ("file".equals(table.getSubType())) {
691                                tableTypeMap.put(tableFullName, table.getType());
692                        } else if ("table".equals(tableTypeMap.get(tableFullName))) {
693                                tableTypeMap.put(tableFullName, table.getType());
694                        } else if ("variable".equals(tableTypeMap.get(tableFullName))) {
695                                tableTypeMap.put(tableFullName, table.getType());
696                        }
697
698                        if (table.getColumns() != null) {
699                                if (!tableColumnMap.containsKey(tableFullName)) {
700                                        tableColumnMap.put(tableFullName, new LinkedHashSet<String>());
701                                }
702                                for (column column : table.getColumns()) {
703                                        String columnFullName = tableFullName + "."
704                                                        + (column.getQualifiedTable() != null
705                                                                        ? (DlineageUtil.getIdentifierNormalTableName(column.getQualifiedTable()) + ".")
706                                                                        : "")
707                                                        + ("false".equals(table.getIsTarget()) ? DlineageUtil.normalizeColumnName(column.getName())
708                                                                        : DlineageUtil.getIdentifierNormalColumnName(column.getName()));
709
710                                        if (!columnMap.containsKey(columnFullName)) {
711                                                columnMap.put(columnFullName, new ArrayList<column>());
712                                                tableColumnMap.get(tableFullName).add(columnFullName);
713                                        }
714
715                                        columnMap.get(columnFullName).add(column);
716                                        columnIds.add(column.getId());
717                                }
718                        }
719                }
720
721                Iterator<String> tableNameIter = tableMap.keySet().iterator();
722                while (tableNameIter.hasNext()) {
723                        String tableName = tableNameIter.next();
724                        List<table> tableList = tableMap.get(tableName);
725                        table table;
726                        if (tableList.size() > 1) {
727                                table standardTable = tableList.get(0);
728                                // Function允许重名,不做合并处理
729                                if (standardTable.isFunction()) {
730                                        continue;
731                                }
732                                
733                                // Variable允许重名,不做合并处理
734                                if (standardTable.isVariable()) {
735                                        continue;
736                                }
737                                
738                                // 临时表不做合并处理
739                                if(SQLUtil.isTempTable(standardTable)) {
740                                        continue;
741                                }
742
743                                String type = tableTypeMap.get(tableName);
744                                table = new table();
745                                table.setId(String.valueOf(++startId));
746                                table.setServer(standardTable.getServer());
747                                table.setDatabase(standardTable.getDatabase());
748                                table.setSchema(standardTable.getSchema());
749                                table.setName(standardTable.getName());
750                                table.setDisplayName(standardTable.getDisplayName());
751                                table.setParent(standardTable.getParent());
752                                table.setMore(standardTable.getMore());
753                                table.setColumns(new ArrayList<column>());
754                                table.setSubType(standardTable.getSubType());
755                                Set<String> processIds = new LinkedHashSet<String>();
756                                for (int k = 0; k < tableList.size(); k++) {
757                                        if (tableList.get(k).getProcessIds() != null) {
758                                                processIds.addAll(tableList.get(k).getProcessIds());
759                                        }
760                                }
761                                if (!processIds.isEmpty()) {
762                                        table.setProcessIds(new ArrayList<String>(processIds));
763                                }
764                                Set<String> alias = new LinkedHashSet<String>();
765                                for (int k = 0; k < tableList.size(); k++) {
766                                        if (tableList.get(k).getAlias() != null) {
767                                                alias.addAll(Arrays.asList(tableList.get(k).getAlias().split("\\s*,\\s*")));
768                                        }
769                                }
770                                if (!alias.isEmpty()) {
771                                        String aliasString = Arrays.toString(alias.toArray(new String[0]));
772                                        table.setAlias(aliasString.substring(1, aliasString.length() - 1));
773                                }
774                                table.setType(type);
775                                for (table item : tableList) {
776                                        if (!SQLUtil.isEmpty(table.getCoordinate()) && !SQLUtil.isEmpty(item.getCoordinate())) {
777                                                if (table.getCoordinate().indexOf(item.getCoordinate()) == -1) {
778                                                        table.appendCoordinate(item.getCoordinate());
779                                                }
780                                        } else if (!SQLUtil.isEmpty(item.getCoordinate())) {
781                                                table.setCoordinate(item.getCoordinate());
782                                        }
783
784                                        if (item.getStarStmt() != null) {
785                                                table.setStarStmt(item.getStarStmt());
786                                        }
787
788                                        tableIdMap.put(item.getId(), table.getId());
789
790                                        if (item.isView()) {
791                                                dataflow.getViews().remove(item);
792                                        } else if (item.isDatabaseType()) {
793                                                dataflow.getDatabases().remove(item);
794                                        } else if (item.isSchemaType()) {
795                                                dataflow.getSchemas().remove(item);
796                                        } else if (item.isStage()) {
797                                                dataflow.getStages().remove(item);
798                                        } else if (item.isDataSource()) {
799                                                dataflow.getDatasources().remove(item);
800                                        } else if (item.isStream()) {
801                                                dataflow.getStreams().remove(item);
802                                        } else if (item.isFile()) {
803                                                dataflow.getPaths().remove(item);
804                                        } else if (item.isVariable()) {
805                                                dataflow.getVariables().remove(item);
806                                        } else if (item.isTable()) {
807                                                dataflow.getTables().remove(item);
808                                        } else if (item.isResultSet()) {
809                                                dataflow.getResultsets().remove(item);
810                                        }
811                                }
812
813                                if (table.isView()) {
814                                        dataflow.getViews().add(table);
815                                } else if (table.isDatabaseType()) {
816                                        dataflow.getDatabases().add(table);
817                                } else if (table.isSchemaType()) {
818                                        dataflow.getSchemas().add(table);
819                                } else if (table.isStage()) {
820                                        dataflow.getStages().add(table);
821                                } else if (table.isDataSource()) {
822                                        dataflow.getDatasources().add(table);
823                                } else if (table.isStream()) {
824                                        dataflow.getStreams().add(table);
825                                } else if (table.isFile()) {
826                                        dataflow.getPaths().add(table);
827                                } else if (table.isVariable()) {
828                                        dataflow.getVariables().add(table);
829                                } else if (table.isResultSet()) {
830                                        dataflow.getResultsets().add(table);
831                                } else {
832                                        dataflow.getTables().add(table);
833                                }
834                        } else {
835                                table = tableList.get(0);
836                                if(Boolean.TRUE.toString().equals(table.getIsDetermined())){
837                                        continue;
838                                }
839                                
840                                if (option.isIgnoreUnusedSynonym() && SubType.synonym.name().equals(table.getSubType())) {
841                                        dataflow.getTables().remove(table);
842                                        tableColumnMap.get(tableName).clear();
843                                        continue;
844                                }
845                        }
846
847                        Set<String> columns = tableColumnMap.get(tableName);
848                        Iterator<String> columnIter = columns.iterator();
849                        List<column> mergeColumns = new ArrayList<column>();
850                        while (columnIter.hasNext()) {
851                                String columnName = columnIter.next();
852                                List<column> columnList = columnMap.get(columnName);
853                                List<column> functions = new ArrayList<column>();
854                                for (column t : columnList) {
855                                        if (Boolean.TRUE.toString().equals(t.getIsFunction())) {
856                                                functions.add(t);
857                                        }
858                                }
859                                if (functions != null && !functions.isEmpty()) {
860                                        for (column function : functions) {
861                                                mergeColumns.add(function);
862                                                columnIdMap.put(function.getId(), function.getId());
863                                                columnMergeIdMap.put(function.getId(), function);
864                                        }
865
866                                        columnList.removeAll(functions);
867                                }
868                                if (!columnList.isEmpty()) {
869                                        column firstColumn = columnList.iterator().next();
870                                        if (columnList.size() > 1) {
871                                                column mergeColumn = new column();
872                                                mergeColumn.setId(String.valueOf(++startId));
873                                                mergeColumn.setName(firstColumn.getName());
874                                                mergeColumn.setDisplayName(firstColumn.getDisplayName());
875                                                mergeColumn.setSource(firstColumn.getSource());
876                                                mergeColumn.setQualifiedTable(firstColumn.getQualifiedTable());
877                                                mergeColumn.setDataType(firstColumn.getDataType());
878                                                mergeColumn.setForeignKey(firstColumn.isForeignKey());
879                                                mergeColumn.setPrimaryKey(firstColumn.isPrimaryKey());
880                                                mergeColumn.setUnqiueKey(firstColumn.isUnqiueKey());
881                                                mergeColumn.setIndexKey(firstColumn.isIndexKey());
882                                                mergeColumns.add(mergeColumn);
883                                                for (column item : columnList) {
884                                                        mergeColumn.appendCoordinate(item.getCoordinate());
885                                                        columnIdMap.put(item.getId(), mergeColumn.getId());
886                                                }
887                                                columnMergeIdMap.put(mergeColumn.getId(), mergeColumn);
888                                                columnIds.add(mergeColumn.getId());
889                                        } else {
890                                                mergeColumns.add(firstColumn);
891                                                columnIdMap.put(firstColumn.getId(), firstColumn.getId());
892                                                columnMergeIdMap.put(firstColumn.getId(), firstColumn);
893                                        }
894                                }
895                        }
896                        table.setColumns(mergeColumns);
897                }
898
899                if (dataflow.getRelationships() != null) {
900                        Map<String, relationship> mergeRelations = new LinkedHashMap<String, relationship>();
901                        for (int i = 0; i < dataflow.getRelationships().size(); i++) {
902                                relationship relation = dataflow.getRelationships().get(i);
903                                
904                                if("crud".equals(relation.getType()) && option.getAnalyzeMode() == AnalyzeMode.crud) {
905                                        String jsonString = JSON.toJSONString(relation, true);
906                                        String key = SHA256.getMd5(jsonString);
907                                        if (!mergeRelations.containsKey(key)) {
908                                                mergeRelations.put(key, relation);
909                                        }
910                                        continue;
911                                }
912                                
913                                targetColumn target = relation.getTarget();
914                                if ("call".equals(relation.getType())) {
915                                        target = relation.getCaller();
916                                }
917                                if (target != null && tableIdMap.containsKey(target.getParent_id())) {
918                                        target.setParent_id(tableIdMap.get(target.getParent_id()));
919                                }
920
921                                if (columnIdMap.containsKey(target.getId())) {
922                                        target.setId(columnIdMap.get(target.getId()));
923                                        target.setCoordinate(columnMergeIdMap.get(target.getId()).getCoordinate());
924                                }
925                                else if(option.isIgnoreUnusedSynonym() && EffectType.synonym.name().equals(relation.getEffectType())){
926                                        continue;
927                                }
928                                
929                                if (!"call".equals(relation.getType()) && !columnIds.contains(target.getId())) {
930                                        continue;
931                                }
932
933                                List<sourceColumn> sources = relation.getSources();
934                                if ("call".equals(relation.getType())) {
935                                        sources = relation.getCallees();
936                                }
937                                Set<sourceColumn> sourceSet = new LinkedHashSet<sourceColumn>();
938                                if (sources != null) {
939                                        for (sourceColumn source : sources) {
940                                                if (!"call".equals(relation.getType()) && !columnIds.contains(source.getId())) {
941                                                        continue;
942                                                }
943                                                if (tableIdMap.containsKey(source.getParent_id())) {
944                                                        source.setParent_id(tableIdMap.get(source.getParent_id()));
945                                                }
946                                                if (tableIdMap.containsKey(source.getSource_id())) {
947                                                        source.setSource_id(tableIdMap.get(source.getSource_id()));
948                                                }
949                                                if (columnIdMap.containsKey(source.getId())) {
950                                                        source.setId(columnIdMap.get(source.getId()));
951                                                        source.setCoordinate(columnMergeIdMap.get(source.getId()).getCoordinate());
952                                                }
953                                        }
954
955                                        sourceSet.addAll(sources);
956                                        if ("call".equals(relation.getType())) {
957                                                relation.setCallees(new ArrayList<sourceColumn>(sourceSet));
958                                        } else {
959                                                relation.setSources(new ArrayList<sourceColumn>(sourceSet));
960                                        }
961                                }
962
963                                String jsonString = JSON.toJSONString(relation, true);
964                                String key = SHA256.getMd5(jsonString);
965                                if (!mergeRelations.containsKey(key)) {
966                                        mergeRelations.put(key, relation);
967                                }
968                        }
969
970                        dataflow.setRelationships(new ArrayList<relationship>(mergeRelations.values()));
971                }
972
973                tableMap.clear();
974                tableTypeMap.clear();
975                tableIdMap.clear();
976                columnMap.clear();
977                tableColumnMap.clear();
978                columnIdMap.clear();
979                columnMergeIdMap.clear();
980                tables.clear();
981                return dataflow;
982        }
983
984        public synchronized dataflow getDataFlow() {
985                if (dataflow != null) {
986                        return dataflow;
987                } else if (dataflowString != null) {
988                        return XML2Model.loadXML(dataflow.class, dataflowString);
989                }
990                return null;
991        }
992
993        List<ErrorInfo> metadataErrors = new ArrayList<>();
994        
995        private synchronized dataflow analyzeSqlScript() {
996                init();
997
998                try {
999                        dataflow dataflow = new dataflow();
1000                        
1001                        if (sqlInfos != null) {
1002                                if (option.getHandleListener() != null) {
1003                                        if (sqlInfos.length == 1) {
1004                                                option.getHandleListener().startAnalyze(null, sqlInfos[0].getSql().length(), false);
1005                                        } else {
1006                                                option.getHandleListener().startAnalyze(null, sqlInfos.length, true);
1007                                        }
1008                                }
1009
1010                                if (sqlenv == null) {
1011                                        if (option.getHandleListener() != null) {
1012                                                option.getHandleListener().startParseSQLEnv();
1013                                        }
1014                                        TSQLEnv[] sqlenvs = new SQLEnvParser(option.getDefaultServer(), option.getDefaultDatabase(),
1015                                                        option.getDefaultSchema()).parseSQLEnv(option.getVendor(), sqlInfos);
1016                                        if (sqlenvs != null && sqlenvs.length > 0) {
1017                                                sqlenv = sqlenvs[0];
1018                                        }
1019                                        if (option.getHandleListener() != null) {
1020                                                option.getHandleListener().endParseSQLEnv();
1021                                        }
1022                                }
1023                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
1024                                Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap = new LinkedHashMap<String, Pair3<StringBuilder, AtomicInteger, String>>();
1025                                for (int i = 0; i < sqlInfos.length; i++) {
1026                                        SqlInfo sqlInfo = sqlInfos[i];
1027                                        if (sqlInfo == null) {
1028                                                sqlInfoMap.put(String.valueOf(i), new ArrayList<SqlInfo>());
1029                                                continue;
1030                                        }
1031                                        String sql = sqlInfo.getSql();
1032                                        if (SQLUtil.isEmpty(sql) && sqlInfo.getFileName() != null
1033                                                        && new File(sqlInfo.getFileName()).exists()) {
1034                                                sql = SQLUtil.getFileContent(sqlInfo.getFileName());
1035                                        }
1036                                        if (SQLUtil.isEmpty(sql) && sqlInfo.getFilePath() != null
1037                                                        && new File(sqlInfo.getFilePath()).exists()) {
1038                                                sql = SQLUtil.getFileContent(sqlInfo.getFilePath());
1039                                        }
1040                                        String sqlTrim = null;
1041                                        if (sql != null) {
1042                                                sqlTrim = sql.substring(0, Math.min(sql.length(), 512)).trim();
1043                                        }
1044                                        if(sql!=null && sqlTrim.startsWith("<") && sqlTrim.indexOf("<dlineage")!=-1){
1045                                                dataflow temp = XML2Model.loadXML(dataflow.class, sql);
1046                                                if(sqlInfos.length == 1){
1047                                                        dataflow = temp;
1048                                                }
1049                                                else {
1050                                                        if (temp.getTables() != null) {
1051                                                                dataflow.getTables().addAll(temp.getTables());
1052                                                        }
1053                                                        if (temp.getViews() != null) {
1054                                                                dataflow.getViews().addAll(temp.getViews());
1055                                                        }
1056                                                        if (temp.getResultsets() != null) {
1057                                                                dataflow.getResultsets().addAll(temp.getResultsets());
1058                                                        }
1059                                                        if (temp.getRelationships() != null) {
1060                                                                dataflow.getRelationships().addAll(temp.getRelationships());
1061                                                        }
1062                                                        if (temp.getErrors() != null) {
1063                                                                dataflow.getErrors().addAll(temp.getErrors());
1064                                                        }
1065                                                }
1066                                        }
1067                                        else if (sql != null && sqlTrim.startsWith("{")) {
1068                                                EDbVendor vendor = SQLUtil.isEmpty(sqlInfo.getDbVendor()) ? option.getVendor()
1069                                                                : EDbVendor.valueOf(sqlInfo.getDbVendor());
1070                                                TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(),
1071                                                                option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql);
1072                                                if (sqlenvs != null && sqlenvs.length > 0) {
1073                                                        if (sqlenv == null) {
1074                                                                sqlenv = sqlenvs[0];
1075                                                        } else {
1076                                                                sqlenv = SQLEnvParser.mergeSQLEnv(Arrays.asList(sqlenv, sqlenvs[0]));
1077                                                        }
1078                                                }
1079                                                if (sqlenv != null) {
1080                                                        if (MetadataReader.isGrabit(sql) || MetadataReader.isSqlflow(sql)) {
1081                                                                String hash = SHA256.getMd5(sql);
1082                                                                String fileHash = SHA256.getMd5(hash);
1083                                                                if (!sqlInfoMap.containsKey(fileHash)) {
1084                                                                        sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1085                                                                        sqlInfoMap.get(fileHash).add(sqlInfo);
1086                                                                }
1087                                                                ModelBindingManager.setGlobalHash(fileHash);
1088                                                                dataflow temp = null;
1089
1090                                                                if (MetadataReader.isGrabit(sql)) {
1091                                                                        temp = new GrabitMetadataAnalyzer().analyzeMetadata(option.getVendor(), sql);
1092                                                                } else {
1093                                                                        temp = new SqlflowMetadataAnalyzer(sqlenv).analyzeMetadata(option.getVendor(), sql);
1094                                                                }
1095//                                                              if (temp.getPackages() != null) {
1096//                                                                      dataflow.getPackages().addAll(temp.getPackages());
1097//                                                              }
1098//                                                              if (temp.getProcedures() != null) {
1099//                                                                      dataflow.getProcedures().addAll(temp.getProcedures());
1100//                                                              }
1101                                                                if (temp.getTables() != null) {
1102                                                                        dataflow.getTables().addAll(temp.getTables());
1103                                                                }
1104                                                                if (temp.getViews() != null) {
1105                                                                        dataflow.getViews().addAll(temp.getViews());
1106                                                                }
1107                                                                if (temp.getResultsets() != null) {
1108                                                                        dataflow.getResultsets().addAll(temp.getResultsets());
1109                                                                }
1110                                                                if (temp.getRelationships() != null) {
1111                                                                        dataflow.getRelationships().addAll(temp.getRelationships());
1112                                                                }
1113                                                                if (temp.getErrors() != null) {
1114                                                                        dataflow.getErrors().addAll(temp.getErrors());
1115                                                                }
1116                                                                if (sql.indexOf("createdBy") != -1) {
1117                                                                        if (sql.toLowerCase().indexOf("sqldep") != -1
1118                                                                                        || sql.toLowerCase().indexOf("grabit") != -1) {
1119                                                                                Map jsonObject = (Map) JSON.parseObject(sql);
1120                                                                                List<Map> queries = (List<Map>) jsonObject.get("queries");
1121                                                                                if (queries != null) {
1122                                                                                        for (int j = 0; j < queries.size(); j++) {
1123                                                                                                Map queryObject = queries.get(j);
1124                                                                                                appendSqlInfo(databaseMap, j, sqlInfo, queryObject);
1125                                                                                        }
1126                                                                                }
1127                                                                        } else if (sql.toLowerCase().indexOf("sqlflow") != -1) {
1128                                                                                Map sqlflow = (Map) JSON.parseObject(sql);
1129                                                                                List<Map> servers = (List<Map>) sqlflow.get("servers");
1130                                                                                if (servers != null) {
1131                                                                                        for (Map serverObject : servers) {
1132                                                                                                List<Map> queries = (List<Map>) serverObject.get("queries");
1133                                                                                                if (queries != null) {
1134                                                                                                        for (int j = 0; j < queries.size(); j++) {
1135                                                                                                                Map queryObject = queries.get(j);
1136                                                                                                                appendSqlInfo(databaseMap, j, sqlInfo, queryObject);
1137                                                                                                        }
1138                                                                                                }
1139                                                                                        }
1140                                                                                }
1141                                                                                List<Map> errorMessages =  (List<Map>) sqlflow.get("errorMessages");
1142                                                                                if(errorMessages!=null && !errorMessages.isEmpty()) {
1143                                                                                        for(Map error: errorMessages){
1144                                                                                                ErrorInfo errorInfo = new ErrorInfo();
1145                                                                                                errorInfo.setErrorType(ErrorInfo.METADATA_ERROR);
1146                                                                                                errorInfo.setErrorMessage((String)error.get("errorMessage"));
1147                                                                                                errorInfo.setFileName(sqlInfo.getFileName());
1148                                                                                                errorInfo.setFilePath(sqlInfo.getFilePath());
1149                                                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L,
1150                                                                                                                ModelBindingManager.getGlobalHash()));
1151                                                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L,
1152                                                                                                                ModelBindingManager.getGlobalHash()));
1153                                                                                                errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L));
1154                                                                                                errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L));
1155                                                                                                metadataErrors.add(errorInfo);
1156                                                                                        }
1157                                                                                }
1158                                                                        }
1159                                                                }
1160                                                        } else {
1161                                                                Map queryObject = (Map) JSON.parseObject(sql);
1162                                                                appendSqlInfo(databaseMap, i, sqlInfo, queryObject);
1163                                                        }
1164                                                } else {
1165                                                        Map queryObject = (Map) JSON.parseObject(sql);
1166                                                        appendSqlInfo(databaseMap, i, sqlInfo, queryObject);
1167                                                }
1168                                        } else {
1169                                                ModelBindingManager.removeGlobalDatabase();
1170                                                ModelBindingManager.removeGlobalSchema();
1171                                                ModelBindingManager.removeGlobalHash();
1172
1173                                                String content = sql;
1174
1175                                                if (content == null) {
1176                                                        continue;
1177                                                }
1178
1179                                                String delimiterChar = String.valueOf(sqlparser.getDelimiterChar());
1180
1181                                                if (sqlInfos.length > 1) {
1182                                                        String endTrim = SQLUtil.endTrim(content);
1183                                                        if (endTrim.endsWith(delimiterChar) || endTrim.endsWith(";")) {
1184                                                                content += "\n";
1185                                                        } else if (option.getVendor() == EDbVendor.dbvredshift
1186                                                                        || option.getVendor() == EDbVendor.dbvgaussdb
1187                                                                        || option.getVendor() == EDbVendor.dbvpostgresql
1188                                                                        || option.getVendor() == EDbVendor.dbvmysql
1189                                                                        || option.getVendor() == EDbVendor.dbvteradata) {
1190                                                                content += ("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n");
1191                                                        } else {
1192                                                                content = endTrim + ";" + "\n";
1193                                                        }
1194                                                }
1195
1196                                                sqlInfo.setSql(content);
1197
1198                                                if (MetadataReader.isMetadata(content)) {
1199                                                        String hash = SHA256.getMd5(content);
1200                                                        ModelBindingManager.setGlobalHash(hash);
1201                                                        dataflow temp = new SQLDepMetadataAnalyzer().analyzeMetadata(option.getVendor(), content);
1202                                                        if (temp.getProcedures() != null) {
1203                                                                dataflow.getProcedures().addAll(temp.getProcedures());
1204                                                        }
1205                                                        if (temp.getTables() != null) {
1206                                                                dataflow.getTables().addAll(temp.getTables());
1207                                                        }
1208                                                        if (temp.getViews() != null) {
1209                                                                dataflow.getViews().addAll(temp.getViews());
1210                                                        }
1211                                                        if (temp.getResultsets() != null) {
1212                                                                dataflow.getResultsets().addAll(temp.getResultsets());
1213                                                        }
1214                                                        if (temp.getRelationships() != null) {
1215                                                                dataflow.getRelationships().addAll(temp.getRelationships());
1216                                                        }
1217                                                        if (temp.getErrors() != null) {
1218                                                                dataflow.getErrors().addAll(temp.getErrors());
1219                                                        }
1220                                                        String fileHash = SHA256.getMd5(hash);
1221                                                        if (!sqlInfoMap.containsKey(fileHash)) {
1222                                                                sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1223                                                                sqlInfoMap.get(fileHash).add(sqlInfo);
1224                                                        }
1225                                                } else {
1226                                                        String sqlHash = SHA256.getMd5(content);
1227                                                        String fileHash = SHA256.getMd5(sqlHash);
1228                                                        if (!sqlInfoMap.containsKey(fileHash)) {
1229                                                                sqlInfoMap.put(fileHash, new ArrayList<SqlInfo>());
1230                                                        }
1231
1232                                                        String database = TSQLEnv.DEFAULT_DB_NAME;
1233                                                        String schema = TSQLEnv.DEFAULT_SCHEMA_NAME;
1234                                                        if (sqlenv != null) {
1235                                                                database = sqlenv.getDefaultCatalogName();
1236                                                                if (database == null) {
1237                                                                        database = TSQLEnv.DEFAULT_DB_NAME;
1238                                                                }
1239                                                                schema = sqlenv.getDefaultSchemaName();
1240                                                                if (schema == null) {
1241                                                                        schema = TSQLEnv.DEFAULT_SCHEMA_NAME;
1242                                                                }
1243                                                        }
1244
1245                                                        boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor());
1246                                                        boolean supportSchema = TSQLEnv.supportSchema(option.getVendor());
1247                                                        StringBuilder builder = new StringBuilder();
1248                                                        if (supportCatalog) {
1249                                                                builder.append(database);
1250                                                        }
1251                                                        if (supportSchema) {
1252                                                                if (builder.length() > 0) {
1253                                                                        builder.append(".");
1254                                                                }
1255                                                                builder.append(schema);
1256                                                        }
1257                                                        String group = builder.toString();
1258                                                        SqlInfo sqlInfoItem = new SqlInfo();
1259                                                        sqlInfoItem.setFileName(sqlInfo.getFileName());
1260                                                        sqlInfoItem.setFilePath(sqlInfo.getFilePath());
1261                                                        sqlInfoItem.setSql(sqlInfo.getSql());
1262                                                        sqlInfoItem.setOriginIndex(0);
1263                                                        sqlInfoItem.setOriginLineStart(0);
1264                                                        int lineEnd = sqlInfo.getSql().split("\n").length - 1;
1265                                                        sqlInfoItem.setOriginLineEnd(lineEnd);
1266                                                        sqlInfoItem.setIndex(0);
1267                                                        sqlInfoItem.setLineStart(0);
1268                                                        sqlInfoItem.setLineEnd(lineEnd);
1269                                                        sqlInfoItem.setHash(SHA256.getMd5(sqlHash));
1270                                                        sqlInfoItem.setGroup(group);
1271                                                        sqlInfoMap.get(fileHash).add(sqlInfoItem);
1272                                                        if (!databaseMap.containsKey(sqlHash)) {
1273                                                                databaseMap.put(sqlHash, new Pair3<StringBuilder, AtomicInteger, String>(
1274                                                                                new StringBuilder(), new AtomicInteger(), group));
1275                                                        }
1276                                                        databaseMap.get(sqlHash).first.append(sqlInfoItem.getSql());
1277                                                        databaseMap.get(sqlHash).second.incrementAndGet();
1278                                                }
1279                                        }
1280                                }
1281
1282                                boolean supportCatalog = TSQLEnv.supportCatalog(option.getVendor());
1283                                boolean supportSchema = TSQLEnv.supportSchema(option.getVendor());
1284
1285                                Iterator<String> schemaIter = databaseMap.keySet().iterator();
1286                                while (schemaIter.hasNext()) {
1287                                        if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
1288                                                break;
1289                                        }
1290                                        String key = schemaIter.next();
1291                                        String group = databaseMap.get(key).third;
1292                                        String[] split = SQLUtil.parseNames(group).toArray(new String[0]);
1293
1294                                        ModelBindingManager.removeGlobalDatabase();
1295                                        ModelBindingManager.removeGlobalSchema();
1296                                        ModelBindingManager.removeGlobalSQLEnv();
1297                                        ModelBindingManager.removeGlobalHash();
1298
1299                                        String defaultDatabase = null;
1300                                        String defaultSchema = null;
1301                                        if(sqlenv!=null){
1302                                                defaultDatabase = sqlenv.getDefaultCatalogName();
1303                                                defaultSchema = sqlenv.getDefaultSchemaName();
1304                                        }
1305                                        if (supportCatalog && supportSchema) {
1306                                                if (split.length >= 2) {
1307                                                        if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 2])) {
1308                                                                ModelBindingManager.setGlobalDatabase(split[split.length - 2]);
1309                                                                sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase());
1310                                                        }
1311                                                }
1312                                                if (split.length >= 1) {
1313                                                        if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) {
1314                                                                ModelBindingManager.setGlobalSchema(split[split.length - 1]);
1315                                                                sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema());
1316                                                        }
1317                                                }
1318                                        } else if (supportCatalog) {
1319                                                if (!TSQLEnv.DEFAULT_DB_NAME.equals(split[split.length - 1])) {
1320                                                        ModelBindingManager.setGlobalDatabase(split[split.length - 1]);
1321                                                        sqlenv.setDefaultCatalogName(ModelBindingManager.getGlobalDatabase());
1322                                                }
1323                                        } else if (supportSchema) {
1324                                                if (!TSQLEnv.DEFAULT_SCHEMA_NAME.equals(split[split.length - 1])) {
1325                                                        ModelBindingManager.setGlobalSchema(split[split.length - 1]);
1326                                                        sqlenv.setDefaultSchemaName(ModelBindingManager.getGlobalSchema());
1327                                                }
1328                                        }
1329                                        if (option.getHandleListener() != null) {
1330                                                option.getHandleListener().startParse(null, databaseMap.get(key).first.toString());
1331                                        }
1332
1333                                        if (sqlenv == null) {
1334                                                sqlenv = new TSQLEnv(option.getVendor()) {
1335
1336                                                        @Override
1337                                                        public void initSQLEnv() {
1338                                                                // TODO Auto-generated method stub
1339
1340                                                        }
1341                                                };
1342                                        }
1343                                        ModelBindingManager.setGlobalSQLEnv(sqlenv);
1344                                        sqlparser.sqltext = databaseMap.get(key).first.toString();
1345                                        ModelBindingManager.setGlobalHash(SHA256.getMd5(key));
1346                                        analyzeAndOutputResult(sqlparser);
1347                                        if(sqlenv!=null){
1348                                                sqlenv.setDefaultCatalogName(defaultDatabase);
1349                                                sqlenv.setDefaultSchemaName(defaultSchema);
1350                                        }
1351                                }
1352
1353                                appendProcesses(dataflow);
1354                                appendOraclePackages(dataflow);
1355                                appendProcedures(dataflow);
1356                                appendTables(dataflow);
1357                                appendViews(dataflow);
1358                                appendResultSets(dataflow);
1359                                appendRelations(dataflow);
1360                                appendErrors(dataflow);
1361                        }
1362
1363                        dataflow = handleDataflowExecProcedure(dataflow);
1364
1365                        if (dataflow != null && option.getAnalyzeMode() != AnalyzeMode.crud) {
1366                                if (!isShowJoin()) {
1367                                        dataflow = mergeTables(dataflow, modelManager.TABLE_COLUMN_ID, option);
1368                                } else {
1369                                        dataflow = removeDuplicateColumns(dataflow);
1370                                }
1371                        }
1372
1373                        if (dataflow != null && option.isNormalizeOutput()) {
1374                                dataflow = getNormalizeDataflow(dataflow);
1375                        }
1376
1377                        if (dataflow != null && option.isIgnoreCoordinate()) {
1378                                dataflow = filterDataflowCoordinate(dataflow);
1379                        }
1380                        
1381                        if (option.isSimpleOutput() || option.isIgnoreRecordSet()) {
1382                                List<String> showTypes = new ArrayList<>();
1383                                if(option.getSimpleShowRelationTypes()!=null) {
1384                                        showTypes.addAll(option.getSimpleShowRelationTypes());
1385                                }
1386                                if(showTypes.isEmpty()) {
1387                                        showTypes.add("fdd");
1388                                }
1389                                if(option.isShowCallRelation()) {
1390                                        showTypes.add("call");
1391                                }
1392                                if(option.isShowERDiagram()) {
1393                                        showTypes.add("er");
1394                                }
1395                                dataflow simpleDataflow = getSimpleDataflow(dataflow, option.isSimpleOutput(), showTypes);
1396                                if (simpleDataflow.getResultsets() != null) {
1397                                        for (table t : simpleDataflow.getResultsets()) {
1398                                                t.setIsTarget(null);
1399                                        }
1400                                }
1401                                return simpleDataflow;
1402                        } else {
1403                                return dataflow;
1404                        }
1405                        
1406                } catch (Exception e) {
1407                        logger.error("analyze sql failed.", e);
1408                        ErrorInfo errorInfo = new ErrorInfo();
1409                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
1410                        if (e.getMessage() == null) {
1411                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
1412                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
1413                                } else {
1414                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
1415                                }
1416                        } else {
1417                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
1418                        }
1419                        errorInfo.fillInfo(this);
1420                        errorInfos.add(errorInfo);
1421                }
1422
1423                modelManager.reset();
1424                return null;
1425        }
1426
1427        private dataflow handleDataflowExecProcedure(dataflow dataflow) {
1428                Set<String> procedures = new HashSet<String>();
1429                for (procedure procedure : dataflow.getProcedures()) {
1430                        procedures.add(DlineageUtil.getIdentifierNormalTableName(procedure.getName()));
1431                }
1432                List<table> removeResultSets = new ArrayList<table>();
1433                
1434                Map<String, table> allMap = new HashMap<String, table>();
1435                
1436                if (dataflow.getResultsets() != null) {
1437                        for (table t : dataflow.getResultsets()) {
1438                                allMap.put(t.getId().toLowerCase(), t);
1439                        }
1440                }
1441
1442                if (dataflow.getTables() != null) {
1443                        for (table t : dataflow.getTables()) {
1444                                allMap.put(t.getId().toLowerCase(), t);
1445                        }
1446                }
1447
1448                if (dataflow.getViews() != null) {
1449                        for (table t : dataflow.getViews()) {
1450                                allMap.put(t.getId().toLowerCase(), t);
1451                        }
1452                }
1453
1454                if (dataflow.getVariables() != null) {
1455                        for (table t : dataflow.getVariables()) {
1456                                allMap.put(t.getId().toLowerCase(), t);
1457                        }
1458                }
1459
1460                
1461                for (table resultSet : dataflow.getResultsets()) {
1462                        String resultSetName = DlineageUtil.getIdentifierNormalTableName(resultSet.getName());
1463                        if (!(ResultSetType.function.name().equals(resultSet.getType())
1464                                        && modelManager.getFunctionTable(resultSetName) != null && procedures.contains(resultSetName))) {
1465                                continue;
1466                        }
1467
1468                        Set<Object> functionTables = modelManager
1469                                        .getFunctionTable(DlineageUtil.getIdentifierNormalTableName(resultSet.getName()));
1470                        List<ResultSet> functionResults = functionTables.stream().filter(t -> t instanceof ResultSet)
1471                                        .map(t -> (ResultSet) t).collect(Collectors.toList());
1472                        if (!(resultSet.getColumns().size() == 1
1473                                        && DlineageUtil.getIdentifierNormalTableName(resultSet.getColumns().get(0).getName()).equals(resultSetName))
1474                                        || functionResults.isEmpty()) {
1475                                continue;
1476                        }
1477
1478                        column column = resultSet.getColumns().get(0);
1479                        String sourceColumnId = column.getId();
1480                        boolean reserveResultSet = false;
1481                        List<relationship> appendRelations = new ArrayList<relationship>();
1482                        Set<relationship> removeRelations = new HashSet<relationship>();
1483                        
1484                        for (relationship relationship : dataflow.getRelationships()) {
1485                                targetColumn targetColumn = relationship.getTarget();
1486                                List<sourceColumn> sourceColumns = relationship.getSources();
1487                                List<sourceColumn> newSourceColumns = new ArrayList<sourceColumn>();
1488                                for (sourceColumn sourceColumn : sourceColumns) {
1489                                        if (!sourceColumn.getId().equals(sourceColumnId)) {
1490                                                continue;
1491                                        }
1492                                        for (ResultSet sourceResultSet : functionResults) {
1493                                                for (ResultColumn resultColumn : sourceResultSet.getColumns()) {
1494                                                        if (!DlineageUtil.compareColumnIdentifier(resultColumn.getName(),
1495                                                                        targetColumn.getColumn())) {
1496                                                                if (targetColumn.getColumn().endsWith("*")) {
1497                                                                        table parent = allMap.get(targetColumn.getParent_id());
1498                                                                        if (parent != null && parent.getColumns().size() > 1) {
1499                                                                                for (column item : parent.getColumns()) {
1500                                                                                        if (DlineageUtil.compareColumnIdentifier(resultColumn.getName(),
1501                                                                                                        item.getName())) {
1502                                                                                                relationship newRelation = appendStarRelation(dataflow, relationship, item, resultColumn);
1503                                                                                                appendRelations.add(newRelation);
1504                                                                                                removeRelations.add(relationship);
1505                                                                                                newSourceColumns.add(newRelation.getSources().get(0));
1506                                                                                                if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) {
1507                                                                                                        dataflow.getResultsets().stream().filter(
1508                                                                                                                        t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId())))
1509                                                                                                                        .forEach(t -> t.setIsTarget(Boolean.FALSE.toString()));
1510                                                                                                }
1511                                                                                        }
1512                                                                                }
1513                                                                        }
1514                                                                }
1515                                                                continue;
1516                                                        }
1517                                                        
1518                                                        sourceColumn sourceColumn1 = new sourceColumn();
1519                                                        sourceColumn1.setId(String.valueOf(resultColumn.getId()));
1520                                                        sourceColumn1.setColumn(resultColumn.getName());
1521                                                        sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId()));
1522                                                        sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet()));
1523                                                        if (resultColumn.getStartPosition() != null
1524                                                                        && resultColumn.getEndPosition() != null) {
1525                                                                sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition())
1526                                                                                + "," + convertCoordinate(resultColumn.getEndPosition()));
1527                                                        }
1528                                                        newSourceColumns.add(sourceColumn1);
1529                                                        
1530                                                        if (resultColumn.getResultSet() != null && resultColumn.getResultSet().isTarget()) {
1531                                                                dataflow.getResultsets().stream().filter(
1532                                                                                t -> t.getId().equals(String.valueOf(resultColumn.getResultSet().getId())))
1533                                                                                .forEach(t -> t.setIsTarget(Boolean.FALSE.toString()));
1534                                                        }
1535                                                }
1536                                        }
1537
1538                                        if (!newSourceColumns.isEmpty()) {
1539                                                if (removeRelations.isEmpty()) {
1540                                                        relationship.setSources(newSourceColumns);
1541                                                }
1542                                        }
1543                                        else {
1544                                                reserveResultSet = true;
1545                                        }
1546                                }
1547                        }
1548                        
1549                        dataflow.getRelationships().addAll(appendRelations);
1550                        dataflow.getRelationships().removeAll(removeRelations);
1551                        
1552                        if(!reserveResultSet) {
1553                                removeResultSets.add(resultSet);
1554                        }
1555                }
1556                dataflow.getResultsets().removeAll(removeResultSets);
1557                return dataflow;
1558        }
1559
1560        private relationship appendStarRelation(dataflow dataflow,
1561                        relationship relationship, column item, ResultColumn resultColumn) {
1562                relationship relationElement = new relationship();
1563                relationElement.setType(relationship.getType());
1564                relationElement.setEffectType(relationship.getEffectType());
1565                relationElement.setSqlHash(relationship.getSqlHash());
1566                relationElement.setSqlComment(relationship.getSqlComment());
1567                relationElement.setProcedureId(relationship.getProcedureId());
1568                relationElement.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID));
1569                relationElement.setProcessId(relationship.getProcessId());
1570                relationElement.setProcessType(relationship.getProcessType());
1571                
1572                targetColumn targetColumn1 = new targetColumn();
1573                targetColumn1.setId(String.valueOf(item.getId()));
1574                targetColumn1.setColumn(item.getName());
1575                targetColumn1.setParent_id(relationship.getTarget().getParent_id());
1576                targetColumn1.setParent_name(relationship.getTarget().getParent_name());
1577                targetColumn1.setParent_alias(relationship.getTarget().getParent_alias());
1578                if (relationship.getTarget().getCoordinate() != null) {
1579                        targetColumn1.setCoordinate(item.getCoordinate());
1580                }
1581                relationElement.setTarget(targetColumn1);       
1582                
1583                sourceColumn sourceColumn1 = new sourceColumn();
1584                sourceColumn1.setId(String.valueOf(resultColumn.getId()));
1585                sourceColumn1.setColumn(resultColumn.getName());
1586                sourceColumn1.setParent_id(String.valueOf(resultColumn.getResultSet().getId()));
1587                sourceColumn1.setParent_name(getResultSetName(resultColumn.getResultSet()));
1588                if (resultColumn.getStartPosition() != null
1589                                && resultColumn.getEndPosition() != null) {
1590                        sourceColumn1.setCoordinate(convertCoordinate(resultColumn.getStartPosition())
1591                                        + "," + convertCoordinate(resultColumn.getEndPosition()));
1592                }
1593                relationElement.addSource(sourceColumn1);
1594                return relationElement;
1595        }
1596
1597        private dataflow getNormalizeDataflow(dataflow instance) {
1598                List<table> tables = new ArrayList<>();
1599                if (instance.getResultsets() != null) {
1600                        for (table t : instance.getResultsets()) {
1601                                tables.add(t);
1602                        }
1603                }
1604
1605                if (instance.getTables() != null) {
1606                        for (table t : instance.getTables()) {
1607                                tables.add(t);
1608                        }
1609                }
1610
1611                if (instance.getViews() != null) {
1612                        for (table t : instance.getViews()) {
1613                                tables.add(t);
1614                        }
1615                }
1616
1617                if (instance.getPaths() != null) {
1618                        for (table t : instance.getPaths()) {
1619                                tables.add(t);
1620                        }
1621                }
1622
1623                if (instance.getStages() != null) {
1624                        for (table t : instance.getStages()) {
1625                                tables.add(t);
1626                        }
1627                }
1628
1629                if (instance.getSequences() != null) {
1630                        for (table t : instance.getSequences()) {
1631                                tables.add(t);
1632                        }
1633                }
1634
1635                if (instance.getDatasources() != null) {
1636                        for (table t : instance.getDatasources()) {
1637                                tables.add(t);
1638                        }
1639                }
1640
1641                if (instance.getDatabases() != null) {
1642                        for (table t : instance.getDatabases()) {
1643                                tables.add(t);
1644                        }
1645                }
1646
1647                if (instance.getSchemas() != null) {
1648                        for (table t : instance.getSchemas()) {
1649                                tables.add(t);
1650                        }
1651                }
1652
1653                if (instance.getStreams() != null) {
1654                        for (table t : instance.getStreams()) {
1655                                tables.add(t);
1656                        }
1657                }
1658
1659                if (instance.getVariables() != null) {
1660                        for (table t : instance.getVariables()) {
1661                                tables.add(t);
1662                        }
1663                }
1664
1665                Map<String, String> idNameMap = new HashMap();
1666
1667                for(table table: tables){
1668                        if(table.getDatabase()!=null) {
1669                                table.setDatabase(DlineageUtil.getIdentifierNormalName(table.getDatabase(), ESQLDataObjectType.dotCatalog));
1670                        }
1671                        if(table.getSchema()!=null) {
1672                                table.setSchema(DlineageUtil.getIdentifierNormalName(table.getSchema(), ESQLDataObjectType.dotSchema));
1673                        }
1674                        if(table.getName()!=null) {
1675                                table.setName(DlineageUtil.getIdentifierNormalName(table.getName(), ESQLDataObjectType.dotTable));
1676                                idNameMap.put(table.getId(), table.getName());
1677                        }
1678                        if(table.getColumns()!=null){
1679                                for(column column: table.getColumns()){
1680                                        column.setName(DlineageUtil.getIdentifierNormalName(column.getName(), ESQLDataObjectType.dotColumn));
1681                                        idNameMap.put(column.getId(), column.getName());
1682                                }
1683                        }
1684                }
1685                if(instance.getPackages()!=null){
1686                        for(oraclePackage oraclePackage: instance.getPackages()){
1687                                if(oraclePackage.getDatabase()!=null) {
1688                                        oraclePackage.setDatabase(DlineageUtil.getIdentifierNormalName(oraclePackage.getDatabase(), ESQLDataObjectType.dotCatalog));
1689                                }
1690                                if(oraclePackage.getSchema()!=null) {
1691                                        oraclePackage.setSchema(DlineageUtil.getIdentifierNormalName(oraclePackage.getSchema(), ESQLDataObjectType.dotSchema));
1692                                }
1693                                if(oraclePackage.getName()!=null) {
1694                                        oraclePackage.setName(DlineageUtil.getIdentifierNormalName(oraclePackage.getName(), ESQLDataObjectType.dotTable));
1695                                        idNameMap.put(oraclePackage.getId(), oraclePackage.getName());
1696                                }
1697                                if(oraclePackage.getArguments()!=null){
1698                                        for(argument argument: oraclePackage.getArguments()){
1699                                                argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn));
1700                                                idNameMap.put(argument.getId(), argument.getName());
1701                                        }
1702                                }
1703                                if(oraclePackage.getProcedures()!=null){
1704                                        for(procedure procedure: oraclePackage.getProcedures()){
1705                                                if(procedure.getDatabase()!=null) {
1706                                                        procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog));
1707                                                }
1708                                                if(procedure.getSchema()!=null) {
1709                                                        procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema));
1710                                                }
1711                                                if(procedure.getName()!=null) {
1712                                                        procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable));
1713                                                        idNameMap.put(procedure.getId(), procedure.getName());
1714                                                }
1715                                                for(argument argument: procedure.getArguments()){
1716                                                        argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn));
1717                                                        idNameMap.put(argument.getId(), argument.getName());
1718                                                }
1719                                        }
1720                                }
1721                        }
1722                }
1723                if(instance.getProcedures()!=null){
1724                        for(procedure procedure: instance.getProcedures()){
1725                                if(procedure.getDatabase()!=null) {
1726                                        procedure.setDatabase(DlineageUtil.getIdentifierNormalName(procedure.getDatabase(), ESQLDataObjectType.dotCatalog));
1727                                }
1728                                if(procedure.getSchema()!=null) {
1729                                        procedure.setSchema(DlineageUtil.getIdentifierNormalName(procedure.getSchema(), ESQLDataObjectType.dotSchema));
1730                                }
1731                                if(procedure.getName()!=null) {
1732                                        procedure.setName(DlineageUtil.getIdentifierNormalName(procedure.getName(), ESQLDataObjectType.dotTable));
1733                                        idNameMap.put(procedure.getId(), procedure.getName());
1734                                }
1735                                for(argument argument: procedure.getArguments()){
1736                                        argument.setName(DlineageUtil.getIdentifierNormalName(argument.getName(), ESQLDataObjectType.dotColumn));
1737                                        idNameMap.put(argument.getId(), argument.getName());
1738                                }
1739                        }
1740                }
1741                if (instance.getProcesses() != null) {
1742                        for (process process : instance.getProcesses()) {
1743                                if(process.getDatabase()!=null) {
1744                                        process.setDatabase(DlineageUtil.getIdentifierNormalName(process.getDatabase(), ESQLDataObjectType.dotCatalog));
1745                                }
1746                                if(process.getSchema()!=null) {
1747                                        process.setSchema(DlineageUtil.getIdentifierNormalName(process.getSchema(), ESQLDataObjectType.dotSchema));
1748                                }
1749                                if (process.getProcedureId() != null) {
1750                                        process.setProcedureName(DlineageUtil.getIdentifierNormalName(process.getProcedureName(), ESQLDataObjectType.dotTable));
1751                                        idNameMap.put(process.getId(), process.getName());
1752                                }
1753                        }
1754                }
1755
1756                if(instance.getRelationships()!=null){
1757                        for(relationship relation: instance.getRelationships()){
1758                                targetColumn targetColumn = relation.getTarget();
1759                                if(targetColumn != null) {
1760                                        targetColumn.setColumn(idNameMap.get(targetColumn.getId()));
1761                                        targetColumn.setTarget_name(idNameMap.get(targetColumn.getTarget_id()));
1762                                        targetColumn.setParent_name(idNameMap.get(targetColumn.getParent_id()));
1763                                }
1764                                List<sourceColumn> sourceColumns = relation.getSources();
1765                                if(sourceColumns!=null){
1766                                        for(sourceColumn sourceColumn: sourceColumns){
1767                                                sourceColumn.setColumn(idNameMap.get(sourceColumn.getId()));
1768                                                sourceColumn.setSource_name(idNameMap.get(sourceColumn.getSource_id()));
1769                                                sourceColumn.setParent_name(idNameMap.get(sourceColumn.getParent_id()));
1770                                        }
1771                                }
1772                                targetColumn = relation.getCaller();
1773                                if(targetColumn != null) {
1774                                        targetColumn.setName(idNameMap.get(targetColumn.getId()));
1775                                }
1776                                sourceColumns = relation.getCallees();
1777                                if(sourceColumns!=null){
1778                                        for(sourceColumn sourceColumn: sourceColumns){
1779                                                sourceColumn.setName(idNameMap.get(sourceColumn.getId()));
1780                                        }
1781                                }
1782                        }
1783                }
1784
1785
1786                return instance;
1787        }
1788
1789        private dataflow filterDataflowCoordinate(dataflow instance) {
1790                List<table> tables = new ArrayList<>();
1791                if (instance.getResultsets() != null) {
1792                        for (table t : instance.getResultsets()) {
1793                                tables.add(t);
1794                        }
1795                }
1796
1797                if (instance.getTables() != null) {
1798                        for (table t : instance.getTables()) {
1799                                tables.add(t);
1800                        }
1801                }
1802
1803                if (instance.getViews() != null) {
1804                        for (table t : instance.getViews()) {
1805                                tables.add(t);
1806                        }
1807                }
1808
1809                if (instance.getPaths() != null) {
1810                        for (table t : instance.getPaths()) {
1811                                tables.add(t);
1812                        }
1813                }
1814
1815                if (instance.getStages() != null) {
1816                        for (table t : instance.getStages()) {
1817                                tables.add(t);
1818                        }
1819                }
1820
1821                if (instance.getSequences() != null) {
1822                        for (table t : instance.getSequences()) {
1823                                tables.add(t);
1824                        }
1825                }
1826
1827                if (instance.getDatasources() != null) {
1828                        for (table t : instance.getDatasources()) {
1829                                tables.add(t);
1830                        }
1831                }
1832
1833                if (instance.getDatabases() != null) {
1834                        for (table t : instance.getDatabases()) {
1835                                tables.add(t);
1836                        }
1837                }
1838
1839                if (instance.getSchemas() != null) {
1840                        for (table t : instance.getSchemas()) {
1841                                tables.add(t);
1842                        }
1843                }
1844
1845                if (instance.getStreams() != null) {
1846                        for (table t : instance.getStreams()) {
1847                                tables.add(t);
1848                        }
1849                }
1850
1851                if (instance.getVariables() != null) {
1852                        for (table t : instance.getVariables()) {
1853                                tables.add(t);
1854                        }
1855                }
1856
1857                for(table table: tables){
1858                        table.setCoordinate(null);
1859                        if(table.getColumns()!=null){
1860                                for(column column: table.getColumns()){
1861                                        column.setCoordinate(null);
1862                                }
1863                        }
1864                }
1865                if(instance.getPackages()!=null){
1866                        for(oraclePackage oraclePackage: instance.getPackages()){
1867                                oraclePackage.setCoordinate(null);
1868                                if(oraclePackage.getProcedures()!=null){
1869                                        for(procedure procedure: oraclePackage.getProcedures()){
1870                                                procedure.setCoordinate(null);
1871                                                for(argument argument: procedure.getArguments()){
1872                                                        argument.setCoordinate(null);
1873                                                }
1874                                        }
1875                                }
1876                        }
1877                }
1878                if(instance.getProcedures()!=null){
1879                        for(procedure procedure: instance.getProcedures()){
1880                                procedure.setCoordinate(null);
1881                                for(argument argument: procedure.getArguments()){
1882                                        argument.setCoordinate(null);
1883                                }
1884                        }
1885                }
1886                if (instance.getProcesses() != null) {
1887                        for (process process : instance.getProcesses()) {
1888                                process.setCoordinate(null);
1889                        }
1890                }
1891
1892                if(instance.getRelationships()!=null){
1893                        for(relationship relation: instance.getRelationships()){
1894                                targetColumn targetColumn = relation.getTarget();
1895                                if(targetColumn != null) {
1896                                        targetColumn.setCoordinate(null);
1897                                }
1898                                List<sourceColumn> sourceColumns = relation.getSources();
1899                                if(sourceColumns!=null){
1900                                        for(sourceColumn sourceColumn: sourceColumns){
1901                                                sourceColumn.setCoordinate(null);
1902                                        }
1903                                }
1904                                targetColumn = relation.getCaller();
1905                                if(targetColumn != null) {
1906                                        targetColumn.setCoordinate(null);
1907                                }
1908                                sourceColumns = relation.getCallees();
1909                                if(sourceColumns!=null){
1910                                        for(sourceColumn sourceColumn: sourceColumns){
1911                                                sourceColumn.setCoordinate(null);
1912                                        }
1913                                }
1914                        }
1915                }
1916
1917                return instance;
1918        }
1919
1920        private void appendSqlInfo(Map<String, Pair3<StringBuilder, AtomicInteger, String>> databaseMap, int index,
1921                        SqlInfo sqlInfo, Map queryObject) {
1922                EDbVendor vendor = option.getVendor();
1923                if (!SQLUtil.isEmpty(sqlInfo.getDbVendor())) {
1924                        vendor = EDbVendor.valueOf(sqlInfo.getDbVendor());
1925                }
1926
1927                boolean supportCatalog = TSQLEnv.supportCatalog(vendor);
1928                boolean supportSchema = TSQLEnv.supportSchema(vendor);
1929
1930                String content = (String) queryObject.get("sourceCode");
1931                if (SQLUtil.isEmpty(content)) {
1932                        return;
1933                }
1934                StringBuilder builder = new StringBuilder();
1935                if (supportCatalog) {
1936                        String database = (String) queryObject.get("database");
1937                        if (database.indexOf(".") != -1) {
1938                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
1939                                database = delimitedChar + SQLUtil.trimColumnStringQuote(database) + delimitedChar;
1940                        }
1941                        builder.append(database);
1942                }
1943                if (supportSchema) {
1944                        String schema = (String) queryObject.get("schema");
1945                        if (schema.indexOf(".") != -1) {
1946                                String delimitedChar = TSQLEnv.delimitedChar(vendor);
1947                                schema = delimitedChar + SQLUtil.trimColumnStringQuote(schema) + delimitedChar;
1948                        }
1949                        if (builder.length() > 0) {
1950                                builder.append(".");
1951                        }
1952                        builder.append(schema);
1953                }
1954                String group = builder.toString();
1955                String sqlHash = SHA256.getMd5(content);
1956                String hash = SHA256.getMd5(sqlHash);
1957                if (!databaseMap.containsKey(sqlHash)) {
1958                        databaseMap.put(sqlHash,
1959                                        new Pair3<StringBuilder, AtomicInteger, String>(new StringBuilder(), new AtomicInteger(), group));
1960                }
1961                TGSqlParser parser = new TGSqlParser(option.getVendor());
1962                String delimiterChar = String.valueOf(parser.getDelimiterChar());
1963                StringBuilder buffer = new StringBuilder(content);
1964                if (content.trim().endsWith(delimiterChar) || content.trim().endsWith(";")) {
1965                        buffer.append("\n");
1966                } else if(vendor == EDbVendor.dbvredshift
1967                                || vendor == EDbVendor.dbvgaussdb
1968                                || vendor == EDbVendor.dbvpostgresql
1969                                || vendor == EDbVendor.dbvmysql
1970                                || vendor == EDbVendor.dbvteradata){
1971                        buffer.append("\n\n-- " + TBaseType.sqlflow_stmt_delimiter_str + "\n\n");
1972                } else{
1973                        SQLUtil.endTrim(buffer);
1974                        buffer.append(";").append("\n");
1975                }
1976
1977                int lineStart = databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1;
1978                if (databaseMap.get(sqlHash).first.toString().length() == 0) {
1979                        lineStart = 0;
1980                }
1981                databaseMap.get(sqlHash).first.append(buffer.toString());
1982                SqlInfo sqlInfoItem = new SqlInfo();
1983                sqlInfoItem.setServer(sqlInfo.getServer());
1984                sqlInfoItem.setDbVendor(sqlInfo.getDbVendor());
1985                sqlInfoItem.setFileName(sqlInfo.getFileName());
1986                sqlInfoItem.setFilePath(sqlInfo.getFilePath());
1987                sqlInfoItem.setSql(buffer.toString());
1988                sqlInfoItem.setOriginIndex(index);
1989                sqlInfoItem.setOriginLineStart(0);
1990                sqlInfoItem.setOriginLineEnd(buffer.toString().split("\n", -1).length - 1);
1991                sqlInfoItem.setIndex(databaseMap.get(sqlHash).second.getAndIncrement());
1992                sqlInfoItem.setLineStart(lineStart);
1993                sqlInfoItem.setLineEnd(databaseMap.get(sqlHash).first.toString().split("\n", -1).length - 1);
1994                sqlInfoItem.setGroup(group);
1995                sqlInfoItem.setHash(hash);
1996
1997                if (!sqlInfoMap.containsKey(hash)) {
1998                        sqlInfoMap.put(hash, new ArrayList<SqlInfo>());
1999                }
2000                sqlInfoMap.get(hash).add(sqlInfoItem);
2001        }
2002
2003        static String getTextOutput(dataflow dataflow) {
2004                StringBuffer buffer = new StringBuffer();
2005                List<relationship> relations = dataflow.getRelationships();
2006                if (relations != null) {
2007                        for (int i = 0; i < relations.size(); i++) {
2008                                relationship relation = relations.get(i);
2009                                targetColumn target = relation.getTarget();
2010                                List<sourceColumn> sources = relation.getSources();
2011                                if (target != null && sources != null && sources.size() > 0) {
2012                                        buffer.append(target.getColumn()).append(" depends on: ");
2013                                        Set<String> columnSet = new LinkedHashSet<String>();
2014                                        for (int j = 0; j < sources.size(); j++) {
2015                                                sourceColumn sourceColumn = sources.get(j);
2016                                                String columnName = sourceColumn.getColumn();
2017                                                if (sourceColumn.getParent_name() != null && sourceColumn.getParent_name().length() > 0) {
2018                                                        columnName = sourceColumn.getParent_name() + "." + columnName;
2019                                                }
2020                                                columnSet.add(columnName);
2021                                        }
2022                                        String[] columns = columnSet.toArray(new String[0]);
2023                                        for (int j = 0; j < columns.length; j++) {
2024                                                buffer.append(columns[j]);
2025                                                if (j == columns.length - 1) {
2026                                                        buffer.append("\n");
2027                                                } else
2028                                                        buffer.append(", ");
2029                                        }
2030                                }
2031                        }
2032                }
2033                return buffer.toString();
2034        }
2035
2036        private String mergeRelationType(List<Pair<sourceColumn, List<String>>> typePaths) {
2037                RelationshipType relationType = RelationshipType.join;
2038                for (int i = 0; i < typePaths.size(); i++) {
2039                        List<String> path = typePaths.get(i).second;
2040                        RelationshipType type = RelationshipType.valueOf(getRelationType(path));
2041                        if (type.ordinal() < relationType.ordinal()) {
2042                                relationType = type;
2043                        }
2044                }
2045                return relationType.name();
2046        }
2047
2048        private String getRelationType(List<String> typePaths) {
2049                if (typePaths.contains("join"))
2050                        return "join";
2051                if (typePaths.contains("fdr"))
2052                        return "fdr";
2053                if (typePaths.contains("frd"))
2054                        return "frd";
2055                if (typePaths.contains("fddi"))
2056                        return "fddi";
2057                return "fdd";
2058        }
2059
2060        public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput) throws Exception {
2061                return getSimpleDataflow(instance, simpleOutput, Arrays.asList("fdd"));
2062        }
2063        
2064        public dataflow getSimpleDataflow(dataflow instance, boolean simpleOutput, List<String> types) throws Exception {
2065                ModelBindingManager.setGlobalVendor(option.getVendor());
2066                allMap.clear();
2067                targetTables.clear();
2068                resultSetMap.clear();
2069                tableMap.clear();
2070                viewMap.clear();
2071                cursorMap.clear();
2072                variableMap.clear();
2073                fileMap.clear();
2074                stageMap.clear();
2075                sequenceMap.clear();
2076                dataSourceMap.clear();
2077                databaseMap.clear();
2078                schemaMap.clear();
2079                streamMap.clear();
2080                dataflow simple = new dataflow();
2081                List<relationship> simpleRelations = new ArrayList<relationship>();
2082                List<relationship> relations = instance.getRelationships();
2083                if (instance.getResultsets() != null) {
2084                        for (table t : instance.getResultsets()) {
2085                                resultSetMap.put(t.getId().toLowerCase(), t);
2086                                allMap.put(t.getId().toLowerCase(), t);
2087                        }
2088                }
2089
2090                if (instance.getTables() != null) {
2091                        for (table t : instance.getTables()) {
2092                                tableMap.put(t.getId().toLowerCase(), t);
2093                                allMap.put(t.getId().toLowerCase(), t);
2094                        }
2095                }
2096
2097                if (instance.getViews() != null) {
2098                        for (table t : instance.getViews()) {
2099                                viewMap.put(t.getId().toLowerCase(), t);
2100                                allMap.put(t.getId().toLowerCase(), t);
2101                        }
2102                }
2103
2104                if (instance.getPaths() != null) {
2105                        for (table t : instance.getPaths()) {
2106                                fileMap.put(t.getId().toLowerCase(), t);
2107                                allMap.put(t.getId().toLowerCase(), t);
2108                        }
2109                }
2110
2111                if (instance.getStages() != null) {
2112                        for (table t : instance.getStages()) {
2113                                stageMap.put(t.getId().toLowerCase(), t);
2114                                allMap.put(t.getId().toLowerCase(), t);
2115                        }
2116                }
2117                
2118                if (instance.getSequences() != null) {
2119                        for (table t : instance.getSequences()) {
2120                                sequenceMap.put(t.getId().toLowerCase(), t);
2121                                allMap.put(t.getId().toLowerCase(), t);
2122                        }
2123                }
2124
2125                if (instance.getDatasources() != null) {
2126                        for (table t : instance.getDatasources()) {
2127                                dataSourceMap.put(t.getId().toLowerCase(), t);
2128                                allMap.put(t.getId().toLowerCase(), t);
2129                        }
2130                }
2131
2132                if (instance.getDatabases() != null) {
2133                        for (table t : instance.getDatabases()) {
2134                                databaseMap.put(t.getId().toLowerCase(), t);
2135                                allMap.put(t.getId().toLowerCase(), t);
2136                        }
2137                }
2138
2139                if (instance.getSchemas() != null) {
2140                        for (table t : instance.getSchemas()) {
2141                                schemaMap.put(t.getId().toLowerCase(), t);
2142                                allMap.put(t.getId().toLowerCase(), t);
2143                        }
2144                }
2145
2146                if (instance.getStreams() != null) {
2147                        for (table t : instance.getStreams()) {
2148                                streamMap.put(t.getId().toLowerCase(), t);
2149                                allMap.put(t.getId().toLowerCase(), t);
2150                        }
2151                }
2152
2153                if (instance.getVariables() != null) {
2154                        for (table t : instance.getVariables()) {
2155                                if(SubType.cursor.name().equals(t.getSubType())){
2156                                        cursorMap.put(t.getId().toLowerCase(), t);
2157                                }
2158                                else {
2159                                        variableMap.put(t.getId().toLowerCase(), t);
2160                                }
2161                                allMap.put(t.getId().toLowerCase(), t);
2162                        }
2163                }
2164
2165                if (relations != null) {
2166                        
2167                        List<relationship> filterRelations = new ArrayList<>();
2168                        for (relationship relationElem : relations) {
2169                                if (!types.contains(relationElem.getType()))
2170                                        continue;
2171                                else {
2172                                        filterRelations.add(relationElem);
2173                                }
2174                        }
2175                        
2176                        relations = filterRelations;
2177                        
2178                        Map<String, Set<relationship>> targetIdRelationMap = new HashMap<String, Set<relationship>>();
2179                        for (relationship relation : relations) {
2180                                if (relation.getTarget() != null) {
2181                                        String key = relation.getTarget().getParent_id() + "." + relation.getTarget().getId();
2182                                        if (!targetIdRelationMap.containsKey(key)) {
2183                                                targetIdRelationMap.put(key, new TreeSet<relationship>(new Comparator<relationship>() {
2184                                                        @Override
2185                                                        public int compare(relationship o1, relationship o2) {
2186                                                                return o1.getId().compareTo(o2.getId());
2187                                                        }
2188                                                }));
2189                                        }
2190                                        targetIdRelationMap.get(key).add(relation);
2191                                }
2192                        }
2193
2194                        Iterator<String> keys = targetIdRelationMap.keySet().iterator();
2195                        while (keys.hasNext()) {
2196                                String key = keys.next();
2197                                if (targetIdRelationMap.get(key).size() > 500) {
2198                                        keys.remove();
2199                                }
2200                        }
2201
2202                        for (relationship relationElem : relations) {
2203                                if (RelationshipType.call.name().equals(relationElem.getType())) {
2204                                        continue;
2205                                }
2206                                if (RelationshipType.er.name().equals(relationElem.getType())) {
2207                                        continue;
2208                                }
2209                                targetColumn target = relationElem.getTarget();
2210                                String targetParent = target.getParent_id();
2211                                if (isTarget(instance, targetParent, simpleOutput)) {
2212                                        List<Pair<sourceColumn, List<String>>> relationSources = new ArrayList<Pair<sourceColumn, List<String>>>();
2213                                        findSourceRelations(target, instance, targetIdRelationMap, relationElem, relationSources,
2214                                                        new String[] { relationElem.getType() }, simpleOutput);
2215                                        if (relationSources.size() > 0) {
2216                                                Map<sourceColumn, List<Pair<sourceColumn, List<String>>>> columnMap = new LinkedHashMap<sourceColumn, List<Pair<sourceColumn, List<String>>>>();
2217                                                for (Pair<sourceColumn, List<String>> t : relationSources) {
2218                                                        sourceColumn key = ((Pair<sourceColumn, List<String>>) t).first;
2219                                                        if (!columnMap.containsKey(key)) {
2220                                                                columnMap.put(key, new ArrayList<Pair<sourceColumn, List<String>>>());
2221                                                        }
2222                                                        columnMap.get(key).add(t);
2223                                                }
2224                                                Iterator<sourceColumn> iter = columnMap.keySet().iterator();
2225                                                Map<String, List<sourceColumn>> relationSourceMap = new HashMap<String, List<sourceColumn>>();
2226                                                while (iter.hasNext()) {
2227                                                        sourceColumn column = iter.next();
2228                                                        String relationType = mergeRelationType(columnMap.get(column));
2229                                                        if (!relationSourceMap.containsKey(relationType)) {
2230                                                                relationSourceMap.put(relationType, new ArrayList<sourceColumn>());
2231                                                        }
2232                                                        relationSourceMap.get(relationType).add(column);
2233                                                }
2234
2235                                                Iterator<String> sourceIter = relationSourceMap.keySet().iterator();
2236                                                while (sourceIter.hasNext()) {
2237                                                        String relationType = sourceIter.next();
2238                                                        relationship simpleRelation = (relationship) relationElem.clone();
2239                                                        simpleRelation.setSources(relationSourceMap.get(relationType));
2240                                                        simpleRelation.setType(relationType);
2241                                                        simpleRelation.setId(String.valueOf(++ModelBindingManager.get().RELATION_ID));
2242                                                        simpleRelations.add(simpleRelation);
2243                                                }
2244                                        }
2245                                }
2246                        }
2247                }
2248
2249                simple.setProcedures(instance.getProcedures());
2250                simple.setPackages(instance.getPackages());
2251                simple.setProcesses(instance.getProcesses());
2252                simple.setErrors(instance.getErrors());
2253                List<table> tables = new ArrayList<table>();
2254                for (table t : instance.getTables()) {
2255                        if (!SQLUtil.isTempTable(t)) {
2256                                tables.add(t);
2257                        }
2258                        else {
2259                                if (option.isIgnoreTemporaryTable()) {
2260                                        continue;
2261                                }
2262                                else {
2263                                        tables.add(t);
2264                                }
2265                        }
2266                }
2267                simple.setStages(instance.getStages());
2268                simple.setSequences(instance.getSequences());
2269                simple.setDatasources(instance.getDatasources());
2270                simple.setStreams(instance.getStreams());
2271                simple.setPaths(instance.getPaths());
2272                simple.setTables(tables);
2273                simple.setViews(instance.getViews());
2274                if(option.isSimpleShowVariable()) {
2275                        simple.setVariables(instance.getVariables());
2276                }
2277                else if(option.isSimpleShowCursor()) {
2278                        simple.setVariables(instance.getVariables().stream().filter(t->SubType.cursor.name().equals(t.getSubType())).collect(Collectors.toList()));
2279                }
2280                if (instance.getResultsets() != null) {
2281                        List<table> resultSets = new ArrayList<table>();
2282                        for (int i = 0; i < instance.getResultsets().size(); i++) {
2283                                table resultSet = instance.getResultsets().get(i);
2284                                if (isTargetResultSet(instance, resultSet.getId(), simpleOutput)) {
2285                                        // special handle function #524 #296
2286                                        resultSets.add(resultSet);
2287                                }
2288                        }
2289                        simple.setResultsets(resultSets);
2290                }
2291
2292                List<table> functions = new ArrayList<table>();
2293                if (option.isShowCallRelation()) {
2294                        for (int i = 0; i < relations.size(); i++) {
2295                                relationship relationElem = relations.get(i);
2296                                if (!RelationshipType.call.name().equals(relationElem.getType())) {
2297                                        continue;
2298                                }
2299                                simpleRelations.add(relationElem);
2300                                for (sourceColumn callee : relationElem.getCallees()) {
2301                                        String calleeId = callee.getId();
2302                                        if (resultSetMap.containsKey(calleeId)) {
2303                                                table function = resultSetMap.get(calleeId);
2304                                                function.setIsTarget("true");
2305                                                functions.add(function);
2306                                        }
2307                                }
2308                        }
2309                }
2310
2311                if (option.isShowERDiagram()) {
2312                        for (int i = 0; i < relations.size(); i++) {
2313                                relationship relationElem = relations.get(i);
2314                                if (!RelationshipType.er.name().equals(relationElem.getType())) {
2315                                        continue;
2316                                }
2317                                simpleRelations.add(relationElem);
2318                                for (sourceColumn callee : relationElem.getCallees()) {
2319                                        String calleeId = callee.getId();
2320                                        if (resultSetMap.containsKey(calleeId)) {
2321                                                table function = resultSetMap.get(calleeId);
2322                                                function.setIsTarget("true");
2323                                                functions.add(function);
2324                                        }
2325                                }
2326                        }
2327                }
2328                
2329                if (!functions.isEmpty()) {
2330                        if (simple.getResultsets() == null) {
2331                                simple.setResultsets(functions);
2332                        } else {
2333                                simple.getResultsets().addAll(functions);
2334                        }
2335                }
2336
2337                simple.setRelationships(simpleRelations);
2338                simple.setOrientation(instance.getOrientation());
2339                targetTables.clear();
2340                resultSetMap.clear();
2341                tableMap.clear();
2342                viewMap.clear();
2343                cursorMap.clear();
2344                variableMap.clear();
2345                fileMap.clear();
2346                stageMap.clear();
2347                dataSourceMap.clear();
2348                databaseMap.clear();
2349                schemaMap.clear();
2350                streamMap.clear();
2351                return simple;
2352        }
2353
2354        private void findSourceRelations(targetColumn target, dataflow instance, Map<String, Set<relationship>> sourceIdRelationMap,
2355                        relationship targetRelation, List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, boolean simpleOutput) {
2356                findStarSourceRelations(target, instance, null, sourceIdRelationMap, targetRelation, relationSources, pathTypes,
2357                                new HashSet<String>(), new LinkedHashSet<transform>(), new LinkedHashSet<candidateTable>(), 0, simpleOutput);
2358        }
2359
2360        private void findStarSourceRelations(targetColumn target, dataflow instance, targetColumn starRelationTarget,
2361                        Map<String, Set<relationship>> sourceIdRelationMap, relationship targetRelation,
2362                        List<Pair<sourceColumn, List<String>>> relationSources, String[] pathTypes, Set<String> paths,
2363                        Set<transform> transforms, Set<candidateTable> candidateTables, int level, boolean simpleOutput) {
2364                if (targetRelation != null && targetRelation.getSources() != null) {
2365                        
2366                        //获取source为*的Column Parent
2367                        String starParentId = null;
2368                        for (int i = 0; i < targetRelation.getSources().size(); i++) {
2369                                sourceColumn source = targetRelation.getSources().get(i);
2370                                if (starRelationTarget != null && "*".equals(source.getColumn())) {
2371                                        starParentId = source.getParent_id();
2372                                }
2373                        }
2374                        
2375                        for (int i = 0; i < targetRelation.getSources().size(); i++) {
2376                                sourceColumn source = targetRelation.getSources().get(i);
2377                                if (starRelationTarget != null && !"*".equals(source.getColumn())
2378                                                && !DlineageUtil.getIdentifierNormalColumnName(starRelationTarget.getColumn())
2379                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(source.getColumn()))) {
2380                                        table parent = allMap.get(source.getParent_id());
2381                                        if (parent != null && isFunction(parent)) {
2382                                                // function返回值未知,不对星号做处理
2383                                        } 
2384                                        else if (parent == null) {
2385                                                continue;
2386                                        } else if(starParentId!=null && starParentId.equals(parent.getId())){
2387                                                //如果source和 * column的parent相同,则跳过
2388                                                continue;
2389                                        }
2390                                }
2391
2392                                String sourceColumnId = source.getId();
2393                                String sourceParentId = source.getParent_id();
2394                                if (sourceParentId == null || sourceColumnId == null) {
2395                                        continue;
2396                                }
2397                                if (isTarget(instance, sourceParentId, simpleOutput)) {
2398                                        List<transform> transforms2 = new ArrayList<transform>(transforms.size());
2399                                        transforms2.addAll(transforms);
2400                                        Collections.reverse(transforms2);
2401                                        
2402                                        List<candidateTable> candidateTables2 = new ArrayList<candidateTable>(candidateTables.size());
2403                                        candidateTables2.addAll(candidateTables);
2404                                        
2405                                        sourceColumn sourceColumnCopy = DlineageUtil.copySourceColumn(source);
2406                                        for (transform t : transforms2) {
2407                                                sourceColumnCopy.addTransform(t);
2408                                        }
2409                                        
2410                                        for (candidateTable t : candidateTables2) {
2411                                                sourceColumnCopy.addCandidateParent(t);
2412                                        }
2413                                        
2414                                        if(Boolean.TRUE.equals(target.isStruct()) && Boolean.TRUE.equals(source.isStruct())) {
2415                                                List<String> targetColumns = SQLUtil.parseNames(target.getColumn());
2416                                                List<String> sourceColumns = SQLUtil.parseNames(source.getColumn());
2417                                                if(!DlineageUtil.getIdentifierNormalColumnName(targetColumns.get(targetColumns.size()-1))
2418                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(sourceColumns.get(sourceColumns.size()-1)))) {
2419                                                        continue;
2420                                                }
2421                                        }
2422                                        relationSources.add(new Pair<sourceColumn, List<String>>(sourceColumnCopy, Arrays.asList(pathTypes)));
2423                                } else {
2424                                        Set<relationship> sourceRelations = sourceIdRelationMap
2425                                                        .get(source.getParent_id() + "." + source.getId());
2426                                        if (sourceRelations != null) {
2427                                                if (paths.contains(source.getParent_id() + "." + source.getId())) {
2428                                                        continue;
2429                                                } else {
2430                                                        paths.add(source.getParent_id() + "." + source.getId());
2431                                                        if (source.getTransforms() != null) {
2432                                                                transforms.addAll(source.getTransforms());
2433                                                        }
2434                                                        if (source.getCandidateParents() != null) {
2435                                                                candidateTables.addAll(source.getCandidateParents());
2436                                                        }
2437                                                }
2438                                                for (relationship relation : sourceRelations) {
2439                                                        LinkedHashSet<transform> transforms2 = new LinkedHashSet<transform>(transforms.size());
2440                                                        transforms2.addAll(transforms);
2441                                                        LinkedHashSet<candidateTable> candidateTables2 = new LinkedHashSet<candidateTable>(candidateTables.size());
2442                                                        candidateTables2.addAll(candidateTables);
2443                                                        String[] types = new String[pathTypes.length + 1];
2444                                                        types[0] = relation.getType();
2445                                                        System.arraycopy(pathTypes, 0, types, 1, pathTypes.length);
2446                                                        if (!"*".equals(source.getColumn())) {
2447                                                                findStarSourceRelations(target, instance, null, sourceIdRelationMap, relation, relationSources,
2448                                                                                types, paths, transforms2, candidateTables2, level + 1, simpleOutput);
2449                                                        } else {
2450                                                                findStarSourceRelations(target, instance,
2451                                                                                starRelationTarget == null ? targetRelation.getTarget() : starRelationTarget,
2452                                                                                sourceIdRelationMap, relation, relationSources, types, paths, transforms, candidateTables2,
2453                                                                                level + 1, simpleOutput);
2454                                                        }
2455                                                }
2456                                        }
2457                                }
2458                        }
2459                }
2460        }
2461
2462        private Map<String, Boolean> targetTables = new HashMap<String, Boolean>();
2463        private Map<String, table> resultSetMap = new HashMap<String, table>();
2464        private Map<String, table> tableMap = new HashMap<String, table>();
2465        private Map<String, table> viewMap = new HashMap<String, table>();
2466        private Map<String, table> cursorMap = new HashMap<String, table>();
2467        private Map<String, table> variableMap = new HashMap<String, table>();
2468        private Map<String, table> fileMap = new HashMap<String, table>();
2469        private Map<String, table> stageMap = new HashMap<String, table>();
2470        private Map<String, table> sequenceMap = new HashMap<String, table>();
2471        private Map<String, table> dataSourceMap = new HashMap<String, table>();
2472        private Map<String, table> databaseMap = new HashMap<String, table>();
2473        private Map<String, table> schemaMap = new HashMap<String, table>();
2474        private Map<String, table> streamMap = new HashMap<String, table>();
2475        private Map<String, table> allMap = new HashMap<String, table>();
2476
2477        private boolean isTarget(dataflow instance, String targetParentId, boolean simpleOutput) {
2478                if (targetTables.containsKey(targetParentId))
2479                        return targetTables.get(targetParentId);
2480                if (isTable(instance, targetParentId)) {
2481                        targetTables.put(targetParentId, true);
2482                        return true;
2483                } else if (isView(instance, targetParentId)) {
2484                        targetTables.put(targetParentId, true);
2485                        return true;
2486                } else if (isFile(instance, targetParentId)) {
2487                        targetTables.put(targetParentId, true);
2488                        return true;
2489                } else if (isDatabase(instance, targetParentId)) {
2490                        targetTables.put(targetParentId, true);
2491                        return true;
2492                } else if (isSchema(instance, targetParentId)) {
2493                        targetTables.put(targetParentId, true);
2494                        return true;
2495                } else if (isStage(instance, targetParentId)) {
2496                        targetTables.put(targetParentId, true);
2497                        return true;
2498                } else if (isSequence(instance, targetParentId)) {
2499                        targetTables.put(targetParentId, true);
2500                        return true;
2501                } else if (isDataSource(instance, targetParentId)) {
2502                        targetTables.put(targetParentId, true);
2503                        return true;
2504                } else if (isStream(instance, targetParentId)) {
2505                        targetTables.put(targetParentId, true);
2506                        return true;
2507                } else if (isCursor(instance, targetParentId) && option.isSimpleShowCursor()) {
2508                        targetTables.put(targetParentId, true);
2509                        return true;
2510                } else if ((isVariable(instance, targetParentId) || isCursor(instance, targetParentId)) && option.isSimpleShowVariable()) {
2511                        targetTables.put(targetParentId, true);
2512                        return true;
2513                } else if (isTargetResultSet(instance, targetParentId, simpleOutput)) {
2514                        targetTables.put(targetParentId, true);
2515                        return true;
2516                }
2517                targetTables.put(targetParentId, false);
2518                return false;
2519        }
2520
2521        private boolean isTargetResultSet(dataflow instance, String targetParent, boolean simpleOutput) {
2522                if (resultSetMap.containsKey(targetParent.toLowerCase())) {
2523                        table result = resultSetMap.get(targetParent.toLowerCase());
2524                        boolean isTarget = result.isTarget();
2525                        Option option = ModelBindingManager.getGlobalOption();
2526                        if (option != null && option.isSqlflowIgnoreFunction() && isFunction(result)) {
2527                                return false;
2528                        }
2529                        if (isTarget && simpleOutput) {
2530                                if (option != null && option.isSimpleShowFunction() && isFunction(result)) {
2531                                        return true;
2532
2533                                } else if (option != null && option.isSimpleShowTopSelectResultSet()) {
2534                                        return true;
2535                                }
2536                                if (ResultSetType.of(result.getType()) != null && option.containsResultSetType(ResultSetType.of(result.getType()))) {
2537                                        return true;
2538                                }
2539                        } else
2540                                return isTarget;
2541                }
2542                return false;
2543        }
2544
2545        private boolean isFunction(table resultSet) {
2546                if("function".equals(resultSet.getType())){
2547                        return true;
2548                }
2549                else if("resultset".equals(resultSet.getType()) && "function".equals(resultSet.getSubType())){
2550                        return true;
2551                }
2552                return false;
2553        }
2554
2555        private boolean isView(dataflow instance, String targetParent) {
2556                if (viewMap.containsKey(targetParent.toLowerCase())) {
2557                        return true;
2558                }
2559                return false;
2560        }
2561
2562        private boolean isCursor(dataflow instance, String targetParent) {
2563                if (cursorMap.containsKey(targetParent.toLowerCase())) {
2564                        return true;
2565                }
2566                return false;
2567        }
2568
2569        private boolean isVariable(dataflow instance, String targetParent) {
2570                if (variableMap.containsKey(targetParent.toLowerCase())) {
2571                        return true;
2572                }
2573                return false;
2574        }
2575
2576        private boolean isFile(dataflow instance, String targetParent) {
2577                if (fileMap.containsKey(targetParent.toLowerCase())) {
2578                        return true;
2579                }
2580                return false;
2581        }
2582
2583        private boolean isStage(dataflow instance, String targetParent) {
2584                if (stageMap.containsKey(targetParent.toLowerCase())) {
2585                        return true;
2586                }
2587                return false;
2588        }
2589        
2590        private boolean isSequence(dataflow instance, String targetParent) {
2591                if (sequenceMap.containsKey(targetParent.toLowerCase())) {
2592                        return true;
2593                }
2594                return false;
2595        }
2596
2597        private boolean isDataSource(dataflow instance, String targetParent) {
2598                if (dataSourceMap.containsKey(targetParent.toLowerCase())) {
2599                        return true;
2600                }
2601                return false;
2602        }
2603
2604        private boolean isDatabase(dataflow instance, String targetParent) {
2605                if (databaseMap.containsKey(targetParent.toLowerCase())) {
2606                        return true;
2607                }
2608                return false;
2609        }
2610
2611        private boolean isSchema(dataflow instance, String targetParent) {
2612                if (schemaMap.containsKey(targetParent.toLowerCase())) {
2613                        return true;
2614                }
2615                return false;
2616        }
2617
2618        private boolean isStream(dataflow instance, String targetParent) {
2619                if (streamMap.containsKey(targetParent.toLowerCase())) {
2620                        return true;
2621                }
2622                return false;
2623        }
2624
2625        private boolean isTable(dataflow instance, String targetParent) {
2626                if (tableMap.containsKey(targetParent.toLowerCase())) {
2627                        if (SQLUtil.isTempTable(tableMap.get(targetParent))) {
2628                                if (option.isIgnoreTemporaryTable()) {
2629                                        return false;
2630                                }
2631                        }
2632                        if (tableMap.get(targetParent).isFunction()) {
2633                                if (option != null && option.isSimpleShowFunction()) {
2634                                        return true;
2635                                } else {
2636                                        return false;
2637                                }
2638                        }
2639                        if (SubType.synonym.name().equals(tableMap.get(targetParent).getSubType())) {
2640                                if (option != null && option.isSimpleShowSynonym()) {
2641                                        return true;
2642                                } else {
2643                                        return false;
2644                                }
2645                        }
2646                        return true;
2647                } else {
2648                        return false;
2649                }
2650        }
2651
2652        private void init() {
2653                metadataErrors.clear();
2654                sqlInfoMap.clear();
2655                errorInfos.clear();
2656                dataflow = null;
2657                dataflowString = null;
2658                ModelBindingManager.removeGlobalDatabase();
2659                ModelBindingManager.removeGlobalSchema();
2660                ModelBindingManager.removeGlobalVendor();
2661                ModelBindingManager.removeGlobalSQLEnv();
2662                ModelBindingManager.removeGlobalHash();
2663                appendResultSets.clear();
2664                appendStarColumns.clear();
2665                appendTableStarColumns.clear();
2666                modelManager.TABLE_COLUMN_ID = option.getStartId();
2667                modelManager.RELATION_ID = option.getStartId();
2668                modelManager.DISPLAY_ID.clear();
2669                modelManager.DISPLAY_NAME.clear();
2670                tableIds.clear();
2671                ModelBindingManager.setGlobalVendor(option.getVendor());
2672                modelManager.reset();
2673        }
2674
2675        private String getErrorMessage(TSyntaxError error, String errorType) {
2676                String s = "", hint = "Syntax error";
2677                if (ErrorInfo.SYNTAX_HINT.equals(errorType)) {
2678                        hint = "Syntax hint";
2679                }
2680                if (error.hint.length() > 0)
2681                        hint = error.hint;
2682                s = s + hint + "(" + error.errorno + ") near: " + error.tokentext;
2683                s = s + "(" + error.lineNo;
2684                s = s + "," + error.columnNo + ")";
2685                return s;
2686        }
2687
2688//      boolean OLD_ENABLE_RESOLVER = TBaseType.isEnableResolver();
2689        private void analyzeAndOutputResult(TGSqlParser sqlparser) {
2690                try {
2691                        accessedSubqueries.clear();
2692                        accessedStatements.clear();
2693                        stmtStack.clear();
2694                        viewDDLMap.clear();
2695                        procedureDDLMap.clear();
2696                        structObjectMap.clear();
2697                        try {
2698                                if(sqlenv!=null) {
2699                                        sqlparser.setSqlEnv(sqlenv);
2700                                }
2701                                int result = sqlparser.parse();
2702                                if (result != 0) {
2703                                        ArrayList<TSyntaxError> errors = sqlparser.getSyntaxErrors();
2704                                        if (errors != null && !errors.isEmpty()) {
2705                                                for (int i = 0; i < errors.size(); i++) {
2706                                                        TSyntaxError error = errors.get(i);
2707                                                        ErrorInfo errorInfo = new ErrorInfo();
2708                                                        errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
2709                                                        errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
2710                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2711                                                                        ModelBindingManager.getGlobalHash()));
2712                                                        String[] segments = error.tokentext.split("\n");
2713                                                        if (segments.length <= 1) {
2714                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2715                                                                                error.columnNo + error.tokentext.length(),
2716                                                                                ModelBindingManager.getGlobalHash()));
2717                                                        } else {
2718                                                                errorInfo.setEndPosition(
2719                                                                                new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2720                                                                                                (long) segments[segments.length - 1].length() + 1,
2721                                                                                                ModelBindingManager.getGlobalHash()));
2722                                                        }
2723                                                        ;
2724                                                        errorInfo.fillInfo(this);
2725                                                        errorInfos.add(errorInfo);
2726                                                }
2727                                        }
2728                                }
2729
2730                                if (option.getHandleListener() != null) {
2731                                        option.getHandleListener().endParse(result == 0);
2732                                }
2733                        } catch (Exception e) {
2734                                logger.error("analyze sql failed.", e);
2735                                if (option.getHandleListener() != null) {
2736                                        option.getHandleListener().endParse(false);
2737                                }
2738                                ErrorInfo errorInfo = new ErrorInfo();
2739                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2740                                if (e.getMessage() == null) {
2741                                        if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2742                                                errorInfo
2743                                                                .setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2744                                        } else {
2745                                                errorInfo.setErrorMessage(e.getClass().getSimpleName());
2746                                        }
2747                                } else {
2748                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2749                                }
2750                                errorInfo.fillInfo(this);
2751                                errorInfos.add(errorInfo);
2752                                return;
2753                        }
2754
2755                        
2756                        TSQLResolver2 resolver = sqlparser.getResolver2();
2757                        if (resolver != null && option.getVendor() == EDbVendor.dbvbigquery) {
2758                                ScopeBuildResult buildResult = resolver.getScopeBuildResult();
2759                                List<TObjectName> columns = buildResult.getAllColumnReferences();
2760                                for (TObjectName col : columns) {
2761                                        structObjectMap.putIfAbsent(col.getSourceTable(), new TObjectNameList());
2762                                        structObjectMap.get(col.getSourceTable()).addObjectName(col);
2763                                }
2764                        }
2765                        
2766                        if (option.getHandleListener() != null) {
2767                                option.getHandleListener().startAnalyzeDataFlow(sqlparser);
2768                        }
2769
2770                        for (int i = 0; i < sqlparser.getSqlstatements().size(); i++) {
2771                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2772                                        break;
2773                                }
2774
2775                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2776                                if (stmt.getErrorCount() == 0) {
2777                                        if (stmt.getParentStmt() == null) {
2778                                                modelManager.collectSqlHash(stmt);
2779                                                if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema
2780                                                                || stmt instanceof TCreateTableSqlStatement
2781                                                                || stmt instanceof TCreateExternalDataSourceStmt || stmt instanceof TCreateStageStmt
2782                                                                || stmt instanceof TMssqlCreateType
2783                                                                || stmt instanceof TMssqlDeclare
2784                                                                || (stmt instanceof TCreateFunctionStmt && hasDb2ReturnStmt((TCreateFunctionStmt)stmt))
2785                                                                || (stmt instanceof TMssqlCreateFunction
2786                                                                                && (((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null
2787                                                                                                || ((TMssqlCreateFunction) stmt).getReturnStmt() != null))) {
2788                                                        boolean listen = false;
2789                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2790                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2791                                                                listen = true;
2792                                                        }
2793                                                        analyzeCustomSqlStmt(stmt);
2794                                                        if (listen && option.getHandleListener() != null) {
2795                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2796                                                        }
2797                                                }
2798                                        }
2799                                }
2800                        }
2801
2802                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2803                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2804                                        break;
2805                                }
2806
2807                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2808                                if (stmt.getErrorCount() == 0) {
2809                                        if (stmt.getParentStmt() == null) {
2810                                                if (stmt instanceof TUseDatabase 
2811                                                                || stmt instanceof TUseSchema
2812                                                                || stmt instanceof TCreateViewSqlStatement 
2813                                                                || stmt instanceof TCreateSynonymStmt 
2814                                                                || stmt instanceof TStoredProcedureSqlStatement) {
2815                                                        boolean listen = false;
2816                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2817                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2818                                                                listen = true;
2819                                                        }
2820                                                        if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema) {
2821                                                                analyzeCustomSqlStmt(stmt);
2822                                                        } else if (stmt instanceof TCreateViewSqlStatement) {
2823                                                                TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt;
2824                                                                if(view.getViewName()!=null) {
2825                                                                        viewDDLMap.put(DlineageUtil.getTableFullName(view.getViewName().toString()), view);
2826                                                                }
2827                                                        } else if (stmt instanceof TCreateSynonymStmt) {
2828                                                                TCreateSynonymStmt synonym = (TCreateSynonymStmt) stmt;
2829                                                                if(synonym.getSynonymName()!=null) {
2830                                                                        viewDDLMap.put(DlineageUtil.getTableFullName(synonym.getSynonymName().toString()), synonym);
2831                                                                }
2832                                                        } else if (stmt instanceof TStoredProcedureSqlStatement) {
2833                                                                TStoredProcedureSqlStatement procedure = (TStoredProcedureSqlStatement) stmt;
2834                                                                if(procedure.getStoredProcedureName() == null) {
2835                                                                        continue;
2836                                                                }
2837                                                                procedureDDLMap.put(DlineageUtil.getProcedureNameWithArgNum(procedure), procedure);
2838                                                        }
2839                                                        if (listen && option.getHandleListener() != null) {
2840                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2841                                                        }
2842                                                }
2843                                        }
2844                                }
2845                        }
2846
2847                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2848                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2849                                        break;
2850                                }
2851
2852                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2853                                if (stmt.getErrorCount() == 0) {
2854                                        if (stmt.getParentStmt() == null) {
2855                                                if (stmt instanceof TUseDatabase 
2856                                                                || stmt instanceof TUseSchema
2857                                                                || stmt instanceof TCreateViewSqlStatement 
2858                                                                || stmt instanceof TCreateSynonymStmt) {
2859                                                        boolean listen = false;
2860                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2861                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2862                                                                listen = true;
2863                                                        }
2864                                                        analyzeCustomSqlStmt(stmt);
2865                                                        if (listen && option.getHandleListener() != null) {
2866                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2867                                                        }
2868                                                }
2869                                        }
2870                                }
2871                        }
2872
2873                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2874                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2875                                        break;
2876                                }
2877
2878                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2879                                if (stmt.getErrorCount() == 0) {
2880                                        if (stmt.getParentStmt() == null) {
2881                                                if (stmt instanceof TUseDatabase || stmt instanceof TUseSchema
2882                                                                || stmt instanceof TStoredProcedureSqlStatement) {
2883                                                        boolean listen = false;
2884                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2885                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2886                                                                listen = true;
2887                                                        }
2888                                                        if (stmt instanceof TPlsqlCreateTrigger)
2889                                                                continue;
2890                                                        analyzeCustomSqlStmt(stmt);
2891                                                        if (listen && option.getHandleListener() != null) {
2892                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2893                                                        }
2894                                                }
2895                                        }
2896                                }
2897                        }
2898
2899                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
2900                                if (option.getHandleListener() != null && option.getHandleListener().isCanceled()) {
2901                                        break;
2902                                }
2903
2904                                TCustomSqlStatement stmt = sqlparser.getSqlstatements().get(i);
2905
2906                                if (option.isIgnoreTopSelect()) {
2907                                        if ((stmt instanceof TSelectSqlStatement && ((TSelectSqlStatement)stmt).getIntoClause() == null && ((TSelectSqlStatement)stmt).getIntoTableClause() == null ) || stmt instanceof TRedshiftDeclare
2908                                                        || stmt instanceof TRedshiftDeclare) {
2909                                                continue;
2910                                        }
2911                                }
2912
2913                                if (stmt.getErrorCount() == 0) {
2914                                        if (stmt.getParentStmt() == null) {
2915                                                if (!(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TCreateStageStmt)
2916                                                                && !(stmt instanceof TCreateExternalDataSourceStmt)
2917                                                                && !(stmt instanceof TCreateViewSqlStatement) && !(stmt instanceof TMssqlDeclare)
2918                                                                && !(stmt instanceof TMssqlCreateFunction
2919                                                                                && ((TMssqlCreateFunction) stmt).getReturnTableDefinitions() != null)) {
2920                                                        boolean listen = false;
2921                                                        if (option.getHandleListener() != null && !accessedStatements.contains(stmt)) {
2922                                                                option.getHandleListener().startAnalyzeStatment(stmt);
2923                                                                listen = true;
2924                                                        }
2925                                                        analyzeCustomSqlStmt(stmt);
2926                                                        if (listen && option.getHandleListener() != null) {
2927                                                                option.getHandleListener().endAnalyzeStatment(stmt);
2928                                                        }
2929                                                }
2930                                        }
2931                                }
2932                        }
2933
2934                        if (option.getHandleListener() != null) {
2935                                option.getHandleListener().endAnalyzeDataFlow(sqlparser);
2936                        }
2937                } catch (Throwable e) {
2938                        logger.error("analyze sql failed.", e);
2939                        ErrorInfo errorInfo = new ErrorInfo();
2940                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
2941                        if (e.getMessage() == null) {
2942                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
2943                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
2944                                } else {
2945                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
2946                                }
2947                        } else {
2948                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
2949                        }
2950                        errorInfo.fillInfo(this);
2951                        errorInfos.add(errorInfo);
2952                }
2953
2954        }
2955
2956        private boolean hasDb2ReturnStmt(TCreateFunctionStmt stmt) {
2957                if (stmt.getReturnStmt() != null) {
2958                        return true;
2959                }
2960                if (stmt.getBodyStatements() != null) {
2961                        for (int i = 0; i < stmt.getBodyStatements().size(); i++) {
2962                                if(stmt.getBodyStatements().get(i) instanceof TDb2ReturnStmt) {
2963                                        return true;
2964                                }
2965                        }
2966                }
2967                return false;
2968        }
2969
2970        private void analyzeCustomSqlStmt(TCustomSqlStatement stmt) {
2971                if (!accessedStatements.contains(stmt)) {
2972                        accessedStatements.add(stmt);
2973                } else if (!(stmt instanceof TUseDatabase || stmt instanceof TUseSchema)) {
2974                        return;
2975                }
2976
2977                ArrayList<TSyntaxError> errors = stmt.getSyntaxHints();
2978                if (errors != null && !errors.isEmpty()) {
2979                        for (int i = 0; i < errors.size(); i++) {
2980                                TSyntaxError error = errors.get(i);
2981                                ErrorInfo errorInfo = new ErrorInfo();
2982                                errorInfo.setErrorType(ErrorInfo.SYNTAX_HINT);
2983                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_HINT));
2984                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
2985                                                ModelBindingManager.getGlobalHash()));
2986                                String[] segments = error.tokentext.split("\n");
2987                                if (segments.length == 1) {
2988                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
2989                                                        error.columnNo + error.tokentext.length(), ModelBindingManager.getGlobalHash()));
2990                                } else {
2991                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
2992                                                        (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()));
2993                                }
2994                                errorInfo.fillInfo(this);
2995                                errorInfos.add(errorInfo);
2996                        }
2997                }
2998
2999                if (option.getAnalyzeMode() == AnalyzeMode.dynamic) {
3000                        if (!(stmt instanceof TStoredProcedureSqlStatement
3001                                        || stmt instanceof TExecuteSqlStatement
3002                                        || stmt instanceof TMssqlExecute
3003                                        || stmt instanceof TExecImmeStmt)) {
3004                                return;
3005                        }
3006                }
3007
3008                if(DlineageUtil.getTopStmt(stmt) == stmt){
3009                        modelManager.collectSqlHash(stmt);
3010                }
3011
3012                try {
3013                        if (stmt instanceof TUseDatabase) {
3014                                if (((TUseDatabase) stmt).getDatabaseName() != null) {
3015                                        ModelBindingManager.setGlobalDatabase(((TUseDatabase) stmt).getDatabaseName().toString());
3016                                }
3017                        } else if (stmt instanceof TUseSchema) {
3018                                if (((TUseSchema) stmt).getSchemaName() != null) {
3019                                        String schemaName = ((TUseSchema) stmt).getSchemaName().toString();
3020                                        List<String> splits = SQLUtil.parseNames(schemaName);
3021                                        if (splits.size() == 1) {
3022                                                ModelBindingManager.setGlobalSchema(schemaName);
3023                                        } else if (splits.size() > 1) {
3024                                                ModelBindingManager.setGlobalSchema(splits.get(splits.size() - 1));
3025                                                ModelBindingManager.setGlobalDatabase(splits.get(splits.size() - 2));
3026                                        }
3027                                }
3028                        } else if (stmt instanceof TPlsqlRecordTypeDefStmt) {
3029                                this.stmtStack.push(stmt);
3030                                this.analyzePlsqlRecordTypeDefStmt((TPlsqlRecordTypeDefStmt) stmt);
3031                                this.stmtStack.pop();
3032                        } else if (stmt instanceof TPlsqlTableTypeDefStmt) {
3033                                this.stmtStack.push(stmt);
3034                                this.analyzePlsqlTableTypeDefStmt((TPlsqlTableTypeDefStmt) stmt);
3035                                this.stmtStack.pop();
3036                        } else if (stmt instanceof TStoredProcedureSqlStatement) {
3037                                this.stmtStack.push(stmt);
3038                                this.analyzeStoredProcedureStmt((TStoredProcedureSqlStatement) stmt);
3039                                this.stmtStack.pop();
3040                        } else if (stmt instanceof TCreateTableSqlStatement) {
3041                                stmtStack.push(stmt);
3042                                analyzeCreateTableStmt((TCreateTableSqlStatement) stmt);
3043                                stmtStack.pop();
3044                        } else if (stmt instanceof TCreateStageStmt) {
3045                                stmtStack.push(stmt);
3046                                analyzeCreateStageStmt((TCreateStageStmt) stmt);
3047                                stmtStack.pop();
3048                        } else if (stmt instanceof TCreateExternalDataSourceStmt) {
3049                                stmtStack.push(stmt);
3050                                analyzeCreateExternalDataSourceStmt((TCreateExternalDataSourceStmt) stmt);
3051                                stmtStack.pop();
3052                        } else if (stmt instanceof TCreateStreamStmt) {
3053                                stmtStack.push(stmt);
3054                                analyzeCreateStreamStmt((TCreateStreamStmt) stmt);
3055                                stmtStack.pop();
3056                        } else if (stmt instanceof TSelectSqlStatement) {
3057                                analyzeSelectStmt((TSelectSqlStatement) stmt);
3058                        } else if (stmt instanceof TDropTableSqlStatement) {
3059                                stmtStack.push(stmt);
3060                                analyzeDropTableStmt((TDropTableSqlStatement) stmt);
3061                                stmtStack.pop();
3062                        } else if (stmt instanceof TTruncateStatement) {
3063                                stmtStack.push(stmt);
3064                                analyzeTruncateTableStmt((TTruncateStatement) stmt);
3065                                stmtStack.pop();
3066                        } else if (stmt instanceof TCreateMaterializedSqlStatement) {
3067                                stmtStack.push(stmt);
3068                                TCreateMaterializedSqlStatement view = (TCreateMaterializedSqlStatement) stmt;
3069                                analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName());
3070                                stmtStack.pop();
3071                        } else if (stmt instanceof TCreateViewSqlStatement) {
3072                                stmtStack.push(stmt);
3073                                TCreateViewSqlStatement view = (TCreateViewSqlStatement) stmt;
3074                                analyzeCreateViewStmt(view, view.getSubquery(), view.getViewAliasClause(), view.getViewName());
3075                                stmtStack.pop();
3076                        } else if(stmt instanceof TDb2SqlVariableDeclaration){
3077                                stmtStack.push(stmt);
3078                                analyzeDb2Declare((TDb2SqlVariableDeclaration)stmt);
3079                                stmtStack.pop();
3080                        } else if (stmt instanceof TMssqlCreateType) {
3081                                stmtStack.push(stmt);
3082                                TMssqlCreateType createType = (TMssqlCreateType) stmt;
3083                                analyzeMssqlCreateType(createType);
3084                                stmtStack.pop();
3085                        } else if (stmt instanceof TMssqlDeclare) {
3086                                stmtStack.push(stmt);
3087                                TMssqlDeclare declare = (TMssqlDeclare) stmt;
3088                                analyzeMssqlDeclare(declare);
3089                                stmtStack.pop();
3090                        } else if (stmt instanceof TInsertSqlStatement) {
3091                                stmtStack.push(stmt);
3092                                TInsertSqlStatement insert = (TInsertSqlStatement)stmt;
3093                                analyzeInsertStmt(insert);
3094                                if(insert.getMultiInsertStatements()!=null) {
3095                                        for(int i=0;i<insert.getMultiInsertStatements().size();i++) {
3096                                                analyzeInsertStmt(insert.getMultiInsertStatements().get(i));
3097                                        }
3098                                }
3099                                stmtStack.pop();
3100                        } else if (stmt instanceof TRedshiftCopy) {
3101                                stmtStack.push(stmt);
3102                                analyzeRedshiftCopyStmt((TRedshiftCopy) stmt);
3103                                stmtStack.pop();
3104                        } else if (stmt instanceof TSnowflakeCopyIntoStmt) {
3105                                stmtStack.push(stmt);
3106                                analyzeCopyIntoStmt((TSnowflakeCopyIntoStmt) stmt);
3107                                stmtStack.pop();
3108                        } else if (stmt instanceof TUnloadStmt) {
3109                                stmtStack.push(stmt);
3110                                analyzeUnloadStmt((TUnloadStmt) stmt);
3111                                stmtStack.pop();
3112                        } else if (stmt instanceof TUpdateSqlStatement) {
3113                                stmtStack.push(stmt);
3114                                analyzeUpdateStmt((TUpdateSqlStatement) stmt);
3115                                stmtStack.pop();
3116                        } else if (stmt instanceof TMergeSqlStatement) {
3117                                stmtStack.push(stmt);
3118                                analyzeMergeStmt((TMergeSqlStatement) stmt);
3119                                stmtStack.pop();
3120                        } else if (stmt instanceof TDeleteSqlStatement) {
3121                                stmtStack.push(stmt);
3122                                analyzeDeleteStmt((TDeleteSqlStatement) stmt);
3123                                stmtStack.pop();
3124                        } else if (stmt instanceof TCursorDeclStmt) {
3125                                stmtStack.push(stmt);
3126                                analyzeCursorDeclStmt((TCursorDeclStmt) stmt);
3127                                stmtStack.pop();
3128                        } else if (stmt instanceof TFetchStmt) {
3129                                stmtStack.push(stmt);
3130                                analyzeFetchStmt((TFetchStmt) stmt);
3131                                stmtStack.pop();
3132                        } else if (stmt instanceof TMssqlFetch) {
3133                                stmtStack.push(stmt);
3134                                analyzeFetchStmt((TMssqlFetch) stmt);
3135                                stmtStack.pop();
3136                        } else if (stmt instanceof TForStmt) {
3137                                stmtStack.push(stmt);
3138                                analyzeForStmt((TForStmt) stmt);
3139                                stmtStack.pop();
3140                        } else if (stmt instanceof TOpenforStmt) {
3141                                stmtStack.push(stmt);
3142                                analyzeOpenForStmt((TOpenforStmt) stmt);
3143                                stmtStack.pop();
3144                        } else if (stmt instanceof TLoopStmt) {
3145                                stmtStack.push(stmt);
3146                                analyzeLoopStmt((TLoopStmt) stmt);
3147                                stmtStack.pop();
3148                        } else if (stmt instanceof TAssignStmt) {
3149                                stmtStack.push(stmt);
3150                                analyzeAssignStmt((TAssignStmt) stmt);
3151                                stmtStack.pop();
3152                        } else if (stmt instanceof TSetStmt) {
3153                                stmtStack.push(stmt);
3154                                analyzeSetStmt((TSetStmt) stmt);
3155                                stmtStack.pop();
3156                        } else if (stmt instanceof TMssqlSet) {
3157                                stmtStack.push(stmt);
3158                                analyzeMssqlSetStmt((TMssqlSet) stmt);
3159                                stmtStack.pop();
3160                        } else if (stmt instanceof TVarDeclStmt) {
3161                                stmtStack.push(stmt);
3162                                analyzeVarDeclStmt((TVarDeclStmt) stmt);
3163                                stmtStack.pop();
3164                        } else if (stmt instanceof TCreateDatabaseSqlStatement) {
3165                                stmtStack.push(stmt);
3166                                analyzeCloneDatabaseStmt((TCreateDatabaseSqlStatement) stmt);
3167                                stmtStack.pop();
3168                        } else if (stmt instanceof TCreateSchemaSqlStatement) {
3169                                stmtStack.push(stmt);
3170                                analyzeCloneSchemaStmt((TCreateSchemaSqlStatement) stmt);
3171                                stmtStack.pop();
3172                        } else if (stmt instanceof TAlterTableStatement) {
3173                                stmtStack.push(stmt);
3174                                analyzeAlterTableStmt((TAlterTableStatement) stmt);
3175                                stmtStack.pop();
3176                        } else if (stmt instanceof TRenameStmt) {
3177                                stmtStack.push(stmt);
3178                                analyzeRenameStmt((TRenameStmt) stmt);
3179                                stmtStack.pop();
3180                        } else if (stmt instanceof TCreateSynonymStmt) {
3181                                stmtStack.push(stmt);
3182                                analyzeCreateSynonymStmt((TCreateSynonymStmt) stmt);
3183                                stmtStack.pop();
3184                        } else if (stmt instanceof TLoadDataStmt) {
3185                                stmtStack.push(stmt);
3186                                analyzeLoadDataStmt((TLoadDataStmt) stmt);
3187                                stmtStack.pop();
3188                        } else if (stmt instanceof THiveLoad) {
3189                                stmtStack.push(stmt);
3190                                analyzeHiveLoadStmt((THiveLoad) stmt);
3191                                stmtStack.pop();
3192                        } else if (stmt instanceof TDb2ReturnStmt) {
3193                                stmtStack.push(stmt);
3194                                analyzeDb2ReturnStmt((TDb2ReturnStmt) stmt);
3195                                stmtStack.pop();
3196                        } else if (stmt instanceof TReturnStmt) {
3197                                stmtStack.push(stmt);
3198                                analyzeReturnStmt((TReturnStmt) stmt);
3199                                stmtStack.pop();
3200                        } else if (stmt instanceof TMssqlReturn) {
3201                                stmtStack.push(stmt);
3202                                analyzeMssqlReturnStmt((TMssqlReturn) stmt);
3203                                stmtStack.pop();
3204                        } else if (stmt instanceof TExecuteSqlStatement) {
3205                                String sqlText = ((TExecuteSqlStatement) stmt).getPreparedSqlText();
3206                                if(sqlText == null) {
3207                                        sqlText = ((TExecuteSqlStatement) stmt).getSqlText();
3208                                }
3209                                if (sqlText != null) {
3210                                        modelManager.collectDynamicSqlHash(stmt);
3211                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3212                                        sqlparser.sqltext = SQLUtil.trimColumnStringQuote(sqlText);
3213                                        int result = sqlparser.parse();
3214                                        if (result != 0) {
3215                                                errors = sqlparser.getSyntaxErrors();
3216                                                if (errors != null && !errors.isEmpty()) {
3217                                                        for (int i = 0; i < errors.size(); i++) {
3218                                                                TSyntaxError error = errors.get(i);
3219                                                                ErrorInfo errorInfo = new ErrorInfo();
3220                                                                errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
3221                                                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
3222                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
3223                                                                                ModelBindingManager.getGlobalHash()));
3224                                                                String[] segments = error.tokentext.split("\n");
3225                                                                if (segments.length == 1) {
3226                                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
3227                                                                                        error.columnNo + error.tokentext.length(),
3228                                                                                        ModelBindingManager.getGlobalHash()));
3229                                                                } else {
3230                                                                        errorInfo.setEndPosition(
3231                                                                                        new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
3232                                                                                                        (long) segments[segments.length - 1].length() + 1,
3233                                                                                                        ModelBindingManager.getGlobalHash()));
3234                                                                }
3235                                                                errorInfo.fillInfo(this);
3236                                                                errorInfos.add(errorInfo);
3237                                                        }
3238                                                }
3239                                        } else if (sqlparser.sqlstatements != null) {
3240                                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3241                                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3242                                                }
3243                                        }
3244                                }
3245                                else if (((TExecuteSqlStatement) stmt).getStmtString() != null) {
3246                                        modelManager.collectDynamicSqlHash(stmt);
3247                                }
3248                        } else if (stmt instanceof TMssqlExecute) {
3249                                TMssqlExecute executeStmt = (TMssqlExecute)stmt;
3250                                if (executeStmt.getSqlText() != null) {
3251                                        modelManager.collectDynamicSqlHash(stmt);
3252                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3253                                        sqlparser.sqltext = ((TMssqlExecute) stmt).getSqlText();
3254                                        int result = sqlparser.parse();
3255                                        if (result != 0) {
3256                                                errors = sqlparser.getSyntaxErrors();
3257                                                if (errors != null && !errors.isEmpty()) {
3258                                                        for (int i = 0; i < errors.size(); i++) {
3259                                                                TSyntaxError error = errors.get(i);
3260                                                                ErrorInfo errorInfo = new ErrorInfo();
3261                                                                errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
3262                                                                errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
3263                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
3264                                                                                ModelBindingManager.getGlobalHash()));
3265                                                                String[] segments = error.tokentext.split("\n");
3266                                                                if (segments.length == 1) {
3267                                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
3268                                                                                        error.columnNo + error.tokentext.length(),
3269                                                                                        ModelBindingManager.getGlobalHash()));
3270                                                                } else {
3271                                                                        errorInfo.setEndPosition(
3272                                                                                        new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
3273                                                                                                        (long) segments[segments.length - 1].length() + 1,
3274                                                                                                        ModelBindingManager.getGlobalHash()));
3275                                                                }
3276                                                                errorInfo.fillInfo(this);
3277                                                                errorInfos.add(errorInfo);
3278                                                        }
3279                                                }
3280                                        } else if (sqlparser.sqlstatements != null) {
3281                                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3282                                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3283                                                }
3284                                        }
3285                                } else if (executeStmt.getModuleName() != null) {
3286                                        stmtStack.push(stmt);
3287                                        analyzeMssqlExecute(executeStmt);
3288                                        stmtStack.pop();
3289                                }
3290                        } else if (stmt instanceof TExecImmeStmt) {
3291                                TExecImmeStmt execImmeStmt = (TExecImmeStmt) stmt;
3292                                modelManager.collectDynamicSqlHash(stmt);
3293                                synchronized (DataFlowAnalyzer.class) {
3294                                        TStatementList stmts = execImmeStmt.getDynamicStatements();
3295                                        if (stmts != null && stmts.size() > 0) {
3296                                                for (int i = 0; i < stmts.size(); i++) {
3297                                                        analyzeCustomSqlStmt(stmts.get(i));
3298                                                }
3299                                        }
3300
3301                                        String dynamicSql = execImmeStmt.getDynamicSQL();
3302                                        if (!SQLUtil.isEmpty(dynamicSql)) {
3303                                                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
3304                                                sqlparser.sqltext = dynamicSql;
3305                                                int result = sqlparser.parse();
3306                                                if (result != 0) {
3307                                                        errors = sqlparser.getSyntaxErrors();
3308                                                        if (errors != null && !errors.isEmpty()) {
3309                                                                for (int i = 0; i < errors.size(); i++) {
3310                                                                        TSyntaxError error = errors.get(i);
3311                                                                        ErrorInfo errorInfo = new ErrorInfo();
3312                                                                        errorInfo.setErrorType(ErrorInfo.SYNTAX_ERROR);
3313                                                                        errorInfo.setErrorMessage(getErrorMessage(error, ErrorInfo.SYNTAX_ERROR));
3314                                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(error.lineNo, error.columnNo,
3315                                                                                        ModelBindingManager.getGlobalHash()));
3316                                                                        String[] segments = error.tokentext.split("\n");
3317                                                                        if (segments.length == 1) {
3318                                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(error.lineNo,
3319                                                                                                error.columnNo + error.tokentext.length(),
3320                                                                                                ModelBindingManager.getGlobalHash()));
3321                                                                        } else {
3322                                                                                errorInfo.setEndPosition(
3323                                                                                                new Pair3<Long, Long, String>(error.lineNo + segments.length - 1,
3324                                                                                                                (long) segments[segments.length - 1].length() + 1,
3325                                                                                                                ModelBindingManager.getGlobalHash()));
3326                                                                        }
3327                                                                        errorInfo.fillInfo(this);
3328                                                                        errorInfos.add(errorInfo);
3329                                                                }
3330                                                        }
3331                                                } else if (sqlparser.sqlstatements != null) {
3332                                                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
3333                                                                analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
3334                                                        }
3335                                                }
3336                                        }
3337                                }
3338                        } else if (stmt instanceof TCallStatement) {
3339                                TCallStatement callStmt = (TCallStatement)stmt;
3340                                stmtStack.push(stmt);
3341                                analyzeCallStmt(callStmt);
3342                                stmtStack.pop();
3343                        } else if (stmt instanceof TBasicStmt) {
3344                                TBasicStmt oracleBasicStmt = (TBasicStmt) stmt;
3345                                stmtStack.push(stmt);
3346                                analyzeOracleBasicStmt(oracleBasicStmt);
3347                                stmtStack.pop();
3348                        } else if (stmt instanceof TIfStmt) {
3349                                TIfStmt ifStmt = (TIfStmt) stmt;
3350                                stmtStack.push(stmt);
3351                                analyzeIfStmt(ifStmt);
3352                                stmtStack.pop();
3353                        } else if (stmt instanceof TElsifStmt) {
3354                                TElsifStmt elsIfStmt = (TElsifStmt) stmt;
3355                                stmtStack.push(stmt);
3356                                analyzeElsIfStmt(elsIfStmt);
3357                                stmtStack.pop();
3358                        } else if (stmt.getStatements() != null && stmt.getStatements().size() > 0) {
3359                                for (int i = 0; i < stmt.getStatements().size(); i++) {
3360                                        analyzeCustomSqlStmt(stmt.getStatements().get(i));
3361                                }
3362                        } else if (stmt instanceof TCreateIndexSqlStatement) {
3363                                stmtStack.push(stmt);
3364                                analyzeCreateIndexStageStmt((TCreateIndexSqlStatement) stmt);
3365                                stmtStack.pop();
3366                        }
3367                } catch (Exception e) {
3368            StringBuffer errorMessage = new StringBuffer();
3369            errorMessage.append("analyze sql stmt failed, ");
3370            if (stmt.getStartToken() != null) {
3371                errorMessage.append("line: " + stmt.getStartToken().lineNo + ", column: " + stmt.getStartToken().columnNo).append(", ");
3372            }
3373            if (stmt.getGsqlparser() != null && !SQLUtil.isEmpty(stmt.getGsqlparser().sqlfilename)) {
3374                errorMessage.append("file: "+ stmt.getGsqlparser().sqlfilename).append(", ");
3375            }
3376            if (stmt.toString() != null) {
3377                errorMessage.append("sql:\n" + stmt.toString());
3378            }
3379            logger.error(errorMessage.toString(), e);
3380                        ErrorInfo errorInfo = new ErrorInfo();
3381                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
3382                        if (e.getMessage() == null) {
3383                                if (e.getStackTrace() != null && e.getStackTrace().length > 0) {
3384                                        errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getStackTrace()[0].toString());
3385                                } else {
3386                                        errorInfo.setErrorMessage(e.getClass().getSimpleName());
3387                                }
3388                        } else {
3389                                errorInfo.setErrorMessage(e.getClass().getSimpleName() + ": " + e.getMessage());
3390                        }
3391                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
3392                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
3393                        String[] segments = stmt.getEndToken().getAstext().split("\n", -1);
3394                        if (segments.length == 1) {
3395                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
3396                                                stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
3397                                                ModelBindingManager.getGlobalHash()));
3398                        } else {
3399                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo + segments.length - 1,
3400                                                (long) segments[segments.length - 1].length() + 1, ModelBindingManager.getGlobalHash()));
3401                        }
3402                        errorInfo.fillInfo(this);
3403                        errorInfos.add(errorInfo);
3404                }
3405        }
3406
3407        private void analyzePlsqlRecordTypeDefStmt(TPlsqlRecordTypeDefStmt stmt) {
3408                TObjectName typeName = stmt.getTypeName();
3409                Variable variable = modelFactory.createVariable(typeName);
3410                variable.setSubType(SubType.record_type);
3411        
3412                if (stmt.getFieldDeclarations() != null) {
3413                        for (int i = 0; i < stmt.getFieldDeclarations().size(); i++) {
3414                                TParameterDeclaration param = stmt.getFieldDeclarations().getParameterDeclarationItem(i);
3415                                String dataTypeName = param.getDataType().getDataTypeName();
3416                                TObjectName columnName = param.getParameterName();      
3417                                TableColumn variableProperty = modelFactory.createTableColumn(variable, columnName, true);
3418                                if(dataTypeName.indexOf(".")!=-1) {
3419                                        String tableName = dataTypeName.substring(0, dataTypeName.lastIndexOf("."));
3420                                        Table table = modelFactory.createTableByName(tableName, true);
3421                                        if(table!=null) {
3422                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(table, dataTypeName);
3423                                                if (tableColumn != null) {
3424                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3425                                                        relation.setEffectType(EffectType.rowtype);
3426                                                        relation.setTarget(new TableColumnRelationshipElement(variableProperty));
3427                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
3428                                                }
3429                                        }
3430                                }
3431                        }
3432                        variable.setDetermined(true);
3433                }
3434                else {
3435                        TObjectName starColumn = new TObjectName();
3436                        starColumn.setString("*");
3437                }
3438        }
3439        
3440        private void analyzePlsqlTableTypeDefStmt(TPlsqlTableTypeDefStmt stmt) {
3441                TTypeName typeName = stmt.getElementDataType();
3442                if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) {
3443                        Variable cursorVariable = modelFactory.createVariable(stmt.getTypeName());
3444                        cursorVariable.setSubType(SubType.record_type);
3445
3446                        Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false);
3447                        if(!variableTable.isCreateTable()) {
3448                                TObjectName starColumn1 = new TObjectName();
3449                                starColumn1.setString("*");
3450                                TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true);
3451                                variableTableStarColumn.setShowStar(false);
3452                                variableTableStarColumn.setExpandStar(true);
3453
3454                                TObjectName starColumn = new TObjectName();
3455                                starColumn.setString("*");
3456                                TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
3457                                variableProperty.setShowStar(false);
3458                                variableProperty.setExpandStar(true);
3459
3460                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3461                                dataflowRelation.setEffectType(EffectType.rowtype);
3462                                dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn));
3463                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
3464                        } else {
3465                                for (TableColumn sourceColumn : variableTable.getColumns()) {
3466                                        String columnName = sourceColumn.getName();
3467                                        TObjectName targetColumn = new TObjectName();
3468                                        targetColumn.setString(columnName);
3469                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true);
3470                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
3471                                        dataflowRelation.setEffectType(EffectType.rowtype);
3472                                        dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn));
3473                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
3474                                }
3475                        }
3476                } 
3477        }
3478
3479        private void analyzeMssqlCreateType(TMssqlCreateType createType) {
3480
3481        }
3482
3483        private void analyzeMssqlExecute(TMssqlExecute executeStmt) {
3484                if (executeStmt.getModuleName() != null) {
3485                        TObjectName module = executeStmt.getModuleName();
3486                        if(module.toString().toLowerCase().endsWith("sp_rename")) {
3487                                String oldTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString());        
3488                                Table oldNameTableModel = modelFactory.createTableByName(oldTableName, true);
3489                                List<String> oldTableNames = SQLUtil.parseNames(oldNameTableModel.getName());
3490                                TObjectName oldStarColumn = new TObjectName();
3491                                oldStarColumn.setString("*");
3492                                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
3493                                
3494                                String newTableName = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(1).toString());
3495                                List<String> newTableNames = SQLUtil.parseNames(newTableName);
3496                                if (oldTableNames.size() > newTableNames.size()) {
3497                                        for (int i = oldTableNames.size() - newTableNames.size() - 1; i >= 0; i--) {
3498                                                newTableName = (oldTableNames.get(i) + ".") + newTableName;
3499                                        }
3500                                }
3501
3502                                Table newNameTableModel = modelFactory.createTableByName(newTableName, true);
3503                                TObjectName newStarColumn = new TObjectName();
3504                                newStarColumn.setString("*");
3505                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true);
3506                                
3507                                Process process = modelFactory.createProcess(executeStmt);
3508                                newNameTableModel.addProcess(process);
3509                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
3510                                relation.setEffectType(EffectType.rename_table);
3511                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
3512                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
3513                                relation.setProcess(process);
3514                                
3515                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
3516                                        oldTableStarColumn.setShowStar(false);
3517                                        relation.setShowStarRelation(false);
3518                                }
3519
3520                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
3521                                        newTableStarColumn.setShowStar(false);
3522                                        relation.setShowStarRelation(false);
3523                                }
3524                        }
3525                        else if(module.toString().toLowerCase().endsWith("sp_executesql")) {
3526                                String sql = SQLUtil.trimColumnStringQuote(executeStmt.getParameters().getExecParameter(0).toString()); 
3527                                if(sql.startsWith("N")) {
3528                                        sql =  SQLUtil.trimColumnStringQuote(sql.substring(1));
3529                                }
3530                                executeDynamicSql(sql);
3531                        }
3532                        else {
3533                                int argumentSize = executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size();
3534                                String procedureNameWithArgSize = module.toString() + "(" + argumentSize + ")";
3535                                if (argumentSize <= 0  || !DlineageUtil.supportFunctionOverride(option.getVendor())) {
3536                                        procedureNameWithArgSize = module.toString();
3537                                }
3538                                if (procedureDDLMap.containsKey(procedureNameWithArgSize)) {
3539                                        analyzeCustomSqlStmt(procedureDDLMap.get(procedureNameWithArgSize));
3540                                }
3541                                Procedure procedure = modelFactory.createProcedureByName(module, executeStmt.getParameters() == null ? 0 : executeStmt.getParameters().size());
3542                                String procedureParent = getProcedureParentName(executeStmt);
3543                                if (procedureParent != null) {
3544                                        Procedure caller = modelManager
3545                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3546                                        if (caller != null) {
3547                                                CallRelationship callRelation = modelFactory.createCallRelation();
3548                                                callRelation.setCallObject(executeStmt);
3549                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3550                                                callRelation.addSource(new ProcedureRelationshipElement(procedure));
3551                                                if(isBuiltInFunctionName(module) || isKeyword(module)){
3552                                                        callRelation.setBuiltIn(true);
3553                                                }
3554                                        }
3555                                }
3556
3557                                if (procedure.getArguments() != null) {
3558                                        for (int i = 0; i < procedure.getArguments().size(); i++) {
3559                                                Argument argument = procedure.getArguments().get(i);
3560                                                Variable variable = modelFactory.createVariable(procedure, argument.getName(), false);
3561                                                if (variable != null) {
3562                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3563                                                                Transform transform = new Transform();
3564                                                                transform.setType(Transform.FUNCTION);
3565                                                                transform.setCode(module);
3566                                                                variable.getColumns().get(0).setTransform(transform);
3567                                                        }
3568                                                        Process process = modelFactory.createProcess(executeStmt);
3569                                                        variable.addProcess(process);
3570                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), executeStmt, argument.getName(), i, process);
3571                                                }
3572                                        }
3573                                }
3574                        }
3575                }
3576        }
3577
3578        private void analyzeDropTableStmt(TDropTableSqlStatement stmt) {
3579                TTable dropTable = stmt.getTargetTable();
3580                if(dropTable == null) {
3581                        return;
3582                }
3583                Table tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(dropTable.getTableName().toString()));
3584                if(tableModel!=null) {
3585                        modelManager.dropTable(tableModel);
3586                }
3587                
3588                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
3589                        tableModel = modelFactory.createTable(dropTable);
3590                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
3591                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
3592                        crudRelationship.setEffectType(EffectType.drop_table);
3593                }
3594        }
3595        
3596        private void analyzeTruncateTableStmt(TTruncateStatement stmt) {
3597                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
3598                        TObjectName table = stmt.getTableName();
3599                        Table tableModel = modelFactory.createTableByName(table);
3600                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
3601                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
3602                        crudRelationship.setEffectType(EffectType.truncate_table);
3603                }
3604        }
3605
3606        private void analyzeCallStmt(TCallStatement callStmt) {
3607                if (callStmt.getRoutineExpr() != null && callStmt.getRoutineExpr().getFunctionCall() != null) {
3608
3609                        TFunctionCall functionCall = callStmt.getRoutineExpr().getFunctionCall();
3610                        Procedure callee = modelManager.getProcedureByName(
3611                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3612                        if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3613                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3614                                callee = modelManager.getProcedureByName(DlineageUtil
3615                                                .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3616                        }
3617                        if (callee != null) {
3618                                String procedureParent = getProcedureParentName(callStmt);
3619                                if (procedureParent != null) {
3620                                        Procedure caller = modelManager
3621                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3622                                        if (caller != null) {
3623                                                CallRelationship callRelation = modelFactory.createCallRelation();
3624                                                callRelation.setCallObject(callStmt);
3625                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3626                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3627                                                if (isBuiltInFunctionName(functionCall.getFunctionName())
3628                                                                || isKeyword(functionCall.getFunctionName())) {
3629                                                        callRelation.setBuiltIn(true);
3630                                                }
3631                                        }
3632                                }
3633                                if (callee.getArguments() != null) {
3634                                        for (int i = 0; i < callee.getArguments().size(); i++) {
3635                                                Argument argument = callee.getArguments().get(i);
3636                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3637                                                if (variable != null) {
3638                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3639                                                                Transform transform = new Transform();
3640                                                                transform.setType(Transform.FUNCTION);
3641                                                                transform.setCode(functionCall);
3642                                                                variable.getColumns().get(0).setTransform(transform);
3643                                                        }
3644                                                        Process process = modelFactory.createProcess(callStmt);
3645                                                        variable.addProcess(process);
3646                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i,
3647                                                                        process);
3648                                                }
3649                                        }
3650                                }
3651                        } else {
3652                                Function function = (Function) createFunction(functionCall);
3653                                String procedureParent = getProcedureParentName(callStmt);
3654                                if (procedureParent != null) {
3655                                        Procedure caller = modelManager
3656                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3657                                        if (caller != null) {
3658                                                CallRelationship callRelation = modelFactory.createCallRelation();
3659                                                callRelation.setCallObject(callStmt);
3660                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3661                                                callRelation.addSource(new FunctionRelationshipElement(function));
3662                                                if (isBuiltInFunctionName(functionCall.getFunctionName())
3663                                                                || isKeyword(functionCall.getFunctionName())) {
3664                                                        callRelation.setBuiltIn(true);
3665                                                }
3666                                        }
3667                                }
3668                        }
3669                }
3670                else if (callStmt.getRoutineName() != null) {
3671                        TObjectName function = callStmt.getRoutineName();
3672                        String functionName = function.toString();
3673                        Procedure callee = modelManager.getProcedureByName(
3674                                        DlineageUtil.getIdentifierNormalTableName(functionName));
3675                        if (callee == null && procedureDDLMap.containsKey(functionName)) {
3676                                analyzeCustomSqlStmt(procedureDDLMap.get(functionName));
3677                                callee = modelManager.getProcedureByName(functionName);
3678                        }
3679                        if (callee != null) {
3680                                String procedureParent = getProcedureParentName(callStmt);
3681                                if (procedureParent != null) {
3682                                        Procedure caller = modelManager
3683                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3684                                        if (caller != null) {
3685                                                CallRelationship callRelation = modelFactory.createCallRelation();
3686                                                callRelation.setCallObject(callStmt);
3687                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3688                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3689                                                if (isBuiltInFunctionName(function)
3690                                                                || isKeyword(function)) {
3691                                                        callRelation.setBuiltIn(true);
3692                                                }
3693                                        }
3694                                }
3695                                if (callee.getArguments() != null) {
3696                                        for (int i = 0; i < callee.getArguments().size(); i++) {
3697                                                Argument argument = callee.getArguments().get(i);
3698                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3699                                                if (variable != null) {
3700                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3701                                                                Transform transform = new Transform();
3702                                                                transform.setType(Transform.FUNCTION);
3703                                                                transform.setCode(callStmt);
3704                                                                variable.getColumns().get(0).setTransform(transform);
3705                                                        }
3706                                                        Process process = modelFactory.createProcess(callStmt);
3707                                                        variable.addProcess(process);
3708                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), callStmt, i,
3709                                                                        process);
3710                                                }
3711                                        }
3712                                }
3713                        }
3714                }
3715        }
3716
3717        private boolean analyzeCustomFunctionCall(TFunctionCall functionCall) {
3718                Procedure callee = modelManager.getProcedureByName(
3719                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3720                if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3721                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3722                        callee = modelManager.getProcedureByName(
3723                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3724                }
3725                if (callee != null) {
3726                        String procedureParent = getProcedureParentName(stmtStack.peek());
3727                        if (procedureParent != null) {
3728                                Procedure caller = modelManager
3729                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3730                                if (caller != null) {
3731                                        CallRelationship callRelation = modelFactory.createCallRelation();
3732                                        callRelation.setCallObject(functionCall);
3733                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3734                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
3735                                        if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3736                                                callRelation.setBuiltIn(true);
3737                                        }
3738                                }
3739                        }
3740                        if (callee.getArguments() != null) {
3741                                for (int i = 0; i < callee.getArguments().size(); i++) {
3742                                        Argument argument = callee.getArguments().get(i);
3743                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3744                                        if(variable!=null) {
3745                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3746                                                        Transform transform = new Transform();
3747                                                        transform.setType(Transform.FUNCTION);
3748                                                        transform.setCode(functionCall);
3749                                                        variable.getColumns().get(0).setTransform(transform);
3750                                                }
3751                                                Process process = modelFactory.createProcess(functionCall);
3752                                                variable.addProcess(process);
3753                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process);
3754                                        }
3755                                }
3756                        }
3757                        return true;
3758                }
3759                return false;
3760        }
3761
3762        private void analyzeOracleBasicStmt(TBasicStmt oracleBasicStmt) {
3763                if (oracleBasicStmt.getExpr() == null || oracleBasicStmt.getExpr().getFunctionCall() == null) {
3764                        return;
3765                }
3766
3767                TFunctionCall functionCall = oracleBasicStmt.getExpr().getFunctionCall();
3768                Procedure callee = modelManager.getProcedureByName(
3769                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3770                if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3771                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3772                        callee = modelManager.getProcedureByName(
3773                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3774                }
3775                if (callee != null) {
3776                        String procedureParent = getProcedureParentName(oracleBasicStmt);
3777                        if (procedureParent != null) {
3778                                Procedure caller = modelManager
3779                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3780                                if (caller != null) {
3781                                        CallRelationship callRelation = modelFactory.createCallRelation();
3782                                        callRelation.setCallObject(functionCall);
3783                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3784                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
3785                                        if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString())
3786                                                        || (isBuiltInFunctionName(functionCall.getFunctionName())
3787                                                        || isKeyword(functionCall.getFunctionName()))) {
3788                                                callRelation.setBuiltIn(true);
3789                                        }
3790                                }
3791                        }
3792                        if (callee.getArguments() != null) {
3793                                for (int i = 0; i < callee.getArguments().size(); i++) {
3794                                        Argument argument = callee.getArguments().get(i);
3795                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3796                                        if(variable!=null) {
3797                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3798                                                        Transform transform = new Transform();
3799                                                        transform.setType(Transform.FUNCTION);
3800                                                        transform.setCode(functionCall);
3801                                                        variable.getColumns().get(0).setTransform(transform);
3802                                                }
3803                                                Process process = modelFactory.createProcess(functionCall);
3804                                                variable.addProcess(process);
3805                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, i, process);
3806                                        }
3807                                }
3808                        }
3809                } else {
3810                        Function function = modelFactory.createFunction(functionCall);
3811                        String procedureParent = getProcedureParentName(oracleBasicStmt);
3812                        if (procedureParent != null) {
3813                                Procedure caller = modelManager
3814                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3815                                if (caller != null) {
3816                                        CallRelationship callRelation = modelFactory.createCallRelation();
3817                                        callRelation.setCallObject(functionCall);
3818                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
3819                                        callRelation.addSource(new FunctionRelationshipElement(function));
3820                                        if (functionChecker.isOraclePredefinedPackageFunction(functionCall.getFunctionName().toString())
3821                                                        || (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName()))) {
3822                                                callRelation.setBuiltIn(true);
3823                                        }
3824                                }
3825                        }
3826                }
3827        }
3828
3829        private void analyzeIfStmt(TIfStmt ifStmt) {
3830                if (ifStmt.getCondition() != null) {
3831                        columnsInExpr visitor = new columnsInExpr();
3832                        ifStmt.getCondition().inOrderTraverse(visitor);
3833                        List<TParseTreeNode> functions = visitor.getFunctions();
3834
3835                        if (functions != null && !functions.isEmpty()) {
3836                                for (int i = 0; i < functions.size(); i++) {
3837                                        if (!(functions.get(i) instanceof TFunctionCall))
3838                                                continue;
3839                                        TFunctionCall functionCall = (TFunctionCall) functions.get(i);
3840                                        Procedure callee = modelManager.getProcedureByName(DlineageUtil
3841                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3842                                        if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3843                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3844                                                callee = modelManager.getProcedureByName(
3845                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3846                                        }
3847                                        if (callee != null) {
3848                                                String procedureParent = getProcedureParentName(ifStmt);
3849                                                if (procedureParent != null) {
3850                                                        Procedure caller = modelManager
3851                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3852                                                        if (caller != null) {
3853                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3854                                                                callRelation.setCallObject(functionCall);
3855                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3856                                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3857                                                                if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) {
3858                                                                        callRelation.setBuiltIn(true);
3859                                                                }
3860                                                        }
3861                                                }
3862                                                if (callee.getArguments() != null) {
3863                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
3864                                                                Argument argument = callee.getArguments().get(j);
3865                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3866                                                                if(variable!=null) {
3867                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3868                                                                                Transform transform = new Transform();
3869                                                                                transform.setType(Transform.FUNCTION);
3870                                                                                transform.setCode(functionCall);
3871                                                                                variable.getColumns().get(0).setTransform(transform);
3872                                                                        }
3873                                                                        Process process = modelFactory.createProcess(functionCall);
3874                                                                        variable.addProcess(process);
3875                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
3876                                                                }
3877                                                        }
3878                                                }
3879                                        } else {
3880                                                Function function = modelFactory.createFunction(functionCall);
3881                                                String procedureParent = getProcedureParentName(ifStmt);
3882                                                if (procedureParent != null) {
3883                                                        Procedure caller = modelManager
3884                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3885                                                        if (caller != null) {
3886                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3887                                                                callRelation.setCallObject(functionCall);
3888                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3889                                                                callRelation.addSource(new FunctionRelationshipElement(function));
3890                                                                if (isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())) {
3891                                                                        callRelation.setBuiltIn(true);
3892                                                                }
3893                                                        }
3894                                                }
3895                                        }
3896                                }
3897                        }
3898                }
3899
3900                if (ifStmt.getThenStatements() != null) {
3901                        for (int i = 0; i < ifStmt.getThenStatements().size(); ++i) {
3902                                analyzeCustomSqlStmt(ifStmt.getThenStatements().get(i));
3903                                ResultSet returnResult = modelFactory.createResultSet(ifStmt.getThenStatements().get(i), false);
3904                                if(returnResult!=null){
3905                                        for(ResultColumn resultColumn: returnResult.getColumns()){
3906                                                analyzeFilterCondition(resultColumn, ifStmt.getCondition(), null, null, EffectType.function);
3907                                        }
3908                                }
3909                        }
3910                }
3911
3912                if (ifStmt.getElseifStatements() != null) {
3913                        for (int i = 0; i < ifStmt.getElseifStatements().size(); ++i) {
3914                                analyzeCustomSqlStmt(ifStmt.getElseifStatements().get(i));
3915                        }
3916                }
3917
3918                if (ifStmt.getElseStatements() != null) {
3919                        for (int i = 0; i < ifStmt.getElseStatements().size(); ++i) {
3920                                analyzeCustomSqlStmt(ifStmt.getElseStatements().get(i));
3921                        }
3922                }
3923        }
3924
3925        private void analyzeElsIfStmt(TElsifStmt elsIfStmt) {
3926                if (elsIfStmt.getCondition() != null) {
3927                        columnsInExpr visitor = new columnsInExpr();
3928                        elsIfStmt.getCondition().inOrderTraverse(visitor);
3929                        List<TParseTreeNode> functions = visitor.getFunctions();
3930
3931                        if (functions != null && !functions.isEmpty()) {
3932                                for (int i = 0; i < functions.size(); i++) {
3933                                        if (!(functions.get(i) instanceof TFunctionCall))
3934                                                continue;
3935                                        TFunctionCall functionCall = (TFunctionCall) functions.get(i);
3936                                        Procedure callee = modelManager.getProcedureByName(DlineageUtil
3937                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3938                                        if(callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
3939                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3940                                                callee = modelManager.getProcedureByName(
3941                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
3942                                        }
3943                                        if (callee != null) {
3944                                                String procedureParent = getProcedureParentName(elsIfStmt);
3945                                                if (procedureParent != null) {
3946                                                        Procedure caller = modelManager
3947                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3948                                                        if (caller != null) {
3949                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3950                                                                callRelation.setCallObject(functionCall);
3951                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3952                                                                callRelation.addSource(new ProcedureRelationshipElement(callee));
3953                                                                if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3954                                                                        callRelation.setBuiltIn(true);
3955                                                                }
3956                                                        }
3957                                                }
3958                                                if (callee.getArguments() != null) {
3959                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
3960                                                                Argument argument = callee.getArguments().get(j);
3961                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
3962                                                                if(variable!=null) {
3963                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
3964                                                                                Transform transform = new Transform();
3965                                                                                transform.setType(Transform.FUNCTION);
3966                                                                                transform.setCode(functionCall);
3967                                                                                variable.getColumns().get(0).setTransform(transform);
3968                                                                        }
3969                                                                        Process process = modelFactory.createProcess(functionCall);
3970                                                                        variable.addProcess(process);
3971                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
3972                                                                }
3973                                                        }
3974                                                }
3975                                        } else {
3976                                                Function function = modelFactory.createFunction(functionCall);
3977                                                String procedureParent = getProcedureParentName(elsIfStmt);
3978                                                if (procedureParent != null) {
3979                                                        Procedure caller = modelManager
3980                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
3981                                                        if (caller != null) {
3982                                                                CallRelationship callRelation = modelFactory.createCallRelation();
3983                                                                callRelation.setCallObject(functionCall);
3984                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
3985                                                                callRelation.addSource(new FunctionRelationshipElement(function));
3986                                                                if(isBuiltInFunctionName(functionCall.getFunctionName()) || isKeyword(functionCall.getFunctionName())){
3987                                                                        callRelation.setBuiltIn(true);
3988                                                                }
3989                                                        }
3990                                                }
3991                                        }
3992                                }
3993                        }
3994                }
3995
3996                if (elsIfStmt.getThenStatements() != null) {
3997                        for (int i = 0; i < elsIfStmt.getThenStatements().size(); ++i) {
3998                                ResultSet returnResult = modelFactory.createResultSet(elsIfStmt.getThenStatements().get(i), false);
3999                                if (returnResult != null) {
4000                                        for (ResultColumn resultColumn : returnResult.getColumns()) {
4001                                                analyzeFilterCondition(resultColumn, elsIfStmt.getCondition(), null, null, EffectType.function);
4002                                        }
4003                                }
4004                                analyzeCustomSqlStmt(elsIfStmt.getThenStatements().get(i));
4005                        }
4006                }
4007        }
4008
4009        private void analyzeCloneTableStmt(TCreateTableSqlStatement stmt) {
4010                if (stmt.getCloneSourceTable() != null) {
4011                        Table sourceTable = modelFactory.createTableByName(stmt.getCloneSourceTable());
4012                        Table cloneTable = modelFactory.createTableByName(stmt.getTableName());
4013                        Process process = modelFactory.createProcess(stmt);
4014                        cloneTable.addProcess(process);
4015
4016                        if (sourceTable.isDetermined()) {
4017                                for (int k = 0; k < sourceTable.getColumns().size(); k++) {
4018                                        TableColumn sourceColumn = sourceTable.getColumns().get(k);
4019                                        TObjectName objectName = new TObjectName();
4020                                        objectName.setString(sourceColumn.getName());
4021                                        TableColumn tableColumn = modelFactory.createTableColumn(cloneTable, objectName, true);
4022                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4023                                        dataflowRelation.setEffectType(EffectType.clone_table);
4024                                        dataflowRelation
4025                                                        .addSource(new TableColumnRelationshipElement(sourceColumn));
4026                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
4027                                        dataflowRelation.setProcess(process);
4028                                }
4029                                cloneTable.setDetermined(true);
4030                                cloneTable.setFromDDL(true);
4031                        } else {
4032                                TObjectName sourceName = new TObjectName();
4033                                sourceName.setString("*");
4034                                TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceName, false);
4035                                TObjectName targetName = new TObjectName();
4036                                targetName.setString("*");
4037                                TableColumn targetTableColumn = modelFactory.createTableColumn(cloneTable, targetName, false);
4038                                if(sourceTableColumn!=null && targetTableColumn!=null) {
4039                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4040                                        dataflowRelation.setEffectType(EffectType.clone_table);
4041                                        dataflowRelation
4042                                                        .addSource(new TableColumnRelationshipElement(sourceTableColumn));
4043                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
4044                                        dataflowRelation.setProcess(process);
4045                                }
4046                        }
4047                }
4048        }
4049
4050        private void analyzeCloneDatabaseStmt(TCreateDatabaseSqlStatement stmt) {
4051                if (stmt.getCloneSourceDb() != null) {
4052                        Database sourceDatabase = modelFactory.createDatabase(stmt.getCloneSourceDb());
4053                        Database cloneDatabase = modelFactory.createDatabase(stmt.getDatabaseName());
4054                        Process process = modelFactory.createProcess(stmt);
4055                        cloneDatabase.addProcess(process);
4056                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4057                        relation.setEffectType(EffectType.clone_database);
4058                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneDatabase.getRelationRows()));
4059                        relation.addSource(
4060                                        new RelationRowsRelationshipElement<TableRelationRows>(sourceDatabase.getRelationRows()));
4061                        relation.setProcess(process);
4062                }
4063        }
4064
4065        private void analyzeCloneSchemaStmt(TCreateSchemaSqlStatement stmt) {
4066                if (stmt.getCloneSourceSchema() != null) {
4067                        Schema sourceSchema = modelFactory.createSchema(stmt.getCloneSourceSchema());
4068                        Schema cloneSchema = modelFactory.createSchema(stmt.getSchemaName());
4069                        Process process = modelFactory.createProcess(stmt);
4070                        cloneSchema.addProcess(process);
4071                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4072                        relation.setEffectType(EffectType.clone_schema);
4073                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(cloneSchema.getRelationRows()));
4074                        relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(sourceSchema.getRelationRows()));
4075                        relation.setProcess(process);
4076                }
4077        }
4078
4079        private void executeDynamicSql(String sql) {
4080                TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
4081                sqlparser.sqltext = sql;
4082                int result = sqlparser.parse();
4083                if (result == 0) {
4084                        for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
4085                                analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
4086                        }
4087                }
4088        }
4089
4090        private void extractSnowflakeSQLFromProcedure(TCreateProcedureStmt procedure) {
4091                Map<String, String> argMap = new LinkedHashMap<String, String>();
4092                if (procedure.getParameterDeclarations() != null) {
4093                        for (int i = 0; i < procedure.getParameterDeclarations().size(); i++) {
4094                                TParameterDeclaration def = procedure.getParameterDeclarations().getParameterDeclarationItem(i);
4095                                argMap.put(def.getParameterName().toString(), def.getDataType().getDataTypeName());
4096                        }
4097                }
4098                StringBuilder buffer = new StringBuilder();
4099                buffer.append("(function(");
4100                String[] args = argMap.keySet().toArray(new String[0]);
4101                for (int i = 0; i < args.length; i++) {
4102                        buffer.append(args[i].toUpperCase());
4103                        if (i < args.length - 1) {
4104                                buffer.append(",");
4105                        }
4106                }
4107                buffer.append("){\n");
4108
4109                int start = -1;
4110                int end = -1;
4111                boolean dollar = false;
4112                boolean quote = false;
4113                if (procedure.getRoutineBody().indexOf("$$") != -1) {
4114                        start = procedure.getRoutineBody().indexOf("$$") + 2;
4115                        end = procedure.getRoutineBody().lastIndexOf("$$") - 1;
4116                        dollar = true;
4117                } else if (procedure.getRoutineBody().indexOf("'") != -1) {
4118                        start = procedure.getRoutineBody().indexOf("'") + 1;
4119                        end = procedure.getRoutineBody().lastIndexOf("'");
4120                        quote = true;
4121                }
4122                String body = procedure.getRoutineBody().substring(start, end);
4123                if (dollar && body.indexOf("`") != -1) {
4124                        Pattern pattern = Pattern.compile("`.+?`", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
4125                        Matcher matcher = pattern.matcher(body);
4126                        StringBuffer replaceBuffer = new StringBuffer();
4127                        while (matcher.find()) {
4128                                String condition = matcher.group().replace("\r\n", "\n").replace("'", "\\\\'")
4129                                                .replace("\n", "\\\\n'\n+'").replace("`", "'").replace("$", "RDS_CHAR_DOLLAR");
4130                                matcher.appendReplacement(replaceBuffer, condition);
4131                        }
4132                        matcher.appendTail(replaceBuffer);
4133                        body = replaceBuffer.toString().replace("RDS_CHAR_DOLLAR", "$");
4134                }
4135                if (quote && body.indexOf("'") != -1) {
4136                        body = body.replace("''", "'");
4137                }
4138                buffer.append(body);
4139                buffer.append("})(");
4140                for (int i = 0; i < args.length; i++) {
4141                        String type = argMap.get(args[i]);
4142                        if (type.equalsIgnoreCase("VARCHAR")) {
4143                                buffer.append("'pseudo'");
4144                        } else if (type.equalsIgnoreCase("STRING")) {
4145                                buffer.append("'pseudo'");
4146                        } else if (type.equalsIgnoreCase("CHAR")) {
4147                                buffer.append("'pseudo'");
4148                        } else if (type.equalsIgnoreCase("CHARACTER")) {
4149                                buffer.append("'pseudo'");
4150                        } else if (type.equalsIgnoreCase("TEXT")) {
4151                                buffer.append("'pseudo'");
4152                        } else if (type.equalsIgnoreCase("BINARY")) {
4153                                buffer.append("'pseudo'");
4154                        } else if (type.equalsIgnoreCase("VARBINARY")) {
4155                                buffer.append("'pseudo'");
4156                        } else if (type.equalsIgnoreCase("BOOLEAN")) {
4157                                buffer.append(true);
4158                        } else if (type.equalsIgnoreCase("FLOAT")) {
4159                                buffer.append("1.0");
4160                        } else if (type.equalsIgnoreCase("FLOAT4")) {
4161                                buffer.append("1.0");
4162                        } else if (type.equalsIgnoreCase("FLOAT8")) {
4163                                buffer.append("1.0");
4164                        } else if (type.equalsIgnoreCase("DOUBLE")) {
4165                                buffer.append("1.0");
4166                        } else if (type.equalsIgnoreCase("DOUBLE PRECISION")) {
4167                                buffer.append("1.0");
4168                        } else if (type.equalsIgnoreCase("REAL")) {
4169                                buffer.append("1.0");
4170                        } else if (type.equalsIgnoreCase("NUMBER")) {
4171                                buffer.append("1.0");
4172                        } else if (type.equalsIgnoreCase("DECIMAL")) {
4173                                buffer.append("1.0");
4174                        } else if (type.equalsIgnoreCase("NUMERIC")) {
4175                                buffer.append("1.0");
4176                        } else if (type.equalsIgnoreCase("INT")) {
4177                                buffer.append("1");
4178                        } else if (type.equalsIgnoreCase("INTEGER")) {
4179                                buffer.append("1");
4180                        } else if (type.equalsIgnoreCase("BIGINT")) {
4181                                buffer.append("1");
4182                        } else if (type.equalsIgnoreCase("SMALLINT")) {
4183                                buffer.append("1");
4184                        } else if (type.equalsIgnoreCase("DATE")) {
4185                                buffer.append("new Date()");
4186                        } else if (type.equalsIgnoreCase("DATETIME")) {
4187                                buffer.append("new Date()");
4188                        } else if (type.equalsIgnoreCase("TIME")) {
4189                                buffer.append("new Date()");
4190                        } else if (type.equalsIgnoreCase("TIMESTAMP")) {
4191                                buffer.append("new Date()");
4192                        } else if (type.equalsIgnoreCase("TIMESTAMP_LTZ")) {
4193                                buffer.append("new Date()");
4194                        } else if (type.equalsIgnoreCase("TIMESTAMP_NTZ")) {
4195                                buffer.append("new Date()");
4196                        } else if (type.equalsIgnoreCase("TIMESTAMP_TZ")) {
4197                                buffer.append("new Date()");
4198                        } else if (type.equalsIgnoreCase("VARIANT")) {
4199                                buffer.append("{}");
4200                        } else if (type.equalsIgnoreCase("OBJECT")) {
4201                                buffer.append("{}");
4202                        } else if (type.equalsIgnoreCase("ARRAY")) {
4203                                buffer.append("[]");
4204                        } else if (type.equalsIgnoreCase("GEOGRAPHY")) {
4205                                buffer.append("{}");
4206                        }
4207                        if (i < args.length - 1) {
4208                                buffer.append(",");
4209                        }
4210                }
4211                buffer.append(");");
4212
4213                try {
4214                        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
4215                        ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
4216                        nashorn.put("analyzer", this);
4217                        nashorn.eval(new InputStreamReader(
4218                                        getClass().getResourceAsStream("/gudusoft/gsqlparser/parser/snowflake/snowflake.js")));
4219                        nashorn.eval(new StringReader(buffer.toString()));
4220                } catch (ScriptException e) {
4221                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
4222                        sqlparser.sqltext = body;
4223                        int result = sqlparser.parse();
4224                        if (result == 0) {
4225                                for (int i = 0; i < sqlparser.sqlstatements.size(); i++) {
4226                                        analyzeCustomSqlStmt(sqlparser.sqlstatements.get(i));
4227                                }
4228                                return;
4229                        }
4230                        ErrorInfo errorInfo = new ErrorInfo();
4231                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
4232                        errorInfo.setErrorMessage("Invoke script error: " + e.getMessage());
4233                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(procedure.getStartToken().lineNo,
4234                                        procedure.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
4235                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(procedure.getEndToken().lineNo,
4236                                        procedure.getEndToken().columnNo + procedure.getEndToken().getAstext().length(),
4237                                        ModelBindingManager.getGlobalHash()));
4238                        errorInfos.add(errorInfo);
4239                }
4240        }
4241
4242        private void analyzeHiveLoadStmt(THiveLoad stmt) {
4243                if (stmt.getPath() != null && stmt.getTable() != null) {
4244                        Table uriFile = modelFactory.createTableByName(stmt.getPath(), true);
4245                        uriFile.setPath(true);
4246                        uriFile.setCreateTable(true);
4247                        TObjectName fileUri = new TObjectName();
4248                        fileUri.setString("uri=" + stmt.getPath());
4249                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4250
4251                        Table tableModel = modelFactory.createTable(stmt.getTable());
4252                        Process process = modelFactory.createProcess(stmt);
4253                        tableModel.addProcess(process);
4254
4255                        TPartitionExtensionClause p = stmt.getTable().getPartitionExtensionClause();
4256                        if (p.getKeyValues() != null && p.getKeyValues().size() > 0) {
4257                                for (int i = 0; i < p.getKeyValues().size(); i++) {
4258                                        TExpression expression = p.getKeyValues().getExpression(i);
4259                                        if (expression.getLeftOperand().getExpressionType() == EExpressionType.simple_object_name_t) {
4260                                                modelFactory.createTableColumn(tableModel, expression.getLeftOperand().getObjectOperand(),
4261                                                                true);
4262                                        }
4263                                }
4264                        }
4265
4266                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
4267                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4268                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4269                                relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
4270                                relation.setProcess(process);
4271                        }
4272                }
4273        }
4274        
4275        private void analyzeLoadDataStmt(TLoadDataStmt stmt) {
4276                
4277        }
4278
4279        private void analyzeUnloadStmt(TUnloadStmt unloadStmt) {
4280                if (unloadStmt.getSelectSqlStatement() != null && unloadStmt.getS3() != null) {
4281
4282                        Table uriFile = modelFactory.createTableByName(unloadStmt.getS3(), true);
4283                        uriFile.setPath(true);
4284                        uriFile.setCreateTable(true);
4285                        TObjectName fileUri = new TObjectName();
4286                        fileUri.setString("uri=" + unloadStmt.getS3());
4287                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4288
4289                        Process process = modelFactory.createProcess(unloadStmt);
4290                        uriFile.addProcess(process);
4291
4292                        TCustomSqlStatement stmt = unloadStmt.getSelectSqlStatement();
4293                        analyzeCustomSqlStmt(stmt);
4294                        if (stmt instanceof TSelectSqlStatement) {
4295                                TSelectSqlStatement select = (TSelectSqlStatement) stmt;
4296                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(select);
4297                                if (resultSetModel != null) {
4298                                        for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
4299                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
4300                                                if (resultColumn.hasStarLinkColumn()
4301                                                                && resultColumn.getStarLinkColumnNames().size() > 0) {
4302                                                        for (int k = 0; k < resultColumn.getStarLinkColumnNames().size(); k++) {
4303                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(resultSetModel,
4304                                                                                resultColumn.getStarLinkColumnName(k), false);
4305                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4306                                                                dataflowRelation.setEffectType(EffectType.unload);
4307                                                                dataflowRelation
4308                                                                                .addSource(new ResultColumnRelationshipElement(expandStarColumn));
4309                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn));
4310                                                                dataflowRelation.setProcess(process);
4311                                                        }
4312                                                }
4313                                                if (!resultColumn.hasStarLinkColumn() || resultColumn.isShowStar()) {
4314                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4315                                                        dataflowRelation.setEffectType(EffectType.unload);
4316                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
4317                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(fileUriColumn));
4318                                                        dataflowRelation.setProcess(process);
4319                                                }
4320                                        }
4321                                }
4322                        }
4323                }
4324
4325        }
4326
4327        private void analyzeCopyIntoStmt(TSnowflakeCopyIntoStmt stmt) {
4328                if (stmt.getTableName() != null) {
4329                        if (stmt.getStageLocation() != null) {
4330                                Table intoTable = modelManager
4331                                                .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
4332                                if (intoTable == null) {
4333                                        intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
4334                                        TObjectName starColumn = new TObjectName();
4335                                        starColumn.setString("*");
4336                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
4337                                        if (column != null) {
4338                                                column.setExpandStar(false);
4339                                                column.setPseduo(true);
4340                                        }
4341                                }
4342                                Process process = modelFactory.createProcess(stmt);
4343                                intoTable.addProcess(process);
4344
4345                                TObjectName stageName = stmt.getStageLocation().getStageName();
4346                                if (stageName == null || stmt.getStageLocation().getTableName() != null) {
4347                                        stageName = stmt.getStageLocation().getTableName();
4348                                }
4349                                if (stageName != null) {
4350                                        String stageFullName = DlineageUtil.getTableFullName(stageName.toString());
4351                                        Table stage = modelManager.getTableByName(stageFullName);
4352                                        if (stage == null) {
4353                                                stage = modelFactory.createStage(stageName);
4354                                                stage.setCreateTable(true);
4355                                                stage.setStage(true);
4356                                                if (stmt.getStageLocation().getPath() != null) {
4357                                                        stage.setLocation(stmt.getStageLocation().getPath().toString());
4358                                                        TObjectName location = new TObjectName();
4359                                                        location.setString(stmt.getStageLocation().getPath().toString());
4360                                                        modelFactory.createStageLocation(stage, location);
4361                                                } else {
4362                                                        stage.setLocation("unknownPath");
4363                                                        TObjectName location = new TObjectName();
4364                                                        location.setString("unknownPath");
4365                                                        modelFactory.createStageLocation(stage, location);
4366                                                }
4367                                        }
4368
4369                                        if (stage != null && intoTable != null) {
4370                                                if (intoTable != null && !intoTable.getColumns().isEmpty() && !stage.getColumns().isEmpty()) {
4371                                                        for (int i = 0; i < intoTable.getColumns().size(); i++) {
4372                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4373                                                                relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
4374                                                                relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
4375                                                                relation.setProcess(process);
4376                                                        }
4377                                                }
4378                                        }
4379                                } else if (stmt.getStageLocation().getExternalLocation() != null) {
4380                                        Table pathModel = modelFactory.createTableByName(stmt.getStageLocation().getExternalLocation(),
4381                                                        true);
4382                                        pathModel.setPath(true);
4383                                        pathModel.setCreateTable(true);
4384                                        TableColumn fileUriColumn = modelFactory.createFileUri(pathModel,
4385                                                        stmt.getStageLocation().getExternalLocation());
4386                                        if (intoTable != null) {
4387                                                if (intoTable != null && !intoTable.getColumns().isEmpty()) {
4388                                                        for (int i = 0; i < intoTable.getColumns().size(); i++) {
4389                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4390                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4391                                                                relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
4392                                                                relation.setProcess(process);
4393                                                        }
4394                                                }
4395                                        }
4396                                }
4397                        }
4398                        else if (stmt.getSubQuery() != null) {
4399                                analyzeSelectStmt(stmt.getSubQuery());
4400                                
4401                                Table intoTable = modelManager
4402                                                .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
4403                                if (intoTable == null) {
4404                                        intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
4405                                        TObjectName starColumn = new TObjectName();
4406                                        starColumn.setString("*");
4407                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
4408                                        column.setExpandStar(true);
4409                                        column.setPseduo(true);
4410                                        
4411                                        Process process = modelFactory.createProcess(stmt);
4412                                        intoTable.addProcess(process);
4413                                        
4414                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
4415                                        if (resultSetModel != null) {
4416                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
4417                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
4418                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
4419                                                        dataflowRelation.setEffectType(EffectType.copy);
4420                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
4421                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(column));
4422                                                }
4423                                        }
4424                                }
4425                        }
4426                }
4427        }
4428
4429        private void analyzeRedshiftCopyStmt(TRedshiftCopy stmt) {
4430                if (stmt.getTableName() != null && stmt.getFromSource() != null) {
4431
4432                        Table intoTable = modelManager
4433                                        .getTableByName(DlineageUtil.getTableFullName(stmt.getTableName().toString()));
4434                        if (intoTable == null) {
4435                                intoTable = modelFactory.createTableByName(stmt.getTableName(), false);
4436                                if (stmt.getColumnList() == null || stmt.getColumnList().size() == 0) {
4437                                        TObjectName starColumn = new TObjectName();
4438                                        starColumn.setString("*");
4439                                        TableColumn column = modelFactory.createTableColumn(intoTable, starColumn, false);
4440                                        if (column != null) {
4441                                                column.setExpandStar(false);
4442                                                column.setPseduo(true);
4443                                        }
4444                                } else {
4445                                        for (TObjectName columnName : stmt.getColumnList()) {
4446                                                modelFactory.createTableColumn(intoTable, columnName, true);
4447                                        }
4448                                }
4449                        }
4450                        Process process = modelFactory.createProcess(stmt);
4451                        intoTable.addProcess(process);
4452
4453                        if (stmt.getFromSource() != null) {
4454                                Table pathModel = modelFactory.createTableByName(stmt.getFromSource(), true);
4455                                pathModel.setPath(true);
4456                                pathModel.setCreateTable(true);
4457                                TObjectName fileUri = new TObjectName();
4458                                fileUri.setString(stmt.getFromSource());
4459                                TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri);
4460                                if (intoTable != null) {
4461                                        if (intoTable != null && !intoTable.getColumns().isEmpty()) {
4462                                                for (int i = 0; i < intoTable.getColumns().size(); i++) {
4463                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4464                                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4465                                                        relation.setTarget(new TableColumnRelationshipElement(intoTable.getColumns().get(i)));
4466                                                        relation.setProcess(process);
4467                                                }
4468                                        }
4469                                }
4470                        }
4471                }
4472        }
4473
4474        private void analyzeCreateIndexExpressionOperand(TExpression expr, Table tableModel){
4475                if(expr == null) return;
4476                Deque<TExpression> stack = new ArrayDeque<>();
4477                stack.push(expr);
4478                while (!stack.isEmpty()) {
4479                        TExpression current = stack.pop();
4480                        if (current == null) continue;
4481                        TObjectName columnObj = current.getObjectOperand();
4482                        if (columnObj != null) {
4483                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, columnObj, true);
4484                                tableConstraint.setIndexKey(true);
4485                        } else {
4486                                if (current.getRightOperand() != null) {
4487                                        stack.push(current.getRightOperand());
4488                                }
4489                                if (current.getLeftOperand() != null) {
4490                                        stack.push(current.getLeftOperand());
4491                                }
4492                        }
4493                }
4494        }
4495        private void analyzeCreateIndexStageStmt(TCreateIndexSqlStatement stmt) {
4496                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4497                TOrderByItemList columns = stmt.getColumnNameList();
4498        if(columns!=null) {
4499            for (int i = 0; i < columns.size(); i++) {
4500                TExpression expr = columns.getOrderByItem(i).getSortKey();
4501                analyzeCreateIndexExpressionOperand(expr, tableModel);
4502            }
4503        }
4504        }
4505
4506        private void analyzeCreateSynonymStmt(TCreateSynonymStmt stmt) {
4507                TObjectName sourceTableName = stmt.getForName();
4508                if(sourceTableName == null) {
4509                        return;
4510                }
4511                TCustomSqlStatement createView = viewDDLMap
4512                                .get(DlineageUtil.getTableFullName(sourceTableName.toString()));
4513                if (createView != null) {
4514                        analyzeCustomSqlStmt(createView);
4515                }
4516                Table sourceTableModel = modelFactory.createTableByName(sourceTableName);
4517                Process process = modelFactory.createProcess(stmt);
4518                sourceTableModel.addProcess(process);
4519                if(stmt.getSynonymName()!=null) {
4520                        Table synonymTableModel = modelFactory.createTableByName(stmt.getSynonymName());
4521                        synonymTableModel.setSubType(SubType.synonym);
4522                        if(sourceTableModel.isCreateTable()) {
4523                                synonymTableModel.setCreateTable(true);
4524                                for(TableColumn sourceTableColumn: sourceTableModel.getColumns()) {
4525                                        TObjectName columnName = new TObjectName();
4526                                        columnName.setString(sourceTableColumn.getName());
4527                                        TableColumn synonymTableColumn = new TableColumn(synonymTableModel, columnName);
4528                                        synonymTableModel.addColumn(synonymTableColumn);
4529                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4530                                        relation.setEffectType(EffectType.create_synonym);
4531                                        relation.setTarget(new TableColumnRelationshipElement(synonymTableColumn));
4532                                        relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
4533                                        relation.setProcess(process);
4534                                }
4535                        }
4536                        else {
4537                                TObjectName synonymStarColumn = new TObjectName();
4538                                synonymStarColumn.setString("*");
4539                                TableColumn synonymTableStarColumn = modelFactory.createTableColumn(synonymTableModel,
4540                                                synonymStarColumn, true);
4541                                TObjectName sourceStarColumn = new TObjectName();
4542                                sourceStarColumn.setString("*");
4543                                TableColumn sourceTableStarColumn = modelFactory.createTableColumn(sourceTableModel, sourceStarColumn, true);
4544                                
4545                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4546                                relation.setEffectType(EffectType.create_synonym);
4547                                relation.setTarget(new TableColumnRelationshipElement(synonymTableStarColumn));
4548                                relation.addSource(new TableColumnRelationshipElement(sourceTableStarColumn));
4549                                relation.setProcess(process);
4550                        }
4551                }
4552        }
4553        
4554        private void analyzeRenameStmt(TRenameStmt stmt) {
4555                TObjectName oldTableName = stmt.getOldName();
4556                TObjectName newTableName = stmt.getNewName();
4557                
4558                Table oldNameTableModel = modelFactory.createTableByName(oldTableName);
4559                TObjectName oldStarColumn = new TObjectName();
4560                oldStarColumn.setString("*");
4561                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
4562                
4563                Table newNameTableModel = modelFactory.createTableByName(newTableName);
4564                TObjectName newStarColumn = new TObjectName();
4565                newStarColumn.setString("*");
4566                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn, true);
4567                
4568                Process process = modelFactory.createProcess(stmt);
4569                newNameTableModel.addProcess(process);
4570                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4571                relation.setEffectType( EffectType.rename_table);
4572                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4573                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4574                relation.setProcess(process);
4575                
4576                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4577                        oldTableStarColumn.setShowStar(false);
4578                        relation.setShowStarRelation(false);
4579                }
4580
4581                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4582                        newTableStarColumn.setShowStar(false);
4583                        relation.setShowStarRelation(false);
4584                }
4585        }
4586        
4587        private void analyzeAlterTableStmt(TAlterTableStatement stmt) {
4588                TTable oldNameTable = stmt.getTargetTable();
4589                if (oldNameTable == null) {
4590                        return;
4591                }
4592
4593                Table oldNameTableModel = modelFactory.createTable(oldNameTable);
4594                TObjectName oldStarColumn = new TObjectName();
4595                oldStarColumn.setString("*");
4596                TableColumn oldTableStarColumn = modelFactory.createTableColumn(oldNameTableModel, oldStarColumn, true);
4597
4598                for (int i = 0; stmt.getAlterTableOptionList() != null && i < stmt.getAlterTableOptionList().size(); i++) {
4599                        TAlterTableOption option = stmt.getAlterTableOptionList().getAlterTableOption(i);
4600                        if (option.getOptionType() == EAlterTableOptionType.RenameTable
4601                                        || option.getOptionType() == EAlterTableOptionType.swapWith) {
4602                                TObjectName newTableName = option.getNewTableName();
4603                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4604                                boolean containsTable = false;
4605                                for (int j = 0; j < list.size(); j++) {
4606                                        if (list.get(j) instanceof TTable) {
4607                                                TTable newTableTable = (TTable) list.get(j);
4608                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4609                                                newNameTableModel.setStarStmt("rename_table");
4610
4611                                                TObjectName newStarColumn = new TObjectName();
4612                                                newStarColumn.setString("*");
4613                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4614                                                                newStarColumn, true);
4615
4616                                                Process process = modelFactory.createProcess(stmt);
4617                                                newNameTableModel.addProcess(process);
4618                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4619                                                relation.setEffectType(
4620                                                                option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table
4621                                                                                : EffectType.swap_table);                                               
4622                                                if (option.getOptionType() == EAlterTableOptionType.RenameTable) {
4623                                                        relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4624                                                        relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4625                                                } else if (option.getOptionType() == EAlterTableOptionType.swapWith) {
4626                                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4627                                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4628                                                }
4629                                                relation.setProcess(process);
4630                                                containsTable = true;
4631
4632                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4633                                                        oldTableStarColumn.setShowStar(false);
4634                                                        relation.setShowStarRelation(false);
4635                                                }
4636
4637                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4638                                                        newTableStarColumn.setShowStar(false);
4639                                                        relation.setShowStarRelation(false);
4640                                                }
4641                                        }
4642                                }
4643                                if (!containsTable) {
4644                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4645                                        newNameTableModel.setStarStmt("rename_table");
4646                                        TObjectName newStarColumn = new TObjectName();
4647                                        newStarColumn.setString("*");
4648                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4649                                                        true);
4650
4651                                        Process process = modelFactory.createProcess(stmt);
4652                                        newNameTableModel.addProcess(process);
4653                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4654                                        relation.setEffectType(
4655                                                        option.getOptionType() == EAlterTableOptionType.RenameTable ? EffectType.rename_table
4656                                                                        : EffectType.swap_table);
4657                                        if (option.getOptionType() == EAlterTableOptionType.RenameTable) {
4658                                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4659                                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4660                                        } else if (option.getOptionType() == EAlterTableOptionType.swapWith) {
4661                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4662                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4663                                        }
4664                                        relation.setProcess(process);
4665                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4666                                                oldTableStarColumn.setShowStar(false);
4667                                                relation.setShowStarRelation(false);
4668                                        }
4669
4670                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4671                                                newTableStarColumn.setShowStar(false);
4672                                                relation.setShowStarRelation(false);
4673                                        }
4674
4675                                }
4676                        }
4677                        else if (option.getOptionType() == EAlterTableOptionType.appendFrom) {
4678                                TObjectName newTableName = option.getSourceTableName();
4679                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4680                                boolean containsTable = false;
4681                                for (int j = 0; j < list.size(); j++) {
4682                                        if (list.get(j) instanceof TTable) {
4683                                                TTable newTableTable = (TTable) list.get(j);
4684                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4685                                                newNameTableModel.setStarStmt("append_from");
4686
4687                                                TObjectName newStarColumn = new TObjectName();
4688                                                newStarColumn.setString("*");
4689                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4690                                                                newStarColumn, true);
4691
4692                                                Process process = modelFactory.createProcess(stmt);
4693                                                newNameTableModel.addProcess(process);
4694                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4695                                                relation.setEffectType(EffectType.append_from);
4696                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4697                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4698                                                relation.setProcess(process);
4699                                                containsTable = true;
4700
4701                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4702                                                        oldTableStarColumn.setShowStar(false);
4703                                                        relation.setShowStarRelation(false);
4704                                                }
4705
4706                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4707                                                        newTableStarColumn.setShowStar(false);
4708                                                        relation.setShowStarRelation(false);
4709                                                }
4710                                        }
4711                                }
4712                                if (!containsTable) {
4713                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4714                                        newNameTableModel.setStarStmt("append_from");
4715                                        TObjectName newStarColumn = new TObjectName();
4716                                        newStarColumn.setString("*");
4717                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4718                                                        true);
4719
4720                                        Process process = modelFactory.createProcess(stmt);
4721                                        newNameTableModel.addProcess(process);
4722                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4723                                        relation.setEffectType(EffectType.append_from);
4724                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4725                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4726                                        relation.setProcess(process);
4727                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4728                                                oldTableStarColumn.setShowStar(false);
4729                                                relation.setShowStarRelation(false);
4730                                        }
4731
4732                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4733                                                newTableStarColumn.setShowStar(false);
4734                                                relation.setShowStarRelation(false);
4735                                        }
4736
4737                                }
4738                        }
4739                        else if (option.getOptionType() == EAlterTableOptionType.exchangePartition) {
4740                                TObjectName newTableName = option.getNewTableName();
4741                                Stack<TParseTreeNode> list = newTableName.getStartToken().getNodesStartFromThisToken();
4742                                boolean containsTable = false;
4743                                for (int j = 0; j < list.size(); j++) {
4744                                        if (list.get(j) instanceof TTable) {
4745                                                TTable newTableTable = (TTable) list.get(j);
4746                                                Table newNameTableModel = modelFactory.createTable(newTableTable);
4747                                                newNameTableModel.setStarStmt("exchange_partition");
4748
4749                                                TObjectName newStarColumn = new TObjectName();
4750                                                newStarColumn.setString("*");
4751                                                TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel,
4752                                                                newStarColumn, true);
4753
4754                                                Process process = modelFactory.createProcess(stmt);
4755                                                newNameTableModel.addProcess(process);
4756                                                {
4757                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4758                                                        relation.setEffectType(EffectType.exchange_partition);
4759                                                        relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4760                                                        relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4761                                                        relation.setProcess(process);
4762                                                        if (option.getPartitionName() != null) {
4763                                                                relation.setPartition(option.getPartitionName().toString());
4764                                                        }
4765                                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4766                                                                oldTableStarColumn.setShowStar(false);
4767                                                                relation.setShowStarRelation(false);
4768                                                        }
4769
4770                                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4771                                                                newTableStarColumn.setShowStar(false);
4772                                                                relation.setShowStarRelation(false);
4773                                                        }
4774                                                }
4775                                                {
4776                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4777                                                        relation.setEffectType(EffectType.exchange_partition);
4778                                                        relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4779                                                        relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4780                                                        relation.setProcess(process);
4781                                                        if (option.getPartitionName() != null) {
4782                                                                relation.setPartition(option.getPartitionName().toString());
4783                                                        }
4784                                                        if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4785                                                                oldTableStarColumn.setShowStar(false);
4786                                                                relation.setShowStarRelation(false);
4787                                                        }
4788
4789                                                        if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4790                                                                newTableStarColumn.setShowStar(false);
4791                                                                relation.setShowStarRelation(false);
4792                                                        }
4793                                                }
4794                                                containsTable = true;   
4795                                        }
4796                                }
4797                                if (!containsTable) {
4798                                        Table newNameTableModel = modelFactory.createTableByName(newTableName);
4799                                        newNameTableModel.setStarStmt("exchange_partition");
4800                                        TObjectName newStarColumn = new TObjectName();
4801                                        newStarColumn.setString("*");
4802                                        TableColumn newTableStarColumn = modelFactory.createTableColumn(newNameTableModel, newStarColumn,
4803                                                        true);
4804
4805                                        Process process = modelFactory.createProcess(stmt);
4806                                        newNameTableModel.addProcess(process);
4807                                        {
4808                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4809                                                relation.setEffectType(EffectType.exchange_partition);
4810                                                relation.setTarget(new TableColumnRelationshipElement(oldTableStarColumn));
4811                                                relation.addSource(new TableColumnRelationshipElement(newTableStarColumn));
4812                                                if (option.getPartitionName() != null) {
4813                                                        relation.setPartition(option.getPartitionName().toString());
4814                                                }
4815                                                relation.setProcess(process);
4816                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4817                                                        oldTableStarColumn.setShowStar(false);
4818                                                        relation.setShowStarRelation(false);
4819                                                }
4820
4821                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4822                                                        newTableStarColumn.setShowStar(false);
4823                                                        relation.setShowStarRelation(false);
4824                                                }
4825                                        }
4826                                        {
4827                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4828                                                relation.setEffectType(EffectType.exchange_partition);
4829                                                relation.setTarget(new TableColumnRelationshipElement(newTableStarColumn));
4830                                                relation.addSource(new TableColumnRelationshipElement(oldTableStarColumn));
4831                                                if (option.getPartitionName() != null) {
4832                                                        relation.setPartition(option.getPartitionName().toString());
4833                                                }
4834                                                relation.setProcess(process);
4835                                                if ((oldNameTableModel.isCreateTable() || oldNameTableModel.hasSQLEnv())) {
4836                                                        oldTableStarColumn.setShowStar(false);
4837                                                        relation.setShowStarRelation(false);
4838                                                }
4839
4840                                                if ((newNameTableModel.isCreateTable() || newNameTableModel.hasSQLEnv())) {
4841                                                        newTableStarColumn.setShowStar(false);
4842                                                        relation.setShowStarRelation(false);
4843                                                }
4844                                        }
4845                                }
4846                        }
4847                        else if(option.getOptionType() == EAlterTableOptionType.setLocation) {
4848                                TObjectName location = option.getTableLocation();
4849                                Process process = modelFactory.createProcess(stmt);
4850                                process.setType("Set Table Location");
4851                                oldNameTableModel.addProcess(process);
4852                                Table uriFile = modelFactory.createTableByName(location, true);
4853                                uriFile.setPath(true);
4854                                for (int j = 0; j < oldNameTableModel.getColumns().size(); j++) {
4855                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4856                                        TObjectName fileUri = new TObjectName();
4857                                        fileUri.setString("*");
4858                                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
4859                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
4860                                        relation.setTarget(new TableColumnRelationshipElement(oldNameTableModel.getColumns().get(j)));
4861                                        relation.setProcess(process);
4862                                }
4863                        }
4864                        else if (option.getOptionType() == EAlterTableOptionType.AddColumn
4865                                        || option.getOptionType() == EAlterTableOptionType.addColumnIfNotExists) {
4866                                if (option.getColumnDefinitionList() != null) {
4867                                        for (TColumnDefinition column : option.getColumnDefinitionList()) {
4868                                                if (column != null && column.getColumnName() != null) {
4869                                                        TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column.getColumnName(), true);
4870                                                        if(this.option.getAnalyzeMode() == AnalyzeMode.crud) {
4871                                                                CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4872                                                                crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
4873                                                                crudRelationship.setEffectType(EffectType.add_table_column);
4874                                                        }
4875                                                }
4876                                        }
4877                                }
4878                        }
4879                        else if (option.getOptionType() == EAlterTableOptionType.DropColumn && this.option.getAnalyzeMode() == AnalyzeMode.crud) {
4880                                if (option.getColumnNameList() != null) {
4881                                        for (TObjectName column : option.getColumnNameList()) {
4882                                                TableColumn tableColumn = modelFactory.createTableColumn(oldNameTableModel, column, true);
4883                                                CrudRelationship crudRelationship = modelFactory.createCrudRelation();
4884                                                crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
4885                                                crudRelationship.setEffectType(EffectType.drop_table_column);
4886                                        }
4887                                }
4888                        }
4889                        else if(option.getOptionType() == EAlterTableOptionType.AddConstraint || option.getOptionType() == EAlterTableOptionType.AddConstraintFK
4890                                        || option.getOptionType() == EAlterTableOptionType.AddConstraintPK || option.getOptionType() == EAlterTableOptionType.AddConstraintUnique
4891                                        || option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){
4892                                if (option.getTableConstraint() != null) {
4893                                        TConstraint alertTableConstraint = option.getTableConstraint();
4894                                        TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList();
4895                                        for (int k = 0; k < keyNames.size(); k++) {
4896                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4897                                                TObjectName referencedTableName = alertTableConstraint.getReferencedObject();
4898                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4899                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4900                                                if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){
4901                                                        tableConstraint.setPrimaryKey(true);
4902                                                }
4903                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){
4904                                                        tableConstraint.setIndexKey(true);
4905                                                }
4906                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){
4907                                                        tableConstraint.setUnqiueKey(true);
4908                                                }
4909                                                else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
4910                                                        tableConstraint.setForeignKey(true);
4911                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4912                                                        if (referencedTable == null) {
4913                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4914                                                        }
4915                                                        TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList();
4916                                                        if (referencedTableColumns != null) {
4917                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4918                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4919                                                                                        referencedTableColumns.getObjectName(j), false);
4920                                                                        if (tableColumn != null) {
4921                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4922                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4923                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4924                                                                                relation.setEffectType(EffectType.foreign_key);
4925                                                                                Process process = modelFactory.createProcess(stmt);
4926                                                                                relation.setProcess(process);
4927                                                                                if(this.option.isShowERDiagram()){
4928                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4929                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4930                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4931                                                                                }
4932                                                                        }
4933                                                                }
4934                                                        }
4935                                                        else{
4936                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4937                                                                if (tableColumn != null) {
4938                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4939                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
4940                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4941                                                                        relation.setEffectType(EffectType.foreign_key);
4942                                                                        if(this.option.isShowERDiagram()){
4943                                                                                ERRelationship erRelation = modelFactory.createERRelation();
4944                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4945                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4946                                                                        }
4947                                                                }
4948                                                        }
4949                                                }
4950                                        }
4951                                }
4952                                else if (option.getConstraintList() != null) {
4953                                        for(int iCons=0; iCons<option.getConstraintList().size(); iCons++){
4954                                                TConstraint alertTableConstraint = option.getConstraintList().getConstraint(iCons);
4955                                                TPTNodeList<TColumnWithSortOrder> keyNames = alertTableConstraint.getColumnList();
4956                                                if(keyNames != null){
4957                                                        for (int k = 0; k < keyNames.size(); k++) {
4958                                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
4959                                                                TObjectName referencedTableName = alertTableConstraint.getReferencedObject();
4960                                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
4961                                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
4962                                                                if(alertTableConstraint.getConstraint_type() == EConstraintType.primary_key){
4963                                                                        tableConstraint.setPrimaryKey(true);
4964                                                                }
4965                                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.table_index){
4966                                                                        tableConstraint.setIndexKey(true);
4967                                                                }
4968                                                                else if(alertTableConstraint.getConstraint_type() == EConstraintType.unique){
4969                                                                        tableConstraint.setUnqiueKey(true);
4970                                                                }
4971                                                                else if (alertTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
4972                                                                        tableConstraint.setForeignKey(true);
4973                                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
4974                                                                        if (referencedTable == null) {
4975                                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
4976                                                                        }
4977                                                                        TObjectNameList referencedTableColumns = alertTableConstraint.getReferencedColumnList();
4978                                                                        if (referencedTableColumns != null) {
4979                                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
4980                                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
4981                                                                                                        referencedTableColumns.getObjectName(j), false);
4982                                                                                        if (tableColumn != null) {
4983                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
4984                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
4985                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4986                                                                                                relation.setEffectType(EffectType.foreign_key);
4987                                                                                                Process process = modelFactory.createProcess(stmt);
4988                                                                                                relation.setProcess(process);
4989                                                                                                if(this.option.isShowERDiagram()){
4990                                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
4991                                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
4992                                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
4993                                                                                                }
4994                                                                                        }
4995                                                                                }
4996                                                                        }
4997                                                                        else{
4998                                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
4999                                                                                if (tableColumn != null) {
5000                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5001                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
5002                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5003                                                                                        relation.setEffectType(EffectType.foreign_key);
5004                                                                                        Process process = modelFactory.createProcess(stmt);
5005                                                                                        relation.setProcess(process);
5006                                                                                        if(this.option.isShowERDiagram()){
5007                                                                                                ERRelationship erRelation = modelFactory.createERRelation();
5008                                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
5009                                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5010                                                                                        }
5011                                                                                }
5012                                                                        }
5013                                                                }
5014                                                        }
5015                                                }
5016                                        }
5017                                }
5018                                else if (option.getIndexCols() != null){
5019                                        TPTNodeList<TColumnWithSortOrder> keyNames = option.getIndexCols();
5020                                        for (int k = 0; k < keyNames.size(); k++) {
5021                                                TObjectName keyName = keyNames.getElement(k).getColumnName();
5022                                                Table tableModel = modelFactory.createTableByName(stmt.getTableName());
5023                                                TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
5024                                                if(option.getOptionType() == EAlterTableOptionType.AddConstraintPK){
5025                                                        tableConstraint.setPrimaryKey(true);
5026                                                }
5027                                                else if(option.getOptionType() == EAlterTableOptionType.AddConstraintIndex){
5028                                                        tableConstraint.setIndexKey(true);
5029                                                }
5030                                                else if(option.getOptionType() == EAlterTableOptionType.AddConstraintUnique){
5031                                                        tableConstraint.setUnqiueKey(true);
5032                                                }
5033                                                else if (option.getOptionType() == EAlterTableOptionType.AddConstraintFK) {
5034                                                        TObjectName referencedTableName = option.getReferencedObjectName();
5035                                                        tableConstraint.setForeignKey(true);
5036                                                        Table referencedTable = modelManager.getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
5037                                                        if (referencedTable == null) {
5038                                                                referencedTable = modelFactory.createTableByName(referencedTableName);
5039                                                        }
5040                                                        TObjectNameList referencedTableColumns = option.getReferencedColumnList();
5041                                                        if (referencedTableColumns != null) {
5042                                                                for (int j = 0; j < referencedTableColumns.size(); j++) {
5043                                                                        TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
5044                                                                                        referencedTableColumns.getObjectName(j), false);
5045                                                                        if (tableColumn != null) {
5046                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5047                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
5048                                                                                relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5049                                                                                relation.setEffectType(EffectType.foreign_key);
5050                                                                                Process process = modelFactory.createProcess(stmt);
5051                                                                                relation.setProcess(process);
5052                                                                                if(this.option.isShowERDiagram()){
5053                                                                                        ERRelationship erRelation = modelFactory.createERRelation();
5054                                                                                        erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
5055                                                                                        erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5056                                                                                }
5057                                                                        }
5058                                                                }
5059                                                        }
5060                                                        else{
5061                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable, keyName, false);
5062                                                                if (tableColumn != null) {
5063                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5064                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
5065                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5066                                                                        relation.setEffectType(EffectType.foreign_key);
5067                                                                        Process process = modelFactory.createProcess(stmt);
5068                                                                        relation.setProcess(process);
5069                                                                        if(this.option.isShowERDiagram()){
5070                                                                                ERRelationship erRelation = modelFactory.createERRelation();
5071                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
5072                                                                                erRelation.setTarget(new TableColumnRelationshipElement(tableConstraint));
5073                                                                        }
5074                                                                }
5075                                                        }
5076                                                }
5077                                        }
5078                                }
5079                        }
5080                }
5081        }
5082
5083        private void analyzeDeleteStmt(TDeleteSqlStatement stmt) {
5084                TTable table = stmt.getTargetTable();
5085                if (table == null)
5086                        return;
5087                
5088                if (table.getCTE() != null) {
5089                        table = table.getCTE().getSubquery().getTables().getTable(0);
5090                } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) {
5091                        table = table.getLinkTable().getSubquery().getTables().getTable(0);
5092                } else if (table.getSubquery() != null) {
5093                        table = table.getSubquery().getTables().getTable(0);
5094                }
5095                
5096                Table tableModel = modelFactory.createTable(table);
5097                if (getTableLinkedColumns(table) != null && getTableLinkedColumns(table).size() > 0) {
5098                        for (int j = 0; j < getTableLinkedColumns(table).size(); j++) {
5099                                TObjectName object = getTableLinkedColumns(table).getObjectName(j);
5100
5101                                if (object.getDbObjectType() == EDbObjectType.variable) {
5102                                        continue;
5103                                }
5104
5105                                if (object.getColumnNameOnly().startsWith("@")
5106                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
5107                                        continue;
5108                                }
5109
5110                                if (object.getColumnNameOnly().startsWith(":")
5111                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
5112                                        continue;
5113                                }
5114
5115                                if (!isBuiltInFunctionName(object)) {
5116                                        if (object.getSourceTable() == null || object.getSourceTable() == table) {
5117                                                modelFactory.createTableColumn(tableModel, object, false);
5118                                        }
5119                                }
5120                        }
5121                }
5122
5123                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
5124                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
5125                        crudRelationship.setTarget(new TableRelationshipElement(tableModel));
5126                        crudRelationship.setEffectType(EffectType.delete);
5127                }
5128                
5129                if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) {
5130                        analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where,
5131                                        EffectType.delete);
5132                }
5133        }
5134
5135        private TObjectName getProcedureName(TStoredProcedureSqlStatement stmt) {
5136                if (stmt instanceof TTeradataCreateProcedure) {
5137                        return ((TTeradataCreateProcedure) stmt).getProcedureName();
5138                }
5139                return stmt.getStoredProcedureName();
5140        }
5141
5142        private void analyzePlsqlCreatePackage(TPlsqlCreatePackage stmt) {
5143                TObjectName procedureName = getProcedureName(stmt);
5144                OraclePackage oraclePackage;
5145                if (procedureName != null) {
5146                        if (this.modelManager.getOraclePackageByName(
5147                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))) == null) {
5148                                oraclePackage = this.modelFactory.createOraclePackage(stmt);
5149
5150                                if (stmt.getParameterDeclarations() != null) {
5151                                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
5152
5153                                        for (int i = 0; i < parameters.size(); ++i) {
5154                                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
5155                                                if (parameter.getParameterName() != null) {
5156                                                        this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1);
5157                                                } else if (parameter.getDataType() != null) {
5158                                                        this.modelFactory.createProcedureArgument(oraclePackage, parameter, i + 1);
5159                                                }
5160                                        }
5161                                }
5162
5163                                ModelBindingManager.setGlobalOraclePackage(oraclePackage);
5164                        } else {
5165                                ModelBindingManager.setGlobalOraclePackage(this.modelManager.getOraclePackageByName(
5166                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getProcedureNameWithArgs(stmt))));
5167                        }
5168                        
5169                        try {
5170                                if (stmt.getDeclareStatements() != null) {
5171                                        for (int i = 0; i < stmt.getDeclareStatements().size(); ++i) {
5172                                                analyzeCustomSqlStmt(stmt.getDeclareStatements().get(i));
5173                                        }
5174                                }
5175                        } finally {
5176                                ModelBindingManager.removeGlobalOraclePackage();
5177                        }
5178                }
5179        }
5180
5181        private void analyzeStoredProcedureStmt(TStoredProcedureSqlStatement stmt) {
5182
5183                if (stmt instanceof TPlsqlCreatePackage) {
5184                        analyzePlsqlCreatePackage((TPlsqlCreatePackage) stmt);
5185                        return;
5186                }
5187                
5188                ModelBindingManager.setGlobalProcedure(stmt);
5189
5190                try {
5191                        Procedure procedure = null;
5192        
5193                        TObjectName procedureName = getProcedureName(stmt);
5194                        if (procedureName != null) {
5195                                procedure = this.modelFactory.createProcedure(stmt);
5196                                if (procedure != null) {
5197                                        modelManager.bindModel(stmt, procedure);
5198                                }
5199                                if (ModelBindingManager.getGlobalOraclePackage() != null) {
5200                                        ModelBindingManager.getGlobalOraclePackage().addProcedure(procedure);
5201                                        procedure.setParentPackage(ModelBindingManager.getGlobalOraclePackage());
5202                                }
5203                                if (stmt.getParameterDeclarations() != null) {
5204                                        TParameterDeclarationList parameters = stmt.getParameterDeclarations();
5205        
5206                                        for (int i = 0; i < parameters.size(); ++i) {
5207                                                TParameterDeclaration parameter = parameters.getParameterDeclarationItem(i);
5208                                                Argument argument = null;
5209                                                TObjectName argumentName = null;
5210                                                if (parameter.getParameterName() != null) {
5211                                                        argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1);
5212                                                        argumentName = parameter.getParameterName();
5213                                                } else if (parameter.getDataType() != null) {
5214                                                        argument = this.modelFactory.createProcedureArgument(procedure, parameter, i + 1);
5215                                                }
5216                                                
5217                                                if (argument != null) {
5218                                                        if (argumentName == null) {
5219                                                                argumentName = new TObjectName();
5220                                                                argumentName.setString(argument.getName());
5221                                                        }
5222                                                        Variable variable = modelFactory.createVariable(argument.getName());
5223                                                        if (argument.getMode() == EParameterMode.in || argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
5224                                                                variable.setSubType(SubType.of(argument.getMode().name()));
5225                                                        } else {
5226                                                                variable.setSubType(SubType.argument);
5227                                                        }
5228                                                        if(isSimpleDataType(argument.getDataType())){
5229                                                                modelFactory.createTableColumn(variable, argumentName, true);
5230                                                        }
5231                                                        else {
5232                                                                TObjectName variableProperties = new TObjectName();
5233                                                                variableProperties.setString("*");
5234                                                                modelFactory.createTableColumn(variable, variableProperties, true);
5235                                                        }
5236                                                }
5237                                        }
5238                                }
5239                        }
5240        
5241                        if (stmt instanceof TCreateTriggerStmt) {
5242                                TCreateTriggerStmt trigger = (TCreateTriggerStmt) stmt;
5243        
5244                                if (trigger.getFunctionCall() != null) {
5245                                        modelFactory.createProcedureFromFunctionCall(trigger.getFunctionCall());
5246                                }
5247        
5248                                if (trigger.getTables() != null) {
5249                                        for (int i = 0; i < trigger.getTables().size(); i++) {
5250                                                Table tableModel = this.modelFactory.createTriggerOnTable(trigger.getTables().getTable(i));
5251                                        }
5252                                }
5253                        }
5254        
5255                        if (stmt instanceof TPlsqlCreateTrigger
5256                                        && ((TPlsqlCreateTrigger) stmt).getTriggeringClause().getEventClause() instanceof TDmlEventClause) {
5257                                TPlsqlCreateTrigger trigger = (TPlsqlCreateTrigger) stmt;
5258                                TDmlEventClause clause = (TDmlEventClause) ((TPlsqlCreateTrigger) stmt).getTriggeringClause()
5259                                                .getEventClause();
5260                                Table sourceTable = modelFactory.createTableByName(clause.getTableName());
5261        
5262                                for (TTriggerEventItem item : clause.getEventItems()) {
5263                                        if (item instanceof TDmlEventItem) {
5264                                                if (((TDmlEventItem) item).getColumnList() != null) {
5265                                                        for (TObjectName column : ((TDmlEventItem) item).getColumnList()) {
5266                                                                modelFactory.createTableColumn(sourceTable, column, true);
5267                                                        }
5268                                                }
5269                                        }
5270                                }
5271        
5272                                for (TCustomSqlStatement subStmt : ((TPlsqlCreateTrigger) stmt).getStatements()) {
5273                                        if (!(subStmt instanceof TCommonBlock))
5274                                                continue;
5275                                        for (TCustomSqlStatement blockSubStmt : ((TCommonBlock) subStmt).getStatements()) {
5276                                                if (!(blockSubStmt instanceof TBasicStmt))
5277                                                        continue;
5278                                                TBasicStmt basicStmt = (TBasicStmt) blockSubStmt;
5279                                                TExpression expression = basicStmt.getExpr();
5280                                                if (expression != null && expression.getExpressionType() == EExpressionType.function_t) {
5281                                                        Procedure targetProcedure = modelManager.getProcedureByName(DlineageUtil
5282                                                                        .getTableFullName(expression.getFunctionCall().getFunctionName().toString()));
5283                                                        if (targetProcedure == null) {
5284                                                                targetProcedure = modelManager
5285                                                                                .getProcedureByName(DlineageUtil.getTableFullName(procedure.getSchema() + "."
5286                                                                                                + expression.getFunctionCall().getFunctionName().toString()));
5287                                                        }
5288                                                        if (targetProcedure != null && expression.getFunctionCall().getArgs() != null && expression
5289                                                                        .getFunctionCall().getArgs().size() == targetProcedure.getArguments().size()) {
5290                                                                for (int j = 0; j < expression.getFunctionCall().getArgs().size(); j++) {
5291                                                                        TExpression columnExpr = expression.getFunctionCall().getArgs().getExpression(j);
5292                                                                        if (columnExpr.getExpressionType() == EExpressionType.simple_object_name_t) {
5293                                                                                TObjectName columnObject = columnExpr.getObjectOperand();
5294                                                                                if (columnObject.toString().indexOf(":") != -1) {
5295                                                                                        TableColumn tableColumn = modelFactory.createTableColumn(sourceTable,
5296                                                                                                        columnObject, true);
5297                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
5298                                                                                        relation.setEffectType(EffectType.trigger);
5299                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
5300                                                                                        relation.setTarget(
5301                                                                                                        new ArgumentRelationshipElement(targetProcedure.getArguments().get(j)));
5302                                                                                        Process process = modelFactory.createProcess(stmt);
5303                                                                                        relation.setProcess(process);
5304                                                                                }
5305                                                                        }
5306                                                                }
5307                                                        }
5308                                                }
5309                                        }
5310                                }
5311                        }
5312        
5313                        if (stmt instanceof TMssqlCreateFunction) {
5314                                TMssqlCreateFunction createFunction = (TMssqlCreateFunction) stmt;
5315                                if (createFunction.getReturnTableVaraible() != null && createFunction.getReturnTableDefinitions() != null) {
5316                                        Table tableModel = this.modelFactory.createTableByName(createFunction.getReturnTableVaraible(), true);
5317                                        tableModel.setCreateTable(true);
5318                                        String procedureParent = createFunction.getFunctionName().toString();
5319                                        if (procedureParent != null) {
5320                                                tableModel.setParent(procedureParent);
5321                                        }
5322                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
5323        
5324                                        if (createFunction.getReturnTableDefinitions() != null) {
5325                                                for (int j = 0; j < createFunction.getReturnTableDefinitions().size(); j++) {
5326                                                        TTableElement tableElement = createFunction.getReturnTableDefinitions().getTableElement(j);
5327                                                        TColumnDefinition column = tableElement.getColumnDefinition();
5328                                                        if (column != null && column.getColumnName() != null) {
5329                                                                modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
5330                                                        }
5331                                                }
5332                                        }
5333                                }
5334        
5335                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) {
5336                                        String procedureParent = createFunction.getFunctionName().toString();
5337                                        analyzeSelectStmt(createFunction.getReturnStmt().getSubquery());
5338                                        ResultSet resultSetModel = (ResultSet) modelManager
5339                                                        .getModel(createFunction.getReturnStmt().getSubquery());
5340                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5341                                                        resultSetModel);
5342                                }
5343                        } else if (stmt instanceof TCreateFunctionStmt) {
5344                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt;
5345                                if (createFunction.getReturnDataType() != null
5346                                                && createFunction.getReturnDataType().getColumnDefList() != null) {
5347                                        Table tableModel = this.modelFactory.createTableByName(createFunction.getFunctionName(), true);
5348                                        tableModel.setCreateTable(true);
5349                                        String procedureParent = createFunction.getFunctionName().toString();
5350                                        if (procedureParent != null) {
5351                                                tableModel.setParent(procedureParent);
5352                                        }
5353        
5354                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
5355                                        for (int j = 0; j < createFunction.getReturnDataType().getColumnDefList().size(); j++) {
5356                                                TColumnDefinition column = createFunction.getReturnDataType().getColumnDefList().getColumn(j);
5357                                                if (column != null && column.getColumnName() != null) {
5358                                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
5359                                                }
5360                                        }
5361        
5362                                        if (createFunction.getSqlQuery() != null) {
5363                                                analyzeSelectStmt(createFunction.getSqlQuery());
5364                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(createFunction.getSqlQuery());
5365                                                if (resultSetModel != null) {
5366                                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
5367                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
5368                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
5369                                                                        TableColumn tableColumn = tableModel.getColumns().get(j);
5370                                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(resultColumn.getName()),
5371                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
5372                                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5373                                                                                dataflowRelation.setEffectType(EffectType.select);
5374                                                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
5375                                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
5376                                                                        }
5377                                                                }
5378                                                        }
5379                                                }
5380                                        }
5381                                }
5382                                
5383                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getSubquery() != null) {
5384                                        String procedureParent = createFunction.getFunctionName().toString();
5385                                        analyzeSelectStmt(createFunction.getReturnStmt().getSubquery());
5386                                        ResultSet resultSetModel = (ResultSet) modelManager
5387                                                        .getModel(createFunction.getReturnStmt().getSubquery());
5388                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5389                                                        resultSetModel);
5390                                }
5391                                
5392                                if (createFunction.getReturnStmt() != null && createFunction.getReturnStmt().getReturnExpr() != null) {
5393                                        TExpression returnExpression =  createFunction.getReturnStmt().getReturnExpr();
5394                                        ResultSet returnResult = modelFactory.createResultSet(createFunction.getReturnStmt(), false);
5395                                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5396                                        
5397                                        TExpression expression = createFunction.getReturnStmt().getReturnExpr();
5398                                        analyzeResultColumnExpressionRelation(resultColumn, expression);
5399        
5400                                        String procedureParent = createFunction.getFunctionName().toString();
5401                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5402                                                        returnResult);
5403                                }
5404                        }
5405        
5406                        if (stmt instanceof TCreateProcedureStmt) {
5407                                TCreateProcedureStmt createProcedure = (TCreateProcedureStmt) stmt;
5408                                if (EDbVendor.dbvsnowflake == option.getVendor() && createProcedure.getRoutineBodyInConstant() != null) {
5409                                        extractSnowflakeSQLFromProcedure(createProcedure);
5410                                }
5411                        }
5412                                
5413                        if (stmt.getStatements().size() > 0) {
5414                                for (int i = 0; i < stmt.getStatements().size(); ++i) {
5415                                        this.analyzeCustomSqlStmt(stmt.getStatements().get(i));
5416                                }
5417                        }
5418
5419                        if (stmt.getBodyStatements().size() > 0) {
5420                                for (int i = 0; i < stmt.getBodyStatements().size(); ++i) {
5421                                        this.analyzeCustomSqlStmt(stmt.getBodyStatements().get(i));
5422                                }
5423                        }
5424                        
5425                        if (procedure != null && !getLastSelectStmt(stmt).isEmpty()) {
5426                                for (TSelectSqlStatement select : getLastSelectStmt(stmt)) {
5427                                        ResultSet resultSet = (ResultSet) modelManager.getModel(select);
5428                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedure.getName()),
5429                                                        resultSet);
5430                                }
5431//                              List<Argument> outArgs = new ArrayList<Argument>();
5432//                              for (int i = 0; i < procedure.getArguments().size(); i++) {
5433//                                      Argument argument = procedure.getArguments().get(i);
5434//                                      if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
5435//                                              outArgs.add(argument);
5436//                                      }
5437//                              }
5438//
5439//                              if (resultSet != null && resultSet.getColumns().size() == outArgs.size()) {
5440//                                      for (int i = 0; i < outArgs.size(); i++) {
5441//                                              Argument argument = outArgs.get(i);
5442//                                              Variable variable = modelFactory.createVariable(argument.getName(), false);
5443//                                              if (variable != null) {
5444//                                                      DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5445//                                                      dataflowRelation.setEffectType(EffectType.output);
5446//                                                      dataflowRelation
5447//                                                                      .addSource(new ResultColumnRelationshipElement(resultSet.getColumns().get(i)));
5448//                                                      dataflowRelation
5449//                                                                      .setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0)));
5450//                                              }
5451//                                      }
5452//
5453//                              }
5454                        }
5455
5456                        if (stmt instanceof TCreateFunctionStmt && ((TCreateFunctionStmt)stmt).getSqlExpression()!=null) {
5457                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt) stmt;
5458                                TExpression returnExpression = createFunction.getSqlExpression();
5459
5460                                ResultSet returnResult = modelFactory.createResultSet(stmt, false);
5461                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5462
5463                                columnsInExpr visitor = new columnsInExpr();
5464                                returnExpression.inOrderTraverse(visitor);
5465
5466                                List<TObjectName> objectNames = visitor.getObjectNames();
5467                                List<TParseTreeNode> functions = visitor.getFunctions();
5468                                List<TParseTreeNode> constants = visitor.getConstants();
5469                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5470
5471                                if (functions != null && !functions.isEmpty()) {
5472                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5473                                }
5474                                if (subquerys != null && !subquerys.isEmpty()) {
5475                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5476                                }
5477                                if (objectNames != null && !objectNames.isEmpty()) {
5478                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5479                                }
5480                                if (constants != null && !constants.isEmpty()) {
5481                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5482                                }
5483
5484                                String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5485                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5486                                                returnResult);
5487                        }
5488                } finally {
5489                        ModelBindingManager.removeGlobalProcedure();
5490                }
5491
5492        }
5493
5494        private boolean isSimpleDataType(TTypeName dataType) {
5495                if (dataType.getDataType() == EDataType.variant_t) {
5496                        return false;
5497                }
5498                if (dataType.getDataType() == EDataType.cursor_t) {
5499                        return false;
5500                }
5501                if (dataType.getDataType() == EDataType.generic_t) {
5502                        return false;
5503                }
5504                if (dataType.getDataType() == EDataType.unknown_t) {
5505                        return false;
5506                }
5507                if (dataType.getDataType() == EDataType.sql_variant_t) {
5508                        return false;
5509                }
5510                if (dataType.getDataType() == EDataType.table_t) {
5511                        return false;
5512                }
5513                if (dataType.getDataType() == EDataType.raw_t) {
5514                        return false;
5515                }
5516                if (dataType.getDataType() == EDataType.resultset_t) {
5517                        return false;
5518                }
5519                if (dataType.getDataType() == EDataType.row_t) {
5520                        return false;
5521                }
5522                if (dataType.getDataType() == EDataType.map_t) {
5523                        return false;
5524                }
5525                if (dataType.getDataType() == EDataType.anyType_t) {
5526                        return false;
5527                }
5528                if (dataType.getDataType() == EDataType.struct_t) {
5529                        return false;
5530                }
5531                if (dataType.getDataType() == EDataType.structType_t) {
5532                        return false;
5533                }
5534                if (dataType.getDataType() == EDataType.mapType_t) {
5535                        return false;
5536                }
5537                return true;
5538        }
5539
5540        protected void analyzeResultColumnExpressionRelation(Object resultColumn, TExpression expression) {
5541                columnsInExpr visitor = new columnsInExpr();
5542                expression.inOrderTraverse(visitor);
5543                List<TObjectName> objectNames = visitor.getObjectNames();
5544                List<TParseTreeNode> functions = visitor.getFunctions();
5545                List<TParseTreeNode> constants = visitor.getConstants();
5546                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5547
5548                if (functions != null && !functions.isEmpty()) {
5549                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5550                }
5551                if (subquerys != null && !subquerys.isEmpty()) {
5552                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5553                }
5554                if (objectNames != null && !objectNames.isEmpty()) {
5555                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5556                }
5557                if (constants != null && !constants.isEmpty()) {
5558                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5559                }
5560        }
5561
5562        private void analyzeDb2ReturnStmt(TDb2ReturnStmt stmt) {
5563                if (stmt.getReturnExpr() != null) {
5564                        TExpression returnExpression = stmt.getReturnExpr();
5565                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5566                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5567                        
5568                        columnsInExpr visitor = new columnsInExpr();
5569                        stmt.getReturnExpr().inOrderTraverse(visitor);
5570                        
5571                        List<TObjectName> objectNames = visitor.getObjectNames();
5572                        List<TParseTreeNode> functions = visitor.getFunctions();
5573                        List<TParseTreeNode> constants = visitor.getConstants();
5574                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5575
5576                        if (functions != null && !functions.isEmpty()) {
5577                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5578                        }
5579                        if (subquerys != null && !subquerys.isEmpty()) {
5580                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5581                        }
5582                        if (objectNames != null && !objectNames.isEmpty()) {
5583                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5584                        }
5585                        if (constants != null && !constants.isEmpty()) {
5586                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5587                        }
5588
5589                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5590                        if (procedureParent != null) {
5591                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5592                                                returnResult);
5593                        }
5594                }
5595        }
5596
5597        private void analyzeReturnStmt(TReturnStmt stmt) {
5598                if (stmt.getResultColumnList() != null) {
5599                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5600                        for (TResultColumn column : stmt.getResultColumnList()) {
5601                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column);
5602
5603                                columnsInExpr visitor = new columnsInExpr();
5604                                column.getExpr().inOrderTraverse(visitor);
5605
5606                                List<TObjectName> objectNames = visitor.getObjectNames();
5607                                List<TParseTreeNode> functions = visitor.getFunctions();
5608                                List<TParseTreeNode> constants = visitor.getConstants();
5609                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5610
5611                                if (functions != null && !functions.isEmpty()) {
5612                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5613                                }
5614                                if (subquerys != null && !subquerys.isEmpty()) {
5615                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5616                                }
5617                                if (objectNames != null && !objectNames.isEmpty()) {
5618                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5619                                }
5620                                if (constants != null && !constants.isEmpty()) {
5621                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5622                                }
5623
5624                        }
5625
5626                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5627                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5628                                        returnResult);
5629                }
5630                else if(stmt.getExpression()!=null){
5631                        TExpression returnExpression = stmt.getExpression();
5632                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5633                        
5634                        columnsInExpr visitor = null;
5635                        List<TSelectSqlStatement> subquerys = null;
5636                        
5637                        if (returnExpression.getFunctionCall() != null
5638                                        && returnExpression.getFunctionCall().getFunctionName().toString().equalsIgnoreCase("table")
5639                                        && returnExpression.getFunctionCall().getArgs() != null
5640                                        && returnExpression.getFunctionCall().getArgs().size()>0) {
5641                                visitor = new columnsInExpr();
5642                                returnExpression.getFunctionCall().getArgs().getExpression(0).inOrderTraverse(visitor);
5643                                subquerys = visitor.getSubquerys();
5644                                if (subquerys != null && !subquerys.isEmpty()) {
5645                                        analyzeSelectStmt(subquerys.get(0));
5646                                        ResultSet resultSet = (ResultSet) modelManager.getModel(subquerys.get(0));
5647                                        if (resultSet != null && resultSet.getColumns() != null) {
5648                                                for (ResultColumn column : resultSet.getColumns()) {
5649                                                        TObjectName columnName = new TObjectName();
5650                                                        columnName.setString(column.getName());
5651                                                        ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, columnName);
5652                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5653                                                        dataflowRelation.setEffectType(EffectType.select);
5654                                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(column));
5655                                                        dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5656                                                }
5657                                        }
5658                                        returnResult.setDetermined(resultSet.isDetermined());
5659                                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5660                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5661                                                        returnResult);
5662                                        return;
5663                                }
5664                        }
5665                        
5666                        ResultColumn resultColumn = null;
5667                        if (returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5668                                TObjectName columnName = new TObjectName();
5669                                columnName.setString("*");
5670                                resultColumn = modelFactory.createResultColumn(returnResult, columnName);
5671                        }
5672                        else {
5673                                resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5674                        }
5675
5676                        visitor = new columnsInExpr();
5677                        stmt.getExpression().inOrderTraverse(visitor);
5678
5679                        List<TObjectName> objectNames = visitor.getObjectNames();
5680                        List<TParseTreeNode> functions = visitor.getFunctions();
5681                        List<TParseTreeNode> constants = visitor.getConstants();
5682                        subquerys = visitor.getSubquerys();
5683
5684                        if (functions != null && !functions.isEmpty()) {
5685                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5686                        }
5687                        if (subquerys != null && !subquerys.isEmpty()) {
5688                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5689                        }
5690                        if (objectNames != null && !objectNames.isEmpty()) {
5691                                DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5692                                //如果variable对应的不是一个复杂结构,则resultColumn不要设置为*
5693                                if (relation != null && relation.getTarget().getElement() == resultColumn && relation.getSources().size() == 1) {
5694                                        Object column = relation.getSources().iterator().next().getElement();
5695                                        boolean star = true;
5696                                        if (column instanceof TableColumn && ((TableColumn) column).getName().indexOf("*") == -1) {
5697                                                star = false;
5698                                        }
5699                                        if (column instanceof ResultColumn && ((ResultColumn) column).getName().indexOf("*") == -1) {
5700                                                star = false;
5701                                        }
5702                                        if (!star && returnExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5703                                                resultColumn = modelFactory.createResultColumn(returnResult, returnExpression.getObjectOperand());
5704                                                returnResult.getColumns().clear();
5705                                                returnResult.addColumn(resultColumn);
5706                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5707                                        }
5708                                }
5709                        }
5710                        if (constants != null && !constants.isEmpty()) {
5711                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5712                        }
5713
5714                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5715                        if (procedureParent != null) {
5716                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5717                                                returnResult);
5718                        }
5719                }
5720        }
5721
5722        private void analyzeMssqlReturnStmt(TMssqlReturn stmt) {
5723                if (stmt.getResultColumnList() != null) {
5724                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5725                        for (TResultColumn column : stmt.getResultColumnList()) {
5726                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, column);
5727
5728                                columnsInExpr visitor = new columnsInExpr();
5729                                column.getExpr().inOrderTraverse(visitor);
5730
5731                                List<TObjectName> objectNames = visitor.getObjectNames();
5732                                List<TParseTreeNode> functions = visitor.getFunctions();
5733                                List<TParseTreeNode> constants = visitor.getConstants();
5734                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5735
5736                                if (functions != null && !functions.isEmpty()) {
5737                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5738                                }
5739                                if (subquerys != null && !subquerys.isEmpty()) {
5740                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5741                                }
5742                                if (objectNames != null && !objectNames.isEmpty()) {
5743                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5744                                }
5745                                if (constants != null && !constants.isEmpty()) {
5746                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5747                                }
5748
5749                        }
5750
5751                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5752                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5753                                        returnResult);
5754                }
5755                else if(stmt.getReturnExpr()!=null){
5756                        TExpression returnExpression = stmt.getReturnExpr();
5757                        ResultSet returnResult = modelFactory.createResultSet(stmt, true);
5758                        
5759                        if (returnExpression.getSubQuery() == null) {
5760                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, returnExpression);
5761                                columnsInExpr visitor = new columnsInExpr();
5762                                stmt.getReturnExpr().inOrderTraverse(visitor);
5763
5764                                List<TObjectName> objectNames = visitor.getObjectNames();
5765                                List<TParseTreeNode> functions = visitor.getFunctions();
5766                                List<TParseTreeNode> constants = visitor.getConstants();
5767                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
5768
5769                                if (functions != null && !functions.isEmpty()) {
5770                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
5771                                }
5772                                if (subquerys != null && !subquerys.isEmpty()) {
5773                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
5774                                }
5775                                if (objectNames != null && !objectNames.isEmpty()) {
5776                                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
5777                                }
5778                                if (constants != null && !constants.isEmpty()) {
5779                                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
5780                                }
5781                        }
5782                        else {
5783                                analyzeSelectStmt(returnExpression.getSubQuery());
5784                                ResultSet subResultSet = (ResultSet)modelManager.getModel(returnExpression.getSubQuery());
5785                                if (subResultSet != null) {
5786                                        for (ResultColumn subResultColumn : subResultSet.getColumns()) {
5787                                                TObjectName objectName = new TObjectName();
5788                                                objectName.setString(subResultColumn.getName());
5789                                                ResultColumn resultColumn = modelFactory.createResultColumn(returnResult, objectName);
5790                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5791                                                dataflowRelation.setEffectType(EffectType.select);
5792                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(subResultColumn));
5793                                                dataflowRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
5794
5795                                        }
5796                                        
5797                                        if(subResultSet.getRelationRows().hasRelation()) {
5798                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
5799                                                impactRelation.setEffectType(EffectType.select);
5800                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
5801                                                                subResultSet.getRelationRows()));
5802                                                impactRelation.setTarget(
5803                                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(returnResult.getRelationRows()));
5804                                        }
5805                                }
5806                        }
5807                        
5808                        String procedureParent = SQLUtil.trimColumnStringQuote(getProcedureParentName(stmt));
5809                        if (procedureParent != null) {
5810                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent),
5811                                                returnResult);
5812                        }
5813                }
5814        }
5815        
5816        private void analyzeFetchStmt(TFetchStmt stmt) {
5817                if (stmt.getVariableNames() != null) {
5818                        for (int i = 0; i < stmt.getVariableNames().size(); i++) {
5819                                TExpression variableExpression = stmt.getVariableNames().getExpression(i);
5820                                if (variableExpression.getExpressionType() == EExpressionType.simple_object_name_t) {
5821                                        TObjectName columnObject = variableExpression.getObjectOperand();
5822                                        if (columnObject.getDbObjectType() == EDbObjectType.variable) {
5823                                                continue;
5824                                        }
5825
5826                                        if (columnObject.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql
5827                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
5828                                                continue;
5829                                        }
5830
5831                                        if (columnObject.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana
5832                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
5833                                                continue;
5834                                        }
5835
5836                                        Variable cursorVariable = modelFactory.createVariable(columnObject);
5837                                        cursorVariable.setSubType(SubType.record);
5838                                        if (cursorVariable.isDetermined()) {
5839                                                if (stmt.getCursorName() != null) {
5840                                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5841                                                        String variableString = stmt.getCursorName().toString();
5842                                                        if (variableString.startsWith(":")) {
5843                                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5844                                                        }
5845                                                        if (!SQLUtil.isEmpty(procedureName)) {
5846                                                                variableString = procedureName + "."
5847                                                                                + SQLUtil.getIdentifierNormalTableName(variableString);
5848                                                        }
5849                                                        Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5850                                                        if (cursor != null) {
5851                                                                for (TableColumn variableProperty : cursorVariable.getColumns()) {
5852                                                                        boolean flag = false;
5853                                                                        for (TableColumn cursorColumn : cursor.getColumns()) {
5854                                                                                if (getColumnName(cursorColumn.getName())
5855                                                                                                .equalsIgnoreCase(variableProperty.getName())) {
5856                                                                                        DataFlowRelationship dataflowRelation = modelFactory
5857                                                                                                        .createDataFlowRelation();
5858                                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5859                                                                                        dataflowRelation
5860                                                                                                        .addSource(new TableColumnRelationshipElement(cursorColumn));
5861                                                                                        dataflowRelation
5862                                                                                                        .setTarget(new TableColumnRelationshipElement(variableProperty));
5863                                                                                        flag = true;
5864                                                                                        break;
5865                                                                                }
5866                                                                        }
5867
5868                                                                        if (!flag) {
5869                                                                                if (cursor.getColumns().size() == stmt.getVariableNames().size()) {
5870                                                                                        DataFlowRelationship dataflowRelation = modelFactory
5871                                                                                                        .createDataFlowRelation();
5872                                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5873                                                                                        dataflowRelation
5874                                                                                                        .setTarget(new TableColumnRelationshipElement(variableProperty));
5875                                                                                        dataflowRelation.addSource(
5876                                                                                                        new TableColumnRelationshipElement(cursor.getColumns().get(i)));
5877                                                                                }
5878                                                                                else {
5879                                                                                        for (int j = 0; j < cursor.getColumns().size(); j++) {
5880                                                                                                DataFlowRelationship dataflowRelation = modelFactory
5881                                                                                                                .createDataFlowRelation();
5882                                                                                                dataflowRelation.setEffectType(EffectType.cursor);
5883                                                                                                if (stmt.getVariableNames().size() == 1) {
5884                                                                                                        dataflowRelation.addSource(new TableColumnRelationshipElement(
5885                                                                                                                        cursor.getColumns().get(j)));
5886                                                                                                } else {
5887                                                                                                        dataflowRelation.addSource(new TableColumnRelationshipElement(
5888                                                                                                                        cursor.getColumns().get(j), i));
5889                                                                                                }
5890                                                                                                dataflowRelation.setTarget(
5891                                                                                                                new TableColumnRelationshipElement(variableProperty));
5892                                                                                        }
5893                                                                                }
5894                                                                        }
5895                                                                }
5896                                                        }
5897                                                }
5898                                                
5899                                        } else {
5900                                                TableColumn variableProperty = null;
5901                                                if (stmt.getVariableNames().size() == 1) {
5902                                                        if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
5903                                                                TObjectName starColumn = new TObjectName();
5904                                                                starColumn.setString("*");
5905                                                                variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5906                                                        } else {
5907                                                                variableProperty = cursorVariable.getColumns().get(0);
5908                                                        }
5909                                                } else {
5910                                                        variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true);
5911                                                }
5912
5913                                                if (stmt.getCursorName() != null) {
5914                                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5915                                                        String variableString = stmt.getCursorName().toString();
5916                                                        if (variableString.startsWith(":")) {
5917                                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5918                                                        }
5919                                                        if (!SQLUtil.isEmpty(procedureName)) {
5920                                                                variableString = procedureName + "."
5921                                                                                + SQLUtil.getIdentifierNormalTableName(variableString);
5922                                                        }
5923                                                        Table cursor = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
5924                                                        if (cursor != null) {
5925                                                                for (int j = 0; j < cursor.getColumns().size(); j++) {
5926                                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5927                                                                        dataflowRelation.setEffectType(EffectType.cursor);
5928                                                                        if (stmt.getVariableNames().size() == 1) {
5929                                                                                dataflowRelation.addSource(
5930                                                                                                new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5931                                                                        } else {
5932                                                                                dataflowRelation.addSource(
5933                                                                                                new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5934                                                                        }
5935                                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5936                                                                }
5937                                                        }
5938                                                }
5939                                        }
5940                                }
5941                        }
5942                }
5943        }
5944
5945        private void analyzeFetchStmt(TMssqlFetch stmt) {
5946                if (stmt.getVariableNames() != null) {
5947                        for (int i = 0; i < stmt.getVariableNames().size(); i++) {
5948                                TObjectName columnObject = stmt.getVariableNames().getObjectName(i);
5949                                Variable cursorVariable = modelFactory.createVariable(columnObject);
5950                                cursorVariable.setCreateTable(true);
5951                                cursorVariable.setSubType(SubType.record);
5952                                TableColumn variableProperty = null;
5953                                if (stmt.getVariableNames().size() == 1) {
5954                                        if (cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
5955                                                TObjectName starColumn = new TObjectName();
5956                                                starColumn.setString("*");
5957                                                variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
5958                                        } else {
5959                                                variableProperty = cursorVariable.getColumns().get(0);
5960                                        }
5961                                } else {
5962                                        variableProperty = modelFactory.createTableColumn(cursorVariable, columnObject, true);
5963                                }
5964
5965                                if (stmt.getCursorName() != null) {
5966                                        String procedureName = DlineageUtil.getProcedureParentName(stmt);
5967                                        String variableString = stmt.getCursorName().toString();
5968                                        if (variableString.startsWith(":")) {
5969                                                variableString = variableString.substring(variableString.indexOf(":") + 1);
5970                                        }
5971                                        if (!SQLUtil.isEmpty(procedureName)) {
5972                                                variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
5973                                        }
5974                                        Table cursor = modelManager
5975                                                        .getTableByName(DlineageUtil.getTableFullName(variableString));
5976                                        if (cursor != null) {
5977                                                for (int j = 0; j < cursor.getColumns().size(); j++) {
5978                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
5979                                                        dataflowRelation.setEffectType(EffectType.cursor);
5980                                                        if (stmt.getVariableNames().size() == 1) {
5981                                                                dataflowRelation
5982                                                                                .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j)));
5983                                                        } else {
5984                                                                dataflowRelation
5985                                                                                .addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j), i));
5986                                                        }
5987                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
5988                                                }
5989                                        }
5990                                }
5991                        }
5992
5993                }
5994        }
5995
5996        private void analyzeLoopStmt(TLoopStmt stmt) {
5997
5998                if (stmt.getCursorName() != null && stmt.getIndexName() != null) {
5999                        modelManager.bindCursorIndex(stmt.getIndexName(), stmt.getCursorName());
6000                }
6001
6002                if (stmt.getRecordName() != null && stmt.getSubquery() != null) {
6003                        Variable cursorTempTable = modelFactory.createCursor(stmt);
6004                        cursorTempTable.setVariable(true);
6005                        cursorTempTable.setSubType(SubType.cursor);
6006                        modelManager.bindCursorModel(stmt, cursorTempTable);
6007                        analyzeSelectStmt(stmt.getSubquery());
6008
6009                        TableColumn cursorColumn = null;
6010                        if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6011                                TObjectName starColumn = new TObjectName();
6012                                starColumn.setString("*");
6013                                cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6014                        } else {
6015                                cursorColumn = cursorTempTable.getColumns().get(0);
6016                        }
6017
6018
6019                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6020                        if (resultSetModel != null) {
6021                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6022                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6023                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6024                                        dataflowRelation.setEffectType(EffectType.cursor);
6025                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6026                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6027                                }
6028                        }
6029                }
6030
6031                for (int i = 0; i < stmt.getStatements().size(); i++) {
6032                        analyzeCustomSqlStmt(stmt.getStatements().get(i));
6033                }
6034        }
6035
6036        private void analyzeForStmt(TForStmt stmt) {
6037                if (stmt.getSubquery() == null) {
6038                        return;
6039                }
6040
6041                Variable cursorTempTable = modelFactory.createCursor(stmt);
6042                cursorTempTable.setVariable(true);
6043                cursorTempTable.setSubType(SubType.cursor);
6044                cursorTempTable.setCreateTable(true);
6045                modelManager.bindCursorModel(stmt, cursorTempTable);
6046                analyzeSelectStmt(stmt.getSubquery());
6047
6048                TableColumn cursorColumn = null;
6049                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6050                        TObjectName starColumn = new TObjectName();
6051                        starColumn.setString("*");
6052                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6053                } else {
6054                        cursorColumn = cursorTempTable.getColumns().get(0);
6055                }
6056
6057
6058                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6059                if (resultSetModel != null) {
6060                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6061                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6062                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6063                                dataflowRelation.setEffectType(EffectType.cursor);
6064                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6065                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6066                        }
6067                }
6068
6069                if (stmt.getStatements() != null && stmt.getStatements().size() > 0) {
6070                        for (int i = 0; i < stmt.getStatements().size(); i++) {
6071                                analyzeCustomSqlStmt(stmt.getStatements().get(i));
6072                        }
6073                }
6074        }
6075
6076        private void analyzeVarDeclStmt(TVarDeclStmt stmt) {
6077                TTypeName typeName = stmt.getDataType();
6078                if (typeName != null && typeName.toString().toUpperCase().indexOf("ROWTYPE") != -1) {
6079                        Variable cursorVariable = modelFactory.createVariable(stmt.getElementName());
6080                        cursorVariable.setSubType(SubType.record_type);
6081
6082                        Table variableTable = modelFactory.createTableByName(typeName.getDataTypeName(), false);
6083                        if(!variableTable.isCreateTable()) {
6084                                TObjectName starColumn1 = new TObjectName();
6085                                starColumn1.setString("*");
6086                                TableColumn variableTableStarColumn = modelFactory.createTableColumn(variableTable, starColumn1, true);
6087                                variableTableStarColumn.setShowStar(false);
6088                                variableTableStarColumn.setExpandStar(true);
6089
6090                                TObjectName starColumn = new TObjectName();
6091                                starColumn.setString("*");
6092                                TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, starColumn, true);
6093                                variableProperty.setShowStar(false);
6094                                variableProperty.setExpandStar(true);
6095
6096                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6097                                dataflowRelation.setEffectType(EffectType.rowtype);
6098                                dataflowRelation.addSource(new TableColumnRelationshipElement(variableTableStarColumn));
6099                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
6100                        } else {
6101                                for (TableColumn sourceColumn : variableTable.getColumns()) {
6102                                        String columnName = sourceColumn.getName();
6103                                        TObjectName targetColumn = new TObjectName();
6104                                        targetColumn.setString(columnName);
6105                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable, targetColumn, true);
6106                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6107                                        dataflowRelation.setEffectType(EffectType.rowtype);
6108                                        dataflowRelation.addSource(new TableColumnRelationshipElement(sourceColumn));
6109                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
6110                                }
6111                        }
6112                } else if (stmt.getElementName() != null) {
6113                        Variable variable = modelFactory.createVariable(stmt.getElementName());
6114                        variable.setCreateTable(true);
6115                        variable.setSubType(SubType.record);
6116                        TableColumn tableColumn = null;
6117                        if (stmt.getDataType() != null && (modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false)!=null || isCursorType(stmt.getDataType().getDataTypeName()))) {
6118                                Variable cursorVariable = modelFactory.createVariable(stmt.getDataType().getDataTypeName(), false);
6119                                if (cursorVariable != null) {
6120                                        if (cursorVariable.getSubType() == SubType.record_type) {
6121                                                variable.setSubType(SubType.record_type);
6122                                        }
6123                                        if(cursorVariable.isDetermined()) {
6124                                                for (int k = 0; k < cursorVariable.getColumns().size(); k++) {
6125                                                        TableColumn sourceColumn = cursorVariable.getColumns().get(k);
6126                                                        TObjectName objectName = new TObjectName();
6127                                                        objectName.setString(sourceColumn.getName());
6128                                                        tableColumn = modelFactory.createTableColumn(variable, objectName, true);
6129                                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6130                                                        dataflowRelation.setEffectType(EffectType.cursor);
6131                                                        dataflowRelation
6132                                                                        .addSource(new TableColumnRelationshipElement(sourceColumn));
6133                                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
6134                                                }
6135                                                variable.setDetermined(true);
6136                                                return;
6137                                        }
6138                                        else {
6139                                                TObjectName objectName = new TObjectName();
6140                                                objectName.setString("*");
6141                                                tableColumn = modelFactory.createTableColumn(variable, objectName, true);
6142                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6143                                                dataflowRelation.setEffectType(EffectType.cursor);
6144                                                dataflowRelation
6145                                                                .addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
6146                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(tableColumn));
6147                                        }
6148                                }
6149                                else {
6150                                        TObjectName objectName = new TObjectName();
6151                                        objectName.setString("*");
6152                                        tableColumn = modelFactory.createTableColumn(variable, objectName, true);                                       
6153                                }
6154                        } else {
6155                                tableColumn = modelFactory.createTableColumn(variable, stmt.getElementName(), true);
6156                                tableColumn.setVariant(true);
6157                        }
6158
6159                        if (stmt.getDefaultValue() != null) {
6160                                columnsInExpr visitor = new columnsInExpr();
6161                                stmt.getDefaultValue().inOrderTraverse(visitor);
6162                                List<TObjectName> objectNames = visitor.getObjectNames();
6163                                List<TParseTreeNode> functions = visitor.getFunctions();
6164                                List<TParseTreeNode> constants = visitor.getConstants();
6165                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6166
6167                                if (functions != null && !functions.isEmpty()) {
6168                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6169                                }
6170                                if (subquerys != null && !subquerys.isEmpty()) {
6171                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6172                                }
6173                                if (objectNames != null && !objectNames.isEmpty()) {
6174                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6175                                }
6176                                if (constants != null && !constants.isEmpty()) {
6177                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6178                                }
6179                        }
6180                        
6181                        
6182                }
6183        }
6184
6185        private boolean isCursorType(String dataTypeName) {
6186                if (dataTypeName != null && dataTypeName.toLowerCase().contains("cursor")) {
6187                        return true;
6188                }
6189                return false;
6190        }
6191
6192        private void analyzeSetStmt(TSetStmt stmt) {
6193                TExpression right = stmt.getVariableValue();
6194                TObjectName columnObject = stmt.getVariableName();
6195                if (columnObject != null) {
6196                        TableColumn tableColumn = null;
6197                        Variable tableModel;
6198                        if (columnObject.toString().indexOf(".") != -1) {
6199                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6200                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6201                        } else {
6202                                tableModel = modelFactory.createVariable(columnObject);
6203                        }
6204                        tableModel.setCreateTable(true);
6205                        tableModel.setSubType(SubType.record);
6206
6207                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6208                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6209                        } else {
6210                                tableColumn = tableModel.getColumns().get(0);
6211                        }
6212
6213                        if (tableColumn != null && right!=null) {
6214                                columnsInExpr visitor = new columnsInExpr();
6215                                right.inOrderTraverse(visitor);
6216                                List<TObjectName> objectNames = visitor.getObjectNames();
6217                                List<TParseTreeNode> functions = visitor.getFunctions();
6218                                List<TParseTreeNode> constants = visitor.getConstants();
6219                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6220
6221                                if (functions != null && !functions.isEmpty()) {
6222                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6223                                }
6224                                if (subquerys != null && !subquerys.isEmpty()) {
6225                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6226                                }
6227                                if (objectNames != null && !objectNames.isEmpty()) {
6228                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6229                                }
6230                                if (constants != null && !constants.isEmpty()) {
6231                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6232                                }
6233                                
6234                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
6235                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
6236                                }
6237                        }
6238                }
6239
6240                if(stmt.getAssignments()!=null){
6241                        for (int i = 0; i < stmt.getAssignments().size(); i++) {
6242                                TSetAssignment assignStmt = stmt.getAssignments().getElement(i);
6243                                analyzeSetAssignmentStmt(assignStmt);
6244                        }
6245                }
6246        }
6247
6248        private void analyzeSetAssignmentStmt(TSetAssignment stmt) {
6249                TExpression right = stmt.getParameterValue();
6250                TObjectName columnObject = stmt.getParameterName();
6251                if (columnObject != null) {
6252                        TableColumn tableColumn = null;
6253                        Variable tableModel;
6254                        if (columnObject.toString().indexOf(".") != -1) {
6255                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6256                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6257                        } else {
6258                                tableModel = modelFactory.createVariable(columnObject);
6259                        }
6260                        tableModel.setCreateTable(true);
6261                        tableModel.setSubType(SubType.record);
6262                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6263                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6264                        } else {
6265                                tableColumn = tableModel.getColumns().get(0);
6266                        }
6267
6268                        if (tableColumn != null && right!=null) {
6269                                columnsInExpr visitor = new columnsInExpr();
6270                                right.inOrderTraverse(visitor);
6271                                List<TObjectName> objectNames = visitor.getObjectNames();
6272                                List<TParseTreeNode> functions = visitor.getFunctions();
6273                                List<TParseTreeNode> constants = visitor.getConstants();
6274                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6275
6276                                if (functions != null && !functions.isEmpty()) {
6277                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6278                                }
6279                                if (subquerys != null && !subquerys.isEmpty()) {
6280                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6281                                }
6282                                if (objectNames != null && !objectNames.isEmpty()) {
6283                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6284                                }
6285                                if (constants != null && !constants.isEmpty()) {
6286                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6287                                }
6288
6289                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
6290                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
6291                                }
6292                        }
6293                }
6294        }
6295
6296        private void analyzeMssqlSetStmt(TMssqlSet stmt) {
6297                TExpression right = stmt.getVarExpr();
6298                TObjectName columnObject = stmt.getVarName();
6299                if (columnObject != null) {
6300                        TableColumn tableColumn = null;
6301                        Variable tableModel;
6302                        if (columnObject.toString().indexOf(".") != -1) {
6303                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6304                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6305                        } else {
6306                                tableModel = modelFactory.createVariable(columnObject);
6307                        }
6308                        tableModel.setCreateTable(true);
6309                        tableModel.setSubType(SubType.record);
6310                        if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6311                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6312                        }
6313                        else {
6314                                tableColumn = tableModel.getColumns().get(0);
6315                        }
6316
6317                        if (tableColumn != null && right!=null) {
6318                                columnsInExpr visitor = new columnsInExpr();
6319                                right.inOrderTraverse(visitor);
6320                                List<TObjectName> objectNames = visitor.getObjectNames();
6321                                List<TParseTreeNode> functions = visitor.getFunctions();
6322                                List<TParseTreeNode> constants = visitor.getConstants();
6323                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6324
6325                                if (functions != null && !functions.isEmpty()) {
6326                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6327                                }
6328                                if (subquerys != null && !subquerys.isEmpty()) {
6329                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6330                                }
6331                                if (objectNames != null && !objectNames.isEmpty()) {
6332                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6333                                }
6334                                if (constants != null && !constants.isEmpty()) {
6335                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6336                                }
6337
6338                                if(columnObject.toString().equalsIgnoreCase("search_path") && !constants.isEmpty()) {
6339                                        ModelBindingManager.setGlobalSchema(constants.get(0).toString());
6340                                }
6341                        }
6342                        else if(tableColumn!=null && stmt.getSubquery()!=null){
6343                                analyzeCustomSqlStmt(stmt.getSubquery());
6344                                analyzeSubqueryDataFlowRelation(tableColumn, Arrays.asList(stmt.getSubquery()), EffectType.select);
6345                        }
6346                }
6347        }
6348
6349        private void analyzeAssignStmt(TAssignStmt stmt) {
6350                TExpression left = stmt.getLeft();
6351                TExpression right = stmt.getExpression();
6352                TObjectName columnObject = null;
6353                if (left == null) {
6354                        columnObject = stmt.getVariableName();
6355                } else if (left.getExpressionType() == EExpressionType.simple_object_name_t) {
6356                        columnObject = left.getObjectOperand();
6357                }
6358                if (columnObject != null) {
6359                        TableColumn tableColumn = null;
6360                        if (columnObject.getDbObjectType() == EDbObjectType.variable || stmt.getVariableName() != null) {
6361                                Variable tableModel;
6362                                if (columnObject.toString().indexOf(".") != -1) {
6363                                        List<String> splits = SQLUtil.parseNames(columnObject.toString());
6364                                        tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
6365                                } else {
6366                                        tableModel = modelFactory.createVariable(columnObject);
6367                                }
6368                                tableModel.setCreateTable(true);
6369                                tableModel.setSubType(SubType.record);
6370                                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
6371                                        tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6372                                } else {
6373                                        tableColumn = tableModel.getColumns().get(0);
6374                                }
6375                        } else {
6376                                List<String> splits = SQLUtil.parseNames(columnObject.toString());
6377                                if (splits.size() > 1) {
6378                                        Table tableModel = modelManager
6379                                                        .getTableByName(DlineageUtil.getTableFullName(splits.get(splits.size() - 2)));
6380                                        if (tableModel == null) {
6381                                                String procedureName = DlineageUtil.getProcedureParentName(stmt);
6382                                                String variableString = splits.get(splits.size() - 2).toString();
6383                                                if (variableString.startsWith(":")) {
6384                                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
6385                                                }
6386                                                if (!SQLUtil.isEmpty(procedureName)) {
6387                                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
6388                                                }
6389                                                tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
6390                                        }
6391                                        if (tableModel != null) {
6392                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObject, true);
6393                                        }
6394                                }
6395                        }
6396
6397                        if (tableColumn != null && right != null) {
6398                                Transform transform = new Transform();
6399                                transform.setType(Transform.EXPRESSION);
6400                                transform.setCode(right);
6401                                tableColumn.setTransform(transform);;
6402                                columnsInExpr visitor = new columnsInExpr();
6403                                right.inOrderTraverse(visitor);
6404                                List<TObjectName> objectNames = visitor.getObjectNames();
6405                                List<TParseTreeNode> functions = visitor.getFunctions();
6406                                List<TParseTreeNode> constants = visitor.getConstants();
6407                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6408
6409                                if (functions != null && !functions.isEmpty()) {
6410                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
6411                                }
6412                                if (subquerys != null && !subquerys.isEmpty()) {
6413                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
6414                                }
6415                                if (objectNames != null && !objectNames.isEmpty()) {
6416                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
6417                                }
6418                                if (constants != null && !constants.isEmpty()) {
6419                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, functions);
6420                                }
6421                        }
6422                }
6423        }
6424
6425        private void analyzeOpenForStmt(TOpenforStmt stmt) {
6426                if (stmt.getSubquery() == null) {
6427                        return;
6428                }
6429
6430                Variable cursorTempTable = modelFactory.createCursor(stmt);
6431                cursorTempTable.setVariable(true);
6432                cursorTempTable.setSubType(SubType.cursor);
6433                modelManager.bindCursorModel(stmt, cursorTempTable);
6434                analyzeSelectStmt(stmt.getSubquery());
6435
6436                TableColumn cursorColumn = null;
6437                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6438                        TObjectName starColumn = new TObjectName();
6439                        starColumn.setString("*");
6440                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6441                } else {
6442                        cursorColumn = cursorTempTable.getColumns().get(0);
6443                }
6444
6445                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6446                if (resultSetModel != null) {
6447                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6448                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6449                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6450                                dataflowRelation.setEffectType(EffectType.cursor);
6451                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6452                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6453                        }
6454                }
6455        }
6456
6457        private void analyzeCursorDeclStmt(TCursorDeclStmt stmt) {
6458                if (stmt.getSubquery() == null) {
6459                        return;
6460                }
6461
6462                Variable cursorTempTable = modelFactory.createCursor(stmt);
6463                cursorTempTable.setVariable(true);
6464                cursorTempTable.setSubType(SubType.cursor);
6465                modelManager.bindCursorModel(stmt, cursorTempTable);
6466                analyzeSelectStmt(stmt.getSubquery());
6467                
6468                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubquery());
6469                if(resultSetModel!=null && resultSetModel.isDetermined()) {
6470                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6471                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6472                                TObjectName columnName = new TObjectName();
6473                                columnName.setString(resultColumn.getName());
6474                                TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, columnName, true);           
6475                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6476                                dataflowRelation.setEffectType(EffectType.cursor);
6477                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6478                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6479                        }
6480                }
6481                else {
6482                        TableColumn cursorColumn = null;
6483                        if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6484                                TObjectName starColumn = new TObjectName();
6485                                starColumn.setString("*");
6486                                cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6487                        } else {
6488                                cursorColumn = cursorTempTable.getColumns().get(0);
6489                        }
6490                        if (resultSetModel != null) {
6491                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6492                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6493                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6494                                        dataflowRelation.setEffectType(EffectType.cursor);
6495                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6496                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6497                                }
6498                        }
6499                }
6500                
6501        }
6502
6503        private void analyzeDb2Declare(TDb2SqlVariableDeclaration stmt) {
6504                TDeclareVariableList variables = stmt.getVariables();
6505                if (variables == null) {
6506                        return;
6507                }
6508                for (int i = 0; i < variables.size(); i++) {
6509                        TDeclareVariable variable = variables.getDeclareVariable(i);
6510                        if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) {
6511
6512
6513                                TObjectName tableName = variable.getVariableName();
6514                                TTableElementList columns = variable.getTableTypeDefinitions();
6515
6516                                Table tableModel = modelFactory.createTableByName(tableName, true);
6517                                tableModel.setCreateTable(true);
6518                                String procedureParent = getProcedureParentName(stmt);
6519                                if (procedureParent != null) {
6520                                        tableModel.setParent(procedureParent);
6521                                }
6522                                modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
6523
6524                                for (int j = 0; j < columns.size(); j++) {
6525                                        TTableElement tableElement = columns.getTableElement(j);
6526                                        TColumnDefinition column = tableElement.getColumnDefinition();
6527                                        if (column != null && column.getColumnName() != null) {
6528                                                modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
6529                                        }
6530                                }
6531                        } else if (variable.getVariableName() != null) {
6532                                Variable cursorVariable = modelFactory.createVariable(variable.getVariableName());
6533                                cursorVariable.setCreateTable(true);
6534                                cursorVariable.setSubType(SubType.record);
6535                                if(variable.getDatatype()!=null && isSimpleDataType(variable.getDatatype())){
6536                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable,
6537                                                        variable.getVariableName(), true);
6538                                }
6539                                else {
6540                                        TObjectName variableProperties = new TObjectName();
6541                                        variableProperties.setString("*");
6542                                        TableColumn variableProperty = modelFactory.createTableColumn(cursorVariable,
6543                                                        variableProperties, true);
6544                                }
6545                        }
6546                }
6547        }
6548
6549        private void analyzeMssqlDeclare(TMssqlDeclare stmt) {
6550                if (stmt.getDeclareType() == EDeclareType.variable) {
6551                        TDeclareVariableList variables = stmt.getVariables();
6552                        if (variables == null) {
6553                                return;
6554                        }
6555                        for (int i = 0; i < variables.size(); i++) {
6556                                TDeclareVariable variable = variables.getDeclareVariable(i);
6557                                if (variable.getTableTypeDefinitions() != null && variable.getTableTypeDefinitions().size() > 0) {
6558
6559
6560                                        TObjectName tableName = variable.getVariableName();
6561                                        TTableElementList columns = variable.getTableTypeDefinitions();
6562
6563                                        Table tableModel = modelFactory.createTableByName(tableName, true);
6564                                        tableModel.setCreateTable(true);
6565                                        String procedureParent = getProcedureParentName(stmt);
6566                                        if (procedureParent != null) {
6567                                                tableModel.setParent(procedureParent);
6568                                        }
6569                                        modelManager.bindTableFunction(DlineageUtil.getIdentifierNormalTableName(procedureParent), tableModel);
6570
6571                                        for (int j = 0; j < columns.size(); j++) {
6572                                                TTableElement tableElement = columns.getTableElement(j);
6573                                                TColumnDefinition column = tableElement.getColumnDefinition();
6574                                                if (column != null && column.getColumnName() != null) {
6575                                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
6576                                                }
6577                                        }
6578                                } else if (variable.getVariableName() != null) {
6579                                        Variable cursorVariable = modelFactory.createVariable(variable.getVariableName());
6580                                        cursorVariable.setCreateTable(true);
6581                                        cursorVariable.setSubType(SubType.record);
6582                                        TableColumn variableProperty = null;
6583                                        if (variable.getDatatype() != null && isSimpleDataType(variable.getDatatype())) {
6584                                                variableProperty = modelFactory.createTableColumn(cursorVariable, variable.getVariableName(),
6585                                                                true);
6586                                        } else {
6587                                                TObjectName variableProperties = new TObjectName();
6588                                                variableProperties.setString("*");
6589                                                variableProperty = modelFactory.createTableColumn(cursorVariable, variableProperties, true);
6590                                        }
6591                                        
6592                                        if (variable.getDefaultValue() != null && variable.getDefaultValue().getSubQuery() != null) {
6593                                                analyzeSelectStmt(variable.getDefaultValue().getSubQuery());
6594                                                ResultSet resultSetModel = (ResultSet) modelManager
6595                                                                .getModel(variable.getDefaultValue().getSubQuery());
6596                                                if (variableProperty != null && resultSetModel != null) {
6597                                                        for (ResultColumn column : resultSetModel.getColumns()) {
6598                                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6599                                                                dataflowRelation.setEffectType(EffectType.select);
6600                                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(column));
6601                                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(variableProperty));
6602                                                        }
6603                                                }
6604                                        }
6605                                }
6606                        }
6607                } else if (stmt.getDeclareType() == EDeclareType.cursor) {
6608                        Variable cursorTempTable = modelFactory.createCursor(stmt);
6609                        cursorTempTable.setVariable(true);
6610                        cursorTempTable.setSubType(SubType.cursor);
6611                        modelManager.bindCursorModel(stmt, cursorTempTable);
6612                        analyzeSelectStmt(stmt.getSubquery());
6613                        ResultSet resultSetModel = (ResultSet)modelManager.getModel(stmt.getSubquery());
6614                        if (resultSetModel != null && resultSetModel.isDetermined()) {
6615                                for(ResultColumn resultColumn: resultSetModel.getColumns()){
6616                                        TObjectName starColumn = new TObjectName();
6617                                        starColumn.setString(resultColumn.getName());
6618                                        TableColumn cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6619                                        DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6620                                        dataflowRelation.setEffectType(EffectType.cursor);
6621                                        dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6622                                        dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6623                                }
6624                        }
6625                        else {
6626                                TableColumn cursorColumn = null;
6627                                if (cursorTempTable.getColumns() == null || cursorTempTable.getColumns().isEmpty()) {
6628                                        TObjectName starColumn = new TObjectName();
6629                                        starColumn.setString("*");
6630                                        cursorColumn = modelFactory.createTableColumn(cursorTempTable, starColumn, true);
6631                                        cursorColumn.setShowStar(false);
6632                                        cursorColumn.setExpandStar(true);
6633                                } else {
6634                                        cursorColumn = cursorTempTable.getColumns().get(0);
6635                                }
6636
6637                                if (resultSetModel != null) {
6638                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6639                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6640                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
6641                                                dataflowRelation.setEffectType(EffectType.cursor);
6642                                                dataflowRelation.addSource(new ResultColumnRelationshipElement(resultColumn));
6643                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(cursorColumn));
6644                                        }
6645                                }
6646                        }
6647                }
6648        }
6649
6650
6651        private boolean analyzeMssqlJsonDeclare(TMssqlDeclare stmt, String jsonName, Table jsonTable) {
6652                TDeclareVariableList variables = stmt.getVariables();
6653                if (variables == null) {
6654                        return false;
6655                }
6656                for (int i = 0; i < variables.size(); i++) {
6657                        TDeclareVariable variable = variables.getDeclareVariable(i);
6658                        TObjectName variableName = variable.getVariableName();
6659                        if (DlineageUtil.getIdentifierNormalTableName(variableName.toString())
6660                                        .equals(DlineageUtil.getIdentifierNormalTableName(jsonName))) {
6661                                if (variable.getDefaultValue() != null) {
6662                                        Table variableTable = modelFactory.createJsonVariable(variableName);
6663                                        variableTable.setVariable(true);
6664                                        variableTable.setSubType(SubType.scalar);
6665                                        variableTable.setCreateTable(true);
6666                                        TableColumn property = modelFactory.createVariableProperty(variableTable, variable);
6667
6668                                        for (int j = 0; j < jsonTable.getColumns().size(); j++) {
6669                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6670                                                relation.setEffectType(EffectType.select);
6671                                                relation.setTarget(new TableColumnRelationshipElement(jsonTable.getColumns().get(j)));
6672                                                relation.addSource(new TableColumnRelationshipElement(property));
6673                                        }
6674                                }
6675                                return true;
6676                        }
6677                }
6678                return false;
6679        }
6680
6681        private void analyzeCreateTableStmt(TCreateTableSqlStatement stmt) {
6682                if (stmt.getCloneSourceTable() != null) {
6683                        analyzeCloneTableStmt(stmt);
6684                        return;
6685                }
6686
6687                TTable table = stmt.getTargetTable();
6688
6689                boolean hasDefinition = false;
6690
6691                if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
6692                        hasDefinition = true;
6693                }
6694
6695                if (table != null) {
6696                        Table tableModel = modelFactory.createTableFromCreateDDL(table, hasDefinition || stmt.getSubQuery() == null
6697                                        || (stmt.getSubQuery().getSetOperatorType() == ESetOperatorType.none && stmt.getSubQuery().getResultColumnList().toString().indexOf("*") == -1));
6698                        if (stmt.isExternal()) {
6699                                tableModel.setExternal(true);
6700                        }
6701
6702                        if (stmt.getSubQuery() != null) {
6703                                Process process = modelFactory.createProcess(stmt);
6704                                tableModel.addProcess(process);
6705                        }
6706
6707                        String procedureParent = getProcedureParentName(stmt);
6708                        if (procedureParent != null) {
6709                                tableModel.setParent(procedureParent);
6710                        }
6711
6712                        if (hasDefinition) {
6713                                if(stmt.getSubQuery()!=null) {
6714                                        TSelectSqlStatement subquery = stmt.getSubQuery();
6715                                        analyzeSelectStmt(subquery);
6716                                        Process process = modelFactory.createProcess(stmt);
6717                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
6718                                        if(resultSetModel.isDetermined()){
6719                                                tableModel.setFromDDL(true);
6720                                        }
6721                                        if (resultSetModel != null) {
6722                                                int resultSetSize = resultSetModel.getColumns().size();
6723                                                int stmtColumnSize = stmt.getColumnList().size();
6724                                                int j = 0;
6725                                                int tableColumnSize = stmtColumnSize;
6726                                                if (resultSetModel.isDetermined() && resultSetSize > tableColumnSize) {
6727                                                        tableColumnSize = resultSetSize;
6728                                                }
6729                                                for (int i = 0; i < tableColumnSize && j < resultSetSize; i++) {
6730                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
6731                                                        if (i < stmtColumnSize) {
6732                                                                TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName();
6733                                                                
6734                                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
6735                                                                        j++;
6736                                                                } else {
6737                                                                        if (resultSetSize - j == stmt.getColumnList().size() - i) {
6738                                                                                j++;
6739                                                                        }
6740                                                                }
6741
6742                                                                if (alias != null) {
6743                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true);
6744                                                                        if (resultColumn != null) {
6745                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6746                                                                                relation.setEffectType(EffectType.create_table);
6747                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6748                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6749                                                                                relation.setProcess(process);
6750                                                                        }
6751                                                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
6752                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel,
6753                                                                                        (TObjectName) resultColumn.getColumnObject(), true);
6754                                                                        if (resultColumn != null) {
6755                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6756                                                                                relation.setEffectType(EffectType.create_table);
6757                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6758                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6759                                                                                relation.setProcess(process);
6760                                                                        }
6761                                                                } else if (resultColumn.getColumnObject() instanceof TResultColumn) {
6762                                                                        TableColumn viewColumn = modelFactory.createTableColumn(tableModel,
6763                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), true);
6764                                                                        ResultColumn column = (ResultColumn) modelManager
6765                                                                                        .getModel(resultColumn.getColumnObject());
6766                                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
6767                                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
6768                                                                        }
6769                                                                        if (resultColumn != null) {
6770                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6771                                                                                relation.setEffectType(EffectType.create_table);
6772                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6773                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6774                                                                                relation.setProcess(process);
6775                                                                        }
6776                                                                }
6777                                                        }
6778                                                        else if(resultSetModel.isDetermined()){
6779                                                                TObjectName tableName = new TObjectName();
6780                                                                tableName.setString(resultColumn.getName());
6781                                                                TableColumn viewColumn = modelFactory.createTableColumn(tableModel, tableName, true);
6782                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6783                                                                relation.setEffectType(EffectType.create_table);
6784                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
6785                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6786                                                                relation.setProcess(process);
6787                                                                j++;
6788                                                        }
6789                                                }
6790                                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
6791                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
6792                                                        impactRelation.setEffectType(EffectType.create_table);
6793                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
6794                                                                        resultSetModel.getRelationRows()));
6795                                                        impactRelation.setTarget(
6796                                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6797                                                }
6798                                        }
6799
6800                                        if (subquery.getResultColumnList() == null && subquery.getValueClause() != null
6801                                                        && subquery.getValueClause().getValueRows().size() == stmt.getColumnList().size()) {
6802                                                for (int i = 0; i < stmt.getColumnList().size(); i++) {
6803                                                        TObjectName alias = stmt.getColumnList().getColumn(i).getColumnName();
6804
6805                                                        if (alias != null) {
6806                                                                TableColumn viewColumn = modelFactory.createTableColumn(tableModel, alias, true);
6807
6808                                                                TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr();
6809
6810                                                                columnsInExpr visitor = new columnsInExpr();
6811                                                                expression.inOrderTraverse(visitor);
6812                                                                List<TObjectName> objectNames = visitor.getObjectNames();
6813                                                                List<TParseTreeNode> functions = visitor.getFunctions();
6814
6815                                                                if (functions != null && !functions.isEmpty()) {
6816                                                                        analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select);
6817
6818                                                                }
6819
6820                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
6821                                                                if (subquerys != null && !subquerys.isEmpty()) {
6822                                                                        analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select);
6823                                                                }
6824
6825                                                                analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions);
6826                                                                List<TParseTreeNode> constants = visitor.getConstants();
6827                                                                analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions);
6828                                                        }
6829                                                }
6830                                        }
6831                                        
6832                                        return;
6833                                }
6834                                else {
6835                                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
6836                                                TColumnDefinition column = stmt.getColumnList().getColumn(i);
6837                                                if (column.getDatatype() != null && column.getDatatype().getTypeOfList() != null
6838                                                                && column.getDatatype().getTypeOfList().getColumnDefList() != null) {
6839                                                        for (int j = 0; j < column.getDatatype().getTypeOfList().getColumnDefList().size(); j++) {
6840                                                                TObjectName columnName = new TObjectName();
6841                                                                if (column.getDatatype().getDataType() == EDataType.array_t) {
6842//                                                                      columnName.setString(column.getColumnName().getColumnNameOnly() + ".array."
6843//                                                                                      + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6844//                                                                                                      .getColumnName().getColumnNameOnly());
6845                                                                        columnName.setString(column.getColumnName().getColumnNameOnly() + "."
6846                                                                                        + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6847                                                                                        .getColumnName().getColumnNameOnly());
6848                                                                } else {
6849                                                                        columnName.setString(column.getColumnName().getColumnNameOnly() + "."
6850                                                                                        + column.getDatatype().getTypeOfList().getColumnDefList().getColumn(j)
6851                                                                                                        .getColumnName().getColumnNameOnly());
6852                                                                }
6853                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName,
6854                                                                                hasDefinition);
6855                                                                tableColumn.setStruct(true);
6856                                                                tableColumn.setColumnIndex(i);
6857                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6858                                                                
6859                                                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
6860                                                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
6861                                                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
6862                                                                        crudRelationship.setEffectType(EffectType.create_table);
6863                                                                }
6864                                                        }
6865                                                        continue;
6866                                                }
6867                                                if (column.getDatatype() != null && column.getDatatype().getColumnDefList() != null) {
6868                                                        Stack<TColumnDefinition> columnPaths = new Stack<TColumnDefinition>();
6869                                                        flattenStructColumns(hasDefinition, tableModel, column, columnPaths, i);
6870                                                        continue;
6871                                                }
6872                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column.getColumnName(),
6873                                                                hasDefinition);
6874                                                if (tableColumn == null) {
6875                                                        continue;
6876                                                }
6877                                                
6878                                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
6879                                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
6880                                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
6881                                                        crudRelationship.setEffectType(EffectType.create_table);
6882                                                }
6883                                                
6884                                                if (column.getDatatype() != null && column.getDatatype().getDataType() == EDataType.variant_t) {
6885                                                        if (tableColumn != null) {
6886                                                                tableColumn.setVariant(true);
6887                                                        }
6888                                                }
6889                                                if (column.getDatatype() != null) {
6890                                                        String dType = column.getDatatype().getDataTypeName();
6891                                                        if ((!SQLUtil.isEmpty(dType)) && (dType.indexOf("_") > 0)) {
6892                                                                dType = dType.split("_")[0];
6893                                                        }
6894                                                        tableColumn.setDataType(dType);
6895                                                }
6896                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6897                                        }
6898                                }
6899                        }
6900
6901                        if (stmt.getExternalTableOption("DATA_SOURCE") != null) {
6902                                String dataSourceName = stmt.getExternalTableOption("DATA_SOURCE");
6903                                Table dataSource = modelManager.getTableByName(DlineageUtil.getTableFullName(dataSourceName));
6904                                if (dataSource != null) {
6905                                        TableColumn dataSourceColumn = dataSource.getColumns().get(0);
6906                                        for (int i = 0; i < tableModel.getColumns().size(); i++) {
6907                                                TableColumn column = tableModel.getColumns().get(i);
6908                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6909                                                relation.setTarget(new TableColumnRelationshipElement(column));
6910                                                relation.addSource(new TableColumnRelationshipElement(dataSourceColumn));
6911
6912                                                appendTableColumnToSQLEnv(tableModel, column);
6913                                        }
6914                                }
6915                        }
6916
6917                        if (stmt.getSubQuery() != null) {
6918
6919                                analyzeSelectStmt(stmt.getSubQuery());
6920
6921                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
6922                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
6923                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
6924                                        impactRelation.setEffectType(EffectType.create_table);
6925                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
6926                                                        resultSetModel.getRelationRows()));
6927                                        impactRelation.setTarget(
6928                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
6929                                }
6930                        }
6931
6932                        if (stmt.getSubQuery() != null && !stmt.getSubQuery().isCombinedQuery()) {
6933                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
6934                                                .getModel(stmt.getSubQuery().getResultColumnList());
6935                                if(resultSetModel.isDetermined()){
6936                                        tableModel.setDetermined(true);
6937                                        tableModel.setFromDDL(true);
6938                                }
6939                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
6940                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
6941                                        if (resultSetModel.isDetermined() && resultColumn.getName().endsWith("*")) {
6942                                                continue;
6943                                        }
6944
6945                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
6946                                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
6947
6948                                                TAliasClause alias = columnObject.getAliasClause();
6949                                                if (alias != null && alias.getAliasName() != null) {
6950                                                        TableColumn tableColumn = null;
6951                                                        if (!hasDefinition) {
6952                                                                tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(),
6953                                                                                !hasDefinition);
6954                                                        } else {
6955                                                                tableColumn = tableModel.getColumns().get(i);
6956                                                        }
6957
6958                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
6959                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
6960                                                        }
6961
6962                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6963                                                        relation.setEffectType(EffectType.create_table);
6964                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6965                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6966                                                        Process process = modelFactory.createProcess(stmt);
6967                                                        relation.setProcess(process);
6968                                                } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) {
6969                                                        TableColumn tableColumn = null;
6970                                                        TObjectName columnObj = columnObject.getFieldAttr();
6971                                                        if(columnObj == null) {
6972                                                                columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand();
6973                                                        }
6974                                                        if ((columnObj == null || columnObj.toString().endsWith("*")) && !resultColumn.getName().endsWith("*")) {
6975                                                                columnObj = new TObjectName();
6976                                                                columnObj.setString(resultColumn.getName());
6977                                                        }
6978
6979                                                        if(columnObj == null){
6980                                                                logger.info("Can't handle column " + resultColumn.getName());
6981                                                                continue;
6982                                                        }
6983
6984                                                        if (!hasDefinition) {
6985                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObj,
6986                                                                                !hasDefinition);
6987                                                                if (tableColumn == null) {
6988                                                                        if (tableModel.getColumns().isEmpty()) {
6989                                                                                logger.info("Add table " + tableModel.getName() + " column " + columnObj.toString() + " failed");
6990                                                                        }
6991                                                                        else if (resultColumn.getName().endsWith("*")) {
6992                                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
6993                                                                                        tableColumn = tableModel.getColumns().get(j);
6994                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
6995                                                                                        relation.setEffectType(EffectType.create_table);
6996                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
6997                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
6998                                                                                        if (tableColumn.getName().endsWith("*")
6999                                                                                                        && resultColumn.getName().endsWith("*")) {
7000                                                                                                tableModel.setStarStmt("create_table");
7001                                                                                        }
7002                                                                                        Process process = modelFactory.createProcess(stmt);
7003                                                                                        relation.setProcess(process);
7004                                                                                }
7005                                                                        }
7006                                                                        continue;
7007                                                                }
7008                                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7009                                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
7010                                                                }
7011
7012                                                                Object model = modelManager
7013                                                                                .getModel(resultColumn.getColumnObject());
7014                                                                if (model instanceof ResultColumn) {
7015                                                                        ResultColumn column = (ResultColumn) model;
7016                                                                        if (tableColumn.getName().endsWith("*") && column != null
7017                                                                                        && !column.getStarLinkColumns().isEmpty()) {
7018                                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7019                                                                        }
7020
7021                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7022                                                                        relation.setEffectType(EffectType.create_table);
7023                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7024                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7025                                                                        if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
7026                                                                                tableModel.setStarStmt("create_table");
7027                                                                        }
7028                                                                        Process process = modelFactory.createProcess(stmt);
7029                                                                        relation.setProcess(process);
7030                                                                }
7031                                                                else if(model instanceof LinkedHashMap) {
7032                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
7033                                                                        LinkedHashMap<String, ResultColumn> resultColumns =  (LinkedHashMap<String, ResultColumn>)model;
7034                                                                        if (columnObj.toString().endsWith("*")) {
7035                                                                                for (String key : resultColumns.keySet()) {
7036                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName());
7037                                                                                        DataFlowRelationship relation = modelFactory
7038                                                                                                        .createDataFlowRelation();
7039                                                                                        relation.setEffectType(EffectType.create_table);
7040                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7041                                                                                        relation.addSource(
7042                                                                                                        new ResultColumnRelationshipElement(resultColumns.get(key)));
7043                                                                                        Process process = modelFactory.createProcess(stmt);
7044                                                                                        relation.setProcess(process);
7045                                                                                }
7046                                                                        } else if (resultColumns.containsKey(columnName)) {
7047                                                                                ResultColumn column = resultColumns.get(columnName);
7048                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName());
7049                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7050                                                                                relation.setEffectType(EffectType.create_table);
7051                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7052                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
7053                                                                                Process process = modelFactory.createProcess(stmt);
7054                                                                                relation.setProcess(process);
7055                                                                        }
7056                                                                }
7057                                                        } else {
7058                                                                if (resultColumn.getName().endsWith("*")) {
7059                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
7060                                                                                tableColumn = tableModel.getColumns().get(j);
7061                                                                                ResultColumn column = (ResultColumn) modelManager
7062                                                                                                .getModel(resultColumn.getColumnObject());
7063                                                                                if (tableColumn.getName().endsWith("*") && column != null
7064                                                                                                && !column.getStarLinkColumns().isEmpty()) {
7065                                                                                        tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7066                                                                                }
7067
7068                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7069                                                                                relation.setEffectType(EffectType.create_table);
7070                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7071                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7072                                                                                if (tableColumn.getName().endsWith("*")
7073                                                                                                && resultColumn.getName().endsWith("*")) {
7074                                                                                        tableModel.setStarStmt("create_table");
7075                                                                                        ;
7076                                                                                }
7077                                                                                Process process = modelFactory.createProcess(stmt);
7078                                                                                relation.setProcess(process);
7079                                                                        }
7080                                                                } else {
7081                                                                        tableColumn = tableModel.getColumns().get(i);
7082                                                                        Object model = modelManager
7083                                                                                        .getModel(resultColumn.getColumnObject());
7084                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
7085                                                                        if(model instanceof LinkedHashMap) {
7086                                                                                LinkedHashMap<String, ResultColumn> resultColumns =  (LinkedHashMap<String, ResultColumn>)model;
7087                                                                                if (resultColumns.size() == tableModel.getColumns().size()) {
7088                                                                                        int j = 0;
7089                                                                                        for (String key : resultColumns.keySet()) {
7090                                                                                                if (j == i) {
7091                                                                                                        ResultColumn column = resultColumns.get(key);
7092                                                                                                        DataFlowRelationship relation = modelFactory
7093                                                                                                                        .createDataFlowRelation();
7094                                                                                                        relation.setEffectType(EffectType.create_table);
7095                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7096                                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
7097                                                                                                        Process process = modelFactory.createProcess(stmt);
7098                                                                                                        relation.setProcess(process);
7099                                                                                                }
7100                                                                                                j++;
7101                                                                                        }
7102                                                                                } else if (resultColumns.containsKey(columnName)) {
7103                                                                                        ResultColumn column = resultColumns.get(columnName);
7104                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, column.getName());
7105                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7106                                                                                        relation.setEffectType(EffectType.create_table);
7107                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7108                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
7109                                                                                        Process process = modelFactory.createProcess(stmt);
7110                                                                                        relation.setProcess(process);
7111                                                                                } else {
7112                                                                                        throw new UnsupportedOperationException("Can't handle this star case.");
7113                                                                                }
7114                                                                        }
7115                                                                        else if (model instanceof ResultColumn) {
7116                                                                                ResultColumn column = (ResultColumn) modelManager
7117                                                                                                .getModel(resultColumn.getColumnObject());
7118                                                                                if (tableColumn.getName().endsWith("*") && column != null
7119                                                                                                && !column.getStarLinkColumns().isEmpty()) {
7120                                                                                        tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7121                                                                                }
7122
7123                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7124                                                                                relation.setEffectType(EffectType.create_table);
7125                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7126                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7127                                                                                if (tableColumn.getName().endsWith("*")
7128                                                                                                && resultColumn.getName().endsWith("*")) {
7129                                                                                        tableModel.setStarStmt("create_table");
7130                                                                                }
7131                                                                                Process process = modelFactory.createProcess(stmt);
7132                                                                                relation.setProcess(process);
7133                                                                        }
7134                                                                }
7135                                                        }
7136                                                } else {
7137                                                        TableColumn tableColumn = null;
7138                                                        if (!hasDefinition) {
7139                                                                TObjectName columnName = new TObjectName();
7140                                                                columnName.setString(resultColumn.getColumnObject().toString());
7141                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName, !hasDefinition);
7142                                                                if(tableColumn == null){
7143                                                                        continue;
7144                                                                }
7145                                                        } else {
7146                                                                tableColumn = tableModel.getColumns().get(i);
7147                                                        }
7148                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
7149                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
7150                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7151                                                        }
7152
7153                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7154                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7155                                                        }
7156
7157                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7158                                                        relation.setEffectType(EffectType.create_table);
7159                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7160                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7161                                                        Process process = modelFactory.createProcess(stmt);
7162                                                        relation.setProcess(process);
7163                                                }
7164                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
7165                                                TableColumn tableColumn = null;
7166                                                if (!hasDefinition) {
7167                                                        tableColumn = modelFactory.createTableColumn(tableModel,
7168                                                                        (TObjectName) resultColumn.getColumnObject(), !hasDefinition);
7169                                                } else {
7170                                                        tableColumn = tableModel.getColumns().get(i);
7171                                                }
7172
7173                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7174                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
7175                                                }
7176
7177                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7178                                                relation.setEffectType(EffectType.create_table);
7179                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7180                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7181                                                Process process = modelFactory.createProcess(stmt);
7182                                                relation.setProcess(process);
7183                                        }
7184                                }
7185                        } else if (stmt.getSubQuery() != null) {
7186                                SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(stmt.getSubQuery());
7187                                if(resultSetModel.isDetermined()){
7188                                        tableModel.setDetermined(true);
7189                                        tableModel.setFromDDL(true);
7190                                }
7191                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
7192                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
7193                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
7194                                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
7195
7196                                                TAliasClause alias = columnObject.getAliasClause();
7197                                                if (alias != null && alias.getAliasName() != null) {
7198                                                        TableColumn tableColumn = null;
7199                                                        if (!hasDefinition) {
7200                                                                tableColumn = modelFactory.createTableColumn(tableModel, alias.getAliasName(),
7201                                                                                !hasDefinition);
7202                                                                if (tableColumn == null) {
7203                                                                        continue;
7204                                                                }
7205                                                        } else {
7206                                                                tableColumn = tableModel.getColumns().get(i);
7207                                                        }
7208
7209                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7210                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7211                                                        }
7212
7213                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7214                                                        relation.setEffectType(EffectType.create_table);
7215                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7216                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7217                                                        Process process = modelFactory.createProcess(stmt);
7218                                                        relation.setProcess(process);
7219                                                } else if (columnObject.getFieldAttr() != null || (columnObject.getExpr()!=null && columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t)) {
7220                                                        TableColumn tableColumn = null;
7221                                                        TObjectName columnObj = columnObject.getFieldAttr();
7222                                                        if(columnObj == null) {
7223                                                                columnObj = columnObject.getExpr().getLeftOperand().getObjectOperand();
7224                                                        }
7225                                                        if (!hasDefinition) {
7226                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnObj,
7227                                                                                !hasDefinition);
7228                                                                if (tableColumn == null) {
7229                                                                        continue;
7230                                                                }
7231                                                        } else {
7232                                                                tableColumn = tableModel.getColumns().get(i);
7233                                                        }
7234                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
7235                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
7236                                                                tableColumn.bindStarLinkColumns(column.getStarLinkColumns());
7237                                                        }
7238
7239                                                        if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7240                                                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7241                                                        }
7242
7243                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7244                                                        relation.setEffectType(EffectType.create_table);
7245                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7246                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7247                                                        Process process = modelFactory.createProcess(stmt);
7248                                                        relation.setProcess(process);
7249                                                } else {
7250                                                        ErrorInfo errorInfo = new ErrorInfo();
7251                                                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7252                                                        errorInfo.setErrorMessage("Can't handle the table column " + columnObject.toString());
7253                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(
7254                                                                        columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo,
7255                                                                        ModelBindingManager.getGlobalHash()));
7256                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo,
7257                                                                        columnObject.getEndToken().columnNo + columnObject.getEndToken().getAstext().length(),
7258                                                                        ModelBindingManager.getGlobalHash()));
7259                                                        errorInfos.add(errorInfo);
7260                                                        continue;
7261                                                }
7262                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
7263                                                TableColumn tableColumn = null;
7264                                                if (!hasDefinition) {
7265                                                        tableColumn = modelFactory.createTableColumn(tableModel,
7266                                                                        (TObjectName) resultColumn.getColumnObject(), !hasDefinition);
7267                                                } else {
7268                                                        tableColumn = tableModel.getColumns().get(i);
7269                                                }
7270
7271                                                if (!tableColumn.getName().endsWith("*") && tableModel.isDetermined()) {
7272                                                        appendTableColumnToSQLEnv(tableModel, tableColumn);
7273                                                }
7274
7275                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7276                                                relation.setEffectType(EffectType.create_table);
7277                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7278                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
7279                                                Process process = modelFactory.createProcess(stmt);
7280                                                relation.setProcess(process);
7281                                        }
7282                                }
7283                        } else if (stmt.getLikeTableName() != null) {
7284                                Table likeTableModel = modelFactory.createTableByName(stmt.getLikeTableName());
7285
7286                                if(likeTableModel.isCreateTable()){
7287                                        for(TableColumn column: likeTableModel.getColumns()){
7288                                                TObjectName tableColumn = new TObjectName();
7289                                                tableColumn.setString(column.getName());
7290                                                TableColumn createTableColumn = modelFactory.createTableColumn(tableModel, tableColumn, true);
7291                                                createTableColumn.setPrimaryKey(column.getPrimaryKey());
7292                                                createTableColumn.setForeignKey(column.getForeignKey());
7293                                                createTableColumn.setIndexKey(column.getIndexKey());
7294                                                createTableColumn.setUnqiueKey(column.getUnqiueKey());
7295                                                createTableColumn.setDataType(column.getDataType());
7296                                        }
7297                                        tableModel.setCreateTable(true);
7298                                }
7299
7300//                              Process process = modelFactory.createProcess(stmt);
7301//                              process.setType("Like Table");
7302//                              tableModel.addProcess(process);
7303//
7304//
7305//                              DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7306//                              relation.setEffectType(EffectType.like_table);
7307//                              relation.setTarget(
7308//                                              new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
7309//                              relation.addSource(
7310//                                              new RelationRowsRelationshipElement<TableRelationRows>(likeTableModel.getRelationRows()));
7311//                              relation.setProcess(process);
7312                        }
7313
7314                        if (stmt.getStageLocation() != null && stmt.getStageLocation().getStageName() != null) {
7315                                tableModel
7316                                                .setLocation(DlineageUtil.getTableFullName(stmt.getStageLocation().getStageName().toString()));
7317                                Process process = modelFactory.createProcess(stmt);
7318                                process.setType("Create External Table");
7319                                tableModel.addProcess(process);
7320                                Table stage = modelManager.getTableByName(DlineageUtil.getTableFullName(tableModel.getLocation()));
7321                                if (stage == null) {
7322                                        stage = modelManager.getTableByName(
7323                                                        DlineageUtil.getTableFullName(stmt.getStageLocation().toString().replaceFirst("@", "")));
7324                                }
7325                                if (stage == null) {
7326                                        stage = modelFactory.createTableByName(stmt.getStageLocation().toString().replaceFirst("@", ""),
7327                                                        false);
7328                                        stage.setCreateTable(false);
7329                                        stage.setStage(true);
7330                                        if (stmt.getStageLocation().getPath() != null) {
7331                                                stage.setLocation(stmt.getStageLocation().getPath().toString());
7332                                                TObjectName location = new TObjectName();
7333                                                location.setString(stmt.getStageLocation().getPath().toString());
7334                                                modelFactory.createStageLocation(stage, location);
7335                                        } else if (stmt.getRegex_pattern() != null) {
7336                                                stage.setLocation(stmt.getRegex_pattern());
7337                                                TObjectName location = new TObjectName();
7338                                                location.setString(stmt.getRegex_pattern());
7339                                                modelFactory.createStageLocation(stage, location);
7340                                        } else {
7341                                                stage.setLocation("unknownPath");
7342                                                TObjectName location = new TObjectName();
7343                                                location.setString("unknownPath");
7344                                                modelFactory.createStageLocation(stage, location);
7345                                        }
7346                                }
7347                                if (stage != null && !stage.getColumns().isEmpty()) {
7348                                        if (!tableModel.getColumns().isEmpty()) {
7349                                                for (int i = 0; i < tableModel.getColumns().size(); i++) {
7350                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7351                                                        relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
7352                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
7353                                                        relation.setProcess(process);
7354                                                }
7355                                        } else {
7356                                                TObjectName starColumn = new TObjectName();
7357                                                starColumn.setString("*");
7358                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
7359                                                tableColumn.setExpandStar(false);
7360                                                tableColumn.setShowStar(true);
7361                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7362                                                relation.addSource(new TableColumnRelationshipElement(stage.getColumns().get(0)));
7363                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7364                                                relation.setProcess(process);
7365                                        }
7366                                }
7367                        } else if (stmt.getTableOptions() != null && !stmt.getTableOptions().isEmpty()) {
7368                                for (int i = 0; i < stmt.getTableOptions().size(); i++) {
7369                                        TCreateTableOption createTableOption = stmt.getTableOptions().get(i);
7370                                        if (createTableOption.getCreateTableOptionType() != ECreateTableOption.etoBigQueryExternal)
7371                                                continue;
7372                                        List<String> uris = createTableOption.getUris();
7373                                        if (uris == null || uris.isEmpty())
7374                                                continue;
7375                                        Process process = modelFactory.createProcess(stmt);
7376                                        process.setType("Create External Table");
7377                                        tableModel.addProcess(process);
7378                                        if (tableModel.getColumns().isEmpty()) {
7379                                                TObjectName starColumn = new TObjectName();
7380                                                starColumn.setString("*");
7381                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
7382                                                tableColumn.setExpandStar(false);
7383                                                tableColumn.setShowStar(true);
7384                                        }
7385                                        for (String uri : uris) {
7386                                                Table uriFile = modelFactory.createTableByName(uri, true);
7387                                                uriFile.setPath(true);
7388                                                uriFile.setFileFormat(createTableOption.getFormat());
7389                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
7390                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7391                                                        if (stmt.getColumnList() != null) {
7392                                                                TObjectName fileUri = new TObjectName();
7393                                                                fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString());
7394                                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7395                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7396                                                        } else {
7397                                                                TObjectName fileUri = new TObjectName();
7398                                                                fileUri.setString("*");
7399                                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7400                                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7401                                                        }
7402                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
7403                                                        relation.setProcess(process);
7404                                                }
7405                                                if (tableModel.getColumns().isEmpty()) {
7406                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7407                                                        TObjectName fileUri = new TObjectName();
7408                                                        fileUri.setString("*");
7409                                                        TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7410                                                        relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7411                                                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
7412                                                                        tableModel.getRelationRows()));
7413                                                        relation.setProcess(process);
7414                                                }
7415                                        }
7416                                }
7417                        } else if (stmt.getSubQuery() == null && stmt.getTableLocation() != null) {
7418                                Process process = modelFactory.createProcess(stmt);
7419                                process.setType("Create External Table");
7420                                tableModel.addProcess(process);
7421                                Table uriFile = modelFactory.createTableByName(stmt.getTableLocation(), true);
7422                                uriFile.setPath(true);
7423                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
7424                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7425                                        if (stmt.getColumnList() != null) {
7426                                                TObjectName fileUri = new TObjectName();
7427                                                fileUri.setString(tableModel.getColumns().get(j).getColumnObject().toString());
7428                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7429                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7430                                        } else {
7431                                                TObjectName fileUri = new TObjectName();
7432                                                fileUri.setString("*");
7433                                                TableColumn fileUriColumn = modelFactory.createFileUri(uriFile, fileUri);
7434                                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7435                                        }
7436                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(j)));
7437                                        relation.setProcess(process);
7438                                }
7439                        }
7440
7441                        if (stmt.getTableConstraints() != null && stmt.getTableConstraints().size() > 0) {
7442                                for (int i = 0; i < stmt.getTableConstraints().size(); i++) {
7443                                        TConstraint createTableConstraint = stmt.getTableConstraints().getConstraint(i);
7444                                        TPTNodeList<TColumnWithSortOrder> keyNames = createTableConstraint.getColumnList();
7445                                        if (keyNames != null) {
7446                                                for (int k = 0; k < keyNames.size(); k++) {
7447                                                        TObjectName keyName = keyNames.getElement(k).getColumnName();
7448                                                        // Skip functional indexes (expression-based indexes) where columnName is null
7449                                                        if (keyName == null) {
7450                                                                continue;
7451                                                        }
7452                                                        TObjectName referencedTableName = createTableConstraint.getReferencedObject();
7453                                                        TObjectNameList referencedTableColumns = createTableConstraint.getReferencedColumnList();
7454
7455                                                        TableColumn tableConstraint = modelFactory.createTableColumn(tableModel, keyName, true);
7456                                                        if (createTableConstraint.getConstraint_type() == EConstraintType.primary_key) {
7457                                                                tableConstraint.setPrimaryKey(true);
7458                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.table_index) {
7459                                                                tableConstraint.setIndexKey(true);
7460                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.unique) {
7461                                                                tableConstraint.setUnqiueKey(true);
7462                                                        } else if (createTableConstraint.getConstraint_type() == EConstraintType.foreign_key) {
7463                                                                tableConstraint.setForeignKey(true);
7464                                                                Table referencedTable = modelManager
7465                                                                                .getTableByName(DlineageUtil.getTableFullName(referencedTableName.toString()));
7466                                                                if (referencedTable == null) {
7467                                                                        referencedTable = modelFactory.createTableByName(referencedTableName);
7468                                                                }
7469
7470                                                                if (referencedTableColumns != null) {
7471                                                                        for (int j = 0; j < referencedTableColumns.size(); j++) {
7472                                                                                TableColumn tableColumn = modelFactory.createTableColumn(referencedTable,
7473                                                                                                referencedTableColumns.getObjectName(j), false);
7474                                                                                if (tableColumn != null) {
7475                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7476                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
7477                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableConstraint));
7478                                                                                        relation.setEffectType(EffectType.foreign_key);
7479                                                                                        Process process = modelFactory.createProcess(stmt);
7480                                                                                        relation.setProcess(process);
7481                                                                                        if (this.option.isShowERDiagram()) {
7482                                                                                                ERRelationship erRelation = modelFactory.createERRelation();
7483                                                                                                erRelation.addSource(new TableColumnRelationshipElement(tableColumn));
7484                                                                                                erRelation
7485                                                                                                                .setTarget(new TableColumnRelationshipElement(tableConstraint));
7486                                                                                        }
7487                                                                                }
7488                                                                        }
7489                                                                }
7490                                                        }
7491                                                }
7492                                        }
7493                                }
7494                        }
7495
7496                        if (stmt.getHiveTablePartition() != null && stmt.getHiveTablePartition().getColumnDefList() != null) {
7497                                for (int i = 0; i < stmt.getHiveTablePartition().getColumnDefList().size(); i++) {
7498                                        TColumnDefinition column = stmt.getHiveTablePartition().getColumnDefList().getColumn(i);
7499                                        modelFactory.createTableColumn(tableModel, column.getColumnName(), true);
7500                                        appendTableColumnToSQLEnv(tableModel, column.getColumnName());
7501                                }
7502                        }
7503
7504                } else {
7505                        ErrorInfo errorInfo = new ErrorInfo();
7506                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7507                        errorInfo.setErrorMessage("Can't get target table. CreateTableSqlStatement is " + stmt.toString());
7508                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7509                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7510                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7511                                        stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
7512                                        ModelBindingManager.getGlobalHash()));
7513                        errorInfos.add(errorInfo);
7514                }
7515        }
7516
7517        protected void flattenStructColumns(boolean hasDefinition, Table tableModel, TColumnDefinition column,
7518                        Stack<TColumnDefinition> columnPaths, int index) {
7519                columnPaths.push(column);
7520                for (int j = 0; j < column.getDatatype().getColumnDefList().size(); j++) {
7521                        TColumnDefinition columnDefinition = column.getDatatype().getColumnDefList().getColumn(j);
7522                        if (columnDefinition.getDatatype().getColumnDefList() != null) {
7523                                flattenStructColumns(hasDefinition, tableModel, columnDefinition, columnPaths, index);
7524                        } else {
7525                                TObjectName columnName = new TObjectName();
7526                                columnName.setString(getColumnName(columnPaths, columnDefinition));
7527                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnName, hasDefinition);
7528                                tableColumn.setColumnIndex(index);
7529                                tableColumn.setStruct(true);
7530                                
7531                                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
7532                                        CrudRelationship crudRelationship = modelFactory.createCrudRelation();
7533                                        crudRelationship.setTarget(new TableColumnRelationshipElement(tableColumn));
7534                                        crudRelationship.setEffectType(EffectType.create_table);
7535                                }
7536                                
7537                                appendTableColumnToSQLEnv(tableModel, tableColumn);
7538                        }
7539                }
7540                columnPaths.pop();
7541        }
7542
7543        private String getColumnName(Stack<TColumnDefinition> columnPaths, TColumnDefinition column) {
7544                StringBuilder buffer = new StringBuilder();
7545                Iterator<TColumnDefinition> iter = columnPaths.iterator();
7546                while(iter.hasNext()) {
7547                        buffer.append(iter.next().getColumnName().getColumnNameOnly()).append(".");
7548                }
7549                buffer.append(column.getColumnName().getColumnNameOnly());
7550                return buffer.toString();
7551        }
7552
7553        private void appendTableColumnToSQLEnv(Table tableModel, TableColumn tableColumn) {
7554                //tableModel如果非determined,请不要添加到sqlenv里
7555                if (sqlenv != null && tableColumn!=null) {
7556                        TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true);
7557                        if (schema != null) {
7558                                TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
7559                                if (tableColumn.hasStarLinkColumn()) {
7560                                        for (String column : tableColumn.getStarLinkColumnNames()) {
7561                                                tempTable.addColumn(DlineageUtil.getColumnNameOnly(column));
7562                                        }
7563                                } else {
7564                                        tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getName()));
7565                                }
7566                        }
7567                }
7568        }
7569
7570        private void appendTableColumnToSQLEnv(Table tableModel, TObjectName tableColumn) {
7571                if (sqlenv != null) {
7572                        TSQLSchema schema = sqlenv.getSQLSchema(DlineageUtil.getTableSchema(tableModel), true);
7573                        if (schema != null) {
7574                                TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
7575                                tempTable.addColumn(DlineageUtil.getColumnNameOnly(tableColumn.getColumnNameOnly()));
7576                        }
7577                }
7578        }
7579
7580        private void analyzeCreateStageStmt(TCreateStageStmt stmt) {
7581                TObjectName stageName = stmt.getStageName();
7582
7583                if (stageName != null) {
7584
7585                        Table tableModel = modelFactory.createStage(stageName);
7586                        tableModel.setCreateTable(true);
7587                        tableModel.setStage(true);
7588                        tableModel.setLocation(stmt.getExternalStageURL());
7589
7590                        Process process = modelFactory.createProcess(stmt);
7591                        tableModel.addProcess(process);
7592
7593                        TableColumn locationColumn = null;
7594                        if (stmt.getExternalStageURL() != null) {
7595                                TObjectName location = new TObjectName();
7596                                location.setString(stmt.getExternalStageURL());
7597                                locationColumn = modelFactory.createStageLocation(tableModel, location);
7598
7599                                Table pathModel = modelFactory.createTableByName(stmt.getExternalStageURL(), true);
7600                                pathModel.setPath(true);
7601                                pathModel.setCreateTable(true);
7602                                TObjectName fileUri = new TObjectName();
7603                                fileUri.setString(stmt.getExternalStageURL());
7604                                TableColumn fileUriColumn = modelFactory.createFileUri(pathModel, fileUri);
7605
7606                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7607                                relation.addSource(new TableColumnRelationshipElement(fileUriColumn));
7608                                relation.setTarget(new TableColumnRelationshipElement(locationColumn));
7609                                relation.setProcess(process);
7610
7611                        } else {
7612                                for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) {
7613                                        if (temp instanceof TPutStmt) {
7614                                                TPutStmt put = (TPutStmt) temp;
7615                                                TStageLocation stageLocation = put.getStageLocation();
7616                                                if (stageLocation != null && stageLocation.getStageName() != null) {
7617                                                        Table stage = modelManager.getTableByName(
7618                                                                        DlineageUtil.getTableFullName(stageLocation.getStageName().toString()));
7619                                                        if (stage == tableModel) {
7620                                                                TObjectName location = new TObjectName();
7621                                                                if (!SQLUtil.isEmpty(put.getFileName())) {
7622                                                                        location.setString(put.getFileName());
7623                                                                        locationColumn = modelFactory.createStageLocation(tableModel, location);
7624                                                                }
7625                                                                break;
7626                                                        }
7627                                                }
7628                                        }
7629                                }
7630                        }
7631
7632                        String fileFormat = stmt.getFileFormatName();
7633                        if (fileFormat != null) {
7634                                for (TCustomSqlStatement temp : stmt.getGsqlparser().getSqlstatements()) {
7635                                        if (temp instanceof TCreateFileFormatStmt) {
7636                                                TCreateFileFormatStmt fileFormatStmt = (TCreateFileFormatStmt) temp;
7637                                                if (fileFormatStmt.getFileFormatName() != null
7638                                                                && fileFormatStmt.getFileFormatName().toString().equalsIgnoreCase(fileFormat)) {
7639                                                        tableModel.setFileType(fileFormatStmt.getTypeName());
7640                                                        break;
7641                                                }
7642                                        }
7643                                }
7644                        }
7645
7646                        String procedureParent = getProcedureParentName(stmt);
7647                        if (procedureParent != null) {
7648                                tableModel.setParent(procedureParent);
7649                        }
7650
7651                        if (locationColumn != null) {
7652                                List<Table> tables = modelManager.getTablesByName();
7653                                if (tables != null) {
7654                                        for (Table referTable : tables) {
7655                                                if (referTable.getLocation() != null && referTable.getLocation()
7656                                                                .equals(DlineageUtil.getIdentifierNormalTableName(tableModel.getName()))) {
7657                                                        for (int i = 0; i < referTable.getColumns().size(); i++) {
7658                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7659                                                                relation.addSource(new TableColumnRelationshipElement(locationColumn));
7660                                                                relation.setTarget(new TableColumnRelationshipElement(referTable.getColumns().get(i)));
7661                                                        }
7662                                                }
7663                                        }
7664                                }
7665                        }
7666                } else {
7667                        ErrorInfo errorInfo = new ErrorInfo();
7668                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7669                        errorInfo.setErrorMessage("Can't get target table. CreateStageStmt is " + stmt.toString());
7670                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7671                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7672                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7673                                        stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
7674                                        ModelBindingManager.getGlobalHash()));
7675                        errorInfo.fillInfo(this);
7676                        errorInfos.add(errorInfo);
7677                }
7678        }
7679
7680        private void analyzeCreateExternalDataSourceStmt(TCreateExternalDataSourceStmt stmt) {
7681                TObjectName dataSourceName = stmt.getDataSourceName();
7682                String locationUrl = stmt.getOption("LOCATION");
7683                if (dataSourceName != null && locationUrl != null) {
7684                        Table tableModel = modelFactory.createDataSource(dataSourceName);
7685                        tableModel.setCreateTable(true);
7686                        tableModel.setDataSource(true);
7687                        tableModel.setLocation(locationUrl);
7688
7689                        Process process = modelFactory.createProcess(stmt);
7690                        tableModel.addProcess(process);
7691
7692                        TObjectName location = new TObjectName();
7693                        location.setString(locationUrl);
7694                        modelFactory.createTableColumn(tableModel, location, true);
7695
7696                        String procedureParent = getProcedureParentName(stmt);
7697                        if (procedureParent != null) {
7698                                tableModel.setParent(procedureParent);
7699                        }
7700                } else {
7701                        ErrorInfo errorInfo = new ErrorInfo();
7702                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
7703                        errorInfo.setErrorMessage("Can't get target table. CreateExternalDataSourceStmt is " + stmt.toString());
7704                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
7705                                        stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
7706                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
7707                                        stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
7708                                        ModelBindingManager.getGlobalHash()));
7709                        errorInfo.fillInfo(this);
7710                        errorInfos.add(errorInfo);
7711                }
7712        }
7713
7714        private void analyzeCreateStreamStmt(TCreateStreamStmt stmt) {
7715                TObjectName streamName = stmt.getStreamName();
7716
7717                if (streamName != null) {
7718                        Table tableModel = modelFactory.createTableByName(stmt.getTableName());
7719                        tableModel.setCreateTable(true);
7720
7721                        Table streamModel = modelFactory.createStream(streamName);
7722                        streamModel.setCreateTable(true);
7723                        streamModel.setStream(true);
7724
7725                        Process process = modelFactory.createProcess(stmt);
7726                        tableModel.addProcess(process);
7727
7728                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7729                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(streamModel.getRelationRows()));
7730                        relation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
7731                        relation.setProcess(process);
7732                }
7733        }
7734
7735        private String getProcedureParentName(TCustomSqlStatement stmt) {
7736                if (stmt instanceof TStoredProcedureSqlStatement) {
7737                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
7738                                return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
7739                        }
7740                }
7741
7742                stmt = stmt.getParentStmt();
7743                if (stmt == null)
7744                        return null;
7745
7746        if (stmt instanceof TCommonBlock) {
7747                        if(((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
7748                                stmt = (TStoredProcedureSqlStatement)((TCommonBlock) stmt).getBlockBody().getParentObjectName();
7749                        }
7750                }
7751
7752                if (stmt instanceof TStoredProcedureSqlStatement) {
7753                        if (((TStoredProcedureSqlStatement) stmt).getStoredProcedureName() != null) {
7754                                return ((TStoredProcedureSqlStatement) stmt).getStoredProcedureName().toString();
7755                        }
7756                }
7757                if (stmt instanceof TTeradataCreateProcedure) {
7758                        if (((TTeradataCreateProcedure) stmt).getProcedureName() != null) {
7759                                return ((TTeradataCreateProcedure) stmt).getProcedureName().toString();
7760                        }
7761                }
7762
7763                return getProcedureParentName(stmt);
7764        }
7765
7766        private TStoredProcedureSqlStatement getProcedureParent(TCustomSqlStatement stmt) {
7767                if (stmt instanceof TStoredProcedureSqlStatement) {
7768                        return (TStoredProcedureSqlStatement) stmt;
7769                }
7770
7771                stmt = stmt.getParentStmt();
7772                if (stmt == null)
7773                        return null;
7774
7775                if (stmt instanceof TCommonBlock) {
7776                        if (((TCommonBlock) stmt).getBlockBody().getParentObjectName() instanceof TStoredProcedureSqlStatement) {
7777                                stmt = (TStoredProcedureSqlStatement) ((TCommonBlock) stmt).getBlockBody().getParentObjectName();
7778                        }
7779                }
7780
7781                if (stmt instanceof TStoredProcedureSqlStatement) {
7782                        return ((TStoredProcedureSqlStatement) stmt);
7783                }
7784                if (stmt instanceof TTeradataCreateProcedure) {
7785                        return ((TTeradataCreateProcedure) stmt);
7786                }
7787
7788                return getProcedureParent(stmt);
7789        }
7790
7791        private void analyzeMergeStmt(TMergeSqlStatement stmt) {
7792                Object tableModel;
7793                Process process;
7794                if (stmt.getUsingTable() != null) {
7795                        TTable table = stmt.getTargetTable();
7796                        if(table.getSubquery()!=null) {
7797                                tableModel = modelFactory.createQueryTable(table);
7798                                analyzeSelectStmt(table.getSubquery());
7799                                process = modelFactory.createProcess(stmt);
7800                        }
7801                        else {
7802                                tableModel = modelFactory.createTable(table);
7803                                process = modelFactory.createProcess(stmt);
7804                                ((Table)tableModel).addProcess(process);
7805                        }
7806                        
7807                        for(TTable item: stmt.tables) {
7808                                if(item.getSubquery()!=null) {
7809                                        continue;
7810                                }
7811                                Table tableItemModel = modelFactory.createTable(item);                          
7812                                if (tableItemModel.getColumns() == null || tableItemModel.getColumns().isEmpty()) {
7813                                        tableItemModel.addColumnsFromSQLEnv();
7814                                }
7815                        }
7816
7817                        if (stmt.getUsingTable().getSubquery() != null) {
7818                                QueryTable queryTable = modelFactory.createQueryTable(stmt.getUsingTable());
7819                                analyzeSelectStmt(stmt.getUsingTable().getSubquery());
7820
7821                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getUsingTable().getSubquery());
7822                                
7823                                if (queryTable != null && resultSetModel != null && queryTable != resultSetModel) {
7824                                        if (queryTable.getColumns().size() == resultSetModel.getColumns().size()) {
7825                                                for (int i = 0; i < queryTable.getColumns().size(); i++) {
7826                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7827                                                        relation.setEffectType(EffectType.select);
7828                                                        relation.setTarget(new ResultColumnRelationshipElement(queryTable.getColumns().get(i)));
7829                                                        relation.addSource(new ResultColumnRelationshipElement(resultSetModel.getColumns().get(i)));
7830                                                        relation.setProcess(process);
7831                                                }
7832                                        }
7833                                }
7834                                
7835                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
7836                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
7837                                        impactRelation.setEffectType(EffectType.merge);
7838                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
7839                                                        resultSetModel.getRelationRows()));
7840                                        if (tableModel instanceof Table) {
7841                                                impactRelation.setTarget(
7842                                                                new RelationRowsRelationshipElement<TableRelationRows>(((Table)tableModel).getRelationRows()));
7843                                        }
7844                                        else {
7845                                                impactRelation.setTarget(
7846                                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)tableModel).getRelationRows()));
7847                                        }
7848                                }
7849                        } else {
7850                                if (stmt.getUsingTable().getAliasClause() != null && stmt.getUsingTable().getAliasClause().getColumns() != null && stmt.getUsingTable().getValueClause().getRows()!=null) {
7851                                        Table usingTable = modelFactory.createTableFromCreateDDL(stmt.getUsingTable(), false, stmt.getUsingTable().getAliasName() + stmt.getUsingTable().getTableName());
7852                                        usingTable.setCreateTable(true);
7853                                        usingTable.setSubType(SubType.function);
7854                                        for (int z=0;z<stmt.getUsingTable().getAliasClause().getColumns().size();z++) {
7855                                                TObjectName columnName = stmt.getUsingTable().getAliasClause().getColumns().getObjectName(z);
7856                                                TableColumn tableColumn = modelFactory.createTableColumn(usingTable, columnName, true);
7857                                                TResultColumn resultColumn = stmt.getUsingTable().getValueClause().getRows().get(0).getResultColumn(z);
7858                                                modelManager.bindModel(resultColumn, tableColumn);
7859                                                analyzeResultColumnExpressionRelation(tableColumn, resultColumn.getExpr());                                             }
7860                                }
7861                                else {
7862                                        modelFactory.createTable(stmt.getUsingTable());
7863                                }
7864                        }
7865                
7866
7867                        if (stmt.getWhenClauses() != null && stmt.getWhenClauses().size() > 0) {
7868                                for (int i = 0; i < stmt.getWhenClauses().size(); i++) {
7869                                        TMergeWhenClause clause = stmt.getWhenClauses().getElement(i);
7870                                        if (clause.getCondition() != null) {
7871                                                analyzeFilterCondition(null, clause.getCondition(), null, null, EffectType.merge_when);
7872                                        }
7873                                        if (clause.getUpdateClause() != null) {
7874                                                TResultColumnList columns = clause.getUpdateClause().getUpdateColumnList();
7875                                                if (columns == null || columns.size() == 0)
7876                                                        continue;
7877
7878                                                ResultSet resultSet = modelFactory.createResultSet(clause.getUpdateClause(), false);
7879                                                createPseudoImpactRelation(stmt, resultSet, EffectType.merge_update);
7880
7881                                                for (int j = 0; j < columns.size(); j++) {
7882                                                        TResultColumn resultColumn = columns.getResultColumn(j);
7883                                                        if (resultColumn.getExpr().getLeftOperand()
7884                                                                        .getExpressionType() == EExpressionType.simple_object_name_t) {
7885                                                                TObjectName columnObject = resultColumn.getExpr().getLeftOperand().getObjectOperand();
7886
7887                                                                if (columnObject.getDbObjectType() == EDbObjectType.variable) {
7888                                                                        continue;
7889                                                                }
7890
7891                                                                if (columnObject.getColumnNameOnly().startsWith("@")
7892                                                                                && (option.getVendor() == EDbVendor.dbvmssql
7893                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
7894                                                                        continue;
7895                                                                }
7896
7897                                                                if (columnObject.getColumnNameOnly().startsWith(":")
7898                                                                                && (option.getVendor() == EDbVendor.dbvhana
7899                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
7900                                                                        continue;
7901                                                                }
7902
7903                                                                ResultColumn updateColumn = modelFactory.createMergeResultColumn(resultSet,
7904                                                                                columnObject);
7905
7906                                                                TExpression valueExpression = resultColumn.getExpr().getRightOperand();
7907                                                                if (valueExpression == null)
7908                                                                        continue;
7909
7910                                                                columnsInExpr visitor = new columnsInExpr();
7911                                                                valueExpression.inOrderTraverse(visitor);
7912                                                                List<TObjectName> objectNames = visitor.getObjectNames();
7913                                                                List<TParseTreeNode> functions = visitor.getFunctions();
7914
7915                                                                if (functions != null && !functions.isEmpty()) {
7916                                                                        analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.merge_update);
7917                                                                }
7918
7919                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
7920                                                                if (subquerys != null && !subquerys.isEmpty()) {
7921                                                                        analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.merge_update);
7922                                                                }
7923
7924                                                                analyzeDataFlowRelation(updateColumn, objectNames, EffectType.merge_update, functions);
7925
7926                                                                List<TParseTreeNode> constants = visitor.getConstants();
7927                                                                analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.merge_update,
7928                                                                                functions);
7929
7930                                                                if (tableModel instanceof Table) {
7931                                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel, columnObject,
7932                                                                                        false);
7933
7934                                                                        if (tableColumn != null) {
7935                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7936                                                                                relation.setEffectType(EffectType.merge_update);
7937                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7938                                                                                relation.addSource(new ResultColumnRelationshipElement(updateColumn));
7939                                                                                relation.setProcess(process);
7940                                                                        }
7941                                                                }
7942                                                                else {
7943                                                                        TTable targetTable = stmt.getTargetTable().getSubquery().getTables().getTable(0);
7944                                                                        if (targetTable != null && modelManager.getModel(targetTable) instanceof Table) {
7945                                                                                Table targetTableModel = (Table) modelManager.getModel(targetTable);
7946                                                                                TableColumn tableColumn = modelFactory
7947                                                                                                .createTableColumn((Table) targetTableModel, columnObject, false);
7948                                                                                if (tableColumn != null) {
7949                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
7950                                                                                        relation.setEffectType(EffectType.merge_update);
7951                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
7952                                                                                        relation.addSource(new ResultColumnRelationshipElement(updateColumn));
7953                                                                                        relation.setProcess(process);
7954                                                                                }
7955                                                                        }
7956                                                                }
7957                                                        }
7958                                                }
7959                                        }
7960                                        if (clause.getInsertClause() != null && tableModel instanceof Table) {
7961                                                TExpression insertValue = clause.getInsertClause().getInsertValue();
7962                                                if (insertValue != null
7963                                                                && insertValue.getExpressionType() == EExpressionType.objectConstruct_t) {
7964                                                        ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false);
7965
7966                                                        createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert);
7967
7968                                                        TObjectConstruct objectConstruct = insertValue.getObjectConstruct();
7969                                                        for (int z = 0; z < objectConstruct.getPairs().size(); z++) {
7970                                                                TPair pair = objectConstruct.getPairs().getElement(z);
7971
7972                                                                if (pair.getKeyName().getExpressionType() == EExpressionType.simple_constant_t) {
7973                                                                        TObjectName columnObject = new TObjectName();
7974                                                                        TConstant constant = pair.getKeyName().getConstantOperand();
7975                                                                        TSourceToken newSt = new TSourceToken(
7976                                                                                        constant.getValueToken().getTextWithoutQuoted());
7977                                                                        columnObject.setPartToken(newSt);
7978                                                                        columnObject.setSourceTable(stmt.getTargetTable());
7979                                                                        columnObject.setStartToken(constant.getStartToken());
7980                                                                        columnObject.setEndToken(constant.getEndToken());
7981
7982                                                                        ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet,
7983                                                                                        columnObject);
7984
7985                                                                        TExpression valueExpression = pair.getKeyValue();
7986                                                                        if (valueExpression == null)
7987                                                                                continue;
7988
7989                                                                        columnsInExpr visitor = new columnsInExpr();
7990                                                                        valueExpression.inOrderTraverse(visitor);
7991                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
7992                                                                        List<TParseTreeNode> functions = visitor.getFunctions();
7993
7994                                                                        if (functions != null && !functions.isEmpty()) {
7995                                                                                analyzeFunctionDataFlowRelation(insertColumn, functions,
7996                                                                                                EffectType.merge_insert);
7997                                                                        }
7998
7999                                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
8000                                                                        if (subquerys != null && !subquerys.isEmpty()) {
8001                                                                                analyzeSubqueryDataFlowRelation(insertColumn, subquerys,
8002                                                                                                EffectType.merge_insert);
8003                                                                        }
8004
8005                                                                        analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert,
8006                                                                                        functions);
8007
8008                                                                        List<TParseTreeNode> constants = visitor.getConstants();
8009                                                                        analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert,
8010                                                                                        functions);
8011
8012                                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)tableModel,
8013                                                                                        columnObject, false);
8014
8015                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8016                                                                        relation.setEffectType(EffectType.merge_insert);
8017                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8018                                                                        relation.addSource(new ResultColumnRelationshipElement(insertColumn));
8019                                                                        relation.setProcess(process);
8020                                                                }
8021                                                        }
8022                                                } else {
8023                                                        TObjectNameList columns = clause.getInsertClause().getColumnList();
8024                                                        TResultColumnList values = clause.getInsertClause().getValuelist();
8025                                                        if (values == null || values.size() == 0) {
8026                                                                if (clause.getInsertClause().toString().toLowerCase().indexOf("row") != -1) {
8027                                                                        if (stmt.getUsingTable().getSubquery() != null) {
8028                                                                                ResultSet sourceResultSet = modelFactory.createQueryTable(stmt.getUsingTable());
8029                                                                                TObjectName targetStarColumn = new TObjectName();
8030                                                                                targetStarColumn.setString("*");
8031                                                                                TableColumn targetTableColumn = modelFactory.createTableColumn((Table)tableModel,
8032                                                                                                targetStarColumn, true);
8033                                                                                if (sourceResultSet.getColumns() == null
8034                                                                                                || sourceResultSet.getColumns().isEmpty()) {
8035                                                                                        TObjectName sourceStarColumn = new TObjectName();
8036                                                                                        sourceStarColumn.setString("*");
8037                                                                                        modelFactory.createResultColumn(sourceResultSet, sourceStarColumn);
8038                                                                                }
8039                                                                                for (ResultColumn sourceColumn : sourceResultSet.getColumns()) {
8040                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8041                                                                                        relation.setEffectType(EffectType.merge_insert);
8042                                                                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
8043                                                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
8044                                                                                        relation.setProcess(process);
8045                                                                                }
8046                                                                        } else {
8047                                                                                Table sourceTable = modelFactory.createTable(stmt.getUsingTable());
8048                                                                                TObjectName sourceStarColumn = new TObjectName();
8049                                                                                sourceStarColumn.setString("*");
8050                                                                                TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable,
8051                                                                                                sourceStarColumn, true);
8052                                                                                TObjectName targetStarColumn = new TObjectName();
8053                                                                                targetStarColumn.setString("*");
8054                                                                                TableColumn targetTableColumn = modelFactory.createTableColumn(((Table)tableModel),
8055                                                                                                targetStarColumn, true);
8056                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8057                                                                                relation.setEffectType(EffectType.merge_insert);
8058                                                                                relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
8059                                                                                relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
8060                                                                                relation.setProcess(process);
8061                                                                        }
8062
8063                                                                }
8064                                                                continue;
8065                                                        }
8066
8067                                                        List<TObjectName> tableColumns = new ArrayList<TObjectName>();
8068                                                        if (columns == null || columns.size() == 0) {
8069//                                                              if (!((Table)tableModel).getColumns().isEmpty()) {
8070//                                                                      for (int j = 0; j < ((Table)tableModel).getColumns().size(); j++) {
8071//                                                                              if (((Table)tableModel).getColumns().get(j).getColumnObject() == null) {
8072//                                                                                      continue;
8073//                                                                              }
8074//                                                                              tableColumns.add(((Table)tableModel).getColumns().get(j).getColumnObject());
8075//                                                                      }
8076//                                                              } else {
8077                                                                        for (int j = 0; j < values.size(); j++) {
8078                                                                                TResultColumn column = values.getResultColumn(j);
8079                                                                                if (column.getAliasClause() != null) {
8080                                                                                        tableColumns.add(column.getAliasClause().getAliasName());
8081                                                                                } else if (column.getFieldAttr() != null) {
8082                                                                                        tableColumns.add(column.getFieldAttr());
8083                                                                                } else {
8084                                                                                        TObjectName columnName = new TObjectName();
8085                                                                                        columnName.setString(column.toString());
8086                                                                                        tableColumns.add(columnName);
8087                                                                                }
8088//                                                                      }
8089                                                                }
8090                                                        } else {
8091                                                                for (int j = 0; j < columns.size(); j++) {
8092                                                                        tableColumns.add(columns.getObjectName(j));
8093                                                                }
8094                                                        }
8095
8096                                                        ResultSet resultSet = modelFactory.createResultSet(clause.getInsertClause(), false);
8097
8098                                                        createPseudoImpactRelation(stmt, resultSet, EffectType.merge_insert);
8099
8100                                                        for (int j = 0; j < tableColumns.size() && j < values.size(); j++) {
8101                                                                TObjectName columnObject = tableColumns.get(j);
8102
8103                                                                ResultColumn insertColumn = modelFactory.createMergeResultColumn(resultSet,
8104                                                                                columnObject);
8105
8106                                                                TExpression valueExpression = values.getResultColumn(j).getExpr();
8107                                                                if (valueExpression == null)
8108                                                                        continue;
8109
8110                                                                columnsInExpr visitor = new columnsInExpr();
8111                                                                valueExpression.inOrderTraverse(visitor);
8112                                                                List<TObjectName> objectNames = visitor.getObjectNames();
8113                                                                List<TParseTreeNode> functions = visitor.getFunctions();
8114
8115                                                                if (functions != null && !functions.isEmpty()) {
8116                                                                        analyzeFunctionDataFlowRelation(insertColumn, functions, EffectType.merge_insert);
8117                                                                }
8118
8119                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
8120                                                                if (subquerys != null && !subquerys.isEmpty()) {
8121                                                                        analyzeSubqueryDataFlowRelation(insertColumn, subquerys, EffectType.merge_insert);
8122                                                                }
8123
8124                                                                analyzeDataFlowRelation(insertColumn, objectNames, EffectType.merge_insert, functions);
8125
8126                                                                List<TParseTreeNode> constants = visitor.getConstants();
8127                                                                analyzeConstantDataFlowRelation(insertColumn, constants, EffectType.merge_insert,
8128                                                                                functions);
8129
8130                                                                TableColumn tableColumn = modelFactory.createTableColumn(((Table)tableModel), columnObject,
8131                                                                                false);
8132                                                                if(tableColumn == null) {
8133                                                                        if (((Table) tableModel).isCreateTable()) {
8134                                                                                tableColumn = ((Table) tableModel).getColumns().get(j);
8135                                                                        }
8136                                                                        else {
8137                                                                                continue;
8138                                                                        }
8139                                                                }
8140
8141                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8142                                                                relation.setEffectType(EffectType.merge_insert);
8143                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8144                                                                relation.addSource(new ResultColumnRelationshipElement(insertColumn));
8145                                                                relation.setProcess(process);
8146                                                        }
8147                                                }
8148                                        }
8149                                }
8150
8151                        }
8152
8153                        if (stmt.getCondition() != null) {
8154                                analyzeFilterCondition(null, stmt.getCondition(), null, JoinClauseType.on, EffectType.merge);
8155                        }
8156                }
8157        }
8158
8159        private List<TableColumn> bindInsertTableColumn(Table tableModel, TInsertIntoValue value, List<TObjectName> keyMap,
8160                        List<TResultColumn> valueMap) {
8161                List<TableColumn> tableColumns = new ArrayList<TableColumn>();
8162                if (value.getColumnList() != null) {
8163                        for (int z = 0; z < value.getColumnList().size(); z++) {
8164                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8165                                                value.getColumnList().getObjectName(z));
8166                                tableColumns.add(tableColumn);
8167                                keyMap.add(tableColumn.getColumnObject());
8168                        }
8169                }
8170
8171                if (value.getTargetList() != null) {
8172                        for (int z = 0; z < value.getTargetList().size(); z++) {
8173                                TMultiTarget target = value.getTargetList().getMultiTarget(z);
8174                                TResultColumnList columns = target.getColumnList();
8175                                for (int i = 0; i < columns.size(); i++) {
8176                                        if (value.getColumnList() == null) {
8177                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8178                                                                columns.getResultColumn(i).getFieldAttr());
8179                                                tableColumns.add(tableColumn);
8180                                        }
8181                                        valueMap.add(columns.getResultColumn(i));
8182                                }
8183                        }
8184                }
8185
8186                return tableColumns;
8187        }
8188
8189        private TableColumn matchColumn(List<TableColumn> tableColumns, TableColumn targetColumn) {
8190                String columnName = targetColumn.getName();
8191                if (tableColumns == null) {
8192                        return null;
8193                }
8194                for (int i = 0; i < tableColumns.size(); i++) {
8195                        TableColumn column = tableColumns.get(i);
8196                        if (column.getColumnObject() == null) {
8197                                continue;
8198                        }
8199                        if(column.isStruct() && targetColumn.isStruct()) {
8200                                List<String> names = SQLUtil.parseNames(column.getName());
8201                                List<String> targetNames = SQLUtil
8202                                                .parseNames(targetColumn.getName());
8203                                if (!getColumnName(targetNames.get(0))
8204                                                .equals(getColumnName(names.get(0)))) {
8205                                        continue;
8206                                }
8207                        }
8208                        if (getColumnName(column.getColumnObject().toString()).equals(getColumnName(columnName))) {
8209                                return column;
8210                        }
8211                }
8212                return null;
8213        }
8214        
8215        private TableColumn matchColumn(List<TableColumn> tableColumns, TObjectName columnName) {
8216                if (tableColumns == null) {
8217                        return null;
8218                }
8219                for (int i = 0; i < tableColumns.size(); i++) {
8220                        TableColumn column = tableColumns.get(i);
8221                        if (column.getColumnObject() == null) {
8222                                continue;
8223                        }
8224                        if (DlineageUtil.getColumnName(column.getColumnObject()).equalsIgnoreCase(DlineageUtil.getColumnName(columnName)))
8225                                return column;
8226                }
8227                return null;
8228        }
8229
8230        private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, ResultColumn resultColumn) {
8231                if (resultColumns == null) {
8232                        return null;
8233                }
8234
8235                TObjectName columnName = getObjectName(resultColumn);
8236                if (columnName == null) {
8237                        return null;
8238                }
8239
8240                for (int i = 0; i < resultColumns.size(); i++) {
8241                        ResultColumn column = resultColumns.get(i);
8242                        if (column.getAlias() != null
8243                                        && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName)))
8244                                return column;
8245                        if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName)))
8246                                return column;
8247                        if (column.getName() != null && column.getName().endsWith("*")) {
8248                                if ("*".equals(column.getColumnObject().toString())) {
8249                                        return column;
8250                                } else {
8251                                        TObjectName columnObjectName = getObjectName(column);
8252                                        if (columnObjectName.getTableString() != null
8253                                                        && columnObjectName.getTableString().equals(getResultSetAlias(resultColumn))) {
8254                                                return column;
8255                                        }
8256                                }
8257                        }
8258                }
8259                return null;
8260        }
8261
8262        private String getResultSetAlias(ResultColumn resultColumn) {
8263                ResultSet resultSet = resultColumn.getResultSet();
8264                if (resultSet instanceof QueryTable) {
8265                        return ((QueryTable) resultSet).getAlias();
8266                }
8267                return null;
8268        }
8269
8270        private ResultColumn matchResultColumn(List<ResultColumn> resultColumns, TObjectName columnName) {
8271                if (resultColumns == null) {
8272                        return null;
8273                }
8274                for (int i = 0; i < resultColumns.size(); i++) {
8275                        ResultColumn column = resultColumns.get(i);
8276                        if (column.getAlias() != null
8277                                        && getColumnName(column.getAlias()).equalsIgnoreCase(getColumnName(columnName)))
8278                                return column;
8279                        if (column.getName() != null && getColumnName(column.getName()).equalsIgnoreCase(getColumnName(columnName)))
8280                                return column;
8281                        if (column.getName() != null && column.getName().endsWith("*")) {
8282                                if ("*".equals(column.getColumnObject().toString())) {
8283                                        return column;
8284                                } else {
8285                                        TObjectName columnObjectName = getObjectName(column);
8286                                        if (columnObjectName.getTableString() != null
8287                                                        && columnObjectName.getTableString().equals(columnName.getTableString())) {
8288                                                return column;
8289                                        }
8290                                }
8291                        }
8292                }
8293                return null;
8294        }
8295
8296        private void analyzeInsertStmt(TInsertSqlStatement stmt) {
8297                Map<Table, List<TObjectName>> insertTableKeyMap = new LinkedHashMap<Table, List<TObjectName>>();
8298                Map<Table, List<TResultColumn>> insertTableValueMap = new LinkedHashMap<Table, List<TResultColumn>>();
8299                Map<String, List<TableColumn>> tableColumnMap = new LinkedHashMap<String, List<TableColumn>>();
8300                List<Table> inserTables = new ArrayList<Table>();
8301                List<TExpression> expressions = new ArrayList<TExpression>();
8302                boolean hasInsertColumns = false;
8303                
8304                EffectType effectType = EffectType.insert;
8305                if(stmt.getInsertToken()!=null && stmt.getInsertToken().toString().toLowerCase().startsWith("replace")) {
8306                        effectType = EffectType.replace;
8307                }
8308                
8309                if (stmt.getInsertConditions() != null && stmt.getInsertConditions().size() > 0) {
8310                        for (int i = 0; i < stmt.getInsertConditions().size(); i++) {
8311                                TInsertCondition condition = stmt.getInsertConditions().getElement(i);
8312                                if (condition.getCondition() != null) {
8313                                        expressions.add(condition.getCondition());
8314                                }
8315                                for (int j = 0; j < condition.getInsertIntoValues().size(); j++) {
8316                                        TInsertIntoValue value = condition.getInsertIntoValues().getElement(j);
8317                                        TTable table = value.getTable();
8318                                        Table tableModel = modelFactory.createTable(table);
8319
8320                                        inserTables.add(tableModel);
8321                                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
8322                                        List<TResultColumn> valueMap = new ArrayList<TResultColumn>();
8323                                        insertTableKeyMap.put(tableModel, keyMap);
8324                                        insertTableValueMap.put(tableModel, valueMap);
8325
8326                                        List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap);
8327                                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null
8328                                                        && !tableColumns.isEmpty()) {
8329                                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()),
8330                                                                tableColumns);
8331                                        }
8332
8333                                        // if (stmt.getSubQuery() != null)
8334                                        {
8335                                                Process process = modelFactory.createProcess(stmt);
8336                                                tableModel.addProcess(process);
8337                                        }
8338                                }
8339                        }
8340                        hasInsertColumns = true;
8341                } else if (stmt.getInsertIntoValues() != null && stmt.getInsertIntoValues().size() > 0) {
8342                        for (int i = 0; i < stmt.getInsertIntoValues().size(); i++) {
8343                                TInsertIntoValue value = stmt.getInsertIntoValues().getElement(i);
8344                                TTable table = value.getTable();
8345                                Table tableModel = modelFactory.createTable(table);
8346
8347                                inserTables.add(tableModel);
8348                                List<TObjectName> keyMap = new ArrayList<TObjectName>();
8349                                List<TResultColumn> valueMap = new ArrayList<TResultColumn>();
8350                                insertTableKeyMap.put(tableModel, keyMap);
8351                                insertTableValueMap.put(tableModel, valueMap);
8352
8353                                List<TableColumn> tableColumns = bindInsertTableColumn(tableModel, value, keyMap, valueMap);
8354                                if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
8355                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
8356                                }
8357
8358                                // if (stmt.getSubQuery() != null)
8359                                {
8360                                        Process process = modelFactory.createProcess(stmt);
8361                                        tableModel.addProcess(process);
8362                                }
8363                        }
8364                        hasInsertColumns = true;
8365                } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
8366                        TTable table = stmt.getTargetTable();
8367                        Table tableModel = modelFactory.createTable(table);
8368
8369                        inserTables.add(tableModel);
8370                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
8371                        insertTableKeyMap.put(tableModel, keyMap);
8372                        List<TableColumn> tableColumns = new ArrayList<TableColumn>();
8373                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
8374                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
8375                                                stmt.getColumnList().getObjectName(i));
8376                                tableColumns.add(tableColumn);
8377                        }
8378                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
8379                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
8380                        }
8381
8382                        // if (stmt.getSubQuery() != null)
8383                        {
8384                                Process process = modelFactory.createProcess(stmt);
8385                                tableModel.addProcess(process);
8386                        }
8387                        hasInsertColumns = true;
8388                } else if (stmt.getOutputClause() != null && stmt.getOutputClause().getSelectItemList().size() > 0) {
8389                        TTable table = stmt.getTargetTable();
8390                        Table tableModel = modelFactory.createTable(table);
8391
8392                        inserTables.add(tableModel);
8393                        List<TObjectName> keyMap = new ArrayList<TObjectName>();
8394                        insertTableKeyMap.put(tableModel, keyMap);
8395                        List<TableColumn> tableColumns = new ArrayList<TableColumn>();
8396                        for (int i = 0; i < stmt.getOutputClause().getSelectItemList().size(); i++) {
8397                                TObjectName columnName = stmt.getOutputClause().getSelectItemList().getResultColumn(i).getFieldAttr();
8398                                if (columnName.getPseudoTableType() != EPseudoTableType.none) {
8399                                        // Phase 1 already swapped tokens; getColumnNameOnly() returns actual column name
8400                                        String column = columnName.getColumnNameOnly();
8401                                        columnName = new TObjectName();
8402                                        columnName.setString(column);
8403                                } else {
8404                                        String column = columnName.toString().toLowerCase();
8405                                        if ((column.startsWith("inserted.") || column.startsWith("deleted."))
8406                                                        && columnName.getPropertyToken() != null) {
8407                                                column = columnName.getPropertyToken().getAstext();
8408                                                columnName = new TObjectName();
8409                                                columnName.setString(column);
8410                                        }
8411                                }
8412                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel, columnName);
8413                                tableColumns.add(tableColumn);
8414                        }
8415                        if (tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName())) == null && !tableColumns.isEmpty()) {
8416                                tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), tableColumns);
8417                        }
8418
8419                        // if (stmt.getSubQuery() != null)
8420                        {
8421                                Process process = modelFactory.createProcess(stmt);
8422                                tableModel.addProcess(process);
8423                        }
8424                        hasInsertColumns = true;
8425                } else {
8426                        TTable table = stmt.getTargetTable();
8427                        Table tableModel;
8428                        if (table != null) {
8429                                tableModel = modelFactory.createTable(table);
8430                                // if (stmt.getSubQuery() != null)
8431                                {
8432                                        Process process = modelFactory.createProcess(stmt);
8433                                        tableModel.addProcess(process);
8434                                }
8435                                if (tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
8436                                        tableModel.addColumnsFromSQLEnv();
8437                                }
8438                        } else if (stmt.getDirectoryName() != null) {
8439                                tableModel = modelFactory.createTableByName(stmt.getDirectoryName(), true);
8440                                tableModel.setPath(true);
8441                                tableModel.setCreateTable(true);
8442                                TObjectName fileUri = new TObjectName();
8443                                fileUri.setString("uri=" + stmt.getDirectoryName());
8444                                TableColumn tableColumn = modelFactory.createFileUri(tableModel, fileUri);
8445                                // if (stmt.getSubQuery() != null)
8446                                {
8447                                        Process process = modelFactory.createProcess(stmt);
8448                                        tableModel.addProcess(process);
8449                                }
8450                        } else {
8451                                ErrorInfo errorInfo = new ErrorInfo();
8452                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
8453                                errorInfo.setErrorMessage("Can't get target table. InsertSqlStatement is " + stmt.toString());
8454                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
8455                                                stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
8456                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
8457                                                stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
8458                                                ModelBindingManager.getGlobalHash()));
8459                                errorInfo.fillInfo(this);
8460                                errorInfos.add(errorInfo);
8461                                return;
8462                        }
8463                        inserTables.add(tableModel);
8464                        if (table != null
8465                                        && tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(table.getFullName())) == null) {
8466                                if (tableModel.getColumns() != null && !tableModel.getColumns().isEmpty()) {
8467                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()),
8468                                                        tableModel.getColumns());
8469                                } else {
8470                                        tableColumnMap.put(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()), null);
8471                                }
8472                        }
8473                }
8474
8475                if (stmt.getSubQuery() != null) {
8476                        analyzeSelectStmt(stmt.getSubQuery());
8477                }
8478
8479                Iterator<Table> tableIter = inserTables.iterator();
8480                while (tableIter.hasNext()) {
8481                        Table tableModel = tableIter.next();
8482                        List<TableColumn> tableColumns = tableColumnMap.get(DlineageUtil.getIdentifierNormalTableName(tableModel.getFullName()));
8483                        List<TObjectName> keyMap = insertTableKeyMap.get(tableModel);
8484                        List<TResultColumn> valueMap = insertTableValueMap.get(tableModel);
8485                        boolean initColumn = (hasInsertColumns && tableColumns != null && !containStarColumn(tableColumns));
8486
8487                        if (stmt.getSubQuery() != null) {
8488
8489                                List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>();
8490                                if (stmt.getSubQuery().getResultColumnList() != null || stmt.getSubQuery().getTransformClause() != null) {
8491                                        subquerys.add(stmt.getSubQuery());
8492                                } else if (stmt.getSubQuery().getValueClause() != null
8493                                                && stmt.getSubQuery().getValueClause().getRows() != null) {
8494                                        for (TResultColumnList resultColumnList : stmt.getSubQuery().getValueClause().getRows()) {
8495                                                for(TResultColumn resultColumn: resultColumnList) {
8496                                                        if(resultColumn.getExpr()!=null && resultColumn.getExpr().getSubQuery()!=null) {
8497                                                                analyzeSelectStmt(resultColumn.getExpr().getSubQuery());
8498                                                                subquerys.add(resultColumn.getExpr().getSubQuery());
8499                                                        }
8500                                                }
8501                                        }
8502                                }
8503
8504                                for(TSelectSqlStatement subquery: subquerys) {
8505                                        if ((tableModel.isCreateTable() && tableModel.getColumns() != null)
8506                                                        || (subquery.getSetOperatorType() == ESetOperatorType.none
8507                                                                        && stmt.getColumnList() != null && stmt.getColumnList().size() > 0)) {
8508
8509                                                ResultSet resultSetModel = null;
8510
8511                                                if (subquery != null) {
8512                                                        resultSetModel = (ResultSet) modelManager.getModel(subquery);
8513                                                }
8514
8515                                                TResultColumnList resultset = subquery.getResultColumnList();
8516                                                if (resultSetModel == null && resultset != null) {
8517                                                        resultSetModel = (ResultSet) modelManager.getModel(resultset);
8518                                                }
8519
8520                                                if (resultSetModel == null) {
8521                                                        ErrorInfo errorInfo = new ErrorInfo();
8522                                                        errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
8523                                                        errorInfo.setErrorMessage("Can't get resultset model");
8524                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(resultset.getStartToken().lineNo,
8525                                                                        resultset.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
8526                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(resultset.getEndToken().lineNo,
8527                                                                        resultset.getEndToken().columnNo + resultset.getEndToken().getAstext().length(),
8528                                                                        ModelBindingManager.getGlobalHash()));
8529                                                        errorInfos.add(errorInfo);
8530                                                }
8531
8532                                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
8533                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
8534                                                        impactRelation.setEffectType(effectType);
8535                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
8536                                                                        resultSetModel.getRelationRows()));
8537                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
8538                                                                        tableModel.getRelationRows()));
8539                                                }
8540
8541                                                int resultSetSize = resultSetModel.getColumns().size();
8542                                                int j = 0;
8543                                                int starIndex = 0;
8544                                                TObjectNameList items = stmt.getColumnList();
8545                                                List<String> itemNames = new ArrayList<String>();
8546                                                int starColumnCount = 0;
8547                                                for (ResultColumn item : resultSetModel.getColumns()) {
8548                                                        if (item.getName().endsWith("*")) {
8549                                                                starColumnCount += 1;
8550                                                        }
8551                                                }
8552                                                if (items != null) {
8553                                                        for (int i = 0; i < items.size() && j < resultSetSize; i++) {
8554                                                                TObjectName column = items.getObjectName(i);
8555
8556                                                                if (column.getDbObjectType() == EDbObjectType.variable) {
8557                                                                        continue;
8558                                                                }
8559
8560                                                                if (column.getColumnNameOnly().startsWith("@")
8561                                                                                && (option.getVendor() == EDbVendor.dbvmssql
8562                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
8563                                                                        continue;
8564                                                                }
8565
8566                                                                if (column.getColumnNameOnly().startsWith(":")
8567                                                                                && (option.getVendor() == EDbVendor.dbvhana
8568                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
8569                                                                        continue;
8570                                                                }
8571
8572                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
8573                                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
8574                                                                        j++;
8575                                                                } else {
8576                                                                        starIndex++;
8577                                                                        if (resultSetSize - j == items.size() - i) {
8578                                                                                j++;
8579
8580                                                                        }
8581                                                                }
8582                                                                if (column != null) {
8583                                                                        TableColumn tableColumn;
8584                                                                        // if (!initColumn) {
8585                                                                        tableColumn = matchColumn(tableModel.getColumns(), column);
8586                                                                        if (tableColumn == null) {
8587                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8588                                                                                        if (tableModel.getColumns().size() <= i) {
8589                                                                                                continue;
8590                                                                                        }
8591                                                                                        tableColumn = tableModel.getColumns().get(i);
8592                                                                                } else {
8593                                                                                        tableColumn = modelFactory.createTableColumn(tableModel, column, false);
8594                                                                                        if(tableColumn == null) {
8595                                                                                                continue;
8596                                                                                        }
8597                                                                                }
8598                                                                        }
8599//                                                      } else {
8600//                                                              tableColumn = matchColumn(tableColumns, column);
8601//                                                              if (tableColumn == null) {
8602//                                                                      continue;
8603//                                                              }
8604//                                                      }
8605                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8606                                                                        relation.setEffectType(effectType);
8607                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8608                                                                        if (resultColumn.hasStarLinkColumn()
8609                                                                                        && resultColumn.getStarLinkColumnNames().size() > starIndex - 1 && starColumnCount<=1) {
8610                                                                                boolean find = false;
8611                                                                                while (resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8612                                                                                        TObjectName name = resultColumn.getStarLinkColumnName(starIndex - 1);
8613                                                                                        if (itemNames.contains(name.toString())) {
8614                                                                                                starIndex++;
8615                                                                                                continue;
8616                                                                                        }
8617                                                                                        ResultColumn expandStarColumn = modelFactory
8618                                                                                                        .createResultColumn(resultSetModel, name, false);
8619                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8620                                                                                        itemNames.add(resultColumn.getName());
8621                                                                                        find = true;
8622                                                                                        break;
8623                                                                                }
8624                                                                                if (!find) {
8625                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8626                                                                                        itemNames.add(resultColumn.getName());
8627                                                                                }
8628                                                                        } else {
8629                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8630                                                                                itemNames.add(resultColumn.getName());
8631                                                                        }
8632                                                                        Process process = modelFactory.createProcess(stmt);
8633                                                                        relation.setProcess(process);
8634                                                                }
8635                                                        }
8636                                                } else {
8637                                                        List<TableColumn> columns = tableModel.getColumns();
8638                                                        if (columns.size() == 1 && tableModel.isPath()) {
8639                                                                for(int i=0;i<resultSetSize;i++) {
8640                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
8641                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8642                                                                        relation.setEffectType(effectType);
8643                                                                        relation.setTarget(new TableColumnRelationshipElement(tableModel.getColumns().get(0)));
8644                                                                        if (resultColumn.hasStarLinkColumn()
8645                                                                                        && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8646                                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(
8647                                                                                                resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
8648                                                                                                false);
8649                                                                                relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8650                                                                        } else {
8651                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8652                                                                        }
8653                                                                        Process process = modelFactory.createProcess(stmt);
8654                                                                        relation.setProcess(process);
8655                                                                }
8656                                                        } else {
8657                                                                boolean fromStruct = false;
8658                                                                for (int i = 0; i < columns.size() && j < resultSetSize; i++) {
8659                                                                        String column = columns.get(i).getName();
8660                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
8661                                                                        if (!resultColumn.getName().contains("*")) {
8662                                                                                if (resultColumn.getName().equals(resultColumn.getRefColumnName())
8663                                                                                                && resultColumn.getColumnObject().toString().endsWith("*")
8664                                                                                                && resultSetSize == 1) {
8665                                                                                        starIndex++;
8666                                                                                        if (resultSetSize - j == columns.size() - i) {
8667                                                                                                j++;
8668
8669                                                                                        }
8670                                                                                }
8671                                                                                else {
8672                                                                                        j++;
8673                                                                                }
8674                                                                        } else {
8675                                                                                starIndex++;
8676                                                                                if (resultSetSize - j == columns.size() - i) {
8677                                                                                        j++;
8678
8679                                                                                }
8680                                                                        }
8681                                                                        if (column != null) {
8682                                                                                TableColumn tableColumn;
8683                                                                                // if (!initColumn) {
8684                                                                                tableColumn = matchColumn(tableModel.getColumns(), columns.get(i));
8685                                                                                if (tableColumn == null) {
8686                                                                                        if (tableModel.isCreateTable()
8687                                                                                                        && !containStarColumn(tableModel.getColumns())) {
8688                                                                                                if (tableModel.getColumns().size() <= i) {
8689                                                                                                        continue;
8690                                                                                                }
8691                                                                                                tableColumn = tableModel.getColumns().get(i);
8692                                                                                        } else {
8693                                                                                                TObjectName columnName = new TObjectName();
8694                                                                                                columnName.setString(column);
8695                                                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName,
8696                                                                                                                false);
8697                                                                                        }
8698                                                                                }
8699                                                                                else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) {
8700                                                                                        j--;
8701                                                                                        fromStruct = true;
8702                                                                                }
8703                                                                                if(fromStruct && !tableColumn.isStruct()) {
8704                                                                                        fromStruct = false;
8705                                                                                        resultColumn = resultSetModel.getColumns().get(j);
8706                                                                                        j++;
8707                                                                                }
8708                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8709                                                                                relation.setEffectType(effectType);
8710                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8711                                                                                if (resultColumn.hasStarLinkColumn()
8712                                                                                                && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
8713                                                                                        ResultColumn expandStarColumn = modelFactory.createResultColumn(
8714                                                                                                        resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
8715                                                                                                        false);
8716                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
8717                                                                                } else {
8718                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1));
8719                                                                                }
8720                                                                                Process process = modelFactory.createProcess(stmt);
8721                                                                                relation.setProcess(process);
8722                                                                        }
8723                                                                }
8724                                                        }
8725                                                }
8726                                        } else if (!subquery.isCombinedQuery()) {
8727                                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
8728                                                                .getModel(subquery.getResultColumnList() != null ? subquery.getResultColumnList()
8729                                                                                : subquery.getTransformClause());
8730
8731                                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
8732                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
8733                                                        impactRelation.setEffectType(effectType);
8734                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
8735                                                                        resultSetModel.getRelationRows()));
8736                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
8737                                                                        tableModel.getRelationRows()));
8738                                                }
8739
8740                                                List<ResultColumn> columnsSnapshot = new ArrayList<ResultColumn>();
8741                                                columnsSnapshot.addAll(resultSetModel.getColumns());
8742                                                if(resultSetModel.isDetermined() && stmt.getColumnList() == null) {
8743                                                        tableModel.setDetermined(true);
8744                                                }
8745                                                for (int i = 0; i < columnsSnapshot.size(); i++) {
8746                                                        ResultColumn resultColumn = columnsSnapshot.get(i);
8747                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
8748                                                                TableColumn tableColumn;
8749                                                                if (!initColumn) {
8750                                                                        if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8751                                                                                if (tableModel.getColumns().size() <= i) {
8752                                                                                        continue;
8753                                                                                }
8754                                                                                tableColumn = tableModel.getColumns().get(i);
8755                                                                        } else {
8756                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8757                                                                                                (TObjectName) resultColumn.getColumnObject());
8758                                                                        }
8759                                                                        if (containStarColumn(tableColumns)) {
8760                                                                                getStarColumn(tableColumns)
8761                                                                                                .bindStarLinkColumn((TObjectName) resultColumn.getColumnObject());
8762                                                                        }
8763                                                                } else {
8764                                                                        TObjectName matchedColumnName = (TObjectName) resultColumn.getColumnObject();
8765                                                                        tableColumn = matchColumn(tableColumns, matchedColumnName);
8766                                                                        if (tableColumn == null) {
8767                                                                                if (!isEmptyCollection(valueMap)) {
8768                                                                                        int index = indexOfColumn(valueMap, matchedColumnName);
8769                                                                                        if (index != -1) {
8770                                                                                                if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8771                                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(index));
8772                                                                                                } else if (isEmptyCollection(keyMap) && index < tableColumns.size()) {
8773                                                                                                        tableColumn = tableColumns.get(index);
8774                                                                                                } else {
8775                                                                                                        continue;
8776                                                                                                }
8777                                                                                        } else {
8778                                                                                                continue;
8779                                                                                        }
8780                                                                                } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8781                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(i));
8782                                                                                } else if (isEmptyCollection(keyMap) && isEmptyCollection(valueMap)
8783                                                                                                && i < tableColumns.size()) {
8784                                                                                        tableColumn = tableColumns.get(i);
8785                                                                                } else {
8786                                                                                        continue;
8787                                                                                }
8788                                                                        }
8789                                                                }
8790
8791                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8792                                                                relation.setEffectType(effectType);
8793                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8794                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8795                                                                Process process = modelFactory.createProcess(stmt);
8796                                                                relation.setProcess(process);
8797                                                        } else {
8798                                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
8799                                                                if (alias != null && alias.getAliasName() != null) {
8800                                                                        TableColumn tableColumn;
8801                                                                        if (!initColumn) {
8802                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8803                                                                                        if (tableModel.getColumns().size() <= i) {
8804                                                                                                if (tableModel.isPath()) {
8805                                                                                                        tableColumn = tableModel.getColumns().get(0);
8806                                                                                                } else {
8807                                                                                                        continue;
8808                                                                                                }
8809                                                                                        } else {
8810                                                                                                tableColumn = tableModel.getColumns().get(i);
8811                                                                                        }
8812                                                                                } else {
8813                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
8814                                                                                                        alias.getAliasName());
8815                                                                                        if (containStarColumn(resultSetModel)) {
8816                                                                                                tableColumn.notBindStarLinkColumn(true);
8817                                                                                        }
8818                                                                                }
8819                                                                                if (containStarColumn(tableColumns)) {
8820                                                                                        getStarColumn(tableColumns).bindStarLinkColumn(alias.getAliasName());
8821                                                                                }
8822                                                                        } else {
8823                                                                                TObjectName matchedColumnName = alias.getAliasName();
8824                                                                                tableColumn = matchColumn(tableColumns, matchedColumnName);
8825                                                                                if (tableColumn == null) {
8826                                                                                        if (!isEmptyCollection(valueMap)) {
8827                                                                                                int index = indexOfColumn(valueMap, matchedColumnName);
8828                                                                                                if (index != -1) {
8829                                                                                                        if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8830                                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(index));
8831                                                                                                        } else if (isEmptyCollection(keyMap)
8832                                                                                                                        && index < tableColumns.size()) {
8833                                                                                                                tableColumn = tableColumns.get(index);
8834                                                                                                        } else {
8835                                                                                                                continue;
8836                                                                                                        }
8837                                                                                                } else {
8838                                                                                                        continue;
8839                                                                                                }
8840                                                                                        } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8841                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(i));
8842                                                                                        } else {
8843                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8844                                                                                                                alias.getAliasName());
8845                                                                                        }
8846                                                                                }
8847
8848                                                                        }
8849
8850                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8851                                                                        relation.setEffectType(effectType);
8852                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8853                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
8854                                                                        Process process = modelFactory.createProcess(stmt);
8855                                                                        relation.setProcess(process);
8856
8857                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getFieldAttr() != null) {
8858                                                                        TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
8859                                                                                        .getFieldAttr();
8860
8861                                                                        Object model = modelManager.getModel( resultColumn.getColumnObject());
8862                                                                        
8863                                                                        TableColumn tableColumn;
8864                                                                        if (!initColumn) {
8865                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
8866                                                                                        if (fieldAttr.toString().endsWith("*")) {
8867                                                                                                int starIndex = 0;
8868                                                                                                for (TableColumn column : tableModel.getColumns()) {
8869                                                                                                        starIndex++;
8870                                                                                                        DataFlowRelationship relation = modelFactory
8871                                                                                                                        .createDataFlowRelation();
8872                                                                                                        relation.setEffectType(effectType);
8873                                                                                                        relation.setTarget(new TableColumnRelationshipElement(column));
8874                                                                                                        if (resultColumn.getStarLinkColumnList().size() == tableModel
8875                                                                                                                        .getColumns().size()) {
8876                                                                                                                ResultColumn expandStarColumn = modelFactory.createResultColumn(
8877                                                                                                                                resultSetModel,
8878                                                                                                                                resultColumn.getStarLinkColumnList().get(starIndex - 1),
8879                                                                                                                                false);
8880                                                                                                                relation.addSource(
8881                                                                                                                                new ResultColumnRelationshipElement(expandStarColumn));
8882                                                                                                        } else {
8883                                                                                                                relation.addSource(
8884                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
8885                                                                                                        }
8886                                                                                                        Process process = modelFactory.createProcess(stmt);
8887                                                                                                        relation.setProcess(process);
8888                                                                                                }
8889                                                                                                continue;
8890                                                                                        }
8891                                                                                        if (tableModel.getColumns().size() <= i) {
8892                                                                                                continue;
8893                                                                                        }
8894                                                                                        tableColumn = tableModel.getColumns().get(i);
8895                                                                                } else {
8896                                                                                        if(model instanceof LinkedHashMap) {
8897                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model;
8898                                                                                                for(String key: resultColumns.keySet()) {
8899                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, resultColumns.get(key).getName());
8900                                                                                                        DataFlowRelationship relation = modelFactory
8901                                                                                                                        .createDataFlowRelation();
8902                                                                                                        relation.setEffectType(effectType);
8903                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
8904                                                                                                        relation.addSource(
8905                                                                                                                        new ResultColumnRelationshipElement(resultColumns.get(key)));
8906                                                                                                        Process process = modelFactory.createProcess(stmt);
8907                                                                                                        relation.setProcess(process);
8908                                                                                                }
8909                                                                                                continue;
8910                                                                                        }
8911                                                                                        else {
8912                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel, fieldAttr);
8913                                                                                        }
8914                                                                                }
8915                                                                        } else if (tableModel.isDetermined() && i < tableModel.getColumns().size()) {
8916                                                                                if (!isEmptyCollection(valueMap)) {
8917                                                                                        TObjectName matchedColumnName = fieldAttr;
8918                                                                                        int index = indexOfColumn(valueMap, matchedColumnName);
8919                                                                                        if (index != -1) {
8920                                                                                                if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8921                                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(index));
8922                                                                                                } else if (isEmptyCollection(keyMap)
8923                                                                                                                && index < tableColumns.size()) {
8924                                                                                                        tableColumn = tableColumns.get(index);
8925                                                                                                } else {
8926                                                                                                        continue;
8927                                                                                                }
8928                                                                                        } else {
8929                                                                                                continue;
8930                                                                                        }
8931                                                                                } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8932                                                                                        tableColumn = matchColumn(tableColumns, keyMap.get(i));
8933                                                                                } else {
8934                                                                                        tableColumn = tableModel.getColumns().get(i);
8935                                                                                }
8936                                                                        } else {
8937                                                                                TObjectName matchedColumnName = fieldAttr;
8938                                                                                tableColumn = matchColumn(tableColumns, matchedColumnName);
8939                                                                                if (tableColumn == null) {
8940                                                                                        if (!isEmptyCollection(valueMap)) {
8941                                                                                                int index = indexOfColumn(valueMap, matchedColumnName);
8942                                                                                                if (index != -1) {
8943                                                                                                        if (!isEmptyCollection(keyMap) && index < keyMap.size()) {
8944                                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(index));
8945                                                                                                        } else if (isEmptyCollection(keyMap)
8946                                                                                                                        && index < tableColumns.size()) {
8947                                                                                                                tableColumn = tableColumns.get(index);
8948                                                                                                        } else {
8949                                                                                                                continue;
8950                                                                                                        }
8951                                                                                                } else {
8952                                                                                                        continue;
8953                                                                                                }
8954                                                                                        } else if (!isEmptyCollection(keyMap) && i < keyMap.size()) {
8955                                                                                                tableColumn = matchColumn(tableColumns, keyMap.get(i));
8956                                                                                        } else {
8957                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
8958                                                                                                                fieldAttr);
8959                                                                                        }
8960                                                                                }
8961                                                                        }
8962
8963                                                                        if (!"*".equals(getColumnName(tableColumn.getColumnObject()))
8964                                                                                        && "*".equals(getColumnName(fieldAttr))) {
8965                                                                                TObjectName columnObject = fieldAttr;
8966                                                                                TTable sourceTable = columnObject.getSourceTable();
8967                                                                                if (columnObject.getTableToken() != null && sourceTable != null) {
8968                                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
8969                                                                                        for (int j = 0; j < columns.length; j++) {
8970                                                                                                TObjectName columnName = columns[j];
8971                                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
8972                                                                                                        continue;
8973                                                                                                }
8974                                                                                                resultColumn.bindStarLinkColumn(columnName);
8975                                                                                        }
8976                                                                                } else {
8977                                                                                        TTableList tables = stmt.getTables();
8978                                                                                        for (int k = 0; k < tables.size(); k++) {
8979                                                                                                TTable tableElement = tables.getTable(k);
8980                                                                                                TObjectName[] columns = modelManager.getTableColumns(tableElement);
8981                                                                                                for (int j = 0; j < columns.length; j++) {
8982                                                                                                        TObjectName columnName = columns[j];
8983                                                                                                        if (columnName == null || "*".equals(getColumnName(columnName))) {
8984                                                                                                                continue;
8985                                                                                                        }
8986                                                                                                        resultColumn.bindStarLinkColumn(columnName);
8987                                                                                                }
8988                                                                                        }
8989                                                                                }
8990                                                                        }
8991
8992                                                                        if ("*".equals(getColumnName(tableColumn.getColumnObject())) && resultColumn != null
8993                                                                                        && !resultColumn.getStarLinkColumns().isEmpty()) {
8994                                                                                tableColumn.bindStarLinkColumns(resultColumn.getStarLinkColumns());
8995                                                                        }
8996
8997                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
8998                                                                        relation.setEffectType(effectType);
8999                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9000                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9001
9002                                                                        if (tableColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
9003                                                                                tableColumn.getTable().setStarStmt("insert");
9004                                                                        }
9005
9006                                                                        Process process = modelFactory.createProcess(stmt);
9007                                                                        relation.setProcess(process);
9008                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9009                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
9010                                                                        if (!initColumn) {
9011                                                                                TableColumn tableColumn;
9012                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
9013                                                                                        if (tableModel.getColumns().size() <= i) {
9014                                                                                                continue;
9015                                                                                        }
9016                                                                                        tableColumn = tableModel.getColumns().get(i);
9017                                                                                } else {
9018                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9019                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9020                                                                                                                        .getConstantOperand(),
9021                                                                                                        i);
9022                                                                                }
9023
9024                                                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
9025                                                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
9026                                                                                        TSQLSchema schema = sqlenv.getSQLSchema(
9027                                                                                                        tableModel.getDatabase() + "." + tableModel.getSchema(), true);
9028                                                                                        if (schema != null) {
9029                                                                                                TSQLTable tempTable = schema.createTable(
9030                                                                                                                DlineageUtil.getSimpleTableName(tableModel.getName()));
9031                                                                                                tempTable.addColumn(tableColumn.getName());
9032                                                                                        }
9033                                                                                }
9034                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9035                                                                                relation.setEffectType(effectType);
9036                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9037                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9038                                                                                Process process = modelFactory.createProcess(stmt);
9039                                                                                relation.setProcess(process);
9040                                                                        } else {
9041                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9042                                                                                relation.setEffectType(effectType);
9043                                                                                relation.setTarget(
9044                                                                                                new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
9045                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9046                                                                                Process process = modelFactory.createProcess(stmt);
9047                                                                                relation.setProcess(process);
9048                                                                        }
9049                                                                } else {
9050                                                                        if (!initColumn) {
9051                                                                                TableColumn tableColumn;
9052                                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
9053                                                                                        if (tableModel.getColumns().size() <= i) {
9054                                                                                                continue;
9055                                                                                        }
9056                                                                                        tableColumn = tableModel.getColumns().get(i);
9057                                                                                } else {
9058                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9059                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i);
9060                                                                                }
9061                                                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
9062                                                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
9063                                                                                        TSQLSchema schema = sqlenv.getSQLSchema(
9064                                                                                                        tableModel.getDatabase() + "." + tableModel.getSchema(), true);
9065                                                                                        if (schema != null) {
9066                                                                                                TSQLTable tempTable = schema.createTable(
9067                                                                                                                DlineageUtil.getSimpleTableName(tableModel.getName()));
9068                                                                                                tempTable.addColumn(tableColumn.getName());
9069                                                                                        }
9070                                                                                }
9071                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9072                                                                                relation.setEffectType(effectType);
9073                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9074                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9075                                                                                Process process = modelFactory.createProcess(stmt);
9076                                                                                relation.setProcess(process);
9077                                                                        } else {
9078                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9079                                                                                relation.setEffectType(effectType);
9080                                                                                relation.setTarget(
9081                                                                                                new TableColumnRelationshipElement(tableModel.getColumns().get(i)));
9082                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9083                                                                                Process process = modelFactory.createProcess(stmt);
9084                                                                                relation.setProcess(process);
9085                                                                        }
9086                                                                }
9087                                                        }
9088                                                }
9089                                        } else if (stmt.getSubQuery() != null) {
9090                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt.getSubQuery());
9091                                                if (resultSetModel != null) {
9092
9093                                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
9094                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
9095                                                                impactRelation.setEffectType(effectType);
9096                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
9097                                                                                resultSetModel.getRelationRows()));
9098                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
9099                                                                                tableModel.getRelationRows()));
9100                                                        }
9101
9102                                                        if(stmt.getColumnList()!=null && stmt.getColumnList().size()>0) {
9103                                                                for(int i=0;i<stmt.getColumnList().size();i++) {
9104                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9105                                                                                        stmt.getColumnList().getObjectName(i));
9106                                                                }
9107                                                                
9108                                                                List<TableColumn> columns = tableModel.getColumns();
9109                                                                int resultSetSize = resultSetModel.getColumns().size();
9110                                                                int starIndex = 0; 
9111                                                                int j = 0;
9112                                                                boolean fromStruct = false;
9113                                                                for (int i = 0; i < columns.size() && j < resultSetSize; i++) {
9114                                                                        String column = columns.get(i).getName();
9115                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);
9116                                                                        if (!resultColumn.getName().contains("*")) {
9117                                                                                if (resultColumn.getName().equals(resultColumn.getRefColumnName())
9118                                                                                                && resultColumn.getColumnObject().toString().endsWith("*")
9119                                                                                                && resultSetSize == 1) {
9120                                                                                        starIndex++;
9121                                                                                        if (resultSetSize - j == columns.size() - i) {
9122                                                                                                j++;
9123
9124                                                                                        }
9125                                                                                }
9126                                                                                else {
9127                                                                                        j++;
9128                                                                                }
9129                                                                        } else {
9130                                                                                starIndex++;
9131                                                                                if (resultSetSize - j == columns.size() - i) {
9132                                                                                        j++;
9133
9134                                                                                }
9135                                                                        }
9136                                                                        if (column != null) {
9137                                                                                TableColumn tableColumn;
9138                                                                                // if (!initColumn) {
9139                                                                                tableColumn = matchColumn(tableModel.getColumns(), columns.get(i));
9140                                                                                if (tableColumn == null) {
9141                                                                                        if (tableModel.isCreateTable()
9142                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9143                                                                                                if (tableModel.getColumns().size() <= i) {
9144                                                                                                        continue;
9145                                                                                                }
9146                                                                                                tableColumn = tableModel.getColumns().get(i);
9147                                                                                        } else {
9148                                                                                                TObjectName columnName = new TObjectName();
9149                                                                                                columnName.setString(column);
9150                                                                                                tableColumn = modelFactory.createTableColumn(tableModel, columnName,
9151                                                                                                                false);
9152                                                                                        }
9153                                                                                }
9154                                                                                else if (!resultColumn.isStruct() && tableColumn.isStruct() && columns.size() != resultSetSize) {
9155                                                                                        j--;
9156                                                                                        fromStruct = true;
9157                                                                                }
9158                                                                                if(fromStruct && !tableColumn.isStruct()) {
9159                                                                                        fromStruct = false;
9160                                                                                        resultColumn = resultSetModel.getColumns().get(j);
9161                                                                                        j++;
9162                                                                                }
9163                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9164                                                                                relation.setEffectType(effectType);
9165                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9166                                                                                if (resultColumn.hasStarLinkColumn()
9167                                                                                                && resultColumn.getStarLinkColumnNames().size() > starIndex - 1) {
9168                                                                                        ResultColumn expandStarColumn = modelFactory.createResultColumn(
9169                                                                                                        resultSetModel, resultColumn.getStarLinkColumnName(starIndex - 1),
9170                                                                                                        false);
9171                                                                                        relation.addSource(new ResultColumnRelationshipElement(expandStarColumn));
9172                                                                                } else {
9173                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn, starIndex - 1));
9174                                                                                }
9175                                                                                Process process = modelFactory.createProcess(stmt);
9176                                                                                relation.setProcess(process);
9177                                                                        }
9178                                                                }
9179                                                        }
9180                                                        else {
9181                                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9182                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9183                                                                        TAliasClause alias = null;
9184                                                                        if(resultColumn.getColumnObject() instanceof TResultColumn) {
9185                                                                                alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
9186                                                                        }
9187                                                                        if (stmt.getColumnList() != null) {
9188                                                                                if (i < stmt.getColumnList().size()) {
9189                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9190                                                                                        relation.setEffectType(effectType);
9191                                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9192                                                                                                        stmt.getColumnList().getObjectName(i));
9193                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9194                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9195                                                                                        Process process = modelFactory.createProcess(stmt);
9196                                                                                        relation.setProcess(process);
9197                                                                                }
9198                                                                        } else {
9199                                                                                if (alias != null && alias.getAliasName() != null) {
9200                                                                                        TableColumn tableColumn;
9201                                                                                        if (!initColumn) {
9202                                                                                                if (tableModel.isCreateTable()
9203                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9204                                                                                                        if (tableModel.getColumns().size() <= i) {
9205                                                                                                                continue;
9206                                                                                                        }
9207                                                                                                        tableColumn = tableModel.getColumns().get(i);
9208                                                                                                } else {
9209                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9210                                                                                                                        alias.getAliasName());
9211                                                                                                }
9212                                                                                        } else {
9213                                                                                                tableColumn = matchColumn(tableColumns, alias.getAliasName());
9214                                                                                                if (tableColumn == null) {
9215                                                                                                        continue;
9216                                                                                                }
9217                                                                                        }
9218        
9219                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9220                                                                                        relation.setEffectType(effectType);
9221                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9222                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9223                                                                                        Process process = modelFactory.createProcess(stmt);
9224                                                                                        relation.setProcess(process);
9225                                                                                } else if (resultColumn.getColumnObject() instanceof TObjectName 
9226                                                                                                || ( resultColumn.getColumnObject() instanceof TResultColumn && ((TResultColumn) resultColumn.getColumnObject())
9227                                                                                                .getFieldAttr() != null)) {
9228                                                                                        TObjectName fieldAttr = null;
9229                                                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
9230                                                                                                fieldAttr = (TObjectName)resultColumn.getColumnObject();
9231                                                                                        }
9232                                                                                        else if (resultColumn.getColumnObject() instanceof TResultColumn) {
9233                                                                                                fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9234                                                                                                                .getFieldAttr();
9235                                                                                        }
9236                                
9237                                                                                        TableColumn tableColumn;
9238                                                                                        if (!initColumn) {
9239                                                                                                if (tableModel.isCreateTable()
9240                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9241                                                                                                        if (tableModel.getColumns().size() <= i) {
9242                                                                                                                continue;
9243                                                                                                        }
9244                                                                                                        tableColumn = tableModel.getColumns().get(i);
9245                                                                                                } else {
9246                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9247                                                                                                                        fieldAttr);
9248                                                                                                }
9249                                                                                        } else {
9250                                                                                                tableColumn = matchColumn(tableColumns, fieldAttr);
9251                                                                                                if (tableColumn == null) {
9252                                                                                                        continue;
9253                                                                                                }
9254                                                                                        }
9255        
9256                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9257                                                                                        relation.setEffectType(effectType);
9258                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9259                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9260                                                                                        Process process = modelFactory.createProcess(stmt);
9261                                                                                        relation.setProcess(process);
9262                                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9263                                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
9264                                                                                        if (!initColumn) {
9265                                                                                                TableColumn tableColumn;
9266                                                                                                if (tableModel.isCreateTable()
9267                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9268                                                                                                        if (tableModel.getColumns().size() <= i) {
9269                                                                                                                continue;
9270                                                                                                        }
9271                                                                                                        tableColumn = tableModel.getColumns().get(i);
9272                                                                                                } else {
9273                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9274                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9275                                                                                                                                        .getConstantOperand(),
9276                                                                                                                        i);
9277                                                                                                }
9278                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9279                                                                                                relation.setEffectType(effectType);
9280                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9281                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9282                                                                                                Process process = modelFactory.createProcess(stmt);
9283                                                                                                relation.setProcess(process);
9284                                                                                        }
9285                                                                                } else {
9286                                                                                        if (!initColumn) {
9287                                                                                                TableColumn tableColumn;
9288                                                                                                if (tableModel.isCreateTable()
9289                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9290                                                                                                        if (tableModel.getColumns().size() <= i) {
9291                                                                                                                continue;
9292                                                                                                        }
9293                                                                                                        tableColumn = tableModel.getColumns().get(i);
9294                                                                                                } else {
9295                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9296                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(), i);
9297                                                                                                }
9298                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9299                                                                                                relation.setEffectType(effectType);
9300                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9301                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9302                                                                                                Process process = modelFactory.createProcess(stmt);
9303                                                                                                relation.setProcess(process);
9304                                                                                        }
9305                                                                                }
9306                                                                        }
9307                                                                }
9308                                                        }
9309                                                }
9310                                        }
9311                                }
9312                        } else if (stmt.getColumnList() != null && stmt.getColumnList().size() > 0) {
9313                                TObjectNameList items = stmt.getColumnList();
9314                                TMultiTargetList values = stmt.getValues();
9315                                if (values != null) {
9316                                        for (int k = 0; values != null && k < values.size(); k++) {
9317                                                int j = 0;
9318                                                for (int i = 0; i < items.size(); i++) {
9319                                                        TObjectName column = items.getObjectName(i);
9320                                                        TableColumn tableColumn;
9321                                                        if (!initColumn) {
9322                                                                if (tableModel.isCreateTable() && !containStarColumn(tableModel.getColumns())) {
9323                                                                        if (tableModel.getColumns().size() <= i) {
9324                                                                                continue;
9325                                                                        }
9326                                                                        tableColumn = tableModel.getColumns().get(i);
9327                                                                } else {
9328                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, column);
9329                                                                }
9330                                                        } else {
9331                                                                tableColumn = matchColumn(tableColumns, column);
9332                                                                if (tableColumn == null) {
9333                                                                        continue;
9334                                                                }
9335                                                        }
9336                                                        TResultColumn columnObject = values.getMultiTarget(k).getColumnList().getResultColumn(j);
9337                                                        if (columnObject == null) {
9338                                                                continue;
9339                                                        }
9340                                                        TExpression valueExpr = columnObject.getExpr();
9341                                                        columnsInExpr visitor = new columnsInExpr();
9342                                                        valueExpr.inOrderTraverse(visitor);
9343                                                        List<TObjectName> objectNames = visitor.getObjectNames();
9344                                                        List<TParseTreeNode> constants = visitor.getConstants();
9345                                                        List<TParseTreeNode> functions = visitor.getFunctions();
9346                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9347
9348                                                        Process process = modelFactory.createProcess(stmt);
9349                                                        
9350                                                        
9351                                                        
9352                                                        if (functions != null && !functions.isEmpty()) {
9353                                                                analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process);
9354                                                        }
9355
9356                                                        if (subquerys != null && !subquerys.isEmpty()) {
9357                                                                analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process);
9358                                                        }
9359                                                        if (objectNames != null && !objectNames.isEmpty()) {
9360                                                                analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions,
9361                                                                                process, i);
9362                                                        }
9363                                                        //insert into values generate too many constant relations, ignore constant relations.
9364                                                        if (constants != null && !constants.isEmpty()) {
9365                                                                if (!option.isIgnoreInsertIntoValues() || stmt.getParentStmt() != null) {
9366                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, effectType,
9367                                                                                        functions, process);
9368                                                                }
9369                                                        }
9370                                                        j++;
9371                                                }
9372                                        }
9373                                } else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) {
9374                                        analyzeCustomSqlStmt(stmt.getExecuteStmt());
9375                                        Procedure procedure = modelManager.getProcedureByName(DlineageUtil
9376                                                        .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString()));
9377                                        if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) {
9378                                                TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure
9379                                                                .getProcedureObject();
9380                                                List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt);
9381                                                if (stmtItems != null) {
9382                                                        for(TSelectSqlStatement stmtItem: stmtItems) {
9383                                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem);
9384                                                                if (resultSetModel != null) {
9385                                                                        for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9386                                                                                ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9387                                                                                Transform transform = new Transform();
9388                                                                                transform.setType(Transform.FUNCTION);
9389                                                                                transform.setCode(stmt.getExecuteStmt().getModuleName());
9390                                                                                resultColumn.setTransform(transform);
9391                                                                                
9392                                                                                if (stmt.getColumnList() != null) {
9393                                                                                        if (i < stmt.getColumnList().size()) {
9394                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9395                                                                                                relation.setEffectType(effectType);
9396                                                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9397                                                                                                                stmt.getColumnList().getObjectName(i));                                                                                         
9398                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9399                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9400                                                                                                Process process = modelFactory.createProcess(stmt);
9401                                                                                                relation.setProcess(process);                                   
9402                                                                                        }
9403                                                                                } else {
9404                                                                                        if (resultColumn.getColumnObject() instanceof TObjectName) {
9405                                                                                                TObjectName fieldAttr = ((TObjectName) resultColumn.getColumnObject());
9406                                                                                                TableColumn tableColumn;
9407                                                                                                if (!initColumn) {
9408                                                                                                        if (tableModel.isCreateTable()
9409                                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9410                                                                                                                if (tableModel.getColumns().size() <= i) {
9411                                                                                                                        continue;
9412                                                                                                                }
9413                                                                                                                tableColumn = tableModel.getColumns().get(i);
9414                                                                                                        } else {
9415                                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9416                                                                                                                                fieldAttr);
9417                                                                                                        }
9418                                                                                                } else {
9419                                                                                                        tableColumn = matchColumn(tableColumns, fieldAttr);
9420                                                                                                        if (tableColumn == null) {
9421                                                                                                                continue;
9422                                                                                                        }
9423                                                                                                }
9424        
9425                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9426                                                                                                relation.setEffectType(effectType);
9427                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9428                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9429                                                                                                Process process = modelFactory.createProcess(stmt);
9430                                                                                                relation.setProcess(process);
9431
9432                                                                                                
9433                                                                                        } else {
9434                                                                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject())
9435                                                                                                                .getAliasClause();
9436                                                                                                if (alias != null && alias.getAliasName() != null) {
9437                                                                                                        TableColumn tableColumn;
9438                                                                                                        if (!initColumn) {
9439                                                                                                                if (tableModel.isCreateTable()
9440                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9441                                                                                                                        if (tableModel.getColumns().size() <= i) {
9442                                                                                                                                continue;
9443                                                                                                                        }
9444                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9445                                                                                                                } else {
9446                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9447                                                                                                                                        alias.getAliasName());
9448                                                                                                                }
9449                                                                                                        } else {
9450                                                                                                                tableColumn = matchColumn(tableColumns, alias.getAliasName());
9451                                                                                                                if (tableColumn == null) {
9452                                                                                                                        continue;
9453                                                                                                                }
9454                                                                                                        }
9455                                                                                                        
9456                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9457                                                                                                        relation.setEffectType(effectType);
9458                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9459                                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9460                                                                                                        Process process = modelFactory.createProcess(stmt);
9461                                                                                                        relation.setProcess(process);
9462                                                                                                } else if (((TResultColumn) resultColumn.getColumnObject())
9463                                                                                                                .getFieldAttr() != null) {
9464                                                                                                        TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9465                                                                                                                        .getFieldAttr();
9466                                                                                                        TableColumn tableColumn;
9467                                                                                                        if (!initColumn) {
9468                                                                                                                if (tableModel.isCreateTable()
9469                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9470                                                                                                                        if (tableModel.getColumns().size() <= i) {
9471                                                                                                                                continue;
9472                                                                                                                        }
9473                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9474                                                                                                                } else {
9475                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9476                                                                                                                                        fieldAttr);
9477                                                                                                                }
9478                                                                                                        } else {
9479                                                                                                                tableColumn = matchColumn(tableColumns, fieldAttr);
9480                                                                                                                if (tableColumn == null) {
9481                                                                                                                        continue;
9482                                                                                                                }
9483                                                                                                        }
9484                                                                                                        
9485                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9486                                                                                                        relation.setEffectType(effectType);
9487                                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9488                                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9489                                                                                                        Process process = modelFactory.createProcess(stmt);
9490                                                                                                        relation.setProcess(process);                                                                                                   
9491                                                                                                } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9492                                                                                                                .getExpressionType() == EExpressionType.simple_constant_t) {
9493                                                                                                        if (!initColumn) {
9494                                                                                                                TableColumn tableColumn;
9495                                                                                                                if (tableModel.isCreateTable()
9496                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9497                                                                                                                        if (tableModel.getColumns().size() <= i) {
9498                                                                                                                                continue;
9499                                                                                                                        }
9500                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9501                                                                                                                } else {
9502                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9503                                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9504                                                                                                                                                        .getConstantOperand(),
9505                                                                                                                                        i);
9506                                                                                                                }
9507                                                                                                                
9508                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9509                                                                                                                relation.setEffectType(effectType);
9510                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9511                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9512                                                                                                                Process process = modelFactory.createProcess(stmt);
9513                                                                                                                relation.setProcess(process);
9514                                                                                                        }
9515                                                                                                } else {
9516                                                                                                        if (!initColumn) {
9517                                                                                                                TableColumn tableColumn;
9518                                                                                                                if (tableModel.isCreateTable()
9519                                                                                                                                && !containStarColumn(tableModel.getColumns())) {
9520                                                                                                                        if (tableModel.getColumns().size() <= i) {
9521                                                                                                                                continue;
9522                                                                                                                        }
9523                                                                                                                        tableColumn = tableModel.getColumns().get(i);
9524                                                                                                                } else {
9525                                                                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
9526                                                                                                                                        ((TResultColumn) resultColumn.getColumnObject()).getExpr(),
9527                                                                                                                                        i);
9528                                                                                                                }
9529                                                                                                                
9530                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9531                                                                                                                relation.setEffectType(effectType);
9532                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9533                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9534                                                                                                                Process process = modelFactory.createProcess(stmt);
9535                                                                                                                relation.setProcess(process);
9536                                                                                                        }
9537                                                                                                }
9538                                                                                        }
9539                                                                                }
9540                                                                        }
9541                                                                }
9542                                                        }
9543                                                }
9544                                        }
9545                                        else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) {
9546                                                TObjectName functionName = new TObjectName();
9547                                                functionName.setString(procedure.getName());
9548                                                Function function = (Function)createFunction(functionName);
9549                                                if (stmt.getColumnList() != null) {
9550                                                        for (int i = 0; i < stmt.getColumnList().size(); i++) {
9551                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9552                                                                relation.setEffectType(effectType);
9553                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9554                                                                                stmt.getColumnList().getObjectName(i));
9555                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9556                                                                relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
9557                                                                Process process = modelFactory.createProcess(stmt);
9558                                                                relation.setProcess(process);
9559                                                        }
9560                                                }
9561                                        }
9562                                }
9563                        } else if (stmt.getValues() != null && stmt.getValues().size() > 0 && tableModel.isCreateTable()) {
9564                                for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) {
9565                                        TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList();
9566                                        boolean allConstant = true;
9567                                        Process process = modelFactory.createProcess(stmt);
9568                                        for (int x = 0; x < columns.size(); x++) {
9569                                                TableColumn tableColumn = tableModel.getColumns().get(x);
9570                                                TResultColumn columnObject = columns.getResultColumn(x);
9571                                                if (columnObject == null) {
9572                                                        continue;
9573                                                }
9574                                                TExpression valueExpr = columnObject.getExpr();
9575                                                columnsInExpr visitor = new columnsInExpr();
9576                                                valueExpr.inOrderTraverse(visitor);
9577                                                List<TObjectName> objectNames = visitor.getObjectNames();
9578                                                List<TParseTreeNode> constants = visitor.getConstants();
9579                                                List<TParseTreeNode> functions = visitor.getFunctions();
9580                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9581
9582                                                if (functions != null && !functions.isEmpty()) {
9583                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, effectType, process);
9584                                                        allConstant = false;
9585                                                }
9586
9587                                                if (subquerys != null && !subquerys.isEmpty()) {
9588                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, effectType, process);
9589                                                        allConstant = false;
9590                                                }
9591                                                if (objectNames != null && !objectNames.isEmpty()) {
9592                                                        analyzeDataFlowRelation(tableColumn, objectNames, null, effectType, functions,
9593                                                                        process);
9594                                                        allConstant = false;
9595                                                }
9596                                                //insert into values generate too many constant relations, ignore constant relations.
9597                                                if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) {
9598                                                        analyzeConstantDataFlowRelation(tableColumn, constants, effectType, functions,
9599                                                                        process);
9600                                                        allConstant = false;
9601                                                }
9602                                        }
9603                                        
9604                                        if(allConstant) {
9605                                                modelManager.unbindProcessModel(stmt);
9606                                                tableModel.removeProcess(process);
9607                                        }
9608                                }
9609                        } else if (stmt.getRecordName() != null) {
9610                                String procedureName = DlineageUtil.getProcedureParentName(stmt);
9611                                String variableString = stmt.getRecordName().toString();
9612                                if (variableString.startsWith(":")) {
9613                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
9614                                }
9615                                if (!SQLUtil.isEmpty(procedureName)) {
9616                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
9617                                }
9618                                
9619                                Table recordTable = modelManager
9620                                                .getTableByName(DlineageUtil.getTableFullName(variableString));
9621                                if (recordTable != null) {
9622                                        for (int i = 0; i < recordTable.getColumns().size(); i++) {
9623                                                TableColumn sourceTableColumn = recordTable.getColumns().get(i);
9624                                                TableColumn targetTableColumn = modelFactory.createTableColumn(tableModel,
9625                                                                sourceTableColumn.getColumnObject(), false);
9626                                                if (targetTableColumn != null) {
9627                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9628                                                        relation.setEffectType(effectType);
9629                                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
9630                                                        relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
9631                                                        Process process = modelFactory.createProcess(stmt);
9632                                                        relation.setProcess(process);
9633                                                } else if (sourceTableColumn.getName().endsWith("*") && tableModel.isCreateTable()) {
9634                                                        for (TableColumn column : tableModel.getColumns()) {
9635                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9636                                                                relation.setEffectType(effectType);
9637                                                                relation.setTarget(new TableColumnRelationshipElement(column));
9638                                                                relation.addSource(new TableColumnRelationshipElement(sourceTableColumn));
9639                                                                Process process = modelFactory.createProcess(stmt);
9640                                                                relation.setProcess(process);
9641                                                        }
9642                                                }
9643                                        }
9644                                }
9645                        } else if (stmt.getInsertSource() == EInsertSource.values_function && stmt.getFunctionCall() != null) {
9646                                Table cursor = modelManager.getTableByName(
9647                                                DlineageUtil.getTableFullName(stmt.getFunctionCall().getFunctionName().toString()));
9648                                if (cursor != null) {
9649                                        TObjectName starColumn = new TObjectName();
9650                                        starColumn.setString("*");
9651                                        TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
9652                                        insertColumn.setShowStar(false);
9653                                        insertColumn.setExpandStar(true);
9654                                        for (int j = 0; j < cursor.getColumns().size(); j++) {
9655                                                DataFlowRelationship dataflowRelation = modelFactory.createDataFlowRelation();
9656                                                dataflowRelation.setEffectType(effectType);
9657                                                dataflowRelation.addSource(new TableColumnRelationshipElement(cursor.getColumns().get(j)));
9658                                                dataflowRelation.setTarget(new TableColumnRelationshipElement(insertColumn));
9659                                                Process process = modelFactory.createProcess(stmt);
9660                                                dataflowRelation.setProcess(process);
9661                                        }
9662                                }
9663
9664                        } else if (stmt.getInsertSource() == EInsertSource.values && stmt.getValues() != null) {
9665                                TObjectName starColumn = new TObjectName();
9666                                starColumn.setString("*");
9667                                TableColumn insertColumn = modelFactory.createTableColumn(tableModel, starColumn, true);
9668                                insertColumn.setShowStar(false);
9669                                insertColumn.setExpandStar(true);
9670                                for (int k = 0; stmt.getValues() != null && k < stmt.getValues().size(); k++) {
9671                                        TResultColumnList columns = stmt.getValues().getMultiTarget(k).getColumnList();
9672                                        for (int x = 0; x < columns.size(); x++) {
9673                                                TResultColumn columnObject = columns.getResultColumn(x);
9674                                                if (columnObject == null) {
9675                                                        continue;
9676                                                }
9677                                                TExpression valueExpr = columnObject.getExpr();
9678                                                columnsInExpr visitor = new columnsInExpr();
9679                                                valueExpr.inOrderTraverse(visitor);
9680                                                List<TObjectName> objectNames = visitor.getObjectNames();
9681                                                List<TParseTreeNode> constants = visitor.getConstants();
9682                                                List<TParseTreeNode> functions = visitor.getFunctions();
9683                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9684
9685                                                Process process = modelFactory.createProcess(stmt);
9686                                                if (functions != null && !functions.isEmpty()) {
9687                                                        analyzeFunctionDataFlowRelation(insertColumn, functions, effectType, process);
9688                                                }
9689
9690                                                if (subquerys != null && !subquerys.isEmpty()) {
9691                                                        analyzeSubqueryDataFlowRelation(insertColumn, subquerys, effectType, process);
9692                                                }
9693                                                if (objectNames != null && !objectNames.isEmpty()) {
9694                                                        analyzeDataFlowRelation(insertColumn, objectNames, null, effectType, functions,
9695                                                                        process);
9696                                                }
9697                                                //insert into values generate too many constant relations, ignore constant relations.
9698                                                if (constants != null && !constants.isEmpty() && stmt.getParentStmt() != null) {
9699                                                        analyzeConstantDataFlowRelation(insertColumn, constants, effectType, functions,
9700                                                                        process);
9701                                                }
9702                                        }
9703                                }
9704                        }else if (stmt.getExecuteStmt() != null && stmt.getExecuteStmt().getModuleName() != null) {
9705                                analyzeCustomSqlStmt(stmt.getExecuteStmt());
9706                                Procedure procedure = modelManager.getProcedureByName(DlineageUtil
9707                                                .getIdentifierNormalTableName(stmt.getExecuteStmt().getModuleName().toString()));
9708                                if (procedure!=null && procedure.getProcedureObject() instanceof TStoredProcedureSqlStatement) {
9709                                        TStoredProcedureSqlStatement procedureStmt = (TStoredProcedureSqlStatement) procedure
9710                                                        .getProcedureObject();
9711                                        List<TSelectSqlStatement> stmtItems = getLastSelectStmt(procedureStmt);
9712                                        if (stmtItems != null) {
9713                                                for(TSelectSqlStatement stmtItem: stmtItems) {
9714                                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmtItem);
9715                                                        if (resultSetModel != null) {
9716                                                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
9717                                                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
9718                                                                        
9719                                                                        Transform transform = new Transform();
9720                                                                        transform.setType(Transform.FUNCTION);
9721                                                                        transform.setCode(stmt.getExecuteStmt().getModuleName());
9722                                                                        resultColumn.setTransform(transform);
9723                                                                        
9724                                                                        TAliasClause alias = null;
9725
9726                                                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
9727                                                                                alias = ((TResultColumn) resultColumn.getColumnObject())
9728                                                                                                .getAliasClause();
9729                                                                        }
9730                                                                        
9731                                                                        if (alias != null && alias.getAliasName() != null) {
9732                                                                                TableColumn tableColumn;
9733                                                                                if (!initColumn) {
9734                                                                                        if (tableModel.isCreateTable()
9735                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9736                                                                                                if(resultColumn.getName().endsWith("*")) {
9737                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9738                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9739                                                                                                                relation.setEffectType(effectType);
9740                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9741                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9742                                                                                                                Process process = modelFactory.createProcess(stmt);
9743                                                                                                                relation.setProcess(process);
9744                                                                                                        }
9745                                                                                                        continue;
9746                                                                                                }
9747                                                                                                else {
9748                                                                                                        if (tableModel.getColumns().size() <= i) {
9749                                                                                                                continue;
9750                                                                                                        }
9751                                                                                                        tableColumn = tableModel.getColumns().get(i);
9752                                                                                                }
9753                                                                                        } else {
9754                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9755                                                                                                                alias.getAliasName());
9756                                                                                        }
9757                                                                                } else {
9758                                                                                        tableColumn = matchColumn(tableColumns, alias.getAliasName());
9759                                                                                        if (tableColumn == null) {
9760                                                                                                continue;
9761                                                                                        }
9762                                                                                }
9763                                        
9764                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9765                                                                                relation.setEffectType(effectType);
9766                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9767                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9768                                                                                Process process = modelFactory.createProcess(stmt);
9769                                                                                relation.setProcess(process);
9770                                                                        } else if (((TResultColumn) resultColumn.getColumnObject())
9771                                                                                        .getFieldAttr() != null) {
9772                                                                                TObjectName fieldAttr = ((TResultColumn) resultColumn.getColumnObject())
9773                                                                                                .getFieldAttr();
9774                                                                                TableColumn tableColumn;
9775                                                                                if (!initColumn) {
9776                                                                                        if (tableModel.isCreateTable()
9777                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9778                                                                                                if(resultColumn.getName().endsWith("*")) {
9779                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9780                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9781                                                                                                                relation.setEffectType(effectType);
9782                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9783                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9784                                                                                                                Process process = modelFactory.createProcess(stmt);
9785                                                                                                                relation.setProcess(process);
9786                                                                                                        }
9787                                                                                                        continue;
9788                                                                                                }
9789                                                                                                else {
9790                                                                                                        if (tableModel.getColumns().size() <= i) {
9791                                                                                                                continue;
9792                                                                                                        }
9793                                                                                                        tableColumn = tableModel.getColumns().get(i);
9794                                                                                                }
9795                                                                                        } else {
9796                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9797                                                                                                                fieldAttr);
9798                                                                                        }
9799                                                                                } else {
9800                                                                                        tableColumn = matchColumn(tableColumns, fieldAttr);
9801                                                                                        if (tableColumn == null) {
9802                                                                                                continue;
9803                                                                                        }
9804                                                                                }
9805                                                                                
9806                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9807                                                                                relation.setEffectType(effectType);
9808                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9809                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9810                                                                                Process process = modelFactory.createProcess(stmt);
9811                                                                                relation.setProcess(process);
9812                                                                        } else if (((TResultColumn) resultColumn.getColumnObject()).getExpr()
9813                                                                                        .getExpressionType() == EExpressionType.simple_constant_t) {
9814                                                                                if (!initColumn) {
9815                                                                                        TableColumn tableColumn;
9816                                                                                        if (tableModel.isCreateTable()
9817                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9818                                                                                                if(resultColumn.getName().endsWith("*")) {
9819                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9820                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9821                                                                                                                relation.setEffectType(effectType);
9822                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9823                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9824                                                                                                                Process process = modelFactory.createProcess(stmt);
9825                                                                                                                relation.setProcess(process);
9826                                                                                                        }
9827                                                                                                        continue;
9828                                                                                                }
9829                                                                                                else {
9830                                                                                                        if (tableModel.getColumns().size() <= i) {
9831                                                                                                                continue;
9832                                                                                                        }
9833                                                                                                        tableColumn = tableModel.getColumns().get(i);
9834                                                                                                }
9835                                                                                        } else {
9836                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9837                                                                                                                ((TResultColumn) resultColumn.getColumnObject()).getExpr()
9838                                                                                                                                .getConstantOperand(),
9839                                                                                                                i);
9840                                                                                        }
9841                                                                                        
9842                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9843                                                                                        relation.setEffectType(effectType);
9844                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9845                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9846                                                                                        Process process = modelFactory.createProcess(stmt);
9847                                                                                        relation.setProcess(process);
9848                                                                                }
9849                                                                        } else {
9850                                                                                if (!initColumn) {
9851                                                                                        TableColumn tableColumn;
9852                                                                                        if (tableModel.isCreateTable()
9853                                                                                                        && !containStarColumn(tableModel.getColumns())) {
9854                                                                                                if(resultColumn.getName().endsWith("*")) {
9855                                                                                                        for(TableColumn tableColumnItem: tableModel.getColumns()) {
9856                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9857                                                                                                                relation.setEffectType(effectType);
9858                                                                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumnItem));
9859                                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9860                                                                                                                Process process = modelFactory.createProcess(stmt);
9861                                                                                                                relation.setProcess(process);
9862                                                                                                        }
9863                                                                                                        continue;
9864                                                                                                }
9865                                                                                                else {
9866                                                                                                        if (tableModel.getColumns().size() <= i) {
9867                                                                                                                continue;
9868                                                                                                        }
9869                                                                                                        tableColumn = tableModel.getColumns().get(i);
9870                                                                                                }
9871                                                                                        } else {
9872                                                                                                tableColumn = modelFactory.createInsertTableColumn(tableModel,
9873                                                                                                                ((TResultColumn) resultColumn.getColumnObject()).getExpr(),
9874                                                                                                                i);
9875                                                                                        }
9876                                                                                        
9877                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9878                                                                                        relation.setEffectType(effectType);
9879                                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9880                                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
9881                                                                                        Process process = modelFactory.createProcess(stmt);
9882                                                                                        relation.setProcess(process);
9883                                                                                }
9884                                                                        }
9885                                                                }
9886                                                        }
9887                                                }
9888                                        }
9889                                }
9890                                else if (procedure!=null && procedure.getProcedureObject() instanceof TObjectName) {
9891                                        TObjectName functionName = new TObjectName();
9892                                        functionName.setString(procedure.getName());
9893                                        Function function = (Function)createFunction(functionName);
9894                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
9895                                        relation.setEffectType(effectType);
9896                                        TObjectName starColumn = new TObjectName();
9897                                        starColumn.setString("*");
9898                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
9899                                                        starColumn);
9900                                        tableColumn.setExpandStar(false);
9901                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
9902                                        relation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
9903                                        Process process = modelFactory.createProcess(stmt);
9904                                        relation.setProcess(process);
9905                                }
9906                        }
9907                }
9908                
9909                if(stmt.getOnDuplicateKeyUpdate()!=null) {
9910                        TTable table = stmt.getTargetTable();
9911                        Table tableModel = modelFactory.createTable(table);
9912                        for(TResultColumn column: stmt.getOnDuplicateKeyUpdate()) {
9913                                if(column.getExpr()==null || column.getExpr().getExpressionType() != EExpressionType.assignment_t) {
9914                                        continue;
9915                                }
9916                                TExpression left = column.getExpr().getLeftOperand();
9917                                TExpression right = column.getExpr().getRightOperand();
9918                                TObjectName columnObject = left.getObjectOperand();
9919                                if (columnObject != null) {
9920                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false);
9921                                        if (tableColumn != null) {
9922                                                columnsInExpr visitor = new columnsInExpr();
9923                                                right.inOrderTraverse(visitor);
9924                                                List<TObjectName> objectNames = visitor.getObjectNames();
9925                                                List<TParseTreeNode> functions = visitor.getFunctions();
9926                                                List<TParseTreeNode> constants = visitor.getConstants();
9927                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
9928
9929                                                if (functions != null && !functions.isEmpty()) {
9930                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.update);
9931                                                }
9932                                                if (subquerys != null && !subquerys.isEmpty()) {
9933                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.update);
9934                                                }
9935                                                if (objectNames != null && !objectNames.isEmpty()) {
9936                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.update, functions);
9937                                                }
9938                                                if (constants != null && !constants.isEmpty()) {
9939                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.update, functions);
9940                                                }
9941                                        }
9942                                }
9943                        }
9944                }
9945
9946                if (!expressions.isEmpty() && stmt.getSubQuery() != null) {
9947                        analyzeInsertImpactRelation(stmt.getSubQuery(), tableColumnMap, expressions, effectType);
9948                }
9949        }
9950
9951        private List<TSelectSqlStatement> getLastSelectStmt(TStoredProcedureSqlStatement procedureStmt) {
9952                List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>();
9953                if (procedureStmt.getBodyStatements().size() > 0) {
9954                        for (int j = procedureStmt.getBodyStatements().size() - 1; j >= 0; j--) {
9955                                TCustomSqlStatement stmtItem = procedureStmt.getBodyStatements().get(j);
9956                                if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) {
9957                                        if (stmtItem.getStatements() != null) {
9958                                                List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9959                                                if (item != null && !item.isEmpty()) {
9960                                                        stmts.addAll(item);
9961                                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9962                                                                break;
9963                                                        }
9964                                                }
9965                                        }
9966                                        break;
9967                                }
9968                                if (stmtItem instanceof TSelectSqlStatement) {
9969                                        stmts.add((TSelectSqlStatement) stmtItem);
9970                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9971                                                break;
9972                                        }
9973                                } else if (stmtItem.getStatements() != null) {
9974                                        List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9975                                        if (item != null && !item.isEmpty()) {
9976                                                stmts.addAll(item);
9977                                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9978                                                        break;
9979                                                }
9980                                        }
9981                                }
9982                        }
9983                }
9984                return stmts;
9985        }
9986
9987        private List<TSelectSqlStatement> getLastSelectStmt(TCustomSqlStatement stmt) {
9988                List<TSelectSqlStatement> stmts = new ArrayList<TSelectSqlStatement>();
9989                for (int j = stmt.getStatements().size() - 1; j >= 0; j--) {
9990                        TCustomSqlStatement stmtItem = stmt.getStatements().get(j);
9991                        if (stmtItem instanceof TReturnStmt || stmtItem instanceof TMssqlReturn) {
9992                                if (stmtItem.getStatements() != null) {
9993                                        List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
9994                                        if (item != null && !item.isEmpty()) {
9995                                                stmts.addAll(item);
9996                                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
9997                                                        break;
9998                                                }
9999                                        }
10000                                }
10001                                break;
10002                        }
10003                        if (stmtItem instanceof TSelectSqlStatement) {
10004                                stmts.add((TSelectSqlStatement) stmtItem);
10005                                if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
10006                                        break;
10007                                }
10008                        } else if (stmtItem.getStatements() != null) {
10009                                List<TSelectSqlStatement> item = getLastSelectStmt(stmtItem);
10010                                if (item != null && !item.isEmpty()) {
10011                                        stmts.addAll(item);
10012                                        if(option.getVendor()!=EDbVendor.dbvmssql && option.getVendor()!=EDbVendor.dbvazuresql) {
10013                                                break;
10014                                        }
10015                                }
10016                        }
10017                }
10018                return stmts;
10019        }
10020
10021        private TableColumn getStarColumn(List<TableColumn> columns) {
10022                for (TableColumn column : columns) {
10023                        if (column.getName().endsWith("*")) {
10024                                return column;
10025                        }
10026                }
10027                return null;
10028        }
10029
10030        private boolean containStarColumn(List<TableColumn> columns) {
10031                if (columns == null)
10032                        return false;
10033                for (TableColumn column : columns) {
10034                        if (column.getName().endsWith("*")) {
10035                                return true;
10036                        }
10037                }
10038                return false;
10039        }
10040
10041        private boolean containStarColumn(ResultSet resultSet) {
10042                if (resultSet == null || resultSet.getColumns() == null)
10043                        return false;
10044                for (ResultColumn column : resultSet.getColumns()) {
10045                        if (column.getName().endsWith("*")) {
10046                                return true;
10047                        }
10048                }
10049                return false;
10050        }
10051
10052        private int indexOfColumn(List<TResultColumn> columns, TObjectName objectName) {
10053                for (int i = 0; i < columns.size(); i++) {
10054                        if (columns.get(i).toString().trim().equalsIgnoreCase(objectName.toString().trim())) {
10055                                return i;
10056                        }
10057                }
10058                return -1;
10059        }
10060
10061        private boolean isEmptyCollection(Collection<?> keyMap) {
10062                return keyMap == null || keyMap.isEmpty();
10063        }
10064
10065        private void analyzeInsertImpactRelation(TSelectSqlStatement stmt, Map<String, List<TableColumn>> insertMap,
10066                        List<TExpression> expressions, EffectType effectType) {
10067                List<TObjectName> objectNames = new ArrayList<TObjectName>();
10068                for (int i = 0; i < expressions.size(); i++) {
10069                        TExpression condition = expressions.get(i);
10070                        columnsInExpr visitor = new columnsInExpr();
10071                        condition.inOrderTraverse(visitor);
10072                        objectNames.addAll(visitor.getObjectNames());
10073                }
10074
10075                Iterator<String> iter = insertMap.keySet().iterator();
10076                while (iter.hasNext()) {
10077                        String table = iter.next();
10078                        List<TableColumn> tableColumns = insertMap.get(table);
10079                        for (int i = 0; i < tableColumns.size(); i++) {
10080
10081                                TableColumn column = tableColumns.get(i);
10082                                ImpactRelationship relation = modelFactory.createImpactRelation();
10083                                relation.setEffectType(effectType);
10084                                relation.setTarget(new TableColumnRelationshipElement(column));
10085
10086                                for (int j = 0; j < objectNames.size(); j++) {
10087                                        TObjectName columnName = objectNames.get(j);
10088                                        Object model = modelManager.getModel(stmt);
10089                                        if (model instanceof SelectResultSet) {
10090                                                SelectResultSet queryTable = (SelectResultSet) model;
10091                                                List<ResultColumn> columns = queryTable.getColumns();
10092                                                for (int k = 0; k < columns.size(); k++) {
10093                                                        ResultColumn resultColumn = columns.get(k);
10094                                                        if (resultColumn.getAlias() != null
10095                                                                        && columnName.toString().equalsIgnoreCase(resultColumn.getAlias())) {
10096                                                                relation.addSource(
10097                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
10098                                                        } else if (resultColumn.getName() != null
10099                                                                        && columnName.toString().equalsIgnoreCase(resultColumn.getName())) {
10100                                                                relation.addSource(
10101                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
10102                                                        }
10103                                                }
10104                                        }
10105                                }
10106                        }
10107                }
10108        }
10109
10110        private void analyzeUpdateStmt(TUpdateSqlStatement stmt) {
10111                if (stmt.getResultColumnList() == null)
10112                        return;
10113
10114                TTable table = stmt.getTargetTable();
10115                while (table.getCTE() != null || table.getSubquery() != null || (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null)) {
10116                        if (table.getCTE() != null) {
10117                                table = table.getCTE().getSubquery().getTables().getTable(0);
10118                        } else if (table.getLinkTable() != null && table.getLinkTable().getSubquery() != null) {
10119                                table = table.getLinkTable().getSubquery().getTables().getTable(0);
10120                        } else if (table.getSubquery() != null) {
10121                                table = table.getSubquery().getTables().getTable(0);
10122                        }
10123                }
10124                Table tableModel = modelFactory.createTable(table);
10125                Process process = modelFactory.createProcess(stmt);
10126                tableModel.addProcess(process);
10127
10128                for (int i = 0; i < stmt.tables.size(); i++) {
10129                        TTable tableElement = stmt.tables.getTable(i);
10130                        if (tableElement.getSubquery() != null) {
10131                                QueryTable queryTable = modelFactory.createQueryTable(tableElement);
10132                                TSelectSqlStatement subquery = tableElement.getSubquery();
10133                                analyzeSelectStmt(subquery);
10134
10135                                if (subquery.getSetOperatorType() != ESetOperatorType.none) {
10136                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager.getModel(subquery);
10137                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
10138                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
10139                                                ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
10140                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
10141                                                selectSetRalation.setEffectType(EffectType.select);
10142                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
10143                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
10144                                                selectSetRalation.setProcess(process);
10145                                        }
10146                                }
10147
10148                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(tableElement.getSubquery());
10149                                if (resultSetModel != null && resultSetModel != queryTable
10150                                                && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10151                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10152                                        impactRelation.setEffectType(EffectType.update);
10153                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10154                                                        resultSetModel.getRelationRows()));
10155                                        impactRelation.setTarget(
10156                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(queryTable.getRelationRows()));
10157                                }
10158
10159                        } else if (tableElement.getCTE() != null) {
10160                                QueryTable queryTable = modelFactory.createQueryTable(tableElement);
10161
10162                                TObjectNameList cteColumns = tableElement.getCTE().getColumnList();
10163                                if (cteColumns != null) {
10164                                        for (int j = 0; j < cteColumns.size(); j++) {
10165                                                modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
10166                                        }
10167                                }
10168                                TSelectSqlStatement subquery = tableElement.getCTE().getSubquery();
10169                                if (subquery != null && !stmtStack.contains(subquery)) {
10170                                        analyzeSelectStmt(subquery);
10171
10172                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
10173                                        if (resultSetModel != null && resultSetModel != queryTable
10174                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10175                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10176                                                impactRelation.setEffectType(EffectType.select);
10177                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10178                                                                resultSetModel.getRelationRows()));
10179                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10180                                                                queryTable.getRelationRows()));
10181                                        }
10182
10183                                        if (subquery.getSetOperatorType() != ESetOperatorType.none) {
10184                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
10185                                                                .getModel(subquery);
10186                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
10187                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
10188                                                        ResultColumn targetColumn = null;
10189                                                        if (cteColumns != null) {
10190                                                                targetColumn = queryTable.getColumns().get(j);
10191                                                        } else {
10192                                                                targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
10193                                                        }
10194                                                        for (Set<TObjectName> starLinkColumns : sourceColumn.getStarLinkColumns().values()) {
10195                                                                for (TObjectName starLinkColumn : starLinkColumns) {
10196                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
10197                                                                }
10198                                                        }
10199                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
10200                                                        selectSetRalation.setEffectType(EffectType.select);
10201                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
10202                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
10203                                                        selectSetRalation.setProcess(process);
10204                                                }
10205                                        } else {
10206                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
10207                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
10208                                                        ResultColumn targetColumn = null;
10209                                                        if (cteColumns != null) {
10210                                                                targetColumn = queryTable.getColumns().get(j);
10211                                                        } else {
10212                                                                targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
10213                                                        }
10214                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
10215                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
10216                                                        }
10217                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
10218                                                        selectSetRalation.setEffectType(EffectType.select);
10219                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
10220                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
10221                                                        selectSetRalation.setProcess(process);
10222                                                }
10223                                        }
10224                                } else if (tableElement.getCTE().getUpdateStmt() != null) {
10225                                        analyzeCustomSqlStmt(tableElement.getCTE().getUpdateStmt());
10226                                } else if (tableElement.getCTE().getInsertStmt() != null) {
10227                                        analyzeCustomSqlStmt(tableElement.getCTE().getInsertStmt());
10228                                } else if (tableElement.getCTE().getDeleteStmt() != null) {
10229                                        analyzeCustomSqlStmt(tableElement.getCTE().getDeleteStmt());
10230                                }
10231                        } else {
10232                                modelFactory.createTable(stmt.tables.getTable(i));
10233                        }
10234                }
10235
10236                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
10237                        TResultColumn field = stmt.getResultColumnList().getResultColumn(i);
10238
10239                        if (field.getExpr().getExpressionType() == EExpressionType.function_t) {
10240                                // Handle SQL Server XML modify() method for data lineage
10241                                TFunctionCall funcCall = field.getExpr().getFunctionCall();
10242                                if (funcCall != null && funcCall.getFunctionType() == EFunctionType.xmlmodify_t) {
10243                                        analyzeXmlModifyFunction(stmt, tableModel, process, funcCall);
10244                                }
10245                                continue;
10246                        }
10247
10248                        TExpression expression = field.getExpr().getLeftOperand();
10249                        if (expression == null) {
10250                                ErrorInfo errorInfo = new ErrorInfo();
10251                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10252                                errorInfo.setErrorMessage(
10253                                                "Can't get result column expression. Expression is " + field.getExpr().toString());
10254                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(field.getExpr().getStartToken().lineNo,
10255                                                field.getExpr().getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
10256                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(field.getExpr().getEndToken().lineNo,
10257                                                field.getExpr().getEndToken().columnNo + field.getExpr().getEndToken().getAstext().length(),
10258                                                ModelBindingManager.getGlobalHash()));
10259                                errorInfo.fillInfo(this);
10260                                errorInfos.add(errorInfo);
10261                                continue;
10262                        }
10263                        if (expression.getExpressionType() == EExpressionType.list_t) {
10264                                TExpression setExpression = field.getExpr().getRightOperand();
10265                                if (setExpression != null && setExpression.getSubQuery() != null) {
10266                                        TSelectSqlStatement query = setExpression.getSubQuery();
10267                                        analyzeSelectStmt(query);
10268
10269                                        SelectResultSet resultSetModel = (SelectResultSet) modelManager
10270                                                        .getModel(query.getResultColumnList());
10271
10272                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10273                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10274                                                impactRelation.setEffectType(EffectType.update);
10275                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10276                                                                resultSetModel.getRelationRows()));
10277                                                impactRelation.setTarget(
10278                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
10279                                        }
10280
10281                                        TExpressionList columnList = expression.getExprList();
10282                                        for (int j = 0; j < columnList.size(); j++) {
10283                                                TObjectName column = columnList.getExpression(j).getObjectOperand();
10284
10285                                                if (column.getDbObjectType() == EDbObjectType.variable) {
10286                                                        continue;
10287                                                }
10288
10289                                                if (column.getColumnNameOnly().startsWith("@") && (option.getVendor() == EDbVendor.dbvmssql
10290                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
10291                                                        continue;
10292                                                }
10293
10294                                                if (column.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana
10295                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
10296                                                        continue;
10297                                                }
10298
10299                                                ResultColumn resultColumn = resultSetModel.getColumns().get(j);
10300                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false);
10301                                                if (tableColumn != null) {
10302                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10303                                                        relation.setEffectType(EffectType.update);
10304                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
10305                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10306                                                        relation.setProcess(process);
10307                                                }
10308
10309                                        }
10310                                }
10311                        } else if (expression.getExpressionType() == EExpressionType.simple_object_name_t) {
10312                                TExpression setExpression = field.getExpr().getRightOperand();
10313                                if (setExpression != null && setExpression.getSubQuery() != null) {
10314                                        TSelectSqlStatement query = setExpression.getSubQuery();
10315                                        analyzeSelectStmt(query);
10316
10317                                        SelectResultSet resultSetModel = (SelectResultSet) modelManager
10318                                                        .getModel(query.getResultColumnList());
10319
10320                                        if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10321                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10322                                                impactRelation.setEffectType(EffectType.update);
10323                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10324                                                                resultSetModel.getRelationRows()));
10325                                                impactRelation.setTarget(
10326                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
10327                                        }
10328
10329                                        TObjectName column = expression.getObjectOperand();
10330                                        ResultColumn resultColumn = resultSetModel.getColumns().get(0);
10331                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, column, false);
10332                                        if (tableColumn != null) {
10333                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10334                                                relation.setEffectType(EffectType.update);
10335                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
10336                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10337                                                relation.setProcess(process);
10338                                        }
10339                                } else if (setExpression != null) {
10340                                        // ResultSet resultSet = modelFactory.createResultSet(stmt,
10341                                        // true);
10342
10343                                        ResultSet resultSet = modelFactory.createResultSet(stmt, false);
10344
10345                                        createPseudoImpactRelation(stmt, resultSet, EffectType.update);
10346
10347                                        TObjectName columnObject = expression.getObjectOperand();
10348
10349                                        ResultColumn updateColumn = modelFactory.createUpdateResultColumn(resultSet, columnObject);
10350
10351                                        columnsInExpr visitor = new columnsInExpr();
10352                                        field.getExpr().getRightOperand().inOrderTraverse(visitor);
10353
10354                                        List<TObjectName> objectNames = visitor.getObjectNames();
10355                                        List<TParseTreeNode> functions = visitor.getFunctions();
10356                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
10357
10358                                        if (functions != null && !functions.isEmpty()) {
10359                                                analyzeFunctionDataFlowRelation(updateColumn, functions, EffectType.update);
10360                                        }
10361
10362                                        if (subquerys != null && !subquerys.isEmpty()) {
10363                                                analyzeSubqueryDataFlowRelation(updateColumn, subquerys, EffectType.update);
10364                                        }
10365
10366                                        Transform transform = new Transform();
10367                                        transform.setType(Transform.EXPRESSION);
10368                                        transform.setCode(setExpression);
10369                                        updateColumn.setTransform(transform);
10370                                        analyzeDataFlowRelation(updateColumn, objectNames, EffectType.update, functions);
10371
10372                                        List<TParseTreeNode> constants = visitor.getConstants();
10373                                        analyzeConstantDataFlowRelation(updateColumn, constants, EffectType.update, functions);
10374
10375                                        TableColumn tableColumn = modelFactory.createTableColumn(tableModel, columnObject, false);
10376                                        if(tableColumn!=null) {
10377                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10378                                                relation.setEffectType(EffectType.update);
10379                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
10380                                                relation.addSource(new ResultColumnRelationshipElement(updateColumn));
10381                                                relation.setProcess(process);
10382                                        }
10383                                        
10384                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10385                                        impactRelation.setEffectType(EffectType.update);
10386                                        impactRelation.addSource(
10387                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
10388                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
10389                                                        tableModel.getRelationRows()));
10390                                }
10391                        }
10392                }
10393
10394                if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
10395                        for (int i = 0; i < stmt.getJoins().size(); i++) {
10396                                TJoin join = stmt.getJoins().getJoin(i);
10397                                if (join.getJoinItems() != null) {
10398                                        for (int j = 0; j < join.getJoinItems().size(); j++) {
10399                                                TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
10400                                                TExpression expr = joinItem.getOnCondition();
10401                                                analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on,
10402                                                                EffectType.update);
10403                                        }
10404                                }
10405                        }
10406                }
10407
10408                if (stmt.getWhereClause() != null && stmt.getWhereClause().getCondition() != null) {
10409                        analyzeFilterCondition(null, stmt.getWhereClause().getCondition(), null, JoinClauseType.where,
10410                                        EffectType.update);
10411                }
10412
10413                if (stmt.getOutputClause() != null) {
10414                        TOutputClause outputClause = stmt.getOutputClause();
10415                        if (outputClause.getSelectItemList() != null) {
10416                                ResultSet resultSet = modelFactory.createResultSet(outputClause, false);
10417                                for (int j = 0; j < outputClause.getSelectItemList().size(); j++) {
10418                                        TResultColumn sourceColumn = outputClause.getSelectItemList().getResultColumn(j);
10419                                        ResultColumn sourceColumnModel = modelFactory.createResultColumn(resultSet, sourceColumn);
10420                                        analyzeResultColumn(sourceColumn, EffectType.select);
10421
10422                                        if (outputClause.getIntoTable() != null) {
10423                                                Table intoTableModel = modelFactory.createTableByName(outputClause.getIntoTable());
10424                                                intoTableModel.addProcess(process);
10425                                                if (outputClause.getIntoColumnList() != null) {
10426                                                        TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel,
10427                                                                        outputClause.getIntoColumnList().getObjectName(j));
10428
10429                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10430                                                        relation.setEffectType(EffectType.insert);
10431                                                        relation.setTarget(new TableColumnRelationshipElement(intoTableColumn));
10432                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel));
10433                                                } else if (sourceColumn.getAliasClause() != null
10434                                                                || sourceColumn.getExpr().getObjectOperand() != null) {
10435                                                        TObjectName tableColumnObject = null;
10436                                                        if (sourceColumn.getAliasClause() != null) {
10437                                                                tableColumnObject = sourceColumn.getAliasClause().getAliasName();
10438                                                        } else {
10439                                                                tableColumnObject = sourceColumn.getExpr().getObjectOperand();
10440                                                        }
10441
10442                                                        TableColumn intoTableColumn = modelFactory.createInsertTableColumn(intoTableModel,
10443                                                                        tableColumnObject);
10444                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10445                                                        relation.setEffectType(EffectType.insert);
10446                                                        relation.setTarget(new TableColumnRelationshipElement(intoTableColumn));
10447                                                        relation.addSource(new ResultColumnRelationshipElement(sourceColumnModel));
10448                                                }
10449                                        }
10450                                }
10451                        }
10452                }
10453        }
10454
10455        /**
10456         * Analyzes SQL Server XML modify() function to extract data lineage from sql:column() references
10457         * in XQuery expressions.
10458         *
10459         * Example SQL:
10460         * SET [Demographics].modify('... sql:column("deleted.LineTotal") ...')
10461         *
10462         * This extracts:
10463         * - Target column: Demographics (from the XML column being modified)
10464         * - Source column: deleted.LineTotal (from sql:column() reference in XQuery)
10465         */
10466        private void analyzeXmlModifyFunction(TUpdateSqlStatement stmt, Table tableModel, Process process, TFunctionCall funcCall) {
10467                TObjectName funcName = funcCall.getFunctionName();
10468                if (funcName == null || funcName.getPartToken() == null) {
10469                        return;
10470                }
10471
10472                // Get the XML column being modified (e.g., [Demographics] from "[Demographics].modify")
10473                String xmlColumnName = funcName.getPartToken().astext;
10474
10475                // Get the XQuery argument
10476                if (funcCall.getArgs() == null || funcCall.getArgs().size() == 0) {
10477                        return;
10478                }
10479
10480                String xqueryString = funcCall.getArgs().getExpression(0).toString();
10481
10482                // Extract sql:column() references from the XQuery string
10483                List<String> sqlColumnRefs = extractSqlColumnReferences(xqueryString);
10484                if (sqlColumnRefs.isEmpty()) {
10485                        return;
10486                }
10487
10488                // Extract XPath target from XQuery (e.g., /IndividualSurvey/TotalPurchaseYTD)
10489                String xpathTarget = extractXPathTarget(xqueryString);
10490
10491                // Build full target column name including XML path
10492                String fullTargetColumnName = xmlColumnName;
10493                if (xpathTarget != null && !xpathTarget.isEmpty()) {
10494                        fullTargetColumnName = xmlColumnName + "." + xpathTarget;
10495                }
10496
10497                // Create the target table column for the XML column being modified
10498                TableColumn targetTableColumn = modelFactory.createInsertTableColumn(tableModel, fullTargetColumnName);
10499
10500                // Create source-to-target relationships for each sql:column reference
10501                for (String sqlColRef : sqlColumnRefs) {
10502                        // Parse the column reference (e.g., "deleted.LineTotal" -> table="deleted", column="LineTotal")
10503                        String[] parts = sqlColRef.split("\\.", 2);
10504                        String sourceTableName = parts.length > 1 ? parts[0] : null;
10505                        String sourceColumnName = parts.length > 1 ? parts[1] : parts[0];
10506
10507                        // Find the source table in the statement's tables
10508                        TTable sourceTable = null;
10509                        if (sourceTableName != null && stmt.tables != null) {
10510                                for (int j = 0; j < stmt.tables.size(); j++) {
10511                                        TTable t = stmt.tables.getTable(j);
10512                                        String tableName = t.getTableName().toString();
10513                                        String alias = t.getAliasName();
10514                                        if (tableName.equalsIgnoreCase(sourceTableName) ||
10515                                                (alias != null && alias.equalsIgnoreCase(sourceTableName))) {
10516                                                sourceTable = t;
10517                                                break;
10518                                        }
10519                                }
10520                        }
10521
10522                        if (sourceTable != null && targetTableColumn != null) {
10523                                // Create a table model for the source if needed
10524                                Table sourceTableModel = modelFactory.createTable(sourceTable);
10525                                TableColumn sourceColumn = modelFactory.createInsertTableColumn(sourceTableModel, sourceColumnName);
10526
10527                                if (sourceColumn != null) {
10528                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10529                                        relation.setEffectType(EffectType.update);
10530                                        relation.setTarget(new TableColumnRelationshipElement(targetTableColumn));
10531                                        relation.addSource(new TableColumnRelationshipElement(sourceColumn));
10532                                        relation.setProcess(process);
10533                                        relation.setFunction("modify");
10534                                }
10535                        }
10536                }
10537        }
10538
10539        /**
10540         * Extracts sql:column() references from an XQuery string.
10541         * Example: 'sql:column("deleted.LineTotal")' -> ["deleted.LineTotal"]
10542         */
10543        private List<String> extractSqlColumnReferences(String xquery) {
10544                List<String> refs = new ArrayList<>();
10545                if (xquery == null) {
10546                        return refs;
10547                }
10548
10549                int startIdx = 0;
10550                while ((startIdx = xquery.indexOf("sql:column(", startIdx)) >= 0) {
10551                        int parenStart = startIdx + "sql:column(".length();
10552                        int parenEnd = xquery.indexOf(")", parenStart);
10553                        if (parenEnd < 0) {
10554                                break;
10555                        }
10556
10557                        String arg = xquery.substring(parenStart, parenEnd).trim();
10558                        // Remove quotes (single or double)
10559                        if ((arg.startsWith("\"") && arg.endsWith("\"")) ||
10560                                (arg.startsWith("'") && arg.endsWith("'"))) {
10561                                arg = arg.substring(1, arg.length() - 1);
10562                        }
10563
10564                        if (!arg.isEmpty()) {
10565                                refs.add(arg);
10566                        }
10567
10568                        startIdx = parenEnd + 1;
10569                }
10570
10571                return refs;
10572        }
10573
10574        /**
10575         * Extracts the XPath target from an XQuery modify expression.
10576         * Example: 'replace value of (/IndividualSurvey/TotalPurchaseYTD)[1]' -> "IndividualSurvey.TotalPurchaseYTD"
10577         */
10578        private String extractXPathTarget(String xquery) {
10579                if (xquery == null) {
10580                        return null;
10581                }
10582
10583                // Look for patterns like "(/path/to/element)" or "(/path/to/element)[1]"
10584                int replaceIdx = xquery.indexOf("replace value of");
10585                if (replaceIdx < 0) {
10586                        return null;
10587                }
10588
10589                int parenStart = xquery.indexOf("(/", replaceIdx);
10590                if (parenStart < 0) {
10591                        return null;
10592                }
10593
10594                int parenEnd = xquery.indexOf(")", parenStart);
10595                if (parenEnd < 0) {
10596                        return null;
10597                }
10598
10599                String xpath = xquery.substring(parenStart + 1, parenEnd);
10600                // Remove any predicates like [1]
10601                int bracketIdx = xpath.indexOf("[");
10602                if (bracketIdx > 0) {
10603                        xpath = xpath.substring(0, bracketIdx);
10604                }
10605
10606                // Convert XPath to dot notation (e.g., /IndividualSurvey/TotalPurchaseYTD -> IndividualSurvey.TotalPurchaseYTD)
10607                if (xpath.startsWith("/")) {
10608                        xpath = xpath.substring(1);
10609                }
10610                xpath = xpath.replace("/", ".");
10611
10612                return xpath;
10613        }
10614
10615        private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants,
10616                        EffectType effectType, List<TParseTreeNode> functions) {
10617                analyzeConstantDataFlowRelation(modelObject, constants, effectType, functions, null);
10618        }
10619
10620        private void analyzeConstantDataFlowRelation(Object modelObject, List<TParseTreeNode> constants,
10621                        EffectType effectType, List<TParseTreeNode> functions, Process process) {
10622                if (constants == null || constants.size() == 0)
10623                        return;
10624
10625                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10626                relation.setEffectType(effectType);
10627                relation.setProcess(process);
10628
10629                if (functions != null && !functions.isEmpty()) {
10630                        relation.setFunction(getFunctionName(functions.get(0)));
10631                }
10632
10633                if (modelObject instanceof ResultColumn) {
10634                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
10635
10636                } else if (modelObject instanceof TableColumn) {
10637                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
10638
10639                } else {
10640                        throw new UnsupportedOperationException();
10641                }
10642
10643                if (option.isShowConstantTable()) {
10644                        Table constantTable = null;
10645                        if(modelObject instanceof FunctionResultColumn && ((FunctionResultColumn)modelObject).getFunction() instanceof TFunctionCall) {
10646                                TFunctionCall function = (TFunctionCall)((FunctionResultColumn)modelObject).getFunction();
10647                                if(function.getFunctionType() == EFunctionType.struct_t) {
10648                                        constantTable = modelFactory.createConstantsTable(String.valueOf(function.toString().hashCode()));
10649                                }
10650                        }
10651                        if(constantTable == null) {
10652                                constantTable = modelFactory.createConstantsTable(stmtStack.peek());
10653                        }
10654                        for (int i = 0; i < constants.size(); i++) {
10655                                TParseTreeNode constant = constants.get(i);
10656                                if (constant instanceof TConstant) {
10657                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TConstant) constant);
10658                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
10659                                } else if (constant instanceof TObjectName) {
10660                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, (TObjectName) constant,
10661                                                        false);
10662                                        if(constantColumn == null) {
10663                                                continue;
10664                                        }
10665                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
10666                                }
10667                        }
10668                }
10669
10670        }
10671
10672        private String getFunctionName(TParseTreeNode parseTreeNode) {
10673                if (parseTreeNode instanceof TFunctionCall) {
10674                        return ((TFunctionCall) parseTreeNode).getFunctionName().toString();
10675                }
10676                if (parseTreeNode instanceof TCaseExpression) {
10677                        return "case-when";
10678                }
10679                return null;
10680        }
10681
10682        private void analyzeCreateViewStmt(TCustomSqlStatement stmt, TSelectSqlStatement subquery,
10683                        TViewAliasClause viewAlias, TObjectName viewName) {
10684
10685                if (subquery != null) {
10686                        TTableList tables = subquery.getTables();
10687                        if (tables != null) {
10688                                for (int i = 0; i < tables.size(); i++) {
10689                                        TTable table = tables.getTable(i);
10690                                        TCustomSqlStatement createView = viewDDLMap
10691                                                        .get(DlineageUtil.getTableFullName(table.getTableName().toString()));
10692                                        if (createView != null) {
10693                                                analyzeCustomSqlStmt(createView);
10694                                        }
10695                                }
10696                        }
10697                        analyzeSelectStmt(subquery);
10698                }
10699
10700        
10701                if (viewAlias != null && viewAlias.getViewAliasItemList() != null) {
10702                        TViewAliasItemList viewItems = viewAlias.getViewAliasItemList();
10703                        Table viewModel = modelFactory.createView(stmt, viewName, true);
10704                        viewModel.setFromDDL(true);
10705                        viewModel.setDetermined(true);
10706                        Process process = modelFactory.createProcess(stmt);
10707                        viewModel.addProcess(process);
10708                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
10709                        if (resultSetModel != null) {
10710                                int resultSetSize = resultSetModel.getColumns().size();
10711                                int viewItemSize = viewItems.size();
10712                                int j = 0;
10713                                int viewColumnSize = viewItemSize;
10714                                if (resultSetModel.isDetermined() && resultSetSize > viewColumnSize) {
10715                                        viewColumnSize = resultSetSize;
10716                                }
10717                                for (int i = 0; i < viewColumnSize && j < resultSetSize; i++) {
10718                                        ResultColumn resultColumn = resultSetModel.getColumns().get(j);                                 
10719                                        if (i < viewItemSize) {
10720                                                TObjectName alias = viewItems.getViewAliasItem(i).getAlias();
10721
10722                                                if (!resultSetModel.getColumns().get(j).getName().contains("*")) {
10723                                                        j++;
10724                                                } else {
10725                                                        if (resultSetSize - j == viewItems.size() - i) {
10726                                                                j++;
10727                                                        }
10728                                                }
10729
10730                                                if (alias != null) {
10731                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true);
10732                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10733                                                        if (resultColumn != null) {
10734                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10735                                                                relation.setEffectType(EffectType.create_view);
10736                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10737                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10738                                                                relation.setProcess(process);
10739                                                        }
10740                                                } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10741                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10742                                                                        (TObjectName) resultColumn.getColumnObject(), i, true);
10743                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10744                                                        if (resultColumn != null) {
10745                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10746                                                                relation.setEffectType(EffectType.create_view);
10747                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10748                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10749                                                                relation.setProcess(process);
10750                                                        }
10751                                                } else if (resultColumn.getColumnObject() instanceof TResultColumn) {
10752                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10753                                                                        ((TResultColumn) resultColumn.getColumnObject()).getFieldAttr(), i, true);
10754                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10755                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
10756                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
10757                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10758                                                        }
10759                                                        if (resultColumn != null) {
10760                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10761                                                                relation.setEffectType(EffectType.create_view);
10762                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10763                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10764                                                                relation.setProcess(process);
10765                                                        }
10766                                                }
10767                                        }
10768                                        else if(resultSetModel.isDetermined()){
10769                                                TObjectName viewColumnName = new TObjectName();
10770                                                viewColumnName.setString(resultColumn.getName());
10771                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, viewModel.getColumns().size(), true);
10772                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10773                                                relation.setEffectType(EffectType.create_view);
10774                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10775                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10776                                                relation.setProcess(process);
10777                                                j++;
10778                                        }
10779                                }
10780                                if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10781                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10782                                        impactRelation.setEffectType(EffectType.create_view);
10783                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10784                                                        resultSetModel.getRelationRows()));
10785                                        impactRelation.setTarget(
10786                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
10787                                }
10788                        }
10789
10790                        if (subquery.getResultColumnList() == null && subquery.getValueClause() != null
10791                                        && subquery.getValueClause().getValueRows().size() == viewItems.size()) {
10792                                for (int i = 0; i < viewItems.size(); i++) {
10793                                        TObjectName alias = viewItems.getViewAliasItem(i).getAlias();
10794
10795                                        if (alias != null) {
10796                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias, i, true);
10797                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10798                                                TExpression expression = subquery.getValueClause().getValueRows().getValueRowItem(i).getExpr();
10799
10800                                                columnsInExpr visitor = new columnsInExpr();
10801                                                expression.inOrderTraverse(visitor);
10802                                                List<TObjectName> objectNames = visitor.getObjectNames();
10803                                                List<TParseTreeNode> functions = visitor.getFunctions();
10804
10805                                                if (functions != null && !functions.isEmpty()) {
10806                                                        analyzeFunctionDataFlowRelation(viewColumn, functions, EffectType.select);
10807
10808                                                }
10809
10810                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
10811                                                if (subquerys != null && !subquerys.isEmpty()) {
10812                                                        analyzeSubqueryDataFlowRelation(viewColumn, subquerys, EffectType.select);
10813                                                }
10814
10815                                                analyzeDataFlowRelation(viewColumn, objectNames, EffectType.select, functions);
10816                                                List<TParseTreeNode> constants = visitor.getConstants();
10817                                                analyzeConstantDataFlowRelation(viewColumn, constants, EffectType.select, functions);
10818                                        }
10819                                }
10820                        }
10821
10822                } else {
10823                        if (viewName == null) {
10824                                ErrorInfo errorInfo = new ErrorInfo();
10825                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10826                                errorInfo.setErrorMessage("Can't get view name. CreateView is " + stmt.toString());
10827                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(stmt.getStartToken().lineNo,
10828                                                stmt.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
10829                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(stmt.getEndToken().lineNo,
10830                                                stmt.getEndToken().columnNo + stmt.getEndToken().getAstext().length(),
10831                                                ModelBindingManager.getGlobalHash()));
10832                                errorInfo.fillInfo(this);
10833                                errorInfos.add(errorInfo);
10834                                return;
10835                        }
10836                        Table viewModel = modelFactory.createView(stmt, viewName);
10837                        Process process = modelFactory.createProcess(stmt);
10838                        viewModel.addProcess(process);
10839                        if (subquery != null && !subquery.isCombinedQuery()) {
10840                                SelectResultSet resultSetModel = (SelectResultSet) modelManager
10841                                                .getModel(subquery.getResultColumnList());
10842
10843                                boolean determined = false;
10844                                if (!containStarColumn(resultSetModel)) {
10845                                        viewModel.setCreateTable(true);
10846                                        determined = true;
10847                                        viewModel.setFromDDL(true);
10848                                }
10849                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
10850                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
10851                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
10852                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
10853
10854                                                TAliasClause alias = ((TResultColumn) resultColumn.getColumnObject()).getAliasClause();
10855                                                if (alias != null && alias.getAliasName() != null) {
10856                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i,
10857                                                                        determined);
10858                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10859                                                        relation.setEffectType(EffectType.create_view);
10860                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10861                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10862                                                        relation.setProcess(process);
10863                                                        if (determined) {
10864                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10865                                                        }
10866                                                } else if (columnObject.getFieldAttr() != null) {
10867                                                        TObjectName viewColumnObject = columnObject.getFieldAttr();
10868                                                        TableColumn viewColumn;
10869                                                        Object model = modelManager.getModel(resultColumn.getColumnObject());
10870                                                        if ("*".equals(viewColumnObject.getColumnNameOnly())) {
10871                                                                if (model instanceof LinkedHashMap) {
10872                                                                        String columnName = getColumnNameOnly(resultColumn.getName());
10873                                                                        LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model;
10874                                                                        if ("*".equals(columnName)) {
10875                                                                                for (String key : resultColumns.keySet()) {
10876                                                                                        ResultColumn column = resultColumns.get(key);
10877                                                                                        viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName());
10878                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10879                                                                                        relation.setEffectType(EffectType.create_view);
10880                                                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10881                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
10882                                                                                        relation.setProcess(process);
10883                                                                                }
10884                                                                                continue;
10885                                                                        } else if (resultColumns.containsKey(columnName)) {
10886                                                                                ResultColumn column = resultColumns.get(columnName);
10887                                                                                viewColumn = modelFactory.createInsertTableColumn(viewModel, column.getName());
10888                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10889                                                                                relation.setEffectType(EffectType.create_view);
10890                                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10891                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
10892                                                                                relation.setProcess(process);
10893                                                                                continue;
10894                                                                        }
10895                                                                }
10896                                                        }
10897                                                        
10898                                                        if (!SQLUtil.isEmpty(viewColumnObject.getColumnNameOnly())
10899                                                                        && viewColumnObject.getPropertyToken() != null) {
10900                                                                TObjectName object = new TObjectName();
10901                                                                // object.setString(viewColumnObject.getPropertyToken().astext);
10902                                                                object.setPartToken(viewColumnObject.getPropertyToken());
10903                                                                object.setStartToken(viewColumnObject.getPropertyToken());
10904                                                                object.setEndToken(viewColumnObject.getPropertyToken());
10905                                                                viewColumn = modelFactory.createViewColumn(viewModel, object, i, determined);
10906                                                        } else {
10907                                                                viewColumn = modelFactory.createViewColumn(viewModel, columnObject.getFieldAttr(),
10908                                                                                i, determined);
10909                                                        }
10910                                                        
10911                                                        if(determined) {
10912                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10913                                                        }
10914                                                        
10915                                                        if (model instanceof ResultColumn) {
10916                                                                ResultColumn column = (ResultColumn) modelManager
10917                                                                                .getModel(resultColumn.getColumnObject());
10918                                                                if (column != null && !column.getStarLinkColumns().isEmpty()) {
10919                                                                        viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
10920                                                                }
10921                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10922                                                                relation.setEffectType(EffectType.create_view);
10923                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10924                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10925                                                                if (sqlenv == null) {
10926                                                                        if (resultColumn.isShowStar()) {
10927                                                                                relation.setShowStarRelation(true);
10928                                                                                viewColumn.setShowStar(true);
10929                                                                                resultColumn.setShowStar(true);
10930                                                                                setSourceShowStar(resultColumn);
10931                                                                        }
10932                                                                }
10933                                                                if (viewColumn.getName().endsWith("*") && resultColumn.getName().endsWith("*")) {
10934                                                                        viewModel.setStarStmt("create_view");
10935                                                                }
10936                                                                relation.setProcess(process);
10937                                                        }
10938                                                } else if (resultColumn.getAlias() != null && columnObject.getExpr()
10939                                                                .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
10940                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10941                                                                        columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined);
10942                                                        if(determined) {
10943                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
10944                                                        }
10945                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10946                                                        relation.setEffectType(EffectType.create_view);
10947                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10948                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10949                                                        relation.setProcess(process);
10950                                                } else {
10951                                                        TGSqlParser parser = columnObject.getGsqlparser();
10952                                                        TObjectName viewColumnName = parser
10953                                                                        .parseObjectName(generateQuotedName(parser, columnObject.toString()));
10954                                                        if (viewColumnName == null) {
10955                                                                ErrorInfo errorInfo = new ErrorInfo();
10956                                                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
10957                                                                errorInfo.setErrorMessage(
10958                                                                                "Can't parse view column. Column is " + columnObject.toString());
10959                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(
10960                                                                                columnObject.getStartToken().lineNo, columnObject.getStartToken().columnNo,
10961                                                                                ModelBindingManager.getGlobalHash()));
10962                                                                errorInfo
10963                                                                                .setEndPosition(new Pair3<Long, Long, String>(columnObject.getEndToken().lineNo,
10964                                                                                                columnObject.getEndToken().columnNo
10965                                                                                                                + columnObject.getEndToken().getAstext().length(),
10966                                                                                                ModelBindingManager.getGlobalHash()));
10967                                                                errorInfo.fillInfo(this);
10968                                                                errorInfos.add(errorInfo);
10969                                                        } else {
10970                                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i,
10971                                                                                determined);
10972                                                                if(determined) {
10973                                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10974                                                                }
10975                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10976                                                                relation.setEffectType(EffectType.create_view);
10977                                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10978                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10979                                                                relation.setProcess(process);
10980                                                        }
10981                                                }
10982                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
10983                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
10984                                                                (TObjectName) resultColumn.getColumnObject(), i, determined);
10985                                                if(determined) {
10986                                                        appendTableColumnToSQLEnv(viewModel, viewColumn);
10987                                                }
10988                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
10989                                                relation.setEffectType(EffectType.create_view);
10990                                                relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
10991                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
10992                                                relation.setProcess(process);
10993                                        }
10994                                }
10995                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
10996                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
10997                                        impactRelation.setEffectType(EffectType.create_view);
10998                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
10999                                                        resultSetModel.getRelationRows()));
11000                                        impactRelation.setTarget(
11001                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
11002                                }
11003                        } else if (subquery != null && subquery.isCombinedQuery()) {
11004                                SelectSetResultSet resultSetModel = (SelectSetResultSet) modelManager.getModel(subquery);
11005
11006                                boolean determined = false;
11007                                if (!containStarColumn(resultSetModel)) {
11008                                        viewModel.setCreateTable(true);
11009                                        viewModel.setFromDDL(true);
11010                                        determined = true;
11011                                }
11012
11013                                for (int i = 0; i < resultSetModel.getColumns().size(); i++) {
11014                                        ResultColumn resultColumn = resultSetModel.getColumns().get(i);
11015
11016                                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
11017                                                TResultColumn columnObject = ((TResultColumn) resultColumn.getColumnObject());
11018
11019                                                TAliasClause alias = columnObject.getAliasClause();
11020                                                if (alias != null && alias.getAliasName() != null) {
11021                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, alias.getAliasName(), i,
11022                                                                        determined);
11023                                                        if(determined) {
11024                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
11025                                                        }
11026                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
11027                                                        relation.setEffectType(EffectType.create_view);
11028                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
11029                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
11030                                                        relation.setProcess(process);
11031                                                } else if (columnObject.getFieldAttr() != null) {
11032                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
11033                                                                        columnObject.getFieldAttr(), i, determined);
11034                                                        if(determined) {
11035                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
11036                                                        }
11037                                                        ResultColumn column = (ResultColumn) modelManager.getModel(resultColumn.getColumnObject());
11038                                                        if (column != null && !column.getStarLinkColumns().isEmpty()) {
11039                                                                viewColumn.bindStarLinkColumns(column.getStarLinkColumns());
11040                                                        }
11041                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
11042                                                        relation.setEffectType(EffectType.create_view);
11043                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
11044                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
11045                                                        relation.setProcess(process);
11046                                                } else if (resultColumn.getAlias() != null && columnObject.getExpr()
11047                                                                .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
11048                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
11049                                                                        columnObject.getExpr().getLeftOperand().getObjectOperand(), i, determined);
11050                                                        if(determined) {
11051                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
11052                                                        }
11053                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
11054                                                        relation.setEffectType(EffectType.create_view);
11055                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
11056                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
11057                                                        relation.setProcess(process);
11058                                                } else {
11059                                                        TGSqlParser parser = columnObject.getGsqlparser();
11060                                                        TObjectName viewColumnName = parser
11061                                                                        .parseObjectName(generateQuotedName(parser, columnObject.toString()));
11062                                                        TableColumn viewColumn = modelFactory.createViewColumn(viewModel, viewColumnName, i,
11063                                                                        determined);
11064                                                        if(determined) {
11065                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
11066                                                        }
11067                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
11068                                                        relation.setEffectType(EffectType.create_view);
11069                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
11070                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
11071                                                        relation.setProcess(process);
11072                                                }
11073                                        } else if (resultColumn.getColumnObject() instanceof TObjectName) {
11074                                                TableColumn viewColumn = modelFactory.createViewColumn(viewModel,
11075                                                                (TObjectName) resultColumn.getColumnObject(), i, determined);
11076                                                if(viewColumn!=null) {
11077                                                        if(determined) {
11078                                                                appendTableColumnToSQLEnv(viewModel, viewColumn);
11079                                                        }
11080                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
11081                                                        relation.setEffectType(EffectType.create_view);
11082                                                        relation.setTarget(new ViewColumnRelationshipElement(viewColumn));
11083                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
11084                                                        relation.setProcess(process);
11085                                                }
11086                                        }
11087                                }
11088                                if (!resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
11089                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
11090                                        impactRelation.setEffectType(EffectType.create_view);
11091                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
11092                                                        resultSetModel.getRelationRows()));
11093                                        impactRelation.setTarget(
11094                                                        new RelationRowsRelationshipElement<TableRelationRows>(viewModel.getRelationRows()));
11095                                }
11096                        }
11097                }
11098        }
11099
11100        private void setSourceShowStar(Object resultColumn) {
11101                for (Relationship relation : modelManager.getRelations()) {
11102                        Collection<RelationshipElement<?>> sources = (Collection<RelationshipElement<?>>)relation.getSources();
11103                        if (relation.getTarget().getElement() == resultColumn && sources != null) {
11104
11105                                ((AbstractRelationship) relation).setShowStarRelation(true);
11106                                for (RelationshipElement<?> source : sources) {
11107                                        Object column = source.getElement();
11108                                        if (column instanceof TableColumn) {
11109                                                if (((TableColumn) column).isShowStar())
11110                                                        continue;
11111                                                ((TableColumn) column).setShowStar(true);
11112                                        }
11113                                        if (column instanceof ResultColumn) {
11114                                                if (((ResultColumn) column).isShowStar())
11115                                                        continue;
11116                                                ((ResultColumn) column).setShowStar(true);
11117                                        }
11118                                        setSourceShowStar(column);
11119                                }
11120                        }
11121                }
11122        }
11123
11124        private String generateQuotedName(TGSqlParser parser, String name) {
11125                return "\"" + name + "\"";
11126        }
11127
11128        private void appendRelations(dataflow dataflow) {
11129                Relationship[] relations = modelManager.getRelations();
11130
11131                appendRelation(dataflow, relations, DataFlowRelationship.class);
11132                appendRelation(dataflow, relations, IndirectImpactRelationship.class);
11133                appendRecordSetRelation(dataflow, relations);
11134                appendCallRelation(dataflow, relations);
11135                appendRelation(dataflow, relations, ImpactRelationship.class);
11136                appendRelation(dataflow, relations, JoinRelationship.class);
11137                appendRelation(dataflow, relations, ERRelationship.class);
11138                appendRelation(dataflow, relations, CrudRelationship.class);
11139        }
11140
11141        private Set<String> appendStarColumns = new HashSet<String>();
11142        private void appendRelation(dataflow dataflow, Relationship[] relations, Class<? extends Relationship> clazz) {
11143                for (int i = 0; i < relations.length; i++) {
11144                        AbstractRelationship relation = (AbstractRelationship) relations[i];
11145                        if (relation.getClass() == clazz) {
11146                                if (relation.getSources() == null || relation.getTarget() == null) {
11147                                        continue;
11148                                }
11149                                Object targetElement = relation.getTarget().getElement();
11150                                TObjectName targetColumnName = null;
11151                                if(relation.getTarget() instanceof ResultColumnRelationshipElement) {
11152                                        targetColumnName = ((ResultColumnRelationshipElement) relation.getTarget()).getColumnName();
11153                                }
11154                                if (targetElement instanceof ResultColumn) {
11155                                        ResultColumn targetColumn = (ResultColumn) targetElement;
11156                                        if (!targetColumn.isPseduo()) 
11157                                        {
11158                                                if (targetColumnName == null) 
11159                                                {
11160                                                        if ("*".equals(targetColumn.getName())) {
11161                                                                updateResultColumnStarLinks(dataflow, relation, -1);
11162                                                        }
11163
11164                                                        if (targetColumn.hasStarLinkColumn()) {
11165                                                                for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) {
11166                                                                        appendStarRelation(dataflow, relation, j);
11167                                                                }
11168
11169                                                                if (!containsStar(relation.getSources())) {
11170                                                                        continue;
11171                                                                }
11172                                                        }
11173                                                }
11174                                                else {
11175                                                        String columnName = DlineageUtil.getColumnName(targetColumnName);
11176                                                        int index = targetColumn.getStarLinkColumnNames().indexOf(columnName);
11177                                                        if (index != -1) {
11178                                                                int size = targetColumn.getStarLinkColumnNames().size();
11179                                                                if ("*".equals(targetColumn.getName())) {
11180                                                                        if (appendStarColumns.contains(columnName)) {
11181                                                                                updateResultColumnStarLinks(dataflow, relation, index);
11182                                                                        }
11183                                                                        else {
11184                                                                                updateResultColumnStarLinks(dataflow, relation, -1);
11185                                                                                appendStarColumns.add(columnName);
11186                                                                        }
11187                                                                }
11188                                                                appendStarRelation(dataflow, relation, index);
11189                                                                for(int j= size; j < targetColumn.getStarLinkColumnNames().size(); j++) {
11190                                                                        appendStarRelation(dataflow, relation, j);
11191                                                                }
11192                                                                if (!containsStar(relation.getSources())) {
11193                                                                        continue;
11194                                                                }
11195                                                        }
11196                                                }
11197                                        }
11198                                } else if (targetElement instanceof TableColumn) {
11199                                        TableColumn targetColumn = (TableColumn) targetElement;
11200                                        if (!targetColumn.isPseduo()) {
11201                                                if ("*".equals(targetColumn.getName())) {
11202                                                        updateTableColumnStarLinks(dataflow, relation);
11203                                                }
11204
11205                                                if (targetColumn.hasStarLinkColumn() && !targetColumn.isVariant()
11206                                                                && targetColumn.isExpandStar()) {
11207                                                        for (int j = 0; j < targetColumn.getStarLinkColumnNames().size(); j++) {
11208                                                                appendStarRelation(dataflow, relation, j);
11209                                                        }
11210                                                        if (!containsStar(relation.getSources())) {
11211                                                                continue;
11212                                                        }
11213                                                }
11214                                        }
11215                                }
11216
11217                                relationship relationElement = new relationship();
11218                                relationElement.setType(relation.getRelationshipType().name());
11219                                if (relation.getEffectType() != null) {
11220                                        relationElement.setEffectType(relation.getEffectType().name());
11221                                }
11222                                if (relation.getFunction() != null) {
11223                                        relationElement.setFunction(relation.getFunction());
11224                                }
11225                                relationElement.setSqlHash(relation.getSqlHash());
11226                                relationElement.setSqlComment(relation.getSqlComment());
11227
11228                                if (relation.getProcedureId() != null) {
11229                                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11230                                }
11231                                relationElement.setId(String.valueOf(relation.getId()));
11232                                if (relation.getProcess() != null) {
11233                                        relationElement.setProcessId(String.valueOf(relation.getProcess().getId()));
11234                                        if (relation.getProcess().getGspObject() != null) {
11235                                                relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name());
11236                                        }
11237                                }
11238
11239                                if (relation.getPartition() != null) {
11240                                        relationElement.setPartition(relation.getPartition());
11241                                }
11242                                relationElement.setSqlHash(relation.getSqlHash());
11243                                relationElement.setSqlComment(relation.getSqlComment());
11244                                
11245                                if (relation.getProcedureId() != null) {
11246                                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
11247                                }
11248                                
11249                                if (relation instanceof JoinRelationship) {
11250                                        relationElement.setCondition(((JoinRelationship) relation).getJoinCondition());
11251                                        relationElement.setJoinType(((JoinRelationship) relation).getJoinType().name());
11252                                        relationElement.setClause(((JoinRelationship) relation).getJoinClauseType().name());
11253                                }
11254
11255                                if(relation instanceof ImpactRelationship){
11256                                        ImpactRelationship impactRelationship = (ImpactRelationship)relation;
11257                                        if(impactRelationship.getJoinClauseType()!=null){
11258                                                relationElement.setClause(impactRelationship.getJoinClauseType().name());
11259                                        }
11260                                }
11261
11262                                String targetName = null;
11263                                Object columnObject = null;
11264                                List<TObjectName> targetObjectNames = null;
11265
11266                                if (targetElement instanceof ResultSetRelationRows) {
11267                                        ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement;
11268                                        targetColumn target = new targetColumn();
11269                                        target.setId(String.valueOf(targetColumn.getId()));
11270                                        target.setColumn(targetColumn.getName());
11271                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
11272                                        target.setParent_name(getResultSetName(targetColumn.getHolder()));
11273                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11274                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11275                                                                + convertCoordinate(targetColumn.getEndPosition()));
11276                                        }
11277                                        if (relation instanceof RecordSetRelationship) {
11278                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11279                                        }
11280                                        target.setSource("system");
11281                                        targetName = targetColumn.getName();
11282                                        relationElement.setTarget(target);
11283                                } else if (targetElement instanceof TableRelationRows) {
11284                                        TableRelationRows targetColumn = (TableRelationRows) targetElement;
11285                                        targetColumn target = new targetColumn();
11286                                        target.setId(String.valueOf(targetColumn.getId()));
11287                                        target.setColumn(targetColumn.getName());
11288                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
11289                                        target.setParent_name(getTableName(targetColumn.getHolder()));
11290                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11291                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11292                                                                + convertCoordinate(targetColumn.getEndPosition()));
11293                                        }
11294                                        if (relation instanceof RecordSetRelationship) {
11295                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11296                                        }
11297                                        target.setSource("system");
11298                                        targetName = targetColumn.getName();
11299                                        relationElement.setTarget(target);
11300                                } else if (targetElement instanceof ResultColumn) {
11301                                        ResultColumn targetColumn = (ResultColumn) targetElement;
11302                                        targetColumn target = new targetColumn();
11303                                        target.setId(String.valueOf(targetColumn.getId()));
11304                                        target.setColumn(targetColumn.getName());
11305                                        target.setStruct(targetColumn.isStruct());
11306                                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
11307                                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
11308                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11309                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11310                                                                + convertCoordinate(targetColumn.getEndPosition()));
11311                                        }
11312                                        if (relation instanceof RecordSetRelationship) {
11313                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11314                                        }
11315                                        targetName = targetColumn.getName();
11316                                        if (((ResultColumn) targetColumn).getColumnObject() instanceof TResultColumn) {
11317                                                columnsInExpr visitor = new columnsInExpr();
11318                                                ((TResultColumn) ((ResultColumn) targetColumn).getColumnObject()).getExpr()
11319                                                                .inOrderTraverse(visitor);
11320                                                targetObjectNames = visitor.getObjectNames();
11321                                        }
11322
11323                                        if (targetElement instanceof FunctionResultColumn) {
11324                                                columnObject = ((FunctionResultColumn) targetElement).getColumnObject();
11325                                        }
11326                                        if(targetColumn.isPseduo()) {
11327                                                target.setSource("system");
11328                                        }
11329                                        relationElement.setTarget(target);
11330                                } else if (targetElement instanceof TableColumn) {
11331                                        TableColumn targetColumn = (TableColumn) targetElement;
11332                                        targetColumn target = new targetColumn();
11333                                        target.setId(String.valueOf(targetColumn.getId()));
11334                                        target.setColumn(targetColumn.getName());
11335                                        target.setStruct(targetColumn.isStruct());
11336                                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
11337                                        target.setParent_name(getTableName(targetColumn.getTable()));
11338                                        if (relation.getTarget() instanceof TableColumnRelationshipElement) {
11339                                                target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias());
11340                                        }
11341                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11342                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11343                                                                + convertCoordinate(targetColumn.getEndPosition()));
11344                                        }
11345                                        if (relation instanceof RecordSetRelationship) {
11346                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11347                                        }
11348                                        if(targetColumn.isPseduo()) {
11349                                                target.setSource("system");
11350                                        }
11351                                        targetName = targetColumn.getName();
11352                                        relationElement.setTarget(target);
11353                                } else if (targetElement instanceof Argument) {
11354                                        Argument targetColumn = (Argument) targetElement;
11355                                        targetColumn target = new targetColumn();
11356                                        target.setId(String.valueOf(targetColumn.getId()));
11357                                        target.setColumn(targetColumn.getName());
11358                                        target.setParent_id(String.valueOf(targetColumn.getProcedure().getId()));
11359                                        target.setParent_name(targetColumn.getProcedure().getName());
11360                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
11361                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
11362                                                                + convertCoordinate(targetColumn.getEndPosition()));
11363                                        }
11364                                        if (relation instanceof RecordSetRelationship) {
11365                                                target.setFunction(((RecordSetRelationship) relation).getAggregateFunction());
11366                                        }
11367                                        targetName = targetColumn.getName();
11368                                        relationElement.setTarget(target);
11369                                } else if (targetElement instanceof Table) {
11370                                        Table table = (Table) targetElement;
11371                                        targetColumn target = new targetColumn();
11372                                        target.setTarget_id(String.valueOf(table.getId()));
11373                                        target.setTarget_name(getTableName(table));
11374                                        if (table.getStartPosition() != null && table.getEndPosition() != null) {
11375                                                target.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
11376                                                                + convertCoordinate(table.getEndPosition()));
11377                                        }
11378                                        relationElement.setTarget(target);
11379                                } else {
11380                                        continue;
11381                                }
11382
11383                                Collection<RelationshipElement<?>> sourceElements = relation.getSources();
11384                                if (sourceElements.size() == 0) {
11385                                        if(clazz == CrudRelationship.class && option.getAnalyzeMode() == AnalyzeMode.crud) {
11386                                                dataflow.getRelationships().add(relationElement);
11387                                        }
11388                                        continue;
11389                                }
11390
11391                                boolean append = false;
11392                                for (RelationshipElement<?> sourceItem: relation.getSources()) {
11393                                        Object sourceElement = sourceItem.getElement();
11394                                        TObjectName sourceColumnName = null;
11395                                        if (sourceItem instanceof ResultColumnRelationshipElement) {
11396                                                sourceColumnName = ((ResultColumnRelationshipElement) sourceItem).getColumnName();
11397                                        }
11398//                                      if (sourceItem instanceof TableColumnRelationElement
11399//                                                      && (((TableColumnRelationElement) sourceItem).getColumnIndex() != null)) {
11400//                                              TableColumnRelationElement tableColumnRelationElement = (TableColumnRelationElement) sourceItem;
11401//                                              sourceElement = tableColumnRelationElement.getElement().getTable().getColumns()
11402//                                                              .get(tableColumnRelationElement.getColumnIndex() + 1);
11403//                                      }
11404                                        if (sourceElement instanceof ResultColumn) {
11405                                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
11406                                                if (sourceColumn.hasStarLinkColumn() && !relation.isShowStarRelation() && !sourceColumn.isPseduo()) {
11407                                                        List<String> sourceStarColumnNames = sourceColumn.getStarLinkColumnNames();
11408                                                        sourceColumn source = new sourceColumn();
11409                                                        if (targetObjectNames != null && !targetObjectNames.isEmpty()) {
11410
11411                                                                for (int k = 0; k < targetObjectNames.size(); k++) {
11412                                                                        String targetObjectName = getColumnName(targetObjectNames.get(k));
11413                                                                        if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11414                                                                                boolean find = false;
11415                                                                                for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
11416                                                                                        if(column.getName().equalsIgnoreCase(targetObjectName)) {
11417                                                                                                source = new sourceColumn();
11418                                                                                                source.setId(String.valueOf(column.getId()));
11419                                                                                                source.setColumn(targetObjectName);
11420                                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11421                                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11422                                                                                                if (sourceColumn.getStartPosition() != null
11423                                                                                                                && sourceColumn.getEndPosition() != null) {
11424                                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11425                                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
11426                                                                                                }
11427                                                                                                append = true;
11428                                                                                                relationElement.addSource(source);
11429                                                                                                find = true;
11430                                                                                                break;
11431                                                                                        }
11432                                                                                }
11433                                                                                if(find) {
11434                                                                                        continue;
11435                                                                                }
11436                                                                        }
11437                                                                        if (sourceColumn.getStarLinkColumns().containsKey(targetObjectName)) {
11438                                                                                source = new sourceColumn();
11439                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
11440                                                                                                + sourceStarColumnNames.indexOf(targetObjectName));
11441                                                                                source.setColumn(targetObjectName);
11442                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11443                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11444                                                                                if (sourceColumn.getStartPosition() != null
11445                                                                                                && sourceColumn.getEndPosition() != null) {
11446                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11447                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
11448                                                                                }
11449                                                                                append = true;
11450                                                                                relationElement.addSource(source);
11451                                                                        } else {
11452                                                                                source = new sourceColumn();
11453                                                                                source.setId(String.valueOf(sourceColumn.getId()));
11454                                                                                source.setColumn(relationElement.getTarget().getColumn());
11455                                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11456                                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11457                                                                                if (sourceColumn.getStartPosition() != null
11458                                                                                                && sourceColumn.getEndPosition() != null) {
11459                                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11460                                                                                                        + "," + convertCoordinate(sourceColumn.getEndPosition()));
11461                                                                                }
11462                                                                                append = true;
11463                                                                                relationElement.addSource(source);
11464                                                                        }
11465                                                                }
11466                                                        } else {
11467                                                                if (columnObject instanceof TWhenClauseItemList) {
11468                                                                        TCaseExpression expr = (TCaseExpression)((FunctionResultColumn) targetElement).getResultSet().getGspObject();
11469                                                                        List<TExpression> directExpressions = new ArrayList<TExpression>();
11470                                                                        
11471//                                                                      TExpression inputExpr = expr.getInput_expr();
11472//                                                                      if (inputExpr != null) {
11473//                                                                              directExpressions.add(inputExpr);
11474//                                                                      }
11475                                                                        TExpression defaultExpr = expr.getElse_expr();
11476                                                                        if (defaultExpr != null) {
11477                                                                                directExpressions.add(defaultExpr);
11478                                                                        }
11479                                                                        TWhenClauseItemList list = expr.getWhenClauseItemList();
11480                                                                        for (int k = 0; k < list.size(); k++) {
11481                                                                                TWhenClauseItem element = list.getWhenClauseItem(k);
11482                                                                                directExpressions.add(element.getReturn_expr());
11483                                                                        }
11484                                                                        
11485                                                                        for (int k = 0; k < directExpressions.size(); k++) {
11486                                                                                columnsInExpr visitor = new columnsInExpr();
11487                                                                                directExpressions.get(k).inOrderTraverse(visitor);
11488                                                                                List<TObjectName> objectNames = visitor.getObjectNames();
11489                                                                                if (objectNames == null) {
11490                                                                                        continue;
11491                                                                                }
11492                                                                                for (int x = 0; x < objectNames.size(); x++) {
11493                                                                                        String objectName = getColumnName(objectNames.get(x));
11494                                                                                        if (sourceColumn.getStarLinkColumns().containsKey(objectName)) {
11495
11496                                                                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11497                                                                                                        boolean find = false;
11498                                                                                                        for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
11499                                                                                                                if(column.getName().equalsIgnoreCase(objectName)) {
11500                                                                                                                        source = new sourceColumn();
11501                                                                                                                        source.setId(String.valueOf(column.getId()));
11502                                                                                                                        source.setColumn(objectName);
11503                                                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11504                                                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11505                                                                                                                        if (sourceColumn.getStartPosition() != null
11506                                                                                                                                        && sourceColumn.getEndPosition() != null) {
11507                                                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11508                                                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
11509                                                                                                                        }
11510                                                                                                                        append = true;
11511                                                                                                                        relationElement.addSource(source);
11512                                                                                                                        find = true;
11513                                                                                                                        break;
11514                                                                                                                }
11515                                                                                                        }
11516                                                                                                        if(find) {
11517                                                                                                                continue;
11518                                                                                                        }
11519                                                                                                }
11520                                                                                                
11521                                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
11522                                                                                                                + sourceStarColumnNames.indexOf(objectName));
11523                                                                                                source.setColumn(objectName);
11524                                                                                        } else {
11525                                                                                                source.setId(String.valueOf(sourceColumn.getId()));
11526                                                                                                source.setColumn(sourceColumn.getName());
11527                                                                                        }
11528                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11529                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11530                                                                                        if (sourceColumn.getStartPosition() != null
11531                                                                                                        && sourceColumn.getEndPosition() != null) {
11532                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11533                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
11534                                                                                        }
11535                                                                                        append = true;
11536                                                                                        relationElement.addSource(source);
11537                                                                                }
11538                                                                        }
11539                                                                } else {
11540                                                                        String objectName = getColumnName(targetName);
11541                                                                        boolean find = false;
11542                                                                        
11543                                                                        if (!find && sourceColumn.getStarLinkColumns().containsKey(objectName)) {
11544                                                                                source.setId(String.valueOf(sourceColumn.getId()) + "_"
11545                                                                                                + sourceStarColumnNames.indexOf(objectName));
11546                                                                                source.setColumn(objectName);
11547                                                                                find = true;
11548                                                                        }
11549
11550                                                                        if (!find && sourceColumnName != null) {
11551                                                                                objectName = getColumnName(sourceColumnName);
11552                                                                                
11553                                                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
11554                                                                                        for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
11555                                                                                                if(column.getName().equalsIgnoreCase(objectName)) {
11556                                                                                                        source = new sourceColumn();
11557                                                                                                        source.setId(String.valueOf(column.getId()));
11558                                                                                                        source.setColumn(objectName);
11559                                                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11560                                                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11561                                                                                                        if (sourceColumn.getStartPosition() != null
11562                                                                                                                        && sourceColumn.getEndPosition() != null) {
11563                                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition())
11564                                                                                                                                + "," + convertCoordinate(sourceColumn.getEndPosition()));
11565                                                                                                        }
11566                                                                                                        append = true;
11567                                                                                                        relationElement.addSource(source);
11568                                                                                                        find = true;
11569                                                                                                        break;
11570                                                                                                }
11571                                                                                        }
11572                                                                                        if(find) {
11573                                                                                                continue;
11574                                                                                        }
11575                                                                                }
11576                                                                                
11577                                                                                if (sourceColumn.getStarLinkColumns().containsKey(objectName)) {
11578                                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
11579                                                                                                        + sourceStarColumnNames.indexOf(objectName));
11580                                                                                        source.setColumn(objectName);
11581                                                                                        find = true;
11582                                                                                }
11583                                                                        }
11584                                                                        
11585                                                                        if (!find && sourceItem instanceof ResultColumnRelationshipElement) {
11586                                                                                int starIndex = ((ResultColumnRelationshipElement) sourceItem)
11587                                                                                                .getStarIndex();
11588                                                                                if (starIndex > -1 && sourceColumn.getStarLinkColumnList().size() > starIndex) {
11589                                                                                        objectName = getColumnName(sourceColumn.getStarLinkColumnList().get(starIndex));
11590                                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
11591                                                                                                        + starIndex);
11592                                                                                        source.setColumn(objectName);
11593                                                                                        find = true;
11594                                                                                }
11595                                                                        }
11596
11597                                                                        if (!find) {
11598                                                                                source.setId(String.valueOf(sourceColumn.getId()));
11599                                                                                source.setColumn(sourceColumn.getName());
11600                                                                        }
11601
11602                                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11603                                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11604                                                                        if (sourceColumn.getStartPosition() != null
11605                                                                                        && sourceColumn.getEndPosition() != null) {
11606                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11607                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11608                                                                        }
11609                                                                        append = true;
11610                                                                        relationElement.addSource(source);
11611                                                                }
11612                                                        }
11613
11614                                                } else {
11615                                                        sourceColumn source = new sourceColumn();
11616                                                        source.setId(String.valueOf(sourceColumn.getId()));
11617                                                        source.setColumn(sourceColumn.getName());
11618                                                        source.setStruct(sourceColumn.isStruct());
11619                                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
11620                                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
11621                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11622                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11623                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11624                                                        }
11625                                                        append = true;
11626                                                        if (sourceItem.getTransforms() != null) {
11627                                                                for (Transform transform : sourceItem.getTransforms()) {
11628                                                                        source.addTransform(transform);
11629                                                                }
11630                                                        }
11631                                                        if(sourceColumn.isPseduo()) {
11632                                                                source.setSource("system");
11633                                                        }
11634                                                        relationElement.addSource(source);
11635                                                }
11636                                        } else if (sourceElement instanceof TableColumn) {
11637                                                TableColumn sourceColumn = (TableColumn) sourceElement;
11638                                                if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()
11639                                                                && sourceItem instanceof TableColumnRelationshipElement) {
11640                                                        sourceColumn source = new sourceColumn();
11641                                                        boolean find = false;
11642                                                        if (((TableColumnRelationshipElement) sourceItem).getColumnIndex() != null) {
11643                                                                int columnIndex = ((TableColumnRelationshipElement) sourceItem).getColumnIndex();
11644                                                                if (sourceColumn.getStarLinkColumns().size() > columnIndex) {
11645                                                                        source = new sourceColumn();
11646                                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + columnIndex);
11647                                                                        String targetObjectName = getColumnName(
11648                                                                                        sourceColumn.getStarLinkColumnList().get(columnIndex));
11649                                                                        source.setColumn(targetObjectName);
11650                                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11651                                                                        source.setParent_name(sourceColumn.getTable().getName());
11652                                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11653                                                                                source.setParent_alias(
11654                                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11655                                                                        }
11656                                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11657                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11658                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11659                                                                        }
11660                                                                        append = true;
11661                                                                        relationElement.addSource(source);
11662                                                                        find = true;
11663                                                                }
11664                                                        }
11665
11666                                                        if (!find) {
11667                                                                String objectName = getColumnName(targetName);
11668
11669                                                                table tableElement = null;
11670                                                                if (dataflow.getTables() != null) {
11671                                                                        for (table t : dataflow.getTables()) {
11672                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
11673                                                                                        tableElement = t;
11674                                                                                        break;
11675                                                                                }
11676                                                                        }
11677                                                                }
11678                                                                if (tableElement == null && dataflow.getViews() != null) {
11679                                                                        for (table t : dataflow.getViews()) {
11680                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
11681                                                                                        tableElement = t;
11682                                                                                        break;
11683                                                                                }
11684                                                                        }
11685                                                                }
11686                                                                if (tableElement == null && dataflow.getVariables() != null) {
11687                                                                        for (table t : dataflow.getVariables()) {
11688                                                                                if (t.getId().equals(String.valueOf(sourceColumn.getTable().getId()))) {
11689                                                                                        tableElement = t;
11690                                                                                        break;
11691                                                                                }
11692                                                                        }
11693                                                                }
11694
11695                                                                if(tableElement!=null) {
11696                                                                        for (column column : tableElement.getColumns()) {
11697                                                                                if (column.getName().equalsIgnoreCase(objectName)) {
11698                                                                                        source = new sourceColumn();
11699                                                                                        source.setId(String.valueOf(column.getId()));
11700                                                                                        source.setColumn(objectName);
11701                                                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11702                                                                                        source.setParent_name(sourceColumn.getTable().getName());
11703                                                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11704                                                                                                source.setParent_alias(
11705                                                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11706                                                                                        }
11707                                                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11708                                                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11709                                                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11710                                                                                        }
11711                                                                                        if (sourceItem.getTransforms() != null) {
11712                                                                                                for (Transform transform : sourceItem.getTransforms()) {
11713                                                                                                        source.addTransform(transform);
11714                                                                                                }
11715                                                                                        }
11716                                                                                        if (sourceColumn.getCandidateParents() != null) {
11717                                                                                                for(Object item: sourceColumn.getCandidateParents()) {
11718                                                                                                        candidateTable candidateParent = new candidateTable();
11719                                                                                                        if(item instanceof Table) {
11720                                                                                                                candidateParent.setId(String.valueOf(((Table)item).getId()));
11721                                                                                                                candidateParent.setName(getTableName((Table)item));
11722                                                                                                                source.addCandidateParent(candidateParent);
11723                                                                                                        }
11724                                                                                                        else if(item instanceof ResultSet) {
11725                                                                                                                candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
11726                                                                                                                candidateParent.setName(getResultSetName((ResultSet)item));
11727                                                                                                                source.addCandidateParent(candidateParent);
11728                                                                                                        }
11729                                                                                                }
11730                                                                                        }
11731                                                                                        append = true;
11732                                                                                        relationElement.addSource(source);
11733                                                                                        find = true;
11734                                                                                        break;
11735                                                                                }
11736                                                                        }
11737                                                                }
11738                                                        }
11739
11740                                                        if(!find) {
11741                                                                source = new sourceColumn();
11742                                                                source.setId(String.valueOf(sourceColumn.getId()));
11743                                                                source.setColumn(sourceColumn.getName());
11744                                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11745                                                                source.setParent_name(sourceColumn.getTable().getName());
11746                                                                if (sourceItem instanceof TableColumnRelationshipElement) {
11747                                                                        source.setParent_alias(
11748                                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11749                                                                }
11750                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11751                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11752                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11753                                                                }
11754                                                                if (sourceItem.getTransforms() != null) {
11755                                                                        for (Transform transform : sourceItem.getTransforms()) {
11756                                                                                source.addTransform(transform);
11757                                                                        }
11758                                                                }
11759                                                                if (sourceColumn.getCandidateParents() != null) {
11760                                                                        for(Object item: sourceColumn.getCandidateParents()) {
11761                                                                                candidateTable candidateParent = new candidateTable();
11762                                                                                if(item instanceof Table) {
11763                                                                                        candidateParent.setId(String.valueOf(((Table)item).getId()));
11764                                                                                        candidateParent.setName(getTableName((Table)item));
11765                                                                                        source.addCandidateParent(candidateParent);
11766                                                                                }
11767                                                                                else if(item instanceof ResultSet) {
11768                                                                                        candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
11769                                                                                        candidateParent.setName(getResultSetName((ResultSet)item));
11770                                                                                        source.addCandidateParent(candidateParent);
11771                                                                                }
11772                                                                        }
11773                                                                }
11774                                                                append = true;
11775                                                                relationElement.addSource(source);
11776                                                        }
11777
11778                                                } else {
11779                                                        sourceColumn source = new sourceColumn();
11780                                                        source.setId(String.valueOf(sourceColumn.getId()));
11781                                                        source.setColumn(sourceColumn.getName());
11782                                                        source.setStruct(sourceColumn.isStruct());
11783                                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
11784                                                        source.setParent_name(getTableName(sourceColumn.getTable()));
11785                                                        if (sourceItem instanceof TableColumnRelationshipElement) {
11786                                                                source.setParent_alias(
11787                                                                                ((TableColumnRelationshipElement) sourceItem).getTableAlias());
11788                                                        }
11789                                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11790                                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11791                                                                                + convertCoordinate(sourceColumn.getEndPosition()));
11792                                                        }
11793                                                        if (sourceItem.getTransforms() != null) {
11794                                                                for (Transform transform : sourceItem.getTransforms()) {
11795                                                                        source.addTransform(transform);
11796                                                                }
11797                                                        }
11798                                                        if(sourceColumn.isPseduo()) {
11799                                                                source.setSource("system");
11800                                                        }
11801                                                        if (sourceColumn.getCandidateParents() != null) {
11802                                                                for(Object item: sourceColumn.getCandidateParents()) {
11803                                                                        candidateTable candidateParent = new candidateTable();
11804                                                                        if(item instanceof Table) {
11805                                                                                candidateParent.setId(String.valueOf(((Table)item).getId()));
11806                                                                                candidateParent.setName(getTableName((Table)item));
11807                                                                                source.addCandidateParent(candidateParent);
11808                                                                        }
11809                                                                        else if(item instanceof ResultSet) {
11810                                                                                candidateParent.setId(String.valueOf(((ResultSet)item).getId()));
11811                                                                                candidateParent.setName(getResultSetName((ResultSet)item));
11812                                                                                source.addCandidateParent(candidateParent);
11813                                                                        }
11814                                                                }
11815                                                        }
11816                                                        append = true;
11817                                                        relationElement.addSource(source);
11818                                                }
11819                                        } else if (sourceElement instanceof Argument) {
11820                                                Argument sourceColumn = (Argument) sourceElement;
11821                                                sourceColumn source = new sourceColumn();
11822                                                source.setId(String.valueOf(sourceColumn.getId()));
11823                                                source.setColumn(sourceColumn.getName());
11824                                                source.setParent_id(String.valueOf(sourceColumn.getProcedure().getId()));
11825                                                source.setParent_name(sourceColumn.getProcedure().getName());
11826                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11827                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11828                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11829                                                }
11830                                                append = true;
11831                                                relationElement.addSource(source);
11832                                        } else if (sourceElement instanceof TableRelationRows) {
11833                                                TableRelationRows sourceColumn = (TableRelationRows) sourceElement;
11834                                                sourceColumn source = new sourceColumn();
11835                                                source.setId(String.valueOf(sourceColumn.getId()));
11836                                                source.setColumn(sourceColumn.getName());
11837                                                source.setParent_id(String.valueOf(sourceColumn.getHolder().getId()));
11838                                                source.setParent_name(getTableName(sourceColumn.getHolder()));
11839                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11840                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11841                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11842                                                }
11843                                                source.setSource("system");
11844                                                append = true;
11845                                                relationElement.addSource(source);
11846                                        } else if (sourceElement instanceof ResultSetRelationRows) {
11847                                                ResultSetRelationRows sourceColumn = (ResultSetRelationRows) sourceElement;
11848                                                sourceColumn source = new sourceColumn();
11849                                                source.setId(String.valueOf(sourceColumn.getId()));
11850                                                source.setColumn(sourceColumn.getName());
11851                                                source.setParent_id(String.valueOf(sourceColumn.getHolder().getId()));
11852                                                source.setParent_name(getResultSetName(sourceColumn.getHolder()));
11853                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11854                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11855                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11856                                                }
11857                                                source.setSource("system");
11858                                                append = true;
11859                                                relationElement.addSource(source);
11860                                        } else if (sourceElement instanceof Constant) {
11861                                                Constant sourceColumn = (Constant) sourceElement;
11862                                                sourceColumn source = new sourceColumn();
11863                                                source.setId(String.valueOf(sourceColumn.getId()));
11864                                                source.setColumn(sourceColumn.getName());
11865                                                source.setColumn_type("constant");
11866                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
11867                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
11868                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
11869                                                }
11870                                                append = true;
11871                                                relationElement.addSource(source);
11872                                        } else if (sourceElement instanceof Table) {
11873                                                Table table = (Table) sourceElement;
11874                                                sourceColumn source = new sourceColumn();
11875                                                source.setSource_id(String.valueOf(table.getId()));
11876                                                source.setSource_name(getTableName(table));
11877                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
11878                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
11879                                                                        + convertCoordinate(table.getEndPosition()));
11880                                                }
11881                                                append = true;
11882                                                relationElement.addSource(source);
11883                                        }
11884
11885                                        if (relation instanceof ImpactRelationship) {
11886                                                ESqlClause clause = getSqlClause(sourceItem);
11887                                                if (clause != null
11888                                                                && (relationElement.getSources() != null && !relationElement.getSources().isEmpty())) {
11889                                                        relationElement.getSources().get(relationElement.getSources().size() - 1)
11890                                                                        .setClauseType(clause.name());
11891                                                }
11892                                        }
11893                                }
11894                                if (append)
11895                                        dataflow.getRelationships().add(relationElement);
11896                        }
11897                }
11898        }
11899
11900        private boolean containsStar(Collection<RelationshipElement<?>> elements) {
11901                if (elements == null || elements.size() == 0)
11902                        return false;
11903
11904                for (RelationshipElement<?> element : elements) {
11905                        if (element.getElement() instanceof ResultColumn) {
11906                                ResultColumn object = (ResultColumn) element.getElement();
11907                                if (object.getName().endsWith("*") && object.isShowStar())
11908                                        return true;
11909                        } else if (element.getElement() instanceof TableColumn) {
11910                                TableColumn object = (TableColumn) element.getElement();
11911                                if (object.getName().endsWith("*") && object.isShowStar())
11912                                        return true;
11913                        }
11914                }
11915                return false;
11916        }
11917
11918        private Map<String, Set<String>> appendTableStarColumns = new HashMap<String, Set<String>>();
11919
11920        // Tracks column names that have explicit (non-star) sources per target star column.
11921        // Used across relationships to prevent phantom star expansions.
11922        // Key: target star column ID, Value: set of column names with explicit sources.
11923        private Map<Long, Set<String>> explicitStarTargetColumns = new HashMap<Long, Set<String>>();
11924        private void updateResultColumnStarLinks(dataflow dataflow, AbstractRelationship relation, int index) {
11925        try {
11926            if (option.getAnalyzeMode() == AnalyzeMode.crud) {
11927                return;
11928            }
11929
11930            ResultColumn targetColumn = (ResultColumn) relation.getTarget().getElement();
11931
11932            Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
11933            if (sourceElements == null || sourceElements.size() == 0)
11934                return;
11935
11936            for (RelationshipElement<?> sourceItem : sourceElements) {
11937                Object sourceElement = sourceItem.getElement();
11938                if (sourceElement instanceof ResultColumn) {
11939                    ResultColumn source = (ResultColumn) sourceElement;
11940                    if (source.hasStarLinkColumn()) {
11941                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11942                            if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11943                                targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11944                            }
11945                            targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11946                        }
11947                        if (!source.isShowStar()) {
11948                            targetColumn.setShowStar(false);
11949                            relation.setShowStarRelation(false);
11950                        }
11951                    } else if (!"*".equals(source.getName())) {
11952                        if (source.getColumnObject() instanceof TObjectName) {
11953                            if (source instanceof FunctionResultColumn) {
11954
11955                            } else {
11956                                targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject());
11957                            }
11958                        } else if (source.getColumnObject() instanceof TResultColumn) {
11959                            TResultColumn sourceColumn = (TResultColumn) source.getColumnObject();
11960                            if (sourceColumn.getAliasClause() != null) {
11961                                targetColumn.bindStarLinkColumn(sourceColumn.getAliasClause().getAliasName());
11962                            } else if (sourceColumn.getFieldAttr() != null) {
11963                                targetColumn.bindStarLinkColumn(sourceColumn.getFieldAttr());
11964                            } else {
11965                                TObjectName column = new TObjectName();
11966                                if (sourceColumn.getExpr().getExpressionType() == EExpressionType.typecast_t) {
11967                                    column.setString(sourceColumn.getExpr().getLeftOperand().toString());
11968                                } else {
11969                                    column.setString(sourceColumn.toString());
11970                                }
11971                                targetColumn.bindStarLinkColumn(column);
11972                            }
11973                        }
11974                    }
11975                } else if (sourceElement instanceof TableColumn) {
11976                    TableColumn source = (TableColumn) sourceElement;
11977                    if (!source.isPseduo() && source.hasStarLinkColumn()) {
11978                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
11979                            if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
11980                                targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
11981                            }
11982                            targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
11983                        }
11984                        if ((source.getTable().isCreateTable() || source.getTable().hasSQLEnv()) && !source.isShowStar()) {
11985                            targetColumn.setShowStar(false);
11986                            relation.setShowStarRelation(false);
11987                        }
11988
11989                    } else if (!"*".equals(source.getName())) {
11990                        targetColumn.bindStarLinkColumn(source.getColumnObject());
11991                    }
11992                }
11993            }
11994
11995            if (targetColumn.hasStarLinkColumn()) {
11996                table resultSetElement = null;
11997                for (table t : dataflow.getResultsets()) {
11998                    if (t.getId().equals(String.valueOf(targetColumn.getResultSet().getId()))) {
11999                        resultSetElement = t;
12000                        break;
12001                    }
12002                }
12003
12004                int starColumnCount = 0;
12005                for (column item : resultSetElement.getColumns()) {
12006                    if (item.getName() != null && item.getName().endsWith("*")) {
12007                        starColumnCount += 1;
12008                    }
12009                }
12010
12011                if (resultSetElement != null && starColumnCount <= 1) {
12012                    List<String> columns = targetColumn.getStarLinkColumnNames();
12013                    if (index == -1) {
12014                        for (int k = 0; k < columns.size(); k++) {
12015                            String columnName = columns.get(k);
12016                            String id = String.valueOf(targetColumn.getId()) + "_" + k;
12017                            if (appendTableStarColumns.containsKey(resultSetElement.getId()) && appendTableStarColumns.get(resultSetElement.getId()).contains(id)) {
12018                                continue;
12019                            }
12020                            column columnElement = new column();
12021                            columnElement.setId(id);
12022                            columnElement.setName(columnName);
12023                            if (targetColumn.isFunction()) {
12024                                columnElement.setIsFunction(String.valueOf(targetColumn.isFunction()));
12025                            }
12026                            if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12027                                columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12028                                        + convertCoordinate(targetColumn.getEndPosition()));
12029                            }
12030
12031                            if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) {
12032                                boolean find = false;
12033                                for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
12034                                    ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
12035                                    if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName())
12036                                            .equals(columnName)) {
12037                                        find = true;
12038                                        break;
12039                                    }
12040                                }
12041                                if (find) {
12042                                    continue;
12043                                }
12044                            }
12045
12046                            if (!resultSetElement.getColumns().contains(columnElement)) {
12047                                resultSetElement.getColumns().add(columnElement);
12048                                appendTableStarColumns.putIfAbsent(resultSetElement.getId(), new HashSet<String>());
12049                                appendTableStarColumns.get(resultSetElement.getId()).add(id);
12050                            }
12051                        }
12052                    } else {
12053                        int k = index;
12054                        String columnName = columns.get(k);
12055                        column columnElement = new column();
12056                        columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k);
12057                        columnElement.setName(columnName);
12058                        if (targetColumn.isFunction()) {
12059                            columnElement.setIsFunction(String.valueOf(targetColumn.isFunction()));
12060                        }
12061                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12062                            columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12063                                    + convertCoordinate(targetColumn.getEndPosition()));
12064                        }
12065
12066                        if (targetColumn.getResultSet() != null && targetColumn.getResultSet().getColumns() != null) {
12067                            boolean find = false;
12068                            for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
12069                                ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
12070                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(columnName)) {
12071                                    find = true;
12072                                    break;
12073                                }
12074                            }
12075                            if (find) {
12076                                return;
12077                            }
12078                        }
12079
12080                        if (!resultSetElement.getColumns().contains(columnElement)) {
12081                            resultSetElement.getColumns().add(columnElement);
12082                        }
12083                    }
12084                }
12085            }
12086        } catch (Exception e) {
12087            logger.error("updateResultColumnStarLinks occurs unknown exceptions.", e);
12088        }
12089        }
12090
12091        private void updateTableColumnStarLinks(dataflow dataflow, AbstractRelationship relation) {
12092                TableColumn targetColumn = (TableColumn) relation.getTarget().getElement();             
12093                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
12094                if (sourceElements == null || sourceElements.size() == 0)
12095                        return;
12096
12097                TableColumn sourceStarColumn = null;
12098
12099                for (RelationshipElement<?> sourceItem: sourceElements) {
12100                        Object sourceElement = sourceItem.getElement();
12101                        if (sourceElement instanceof ResultColumn) {
12102                                ResultColumn source = (ResultColumn) sourceElement;
12103                                if(source.getResultSet() instanceof Function) {
12104                                        continue;
12105                                }
12106                                if (source.hasStarLinkColumn()) {
12107                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
12108                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
12109                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
12110                                                }
12111                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
12112                                        }
12113                                        if (!source.isShowStar()) {
12114                                                targetColumn.setShowStar(false);
12115                                                relation.setShowStarRelation(false);
12116                                        }
12117                                } else if (!"*".equals(source.getName())) {
12118                                        if (source.getColumnObject() instanceof TObjectName) {
12119                                                targetColumn.bindStarLinkColumn((TObjectName) source.getColumnObject());
12120                                        } else if (source.getColumnObject() instanceof TResultColumn) {
12121                                                if (((TResultColumn) source.getColumnObject()).getAliasClause() != null) {
12122                                                        TObjectName field = ((TResultColumn) source.getColumnObject()).getAliasClause()
12123                                                                        .getAliasName();
12124                                                        if (field != null) {
12125                                                                targetColumn.bindStarLinkColumn(field);
12126                                                        }
12127                                                } else {
12128                                                        TObjectName field = ((TResultColumn) source.getColumnObject()).getFieldAttr();
12129                                                        if (field != null) {
12130                                                                targetColumn.bindStarLinkColumn(field);
12131                                                        } else {
12132                                                                TObjectName column = new TObjectName();
12133                                                                if (((TResultColumn) source.getColumnObject()).getExpr()
12134                                                                                .getExpressionType() == EExpressionType.typecast_t) {
12135                                                                        column.setString(((TResultColumn) source.getColumnObject()).getExpr()
12136                                                                                        .getLeftOperand().toString());
12137                                                                } else {
12138                                                                        column.setString(((TResultColumn) source.getColumnObject()).toString());
12139                                                                }
12140                                                                targetColumn.bindStarLinkColumn(column);
12141                                                        }
12142                                                }
12143                                        }
12144                                }
12145                        } else if (sourceElement instanceof TableColumn) {
12146                                TableColumn source = (TableColumn) sourceElement;
12147                                if (source.hasStarLinkColumn()) {
12148                                        for (Map.Entry<String, Set<TObjectName>> item : source.getStarLinkColumns().entrySet()) {
12149                                                if (!targetColumn.getStarLinkColumns().containsKey(item.getKey())) {
12150                                                        targetColumn.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
12151                                                }
12152                                                targetColumn.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
12153                                        }
12154                                        for (Map.Entry<String, Set<TObjectName>> item : targetColumn.getStarLinkColumns().entrySet()) {
12155                                                if (!source.getStarLinkColumns().containsKey(item.getKey())) {
12156                                                        source.getStarLinkColumns().put(item.getKey(), new LinkedHashSet<TObjectName>());
12157                                                }
12158                                                source.getStarLinkColumns().get(item.getKey()).addAll(item.getValue());
12159                                        }
12160
12161                                        sourceStarColumn = source;
12162
12163                                        if (source.getTable().isCreateTable() && !source.isShowStar()) {
12164                                                targetColumn.setShowStar(false);
12165                                                relation.setShowStarRelation(false);
12166                                        }
12167                                } else if (!"*".equals(source.getName())) {
12168                                        if (source.isStruct()) {
12169                                                targetColumn.bindStarLinkColumn(source.getColumnObject());
12170                                        }
12171                                        else {
12172                                                TObjectName objectName = new TObjectName();
12173                                                objectName.setString(DlineageUtil.getColumnNameOnly(source.getName()));
12174                                                targetColumn.bindStarLinkColumn(objectName);
12175                                        }
12176                                }
12177                        }
12178                }
12179
12180                if (targetColumn.hasStarLinkColumn()) {
12181                        table tableElement = null;
12182                        if (dataflow.getTables() != null) {
12183                                for (table t : dataflow.getTables()) {
12184                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
12185                                                tableElement = t;
12186                                                break;
12187                                        }
12188                                }
12189                        }
12190                        if (tableElement == null && dataflow.getViews() != null) {
12191                                for (table t : dataflow.getViews()) {
12192                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
12193                                                tableElement = t;
12194                                                break;
12195                                        }
12196                                }
12197                        }
12198                        if (tableElement == null && dataflow.getVariables() != null) {
12199                                for (table t : dataflow.getVariables()) {
12200                                        if (t.getId().equals(String.valueOf(targetColumn.getTable().getId()))) {
12201                                                tableElement = t;
12202                                                break;
12203                                        }
12204                                }
12205                        }
12206
12207                        if (tableElement != null) {
12208                                List<String> columns = new ArrayList<String>(targetColumn.getStarLinkColumns().keySet());
12209                                for (int k = 0; k < columns.size(); k++) {
12210                                        String columnName = columns.get(k);
12211                                        if (containStarColumn(targetColumn.getTable().getColumns(), columnName)) {
12212                                                continue;
12213                                        }
12214                                        column columnElement = new column();
12215                                        columnElement.setId(String.valueOf(targetColumn.getId()) + "_" + k);
12216                                        columnElement.setName(columnName);
12217                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12218                                                columnElement.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12219                                                                + convertCoordinate(targetColumn.getEndPosition()));
12220                                        }
12221                                        if (!tableElement.getColumns().contains(columnElement)) {
12222                                                tableElement.getColumns().add(columnElement);
12223                                        }
12224                                }
12225                        }
12226                }
12227
12228                if (sourceStarColumn != null) {
12229                        table tableElement = null;
12230                        if (dataflow.getTables() != null) {
12231                                for (table t : dataflow.getTables()) {
12232                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
12233                                                tableElement = t;
12234                                                break;
12235                                        }
12236                                }
12237                        }
12238                        if (tableElement == null && dataflow.getViews() != null) {
12239                                for (table t : dataflow.getViews()) {
12240                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
12241                                                tableElement = t;
12242                                                break;
12243                                        }
12244                                }
12245                        }
12246                        if (tableElement == null && dataflow.getVariables() != null) {
12247                                for (table t : dataflow.getVariables()) {
12248                                        if (t.getId().equals(String.valueOf(sourceStarColumn.getTable().getId()))) {
12249                                                tableElement = t;
12250                                                break;
12251                                        }
12252                                }
12253                        }
12254
12255                        if (tableElement != null) {
12256                                List<String> columns = new ArrayList<String>(sourceStarColumn.getStarLinkColumns().keySet());
12257                                for (int k = 0; k < columns.size(); k++) {
12258                                        String columnName = columns.get(k);
12259                                        if (containStarColumn(sourceStarColumn.getTable().getColumns(), columnName)) {
12260                                                continue;
12261                                        }
12262                                        column columnElement = new column();
12263                                        columnElement.setId(sourceStarColumn.getId() + "_" + k);
12264                                        columnElement.setName(columnName);
12265                                        if (sourceStarColumn.getStartPosition() != null && sourceStarColumn.getEndPosition() != null) {
12266                                                columnElement.setCoordinate(convertCoordinate(sourceStarColumn.getStartPosition()) + ","
12267                                                                + convertCoordinate(sourceStarColumn.getEndPosition()));
12268                                        }
12269                                        if (!tableElement.getColumns().contains(columnElement)) {
12270                                                tableElement.getColumns().add(columnElement);
12271                                        }
12272                                }
12273                        }
12274                }
12275        }
12276
12277        private ESqlClause getSqlClause(RelationshipElement<?> relationshipElement) {
12278                if (relationshipElement instanceof TableColumnRelationshipElement) {
12279                        return ((TableColumnRelationshipElement) relationshipElement).getRelationLocation();
12280                } else if (relationshipElement instanceof ResultColumnRelationshipElement) {
12281                        return ((ResultColumnRelationshipElement) relationshipElement).getRelationLocation();
12282                }
12283                return null;
12284        }
12285
12286        private void appendStarRelation(dataflow dataflow, AbstractRelationship relation, int index) {
12287                if(option.getAnalyzeMode() == AnalyzeMode.crud) {
12288                        return;
12289                }
12290                
12291                Object targetElement = relation.getTarget().getElement();
12292
12293                relationship relationElement = new relationship();
12294                relationElement.setType(relation.getRelationshipType().name());
12295                if (relation.getEffectType() != null) {
12296                        relationElement.setEffectType(relation.getEffectType().name());
12297                }
12298                relationElement.setSqlHash(relation.getSqlHash());
12299                relationElement.setSqlComment(relation.getSqlComment());
12300
12301                if (relation.getProcedureId() != null) {
12302                        relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12303                }
12304                relationElement.setId(String.valueOf(relation.getId()) + "_" + index);
12305                if (relation.getProcess() != null) {
12306                        relationElement.setProcessId(String.valueOf(relation.getProcess().getId()));
12307                        if (relation.getProcess().getGspObject() != null) {
12308                                relationElement.setProcessType(relation.getProcess().getGspObject().sqlstatementtype.name());
12309                        }
12310                }
12311                if (relation instanceof DataFlowRelationship) {
12312                        relationElement.setSqlHash(((DataFlowRelationship) relation).getSqlHash());
12313                        relationElement.setSqlComment(((DataFlowRelationship) relation).getSqlComment());
12314                
12315                        if (relation.getProcedureId() != null) {
12316                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12317                        }
12318                }
12319                String targetName = "";
12320
12321                if (targetElement instanceof ResultColumn) {
12322                        ResultColumn targetColumn = (ResultColumn) targetElement;
12323
12324                        targetName = targetColumn.getStarLinkColumnNames().get(index);
12325
12326                        
12327                        targetColumn target = new targetColumn();
12328                        target.setId(String.valueOf(targetColumn.getId()) + "_" + index);
12329                        if(targetColumn.getResultSet()!=null && targetColumn.getResultSet().getColumns()!=null) {
12330                                for (int i = 0; i < targetColumn.getResultSet().getColumns().size(); i++) {
12331                                        ResultColumn columnModel = targetColumn.getResultSet().getColumns().get(i);
12332                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(targetName)) {
12333                                                target.setId(String.valueOf(columnModel.getId()));
12334                                                break;
12335                                        }
12336                                }
12337                        }
12338                        target.setColumn(targetName);
12339                        target.setStruct(targetColumn.isStruct());
12340                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
12341                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
12342                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12343                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12344                                                + convertCoordinate(targetColumn.getEndPosition()));
12345                        }
12346                        relationElement.setTarget(target);
12347                } else if (targetElement instanceof TableColumn) {
12348                        TableColumn targetColumn = (TableColumn) targetElement;
12349
12350                        targetName = targetColumn.getStarLinkColumnNames().get(index);
12351
12352                        TableColumn tableColumn = searchTableColumn(targetColumn.getTable().getColumns(), targetName);
12353
12354                        targetColumn target = new targetColumn();
12355                        if (tableColumn == null) {
12356                                target.setId(targetColumn.getId() + "_" + index);
12357                        } else {
12358                                target.setId(String.valueOf(tableColumn.getId()));
12359                        }
12360                        target.setStruct(targetColumn.isStruct());
12361                        target.setColumn(targetName);
12362                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
12363                        target.setParent_name(targetColumn.getTable().getName());
12364                        if (relation.getTarget() instanceof TableColumnRelationshipElement) {
12365                                target.setParent_alias(((TableColumnRelationshipElement) relation.getTarget()).getTableAlias());
12366                        }
12367                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12368                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12369                                                + convertCoordinate(targetColumn.getEndPosition()));
12370                        }
12371                        relationElement.setTarget(target);
12372                } else {
12373                        return;
12374                }
12375
12376                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>) relation.getSources();
12377                if (sourceElements.size() == 0) {
12378                        return;
12379                }
12380
12381                String targetIdentifierName = DlineageUtil.getIdentifierNormalColumnName(targetName);
12382                if (targetIdentifierName == null) {
12383                        return;
12384                }
12385
12386                // Track explicit (non-star) source columns per target star column to prevent
12387                // phantom star expansions. Skip for UNION targets where branches contribute independently.
12388                long targetColumnId = -1;
12389                boolean isUnionTarget = false;
12390                if (targetElement instanceof ResultColumn) {
12391                        ResultColumn tc = (ResultColumn) targetElement;
12392                        targetColumnId = tc.getId();
12393                        isUnionTarget = (tc.getResultSet() instanceof SelectSetResultSet);
12394                } else if (targetElement instanceof TableColumn) {
12395                        targetColumnId = ((TableColumn) targetElement).getId();
12396                }
12397
12398                if (!isUnionTarget && targetColumnId != -1) {
12399                        // Check if any source in this relationship is a non-star source matching the target
12400                        // column name, AND whose parent does NOT also contribute a star source.
12401                        // This distinguishes:
12402                        //   - "b.col_a" (definitive: b only provides explicit cols, not *) => suppress star expansion
12403                        //   - "aTab.id" (not definitive: aTab also provides *) => don't suppress
12404                        boolean hasDefinitiveExplicitSource = hasDefinitiveNonStarSource(sourceElements, targetIdentifierName);
12405                        if (hasDefinitiveExplicitSource) {
12406                                if (!explicitStarTargetColumns.containsKey(targetColumnId)) {
12407                                        explicitStarTargetColumns.put(targetColumnId, new HashSet<String>());
12408                                }
12409                                explicitStarTargetColumns.get(targetColumnId).add(targetIdentifierName);
12410                        }
12411                }
12412
12413                // Column names that have explicit (non-star) sources for this target, across all relationships
12414                Set<String> targetExplicitNames = isUnionTarget ? null : explicitStarTargetColumns.get(targetColumnId);
12415
12416                for (RelationshipElement<?> sourceItem: sourceElements) {
12417                        Object sourceElement = sourceItem.getElement();
12418                        if (sourceElement instanceof ResultColumn) {
12419                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
12420                                if (sourceColumn.hasStarLinkColumn()) {
12421                                        List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames();
12422                                        int linkColumnNameSize = linkColumnNames.size();
12423                                        for (int k = 0; k < linkColumnNameSize; k++) {
12424                                                String sourceName = linkColumnNames.get(k);
12425                                                if (relation.getRelationshipType() == RelationshipType.fdd) {
12426                                                        if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName))
12427                                                                continue;
12428                                                }
12429                                                // Skip star-expanded source when an explicit (non-star) source provides
12430                                                // the same column, either in this relationship or a prior one.
12431                                                if (targetExplicitNames != null && targetExplicitNames.contains(sourceName)) {
12432                                                        continue;
12433                                                }
12434                                                sourceColumn source = new sourceColumn();                                               
12435                                                
12436                                                boolean find = false;
12437                                                if(sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
12438                                                        for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) {
12439                                                                ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i);
12440                                                                if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equals(sourceName)) {
12441                                                                        source.setId(String.valueOf(columnModel.getId()));
12442                                                                        find = true;
12443                                                                        break;
12444                                                                }
12445                                                        }
12446                                                }
12447                                                if(!find) {
12448                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + k);
12449                                                }
12450                                                source.setColumn(sourceName);
12451                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12452                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12453                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12454                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12455                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12456                                                }
12457                                                if (sourceItem.getTransforms() != null) {
12458                                                        for (Transform transform : sourceItem.getTransforms()) {
12459                                                                source.addTransform(transform);
12460                                                        }
12461                                                }
12462                                                relationElement.addSource(source);
12463                                        }
12464                                        if(relationElement.getSources().isEmpty()
12465                                                && !(targetExplicitNames != null && targetExplicitNames.contains(targetIdentifierName))
12466                                                && sourceColumn.getResultSet()!=null && sourceColumn.getResultSet().getColumns()!=null) {
12467                                                for (int i = 0; i < sourceColumn.getResultSet().getColumns().size(); i++) {
12468                                                        ResultColumn columnModel = sourceColumn.getResultSet().getColumns().get(i);
12469                                                        if (DlineageUtil.getIdentifierNormalColumnName(columnModel.getName()).equalsIgnoreCase(targetIdentifierName)) {
12470                                                                sourceColumn source = new sourceColumn();
12471                                                                source.setId(String.valueOf(columnModel.getId()));
12472                                                                source.setColumn(columnModel.getName());
12473                                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12474                                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12475                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12476                                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12477                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12478                                                                }
12479                                                                if (sourceItem.getTransforms() != null) {
12480                                                                        for (Transform transform : sourceItem.getTransforms()) {
12481                                                                                source.addTransform(transform);
12482                                                                        }
12483                                                                }
12484                                                                relationElement.addSource(source);
12485                                                                break;
12486                                                        }
12487                                                }
12488                                        }
12489                                        if (relationElement.getSources().isEmpty()
12490                                                && !(targetExplicitNames != null && targetExplicitNames.contains(targetIdentifierName))) {
12491                                                TObjectName sourceStarLinkColumn = new TObjectName();
12492                                                sourceStarLinkColumn.setString(targetName);
12493                                                boolean newBinding = sourceColumn.bindStarLinkColumn(sourceStarLinkColumn);
12494                                                sourceColumn source = new sourceColumn();
12495                                                String sourceName = DlineageUtil.getColumnName(sourceStarLinkColumn);
12496                                                if (!newBinding) {
12497                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_"
12498                                                                        + sourceColumn.indexOfStarLinkColumn(sourceStarLinkColumn));
12499                                                } else {
12500                                                        source.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize);
12501                                                }
12502                                                source.setColumn(sourceName);
12503                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12504                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12505                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12506                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12507                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12508                                                }
12509                                                if (sourceItem.getTransforms() != null) {
12510                                                        for (Transform transform : sourceItem.getTransforms()) {
12511                                                                source.addTransform(transform);
12512                                                        }
12513                                                }
12514                                                relationElement.addSource(source);
12515
12516                                                if (newBinding) {
12517                                                        table resultSetElement = null;
12518                                                        for (table t : dataflow.getResultsets()) {
12519                                                                if (t.getId().equals(String.valueOf(sourceColumn.getResultSet().getId()))) {
12520                                                                        resultSetElement = t;
12521                                                                        break;
12522                                                                }
12523                                                        }
12524                                                        if (resultSetElement != null) {
12525                                                                column columnElement = new column();
12526                                                                columnElement.setId(String.valueOf(sourceColumn.getId()) + "_" + linkColumnNameSize);
12527                                                                columnElement.setName(sourceName);
12528                                                                if (sourceColumn.isFunction()) {
12529                                                                        columnElement.setIsFunction(String.valueOf(sourceColumn.isFunction()));
12530                                                                }
12531                                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12532                                                                        columnElement.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12533                                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12534                                                                }
12535                                                                resultSetElement.getColumns().add(columnElement);
12536                                                        }
12537                                                }
12538                                        }
12539                                } else {
12540                                        sourceColumn source = new sourceColumn();
12541                                        source.setId(String.valueOf(sourceColumn.getId()));
12542                                        source.setColumn(sourceColumn.getName());
12543                                        source.setStruct(sourceColumn.isStruct());
12544                                        source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12545                                        source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12546                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12547                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12548                                                                + convertCoordinate(sourceColumn.getEndPosition()));
12549                                        }
12550                                        if (relation.getRelationshipType() == RelationshipType.fdd) {
12551                                                if (!targetIdentifierName
12552                                                                .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))) {
12553                                                        if (!"*".equals(sourceColumn.getName())) {
12554                                                                continue;
12555                                                        }
12556                                                        else {
12557                                                                boolean flag = false;
12558                                                                for(ResultColumn column: sourceColumn.getResultSet().getColumns()) {
12559                                                                        if(targetIdentifierName
12560                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
12561                                                                                flag = true;
12562                                                                                break;
12563                                                                        }
12564                                                                }
12565                                                                if(flag) {
12566                                                                        continue;
12567                                                                }
12568                                                        }
12569                                                }
12570                                        }
12571                                        if (sourceItem.getTransforms() != null) {
12572                                                for (Transform transform : sourceItem.getTransforms()) {
12573                                                        source.addTransform(transform);
12574                                                }
12575                                        }
12576                                        relationElement.addSource(source);
12577                                }
12578                        } else if (sourceElement instanceof TableColumn) {
12579                                TableColumn sourceColumn = (TableColumn) sourceElement;
12580                                if (!sourceColumn.isPseduo() && sourceColumn.hasStarLinkColumn()) {
12581                                        List<String> linkColumnNames = sourceColumn.getStarLinkColumnNames();
12582                                        int linkColumnNameSize = linkColumnNames.size();
12583                                        for (int k = 0; k < linkColumnNameSize; k++) {
12584                                                String sourceName = linkColumnNames.get(k);
12585                                                if (relation.getRelationshipType() == RelationshipType.fdd) {
12586                                                        if (!targetIdentifierName.equalsIgnoreCase(sourceName) && !"*".equals(sourceName))
12587                                                                continue;
12588                                                }
12589
12590                                                TableColumn tableColumn = searchTableColumn(sourceColumn.getTable().getColumns(), sourceName);
12591
12592                                                sourceColumn source = new sourceColumn();
12593                                                if (tableColumn == null) {
12594                                                        source.setId(sourceColumn.getId() + "_" + k);
12595                                                } else {
12596                                                        source.setId(String.valueOf(tableColumn.getId()));
12597                                                }
12598                                                source.setColumn(sourceName);
12599                                                source.setStruct(sourceColumn.isStruct());
12600                                                if (containStarColumn(sourceElements, sourceName)) {
12601                                                        continue;
12602                                                }
12603                                                // Cross-relationship check: skip if explicit source was found in prior relationship
12604                                                if (targetExplicitNames != null && targetExplicitNames.contains(sourceName)) {
12605                                                        continue;
12606                                                }
12607                                                if (sourceColumn.getTable().getColumns().size() > 1) {
12608                                                        for (int y = 0; y < sourceColumn.getTable().getColumns().size(); y++) {
12609                                                                if (sourceColumn.getTable().getColumns().get(y).getName()
12610                                                                                .equalsIgnoreCase(sourceName)) {
12611                                                                        source.setId(String.valueOf(sourceColumn.getTable().getColumns().get(y).getId()));
12612                                                                        break;
12613                                                                }
12614                                                        }
12615                                                }
12616                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
12617                                                source.setParent_name(getTableName(sourceColumn.getTable()));
12618                                                if (sourceItem instanceof TableColumnRelationshipElement) {
12619                                                        source.setParent_alias(
12620                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
12621                                                }
12622                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12623                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12624                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12625                                                }
12626                                                if (sourceItem.getTransforms() != null) {
12627                                                        for (Transform transform : sourceItem.getTransforms()) {
12628                                                                source.addTransform(transform);
12629                                                        }
12630                                                }
12631                                                relationElement.addSource(source);
12632                                        }
12633                                } else {
12634                                        sourceColumn source = new sourceColumn();
12635                                        source.setId(String.valueOf(sourceColumn.getId()));
12636                                        source.setColumn(sourceColumn.getName());
12637                                        source.setStruct(sourceColumn.isStruct());
12638                                        source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
12639                                        source.setParent_name(getTableName(sourceColumn.getTable()));
12640                                        if (sourceItem instanceof TableColumnRelationshipElement) {
12641                                                source.setParent_alias(((TableColumnRelationshipElement) sourceItem).getTableAlias());
12642                                        }
12643                                        if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12644                                                source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12645                                                                + convertCoordinate(sourceColumn.getEndPosition()));
12646                                        }
12647                                        if (relation.getRelationshipType() == RelationshipType.fdd) {
12648                                                if (!targetIdentifierName
12649                                                                .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(sourceColumn.getName()))
12650                                                                && !"*".equals(sourceColumn.getName()))
12651                                                        continue;
12652                                        }
12653                                        if (sourceItem.getTransforms() != null) {
12654                                                for (Transform transform : sourceItem.getTransforms()) {
12655                                                        source.addTransform(transform);
12656                                                }
12657                                        }
12658                                        relationElement.addSource(source);
12659                                }
12660                        }
12661                }
12662
12663                if (relationElement.getTarget() != null && relationElement.getSources() != null
12664                                && !relationElement.getSources().isEmpty()) {
12665                        dataflow.getRelationships().add(relationElement);
12666                }
12667        }
12668
12669        private String getColumnName(TObjectName column) {
12670                if (column == null) {
12671                        return null;
12672                }
12673                String name = column.getColumnNameOnly();
12674                if (name == null || "".equals(name.trim())) {
12675                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
12676                } else
12677                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
12678        }
12679
12680        /**
12681         * For BigQuery/Redshift struct field access, returns the full struct path
12682         * (e.g., "customer.name" from ColumnSource with exposedName="customer", fieldPath=["name"]).
12683         * Checks StructFieldHint first (for 3+ part no-alias), then ColumnSource (for 2-part/alias).
12684         * Returns null if this is not a struct field access.
12685         */
12686        private String getStructFieldFullName(TObjectName column) {
12687                if (column == null) return null;
12688                if (getOption().getVendor() != EDbVendor.dbvbigquery
12689                        && getOption().getVendor() != EDbVendor.dbvredshift) return null;
12690                // Priority 1: StructFieldHint (side-channel, for 3+ part no-alias deep struct access)
12691                gudusoft.gsqlparser.resolver2.model.StructFieldHint hint = column.getStructFieldHint();
12692                if (hint != null && hint.getFieldPath() != null && !hint.getFieldPath().isEmpty()) {
12693                        return hint.toFullReference();
12694                }
12695                // Priority 2: ColumnSource (main resolution, for 2-part and alias cases)
12696                gudusoft.gsqlparser.resolver2.model.ColumnSource source = column.getColumnSource();
12697                if (source != null && source.isStructFieldAccess() && source.hasFieldPath()) {
12698                        return source.getFieldPath().toFullReference(source.getExposedName());
12699                }
12700                return null;
12701        }
12702
12703        /**
12704         * Get the base column name for a struct field access column.
12705         * Checks StructFieldHint first (3+ part no-alias), then ColumnSource (2-part/alias).
12706         * Returns null if not a struct field access.
12707         */
12708        private String getStructFieldBaseName(TObjectName column) {
12709                if (column == null) return null;
12710                gudusoft.gsqlparser.resolver2.model.StructFieldHint hint = column.getStructFieldHint();
12711                if (hint != null && hint.getBaseColumn() != null) {
12712                        return hint.getBaseColumn();
12713                }
12714                gudusoft.gsqlparser.resolver2.model.ColumnSource source = column.getColumnSource();
12715                if (source != null && source.isStructFieldAccess()) {
12716                        return source.getExposedName();
12717                }
12718                return null;
12719        }
12720
12721        private String getColumnName(String column) {
12722                if (column == null) {
12723                        return null;
12724                }
12725                String name = column.substring(column.lastIndexOf(".") + 1);
12726                if (name == null || "".equals(name.trim())) {
12727                        return DlineageUtil.getIdentifierNormalColumnName(column.toString().trim());
12728                } else
12729                        return DlineageUtil.getIdentifierNormalColumnName(name.trim());
12730        }
12731        
12732        private String getColumnNameOnly(String column) {
12733                if (column == null) {
12734                        return null;
12735                }
12736                return DlineageUtil.getColumnNameOnly(column);
12737        }
12738
12739        private void appendRecordSetRelation(dataflow dataflow, Relationship[] relations) {
12740                for (int i = 0; i < relations.length; i++) {
12741                        AbstractRelationship relation = (AbstractRelationship) relations[i];
12742                        relationship relationElement = new relationship();
12743                        relationElement.setType(relation.getRelationshipType().name());
12744                        if (relation.getFunction() != null) {
12745                                relationElement.setFunction(relation.getFunction());
12746                        }
12747                        if (relation.getEffectType() != null) {
12748                                relationElement.setEffectType(relation.getEffectType().name());
12749                        }
12750                        relationElement.setSqlHash(relation.getSqlHash());
12751                        relationElement.setSqlComment(relation.getSqlComment());
12752
12753                        if (relation.getProcedureId() != null) {
12754                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12755                        }
12756                        relationElement.setId(String.valueOf(relation.getId()));
12757
12758                        if (relation instanceof RecordSetRelationship) {
12759                                RecordSetRelationship recordCountRelation = (RecordSetRelationship) relation;
12760
12761                                Object targetElement = recordCountRelation.getTarget().getElement();
12762                                if (targetElement instanceof ResultColumn) {
12763                                        ResultColumn targetColumn = (ResultColumn) targetElement;
12764                                        targetColumn target = new targetColumn();
12765                                        target.setId(String.valueOf(targetColumn.getId()));
12766                                        target.setColumn(targetColumn.getName());
12767                                        target.setStruct(targetColumn.isStruct());
12768                                        target.setFunction(recordCountRelation.getAggregateFunction());
12769                                        target.setParent_id(String.valueOf(targetColumn.getResultSet().getId()));
12770                                        target.setParent_name(getResultSetName(targetColumn.getResultSet()));
12771                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12772                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12773                                                                + convertCoordinate(targetColumn.getEndPosition()));
12774                                        }
12775                                        relationElement.setTarget(target);
12776                                } else if (targetElement instanceof TableColumn) {
12777                                        TableColumn targetColumn = (TableColumn) targetElement;
12778                                        targetColumn target = new targetColumn();
12779                                        target.setId(String.valueOf(targetColumn.getId()));
12780                                        target.setColumn(targetColumn.getName());
12781                                        target.setStruct(targetColumn.isStruct());
12782                                        target.setFunction(recordCountRelation.getAggregateFunction());
12783                                        target.setParent_id(String.valueOf(targetColumn.getTable().getId()));
12784                                        target.setParent_name(getTableName(targetColumn.getTable()));
12785                                        if (recordCountRelation.getTarget() instanceof TableColumnRelationshipElement) {
12786                                                target.setParent_alias(
12787                                                                ((TableColumnRelationshipElement) recordCountRelation.getTarget()).getTableAlias());
12788                                        }
12789                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12790                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12791                                                                + convertCoordinate(targetColumn.getEndPosition()));
12792                                        }
12793                                        relationElement.setTarget(target);
12794                                } else if (targetElement instanceof ResultSetRelationRows) {
12795                                        ResultSetRelationRows targetColumn = (ResultSetRelationRows) targetElement;
12796                                        targetColumn target = new targetColumn();
12797                                        target.setId(String.valueOf(targetColumn.getId()));
12798                                        target.setColumn(targetColumn.getName());
12799                                        target.setParent_id(String.valueOf(targetColumn.getHolder().getId()));
12800                                        target.setParent_name(getResultSetName(targetColumn.getHolder()));
12801                                        if (targetColumn.getStartPosition() != null && targetColumn.getEndPosition() != null) {
12802                                                target.setCoordinate(convertCoordinate(targetColumn.getStartPosition()) + ","
12803                                                                + convertCoordinate(targetColumn.getEndPosition()));
12804                                        }
12805                                        target.setSource("system");
12806                                        relationElement.setTarget(target);
12807                                } else {
12808                                        continue;
12809                                }
12810
12811                                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)recordCountRelation.getSources();
12812                                if (sourceElements.size() == 0) {
12813                                        continue;
12814                                }
12815
12816                                boolean append = false;
12817                                for (RelationshipElement<?> sourceItem: sourceElements) {
12818                                        Object sourceElement = sourceItem.getElement();
12819                                        if (sourceElement instanceof Table) {
12820                                                Table table = (Table) sourceElement;
12821                                                sourceColumn source = new sourceColumn();
12822                                                source.setSource_id(String.valueOf(table.getId()));
12823                                                source.setSource_name(getTableName(table));
12824                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
12825                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
12826                                                                        + convertCoordinate(table.getEndPosition()));
12827                                                }
12828                                                append = true;
12829                                                relationElement.addSource(source);
12830                                        } else if (sourceElement instanceof QueryTable) {
12831                                                QueryTable table = (QueryTable) sourceElement;
12832                                                sourceColumn source = new sourceColumn();
12833                                                source.setSource_id(String.valueOf(table.getId()));
12834                                                source.setSource_name(getResultSetName(table));
12835                                                if (table.getStartPosition() != null && table.getEndPosition() != null) {
12836                                                        source.setCoordinate(convertCoordinate(table.getStartPosition()) + ","
12837                                                                        + convertCoordinate(table.getEndPosition()));
12838                                                }
12839                                                append = true;
12840                                                relationElement.addSource(source);
12841                                        } else if (sourceElement instanceof TableRelationRows) {
12842                                                TableRelationRows relationRows = (TableRelationRows) sourceElement;
12843                                                sourceColumn source = new sourceColumn();
12844                                                source.setId(String.valueOf(relationRows.getId()));
12845                                                source.setColumn(relationRows.getName());
12846                                                source.setParent_id(String.valueOf(relationRows.getHolder().getId()));
12847                                                source.setParent_name(getTableName(relationRows.getHolder()));
12848                                                if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12849                                                        source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12850                                                                        + convertCoordinate(relationRows.getEndPosition()));
12851                                                }
12852                                                source.setSource("system");
12853                                                append = true;
12854                                                relationElement.addSource(source);
12855                                        } else if (sourceElement instanceof ResultSetRelationRows) {
12856                                                ResultSetRelationRows relationRows = (ResultSetRelationRows) sourceElement;
12857                                                sourceColumn source = new sourceColumn();
12858                                                source.setId(String.valueOf(relationRows.getId()));
12859                                                source.setColumn(relationRows.getName());
12860                                                source.setParent_id(String.valueOf(relationRows.getHolder().getId()));
12861                                                source.setParent_name(getResultSetName(relationRows.getHolder()));
12862                                                if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
12863                                                        source.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
12864                                                                        + convertCoordinate(relationRows.getEndPosition()));
12865                                                }
12866                                                source.setSource("system");
12867                                                append = true;
12868                                                relationElement.addSource(source);
12869                                        } else if (sourceElement instanceof TableColumn) {
12870                                                TableColumn sourceColumn = (TableColumn) sourceElement;
12871                                                sourceColumn source = new sourceColumn();
12872                                                source.setId(String.valueOf(sourceColumn.getId()));
12873                                                source.setColumn(sourceColumn.getName());
12874                                                source.setStruct(sourceColumn.isStruct());
12875                                                source.setParent_id(String.valueOf(sourceColumn.getTable().getId()));
12876                                                source.setParent_name(getTableName(sourceColumn.getTable()));
12877                                                if (sourceItem instanceof TableColumnRelationshipElement) {
12878                                                        source.setParent_alias(
12879                                                                        ((TableColumnRelationshipElement) sourceItem).getTableAlias());
12880                                                }
12881                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12882                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12883                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12884                                                }
12885                                                append = true;
12886                                                relationElement.addSource(source);
12887                                        }
12888                                        if (sourceElement instanceof ResultColumn) {
12889                                                ResultColumn sourceColumn = (ResultColumn) sourceElement;
12890                                                sourceColumn source = new sourceColumn();
12891                                                source.setId(String.valueOf(sourceColumn.getId()));
12892                                                source.setColumn(sourceColumn.getName());
12893                                                source.setStruct(sourceColumn.isStruct());
12894                                                source.setParent_id(String.valueOf(sourceColumn.getResultSet().getId()));
12895                                                source.setParent_name(getResultSetName(sourceColumn.getResultSet()));
12896                                                if (sourceColumn.getStartPosition() != null && sourceColumn.getEndPosition() != null) {
12897                                                        source.setCoordinate(convertCoordinate(sourceColumn.getStartPosition()) + ","
12898                                                                        + convertCoordinate(sourceColumn.getEndPosition()));
12899                                                }
12900                                                append = true;
12901                                                relationElement.addSource(source);
12902                                        }
12903                                }
12904
12905                                if (append)
12906                                        dataflow.getRelationships().add(relationElement);
12907                        }
12908                }
12909        }
12910
12911        private void appendCallRelation(dataflow dataflow, Relationship[] relations) {
12912                for (int i = 0; i < relations.length; i++) {
12913                        AbstractRelationship relation = (AbstractRelationship) relations[i];
12914                        relationship relationElement = new relationship();
12915                        relationElement.setType(relation.getRelationshipType().name());
12916                        if (relation.getFunction() != null) {
12917                                relationElement.setFunction(relation.getFunction());
12918                        }
12919                        if (relation.getEffectType() != null) {
12920                                relationElement.setEffectType(relation.getEffectType().name());
12921                        }
12922                        relationElement.setSqlHash(relation.getSqlHash());
12923                        relationElement.setSqlComment(relation.getSqlComment());
12924                        
12925                        if (relation.getProcedureId() != null) {
12926                                relationElement.setProcedureId(String.valueOf(relation.getProcedureId()));
12927                        }
12928                        relationElement.setId(String.valueOf(relation.getId()));
12929
12930                        if (relation instanceof CallRelationship) {
12931                                CallRelationship callRelation = (CallRelationship) relation;
12932                                
12933                                if (callRelation.getCallObject() != null) {
12934                                        relationElement.setCallStmt(callRelation.getCallObject().toString());
12935                                        if (callRelation.getStartPosition() != null && callRelation.getEndPosition() != null) {
12936                                                relationElement.setCallCoordinate(convertCoordinate(callRelation.getStartPosition()) + ","
12937                                                                + convertCoordinate(callRelation.getEndPosition()));
12938                                        }
12939                                }
12940                                
12941                                if (Boolean.TRUE.equals(callRelation.getBuiltIn())) {
12942                                        relationElement.setBuiltIn(true);
12943                                }
12944                                Object targetElement = callRelation.getTarget().getElement();
12945                                if (targetElement instanceof Procedure) {
12946                                        Procedure procedure = (Procedure) targetElement;
12947                                        targetColumn target = new targetColumn();
12948                                        target.setId(String.valueOf(procedure.getId()));
12949                                        target.setName(getProcedureName(procedure));
12950                                        if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) {
12951                                                target.setCoordinate(convertCoordinate(procedure.getStartPosition()) + ","
12952                                                                + convertCoordinate(procedure.getEndPosition()));
12953                                        }
12954                                        String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase();
12955                                        if (clazz.indexOf("function") != -1) {
12956                                                target.setType("function");
12957                                        } else if (clazz.indexOf("trigger") != -1) {
12958                                                target.setType("trigger");
12959                                        } else if (clazz.indexOf("macro") != -1) {
12960                                                target.setType("macro");
12961                                        } else {
12962                                                target.setType("procedure");
12963                                        }
12964                                        relationElement.setCaller(target);
12965                                } else {
12966                                        continue;
12967                                }
12968
12969                                Collection<RelationshipElement<?>> sourceElements = (Collection<RelationshipElement<?>>)callRelation.getSources();
12970                                if (sourceElements.size() == 0) {
12971                                        continue;
12972                                }
12973
12974                                boolean append = false;
12975                                for (RelationshipElement<?> sourceItem: sourceElements) {
12976                                        Object sourceElement = sourceItem.getElement();
12977                                        if (sourceElement instanceof Procedure) {
12978                                                Procedure procedure = (Procedure) sourceElement;
12979                                                sourceColumn source = new sourceColumn();
12980                                                source.setId(String.valueOf(procedure.getId()));
12981                                                source.setName(getProcedureName(procedure));
12982                                                if (procedure.getStartPosition() != null && procedure.getEndPosition() != null) {
12983                                                        source.setCoordinate(convertCoordinate(procedure.getStartPosition()) + ","
12984                                                                        + convertCoordinate(procedure.getEndPosition()));
12985                                                }
12986                                                String clazz = procedure.getProcedureObject().getClass().getSimpleName().toLowerCase();
12987                                                if (clazz.indexOf("function") != -1) {
12988                                                        source.setType("function");
12989                                                } else if (clazz.indexOf("trigger") != -1) {
12990                                                        source.setType("trigger");
12991                                                } else if (clazz.indexOf("macro") != -1) {
12992                                                        source.setType("macro");
12993                                                } else {
12994                                                        source.setType("procedure");
12995                                                }
12996                                                append = true;
12997                                                relationElement.getCallees().add(source);
12998                                        } else if (sourceElement instanceof Function) {
12999                                                Function function = (Function) sourceElement;
13000                                                sourceColumn source = new sourceColumn();
13001                                                source.setId(String.valueOf(function.getId()));
13002                                                source.setName(getFunctionName(function.getFunctionObject()));
13003                                                if (function.getStartPosition() != null && function.getEndPosition() != null) {
13004                                                        source.setCoordinate(convertCoordinate(function.getStartPosition()) + ","
13005                                                                        + convertCoordinate(function.getEndPosition()));
13006                                                }
13007                                                source.setType("function");
13008                                                append = true;
13009                                                relationElement.getCallees().add(source);
13010                                        }
13011                                }
13012
13013                                if (append)
13014                                        dataflow.getRelationships().add(relationElement);
13015                        }
13016                }
13017        }
13018
13019        private void appendResultSets(dataflow dataflow) {
13020                Set<ResultSet> resultSets = modelManager.getResultSets(); 
13021                for (ResultSet resultSet: resultSets) {
13022                        appendResultSet(dataflow, resultSet);
13023                }
13024        }
13025
13026        private void appendResultSet(dataflow dataflow, ResultSet resultSetModel) {
13027                if (!appendResultSets.contains(resultSetModel)) {
13028                        appendResultSets.add(resultSetModel);
13029                } else {
13030                        return;
13031                }
13032
13033                table resultSetElement = new table();
13034                resultSetElement.setId(String.valueOf(resultSetModel.getId()));
13035                resultSetElement.setServer(resultSetModel.getServer());
13036                if (!SQLUtil.isEmpty(resultSetModel.getDatabase())) {
13037                        resultSetElement.setDatabase(resultSetModel.getDatabase());
13038                }
13039                if (!SQLUtil.isEmpty(resultSetModel.getSchema())) {
13040                        resultSetElement.setSchema(resultSetModel.getSchema());
13041                }
13042                resultSetElement.setName(getResultSetName(resultSetModel));
13043                resultSetElement.setType(getResultSetType(resultSetModel));
13044                // if ((ignoreRecordSet || simpleOutput) && resultSetModel.isTarget()) {
13045                resultSetElement.setIsTarget(String.valueOf(resultSetModel.isTarget()));
13046                // }
13047                resultSetElement.setIsDetermined(String.valueOf(resultSetModel.isDetermined()));
13048                if (resultSetModel.getStartPosition() != null && resultSetModel.getEndPosition() != null) {
13049                        resultSetElement.setCoordinate(convertCoordinate(resultSetModel.getStartPosition()) + ","
13050                                        + convertCoordinate(resultSetModel.getEndPosition()));
13051                }
13052                dataflow.getResultsets().add(resultSetElement);
13053
13054                List<ResultColumn> columns = resultSetModel.getColumns();
13055
13056                Map<String, Integer> columnCounts = new HashMap<String, Integer>();
13057                for (ResultColumn column : columns) {
13058                        String columnName = DlineageUtil.getIdentifierNormalColumnName(column.getName());
13059                        if (!columnCounts.containsKey(columnName)) {
13060                                columnCounts.put(columnName, 0);
13061                        }
13062                        columnCounts.put(columnName, columnCounts.get(columnName) + 1);
13063                        // if (column.hasStarLinkColumn()) {
13064                        // List<String> starLinkColumns = column.getStarLinkColumnNames();
13065                        // for (int k = 0; k < starLinkColumns.size(); k++) {
13066                        // columnName = starLinkColumns.get(k);
13067                        // if (!columnCounts.containsKey(columnName)) {
13068                        // columnCounts.put(columnName, 0);
13069                        // }
13070                        // columnCounts.put(columnName, columnCounts.get(columnName) + 1);
13071                        // }
13072                        // }
13073                }
13074
13075                for (int j = 0; j < columns.size(); j++) {
13076                        ResultColumn columnModel = columns.get(j);
13077                        if (columnModel.hasStarLinkColumn()) {
13078                                // List<String> starLinkColumns =
13079                                // columnModel.getStarLinkColumnNames();
13080                                // for (int k = 0; k < starLinkColumns.size(); k++) {
13081                                // column columnElement = new column();
13082                                // columnElement.setId( String.valueOf(columnModel.getId()) +
13083                                // "_" + k);
13084                                // String columnName = starLinkColumns.get(k);
13085                                // columnElement.setName(columnName);
13086                                // if(columnModel.isFunction()){
13087                                // columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
13088                                // }
13089                                // if (columnModel.getStartPosition() != null &&
13090                                // columnModel.getEndPosition() != null) {
13091                                // columnElement.setCoordinate(
13092                                // columnModel.getStartPosition() + "," +
13093                                // columnModel.getEndPosition());
13094                                // }
13095                                // String identifier = columnName;
13096                                // if(columnCounts.containsKey(identifier) &&
13097                                // columnCounts.get(identifier)>1){
13098                                // TObjectName column =
13099                                // columnModel.getStarLinkColumns().get(columnName).iterator().next();
13100                                // if(!SQLUtil.isEmpty(getQualifiedTable(column))){
13101                                // columnElement.setQualifiedTable(getQualifiedTable(column));
13102                                // }
13103                                // }
13104                                // resultSetElement.getColumns().add(columnElement);
13105                                // }
13106                                if (columnModel.isShowStar()) {
13107                                        column columnElement = new column();
13108                                        columnElement.setId(String.valueOf(columnModel.getId()));
13109                                        columnElement.setName(columnModel.getName());
13110                                        if (columnModel.isFunction()) {
13111                                                columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
13112                                        }
13113                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13114                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13115                                                                + convertCoordinate(columnModel.getEndPosition()));
13116                                        }
13117
13118                                        String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName());
13119                                        if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) {
13120                                                String qualifiedTable = getQualifiedTable(columnModel);
13121                                                if (!SQLUtil.isEmpty(qualifiedTable)) {
13122                                                        columnElement.setQualifiedTable(qualifiedTable);
13123                                                }
13124                                        }
13125                                        resultSetElement.getColumns().add(columnElement);
13126                                }
13127                        } else {
13128                                column columnElement = new column();
13129                                columnElement.setId(String.valueOf(columnModel.getId()));
13130                                columnElement.setName(columnModel.getName());
13131                                if (columnModel.isFunction()) {
13132                                        columnElement.setIsFunction(String.valueOf(columnModel.isFunction()));
13133                                }
13134                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13135                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13136                                                        + convertCoordinate(columnModel.getEndPosition()));
13137                                }
13138
13139                                String identifier = DlineageUtil.getIdentifierNormalColumnName(columnModel.getName());
13140                                if (columnCounts.containsKey(identifier) && columnCounts.get(identifier) > 1) {
13141                                        String qualifiedTable = getQualifiedTable(columnModel);
13142                                        if (!SQLUtil.isEmpty(qualifiedTable)) {
13143                                                columnElement.setQualifiedTable(qualifiedTable);
13144                                        }
13145                                }
13146                                resultSetElement.getColumns().add(columnElement);
13147                        }
13148                }
13149
13150                ResultSetRelationRows relationRows = resultSetModel.getRelationRows();
13151                if (relationRows.hasRelation()) {
13152                        column relationRowsElement = new column();
13153                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13154                        relationRowsElement.setName(relationRows.getName());
13155                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13156                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13157                                                + convertCoordinate(relationRows.getEndPosition()));
13158                        }
13159                        relationRowsElement.setSource("system");
13160                        resultSetElement.getColumns().add(relationRowsElement);
13161                }
13162        }
13163
13164        private String getQualifiedTable(ResultColumn columnModel) {
13165                if (columnModel.getColumnObject() instanceof TObjectName) {
13166                        return getQualifiedTable((TObjectName) columnModel.getColumnObject());
13167                }
13168                if (columnModel.getColumnObject() instanceof TResultColumn) {
13169                        TObjectName field = ((TResultColumn) columnModel.getColumnObject()).getFieldAttr();
13170                        if (field != null) {
13171                                return getQualifiedTable(field);
13172                        }
13173                }
13174                return null;
13175        }
13176
13177        private String getQualifiedTable(TObjectName column) {
13178                if (column == null)
13179                        return null;
13180                String[] splits = column.toString().split("\\.");
13181                if (splits.length > 1) {
13182                        return splits[splits.length - 2];
13183                }
13184                return null;
13185        }
13186
13187        /**
13188         * Get the qualified prefix (schema.table) from a column name for 3-part names.
13189         * For example, for "sch.pk_constv2.c_cdsl", returns "sch.pk_constv2".
13190         * Returns null if the column doesn't have both schema and table parts.
13191         */
13192        private String getQualifiedPrefixFromColumn(TObjectName column) {
13193                if (column == null) return null;
13194
13195                // Check if both schema and table tokens are present (3-part name)
13196                String schemaStr = column.getSchemaString();
13197                String tableStr = column.getTableString();
13198
13199                if (schemaStr != null && !schemaStr.isEmpty() &&
13200                        tableStr != null && !tableStr.isEmpty()) {
13201                        return schemaStr + "." + tableStr;
13202                }
13203
13204                // Fallback: parse from toString() for complex cases
13205                String[] splits = column.toString().split("\\.");
13206                if (splits.length >= 3) {
13207                        // Return all parts except the last one (column name)
13208                        StringBuilder prefix = new StringBuilder();
13209                        for (int i = 0; i < splits.length - 1; i++) {
13210                                if (i > 0) prefix.append(".");
13211                                prefix.append(splits[i]);
13212                        }
13213                        return prefix.toString();
13214                }
13215
13216                return null;
13217        }
13218
13219        private String getResultSetType(ResultSet resultSetModel) {
13220                if (resultSetModel instanceof QueryTable) {
13221                        QueryTable table = (QueryTable) resultSetModel;
13222                        if (table.getTableObject().getCTE() != null) {
13223                                return "with_cte";
13224                        }
13225                }
13226
13227                if (resultSetModel instanceof SelectSetResultSet) {
13228                        ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType();
13229                        return "select_" + type.name();
13230                }
13231
13232                if (resultSetModel instanceof SelectResultSet) {
13233                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) {
13234                                return "insert-select";
13235                        }
13236                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) {
13237                                return "update-select";
13238                        }
13239                }
13240
13241                if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) {
13242                        return "merge-update";
13243                }
13244
13245                if (resultSetModel.getGspObject() instanceof TOutputClause) {
13246                        return ResultSetType.output.name();
13247                }
13248
13249                if (resultSetModel.getGspObject() instanceof TMergeInsertClause) {
13250                        return "merge-insert";
13251                }
13252
13253                if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) {
13254                        return "update-set";
13255                }
13256
13257                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) {
13258                        return ResultSetType.array.name();
13259                }
13260
13261                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) {
13262                        return ResultSetType.struct.name();
13263                }
13264
13265                if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) {
13266                        return ResultSetType.function.name();
13267                }
13268
13269                if (resultSetModel.getGspObject() instanceof TAliasClause) {
13270                        return ResultSetType.alias.name();
13271                }
13272
13273                if (resultSetModel.getGspObject() instanceof TCursorDeclStmt) {
13274                        return ResultSetType.cursor.name();
13275                }
13276
13277                if (resultSetModel instanceof PivotedTable) {
13278                        if (((PivotedTable) resultSetModel).isUnpivoted()) {
13279                                return ResultSetType.unpivot_table.name();
13280                        }
13281                        return ResultSetType.pivot_table.name();
13282                }
13283
13284                return "select_list";
13285        }
13286
13287        private String getTableName(Table tableModel) {
13288                if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) {
13289                        return modelManager.DISPLAY_NAME.get(tableModel.getId());
13290                }
13291
13292                String tableName;
13293                if (tableModel.getFullName() != null && tableModel.getFullName().trim().length() > 0) {
13294                        return tableModel.getFullName();
13295                }
13296                if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) {
13297                        tableName = getResultSetWithId("RESULT_OF_" + tableModel.getAlias());
13298
13299                } else {
13300                        tableName = getResultSetDisplayId("RS");
13301                }
13302                modelManager.DISPLAY_NAME.put(tableModel.getId(), tableName);
13303                return tableName;
13304        }
13305
13306        private String getProcedureName(Procedure procedureModel) {
13307                if (modelManager.DISPLAY_NAME.containsKey(procedureModel.getId())) {
13308                        return modelManager.DISPLAY_NAME.get(procedureModel.getId());
13309                }
13310
13311                String procedureName = procedureModel.getFullName();
13312
13313                modelManager.DISPLAY_NAME.put(procedureModel.getId(), procedureName);
13314                return procedureName;
13315        }
13316
13317        private String getProcessName(Process processModel) {
13318                if (modelManager.DISPLAY_NAME.containsKey(processModel.getId())) {
13319                        return modelManager.DISPLAY_NAME.get(processModel.getId());
13320                } else {
13321                        if (processModel.getCustomType() != null) {
13322                                String name = processModel.getCustomType();
13323                                modelManager.DISPLAY_NAME.put(processModel.getId(), name);
13324                                return name;
13325                        }
13326                        String name = processModel.getType();
13327                        String procedureName = getProcedureParentName(processModel.getGspObject());
13328                        if (procedureName != null) {
13329                                name = getResultSetDisplayId(procedureName + " " + name);
13330                        } else {
13331                                name = getResultSetDisplayId("Query " + name);
13332                        }
13333                        modelManager.DISPLAY_NAME.put(processModel.getId(), name);
13334                        return name;
13335                }
13336        }
13337
13338        private String getDisplayIdByType(String type) {
13339                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13340                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
13341                        return type + "-" + (option.getStartId() + 1);
13342                } else {
13343                        long id = modelManager.DISPLAY_ID.get(type);
13344                        modelManager.DISPLAY_ID.put(type, id + 1);
13345                        return type + "-" + (id + 1);
13346                }
13347        }
13348        
13349        private String getDisplayIdByTypeFromZero(String type) {
13350                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13351                        modelManager.DISPLAY_ID.put(type, option.getStartId());
13352                        if(option.getStartId() == 0) {
13353                                return type;
13354                        }
13355                        return type + "-" + (option.getStartId() + 1);
13356                } else {
13357                        long id = modelManager.DISPLAY_ID.get(type);
13358                        modelManager.DISPLAY_ID.put(type, id + 1);
13359                        return type + "-" + (id + 1);
13360                }
13361        }
13362
13363        private String getConstantName(Table tableModel) {
13364                if (modelManager.DISPLAY_NAME.containsKey(tableModel.getId())) {
13365                        return modelManager.DISPLAY_NAME.get(tableModel.getId());
13366                } else {
13367                        String name = getDisplayIdByType("SQL_CONSTANTS");
13368                        modelManager.DISPLAY_NAME.put(tableModel.getId(), name);
13369                        return name;
13370                }
13371        }
13372        
13373        private String getTempTableName(TTable table) {
13374                if (modelManager.DISPLAY_NAME.containsKey((long)System.identityHashCode(table))) {
13375                        return modelManager.DISPLAY_NAME.get((long)System.identityHashCode(table));
13376                } else {
13377                        String name = getDisplayIdByTypeFromZero(table.getName());
13378                        modelManager.DISPLAY_NAME.put((long)System.identityHashCode(table), name);
13379                        return name;
13380                }
13381        }
13382
13383        private String getResultSetName(ResultSet resultSetModel) {
13384
13385                if (modelManager.DISPLAY_NAME.containsKey(resultSetModel.getId())) {
13386                        return modelManager.DISPLAY_NAME.get(resultSetModel.getId());
13387                }
13388                
13389                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.array_t) {
13390                        String name = getResultSetDisplayId("ARRAY");
13391                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13392                        if(option.containsResultSetType(ResultSetType.array)) {
13393                                resultSetModel.setTarget(true);
13394                        }
13395                        return name;
13396                }
13397                
13398                if (resultSetModel.getGspObject() instanceof TFunctionCall && ((TFunctionCall)resultSetModel.getGspObject()).getFunctionType() == EFunctionType.struct_t) {
13399                        String name = getResultSetDisplayId("STRUCT");
13400                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13401                        if(option.containsResultSetType(ResultSetType.struct)) {
13402                                resultSetModel.setTarget(true);
13403                        }
13404                        return name;
13405                }
13406
13407                if (resultSetModel instanceof QueryTable) {
13408                        QueryTable table = (QueryTable) resultSetModel;
13409                        if (table.getAlias() != null && table.getAlias().trim().length() > 0) {
13410                                String name = getResultSetWithId("RESULT_OF_" + table.getAlias().trim());
13411                                if (table.getTableObject().getCTE() != null) {
13412                                        name = getResultSetWithId("RESULT_OF_" + table.getTableObject().getCTE().getTableName().toString()
13413                                                        + "_" + table.getAlias().trim());
13414                                }
13415                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13416                                if(option.containsResultSetType(ResultSetType.result_of)) {
13417                                        resultSetModel.setTarget(true);
13418                                }
13419                                return name;
13420                        } else if (table.getTableObject().getCTE() != null) {
13421                                String name = getResultSetWithId("CTE-" + table.getTableObject().getCTE().getTableName().toString());
13422                                modelManager.DISPLAY_NAME.put(table.getId(), name);
13423                                if(option.containsResultSetType(ResultSetType.cte)) {
13424                                        resultSetModel.setTarget(true);
13425                                }
13426                                return name;
13427                        }
13428                }
13429
13430                if (resultSetModel instanceof SelectResultSet) {
13431                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TInsertSqlStatement) {
13432                                String name = getResultSetDisplayId("INSERT-SELECT");
13433                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13434                                if(option.containsResultSetType(ResultSetType.insert_select)) {
13435                                        resultSetModel.setTarget(true);
13436                                }
13437                                return name;
13438                        }
13439
13440                        if (((SelectResultSet) resultSetModel).getSelectStmt().getParentStmt() instanceof TUpdateSqlStatement) {
13441                                String name = getResultSetDisplayId("UPDATE-SELECT");
13442                                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13443                                if(option.containsResultSetType(ResultSetType.update_select)) {
13444                                        resultSetModel.setTarget(true);
13445                                }
13446                                return name;
13447                        }
13448                }
13449
13450                if (resultSetModel instanceof SelectSetResultSet) {
13451                        ESetOperatorType type = ((SelectSetResultSet) resultSetModel).getSetOperatorType();
13452                        String name = getResultSetDisplayId("RESULT_OF_" + type.name().toUpperCase());
13453                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13454                        if(option.containsResultSetType(ResultSetType.result_of)) {
13455                                resultSetModel.setTarget(true);
13456                        }
13457                        return name;
13458                }
13459
13460                if (resultSetModel.getGspObject() instanceof TMergeUpdateClause) {
13461                        String name = getResultSetDisplayId("MERGE-UPDATE");
13462                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13463                        if(option.containsResultSetType(ResultSetType.merge_update)) {
13464                                resultSetModel.setTarget(true);
13465                        }
13466                        return name;
13467                }
13468
13469                if (resultSetModel.getGspObject() instanceof TOutputClause) {
13470                        String name = getResultSetDisplayId("OUTPUT");
13471                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13472                        if(option.containsResultSetType(ResultSetType.output)) {
13473                                resultSetModel.setTarget(true);
13474                        }
13475                        return name;
13476                }
13477
13478                if (resultSetModel.getGspObject() instanceof TMergeInsertClause) {
13479                        String name = getResultSetDisplayId("MERGE-INSERT");
13480                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13481                        if(option.containsResultSetType(ResultSetType.merge_insert)) {
13482                                resultSetModel.setTarget(true);
13483                        }
13484                        return name;
13485                }
13486
13487                if (resultSetModel.getGspObject() instanceof TUpdateSqlStatement) {
13488                        String name = getResultSetDisplayId("UPDATE-SET");
13489                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13490                        if(option.containsResultSetType(ResultSetType.update_set)) {
13491                                resultSetModel.setTarget(true);
13492                        }
13493                        return name;
13494                }
13495
13496                if (resultSetModel.getGspObject() instanceof TCaseExpression) {
13497                        String name = ((Function) resultSetModel).getFunctionName();
13498                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13499                        if (option.containsResultSetType(ResultSetType.case_when) || option.containsResultSetType(ResultSetType.function)) {
13500                                resultSetModel.setTarget(true);
13501                        }
13502                        return name;
13503                }
13504                
13505                if (resultSetModel.getGspObject() instanceof TFunctionCall || resultSetModel instanceof Function) {
13506                        String name = ((Function) resultSetModel).getFunctionName();
13507                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13508                        if(option.containsResultSetType(ResultSetType.function)) {
13509                                resultSetModel.setTarget(true);
13510                        }
13511                        return name;
13512                }
13513
13514                if (resultSetModel instanceof PivotedTable) {
13515                        String name = getResultSetDisplayId("PIVOT-TABLE");
13516                        if (((PivotedTable) resultSetModel).isUnpivoted()) {
13517                                name = getResultSetDisplayId("UNPIVOT-TABLE");
13518                                if(option.containsResultSetType(ResultSetType.unpivot_table)) {
13519                                        resultSetModel.setTarget(true);
13520                                }
13521                        }
13522                        else {
13523                                if(option.containsResultSetType(ResultSetType.pivot_table)) {
13524                                        resultSetModel.setTarget(true);
13525                                }
13526                        }
13527                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13528                        return name;
13529                }
13530
13531                if (resultSetModel instanceof Alias) {
13532                        String name = getResultSetDisplayId("ALIAS");
13533                        modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13534                        if(option.containsResultSetType(ResultSetType.alias)) {
13535                                resultSetModel.setTarget(true);
13536                        }
13537                        return name;
13538                }
13539
13540                String name = getResultSetDisplayId("RS");
13541                modelManager.DISPLAY_NAME.put(resultSetModel.getId(), name);
13542                if(option.containsResultSetType(ResultSetType.select_list)) {
13543                        resultSetModel.setTarget(true);
13544                }
13545                return name;
13546        }
13547
13548        private String getResultSetWithId(String type) {
13549                type = DlineageUtil.getIdentifierNormalTableName(type);
13550                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13551                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
13552                        return type + "-" + (option.getStartId() + 1);
13553                } else {
13554                        long id = modelManager.DISPLAY_ID.get(type);
13555                        modelManager.DISPLAY_ID.put(type, id + 1);
13556                        return type + "-" + (id + 1);
13557                }
13558        }
13559
13560        private String getResultSetDisplayId(String type) {
13561                if (!modelManager.DISPLAY_ID.containsKey(type)) {
13562                        modelManager.DISPLAY_ID.put(type, option.getStartId() + 1);
13563                        return type + "-" + (option.getStartId() + 1);
13564                } else {
13565                        long id = modelManager.DISPLAY_ID.get(type);
13566                        modelManager.DISPLAY_ID.put(type, id + 1);
13567                        return type + "-" + (id + 1);
13568                }
13569        }
13570
13571        private void appendViews(dataflow dataflow) {
13572                List<TCustomSqlStatement> views = modelManager.getViews();
13573                for (int i = 0; i < views.size(); i++) {
13574                        Table viewModel = (Table) modelManager.getViewModel(views.get(i));
13575                        if (!tableIds.contains(viewModel.getId())) {
13576                                appendViewModel(dataflow, viewModel);
13577                                tableIds.add(viewModel.getId());
13578                        }
13579                }
13580
13581                List<TTable> tables = modelManager.getBaseTables();
13582                for (int i = 0; i < tables.size(); i++) {
13583                        Object model = modelManager.getModel(tables.get(i));
13584                        if (model instanceof Table) {
13585                                Table tableModel = (Table) model;
13586                                if (tableModel.isView()) {
13587                                        if (!tableIds.contains(tableModel.getId())) {
13588                                                appendViewModel(dataflow, tableModel);
13589                                                tableIds.add(tableModel.getId());
13590                                        }
13591                                }
13592                        }
13593                }
13594
13595                List<Table> tableNames = modelManager.getTablesByName();
13596                for (int i = 0; i < tableNames.size(); i++) {
13597                        Table tableModel = tableNames.get(i);
13598                        if (tableModel.isView()) {
13599                                if (!tableIds.contains(tableModel.getId())) {
13600                                        appendViewModel(dataflow, tableModel);
13601                                        tableIds.add(tableModel.getId());
13602                                }
13603                        }
13604                }
13605        }
13606
13607        private void appendViewModel(dataflow dataflow, Table viewModel) {
13608                table viewElement = new table();
13609                viewElement.setId(String.valueOf(viewModel.getId()));
13610                if (!SQLUtil.isEmpty(viewModel.getDatabase())) {
13611                        viewElement.setDatabase(viewModel.getDatabase());
13612                }
13613                if (!SQLUtil.isEmpty(viewModel.getSchema())) {
13614                        viewElement.setSchema(viewModel.getSchema());
13615                }
13616                viewElement.setServer(viewModel.getServer());
13617                viewElement.setName(viewModel.getName());
13618                viewElement.setType("view");
13619                viewElement.setStarStmt(viewModel.getStarStmt());
13620
13621                if(viewModel.isFromDDL()){
13622                        viewElement.setFromDDL(String.valueOf(viewModel.isFromDDL()));
13623                }
13624
13625                if (viewModel.getStartPosition() != null && viewModel.getEndPosition() != null) {
13626                        viewElement.setCoordinate(convertCoordinate(viewModel.getStartPosition()) + ","
13627                                        + convertCoordinate(viewModel.getEndPosition()));
13628                }
13629                if (viewModel.getProcesses() != null) {
13630                        List<String> processIds = new ArrayList<String>();
13631                        for (Process process : viewModel.getProcesses()) {
13632                                processIds.add(String.valueOf(process.getId()));
13633                        }
13634                        viewElement.setProcessIds(processIds);
13635                }
13636                dataflow.getViews().add(viewElement);
13637
13638                List<TableColumn> columns = viewModel.getColumns();
13639
13640                if (containStarColumn(columns)) {
13641                        for (TableColumn column : columns) {
13642                                if (column.getName().endsWith("*")) {
13643                                        for (TableColumn starElement : columns) {
13644                                                if (starElement == column) {
13645                                                        continue;
13646                                                }
13647                                                TObjectName columnObject = starElement.getColumnObject();
13648                                                column.bindStarLinkColumn(columnObject);
13649                                        }
13650                                        if (viewModel.isCreateTable()) {
13651                                                column.setShowStar(false);
13652                                        }
13653                                }
13654                        }
13655                }
13656
13657                for (int j = 0; j < columns.size(); j++) {
13658                        TableColumn columnModel = (TableColumn) columns.get(j);
13659                        if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn()) {
13660                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
13661                                for (int k = 0; k < starLinkColumnList.size(); k++) {
13662                                        column columnElement = new column();
13663                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
13664                                        String columnName = starLinkColumnList.get(k);
13665                                        if (containStarColumn(columns, columnName)) {
13666                                                continue;
13667                                        }
13668                                        columnElement.setName(columnName);
13669                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13670                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13671                                                                + convertCoordinate(columnModel.getEndPosition()));
13672                                        }
13673                                        viewElement.getColumns().add(columnElement);
13674                                }
13675
13676                                if (columnModel.isShowStar()) {
13677                                        column columnElement = new column();
13678                                        columnElement.setId(String.valueOf(columnModel.getId()));
13679                                        columnElement.setName(columnModel.getName());
13680                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13681                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13682                                                                + convertCoordinate(columnModel.getEndPosition()));
13683                                        }
13684                                        viewElement.getColumns().add(columnElement);
13685                                }
13686
13687                        } else {
13688                                column columnElement = new column();
13689                                columnElement.setId(String.valueOf(columnModel.getId()));
13690                                columnElement.setName(columnModel.getName());
13691                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
13692                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13693                                                        + convertCoordinate(columnModel.getEndPosition()));
13694                                }
13695                                if(columnModel.isPseduo()) {
13696                                        columnElement.setSource("system");
13697                                }
13698                                viewElement.getColumns().add(columnElement);
13699                        }
13700                }
13701
13702                TableRelationRows relationRows = viewModel.getRelationRows();
13703                if (relationRows.hasRelation()) {
13704                        column relationRowsElement = new column();
13705                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13706                        relationRowsElement.setName(relationRows.getName());
13707                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13708                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13709                                                + convertCoordinate(relationRows.getEndPosition()));
13710                        }
13711                        relationRowsElement.setSource("system");
13712                        viewElement.getColumns().add(relationRowsElement);
13713                }
13714        }
13715
13716        private void appendStreamModel(dataflow dataflow, Table streamModel) {
13717                table streamElement = new table();
13718                streamElement.setId(String.valueOf(streamModel.getId()));
13719                if (!SQLUtil.isEmpty(streamModel.getDatabase())) {
13720                        streamElement.setDatabase(streamModel.getDatabase());
13721                }
13722                if (!SQLUtil.isEmpty(streamModel.getSchema())) {
13723                        streamElement.setSchema(streamModel.getSchema());
13724                }
13725                streamElement.setServer(streamModel.getServer());
13726                streamElement.setName(streamModel.getName());
13727                streamElement.setType("stream");
13728                if (streamModel.getFileType() != null) {
13729                        streamElement.setFileType(SQLUtil.trimColumnStringQuote(streamModel.getFileType()));
13730                }
13731
13732                if (streamModel.getStartPosition() != null && streamModel.getEndPosition() != null) {
13733                        streamElement.setCoordinate(convertCoordinate(streamModel.getStartPosition()) + ","
13734                                        + convertCoordinate(streamModel.getEndPosition()));
13735                }
13736
13737                if (streamModel.getProcesses() != null) {
13738                        List<String> processIds = new ArrayList<String>();
13739                        for (Process process : streamModel.getProcesses()) {
13740                                processIds.add(String.valueOf(process.getId()));
13741                        }
13742                        streamElement.setProcessIds(processIds);
13743                }
13744                dataflow.getStreams().add(streamElement);
13745
13746                List<TableColumn> columns = streamModel.getColumns();
13747
13748                for (int j = 0; j < columns.size(); j++) {
13749                        TableColumn columnModel = (TableColumn) columns.get(j);
13750                        column columnElement = new column();
13751                        columnElement.setId(String.valueOf(columnModel.getId()));
13752                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13753                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13754                                        + convertCoordinate(columnModel.getEndPosition()));
13755                        streamElement.getColumns().add(columnElement);
13756                }
13757
13758                TableRelationRows relationRows = streamModel.getRelationRows();
13759                if (relationRows.hasRelation()) {
13760                        column relationRowsElement = new column();
13761                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13762                        relationRowsElement.setName(relationRows.getName());
13763                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13764                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13765                                                + convertCoordinate(relationRows.getEndPosition()));
13766                        }
13767                        relationRowsElement.setSource("system");
13768                        streamElement.getColumns().add(relationRowsElement);
13769                }
13770        }
13771
13772        private void appendStageModel(dataflow dataflow, Table stageModel) {
13773                table stageElement = new table();
13774                stageElement.setId(String.valueOf(stageModel.getId()));
13775                if (!SQLUtil.isEmpty(stageModel.getDatabase())) {
13776                        stageElement.setDatabase(stageModel.getDatabase());
13777                }
13778                if (!SQLUtil.isEmpty(stageModel.getSchema())) {
13779                        stageElement.setSchema(stageModel.getSchema());
13780                }
13781                stageElement.setServer(stageModel.getServer());
13782                stageElement.setName(stageModel.getName());
13783                stageElement.setType("stage");
13784                stageElement.setLocation(stageModel.getLocation());
13785                if (stageModel.getFileType() != null) {
13786                        stageElement.setFileType(SQLUtil.trimColumnStringQuote(stageModel.getFileType()));
13787                }
13788
13789                if (stageModel.getStartPosition() != null && stageModel.getEndPosition() != null) {
13790                        stageElement.setCoordinate(convertCoordinate(stageModel.getStartPosition()) + ","
13791                                        + convertCoordinate(stageModel.getEndPosition()));
13792                }
13793
13794                if (stageModel.getProcesses() != null) {
13795                        List<String> processIds = new ArrayList<String>();
13796                        for (Process process : stageModel.getProcesses()) {
13797                                processIds.add(String.valueOf(process.getId()));
13798                        }
13799                        stageElement.setProcessIds(processIds);
13800                }
13801                dataflow.getStages().add(stageElement);
13802
13803                List<TableColumn> columns = stageModel.getColumns();
13804
13805                for (int j = 0; j < columns.size(); j++) {
13806                        TableColumn columnModel = (TableColumn) columns.get(j);
13807                        column columnElement = new column();
13808                        columnElement.setId(String.valueOf(columnModel.getId()));
13809                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13810                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13811                                        + convertCoordinate(columnModel.getEndPosition()));
13812                        stageElement.getColumns().add(columnElement);
13813                }
13814
13815                TableRelationRows relationRows = stageModel.getRelationRows();
13816                if (relationRows.hasRelation()) {
13817                        column relationRowsElement = new column();
13818                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13819                        relationRowsElement.setName(relationRows.getName());
13820                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13821                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13822                                                + convertCoordinate(relationRows.getEndPosition()));
13823                        }
13824                        relationRowsElement.setSource("system");
13825                        stageElement.getColumns().add(relationRowsElement);
13826                }
13827        }
13828
13829        private void appendSequenceModel(dataflow dataflow, Table sequenceModel) {
13830                table sequenceElement = new table();
13831                sequenceElement.setId(String.valueOf(sequenceModel.getId()));
13832                if (!SQLUtil.isEmpty(sequenceModel.getDatabase())) {
13833                        sequenceElement.setDatabase(sequenceModel.getDatabase());
13834                }
13835                if (!SQLUtil.isEmpty(sequenceModel.getSchema())) {
13836                        sequenceElement.setSchema(sequenceModel.getSchema());
13837                }
13838                sequenceElement.setServer(sequenceModel.getServer());
13839                sequenceElement.setName(sequenceModel.getName());
13840                sequenceElement.setType("sequence");
13841                sequenceElement.setLocation(sequenceModel.getLocation());
13842                if (sequenceModel.getFileType() != null) {
13843                        sequenceElement.setFileType(SQLUtil.trimColumnStringQuote(sequenceModel.getFileType()));
13844                }
13845
13846                if (sequenceModel.getStartPosition() != null && sequenceModel.getEndPosition() != null) {
13847                        sequenceElement.setCoordinate(convertCoordinate(sequenceModel.getStartPosition()) + ","
13848                                        + convertCoordinate(sequenceModel.getEndPosition()));
13849                }
13850
13851                if (sequenceModel.getProcesses() != null) {
13852                        List<String> processIds = new ArrayList<String>();
13853                        for (Process process : sequenceModel.getProcesses()) {
13854                                processIds.add(String.valueOf(process.getId()));
13855                        }
13856                        sequenceElement.setProcessIds(processIds);
13857                }
13858                dataflow.getSequences().add(sequenceElement);
13859
13860                List<TableColumn> columns = sequenceModel.getColumns();
13861
13862                for (int j = 0; j < columns.size(); j++) {
13863                        TableColumn columnModel = (TableColumn) columns.get(j);
13864                        column columnElement = new column();
13865                        columnElement.setId(String.valueOf(columnModel.getId()));
13866                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13867                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13868                                        + convertCoordinate(columnModel.getEndPosition()));
13869                        sequenceElement.getColumns().add(columnElement);
13870                }
13871
13872                TableRelationRows relationRows = sequenceModel.getRelationRows();
13873                if (relationRows.hasRelation()) {
13874                        column relationRowsElement = new column();
13875                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13876                        relationRowsElement.setName(relationRows.getName());
13877                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13878                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13879                                                + convertCoordinate(relationRows.getEndPosition()));
13880                        }
13881                        relationRowsElement.setSource("system");
13882                        sequenceElement.getColumns().add(relationRowsElement);
13883                }
13884        }
13885
13886        private void appendDataSourceModel(dataflow dataflow, Table datasourceModel) {
13887                table datasourceElement = new table();
13888                datasourceElement.setId(String.valueOf(datasourceModel.getId()));
13889                if (!SQLUtil.isEmpty(datasourceModel.getDatabase())) {
13890                        datasourceElement.setDatabase(datasourceModel.getDatabase());
13891                }
13892                if (!SQLUtil.isEmpty(datasourceModel.getSchema())) {
13893                        datasourceElement.setSchema(datasourceModel.getSchema());
13894                }
13895                datasourceElement.setServer(datasourceModel.getServer());
13896                datasourceElement.setName(datasourceModel.getName());
13897                datasourceElement.setType("datasource");
13898                datasourceElement.setLocation(datasourceModel.getLocation());
13899                if (datasourceModel.getFileType() != null) {
13900                        datasourceElement.setFileType(SQLUtil.trimColumnStringQuote(datasourceModel.getFileType()));
13901                }
13902
13903                if (datasourceModel.getStartPosition() != null && datasourceModel.getEndPosition() != null) {
13904                        datasourceElement.setCoordinate(convertCoordinate(datasourceModel.getStartPosition()) + ","
13905                                        + convertCoordinate(datasourceModel.getEndPosition()));
13906                }
13907
13908                if (datasourceModel.getProcesses() != null) {
13909                        List<String> processIds = new ArrayList<String>();
13910                        for (Process process : datasourceModel.getProcesses()) {
13911                                processIds.add(String.valueOf(process.getId()));
13912                        }
13913                        datasourceElement.setProcessIds(processIds);
13914                }
13915                dataflow.getDatasources().add(datasourceElement);
13916
13917                List<TableColumn> columns = datasourceModel.getColumns();
13918
13919                for (int j = 0; j < columns.size(); j++) {
13920                        TableColumn columnModel = (TableColumn) columns.get(j);
13921                        column columnElement = new column();
13922                        columnElement.setId(String.valueOf(columnModel.getId()));
13923                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13924                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13925                                        + convertCoordinate(columnModel.getEndPosition()));
13926                        datasourceElement.getColumns().add(columnElement);
13927                }
13928
13929                TableRelationRows relationRows = datasourceModel.getRelationRows();
13930                if (relationRows.hasRelation()) {
13931                        column relationRowsElement = new column();
13932                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13933                        relationRowsElement.setName(relationRows.getName());
13934                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13935                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13936                                                + convertCoordinate(relationRows.getEndPosition()));
13937                        }
13938                        relationRowsElement.setSource("system");
13939                        datasourceElement.getColumns().add(relationRowsElement);
13940                }
13941        }
13942
13943        private void appendDatabaseModel(dataflow dataflow, Table databaseModel) {
13944                table databaseElement = new table();
13945                databaseElement.setId(String.valueOf(databaseModel.getId()));
13946                if (!SQLUtil.isEmpty(databaseModel.getDatabase())) {
13947                        databaseElement.setDatabase(databaseModel.getDatabase());
13948                }
13949                if (!SQLUtil.isEmpty(databaseModel.getSchema())) {
13950                        databaseElement.setSchema(databaseModel.getSchema());
13951                }
13952                databaseElement.setServer(databaseModel.getServer());
13953                databaseElement.setName(databaseModel.getName());
13954                databaseElement.setType("database");
13955                if (databaseModel.getFileType() != null) {
13956                        databaseElement.setFileType(SQLUtil.trimColumnStringQuote(databaseModel.getFileType()));
13957                }
13958
13959                if (databaseModel.getStartPosition() != null && databaseModel.getEndPosition() != null) {
13960                        databaseElement.setCoordinate(convertCoordinate(databaseModel.getStartPosition()) + ","
13961                                        + convertCoordinate(databaseModel.getEndPosition()));
13962                }
13963
13964                if (databaseModel.getProcesses() != null) {
13965                        List<String> processIds = new ArrayList<String>();
13966                        for (Process process : databaseModel.getProcesses()) {
13967                                processIds.add(String.valueOf(process.getId()));
13968                        }
13969                        databaseElement.setProcessIds(processIds);
13970                }
13971                dataflow.getDatabases().add(databaseElement);
13972
13973                List<TableColumn> columns = databaseModel.getColumns();
13974
13975                for (int j = 0; j < columns.size(); j++) {
13976                        TableColumn columnModel = (TableColumn) columns.get(j);
13977                        column columnElement = new column();
13978                        columnElement.setId(String.valueOf(columnModel.getId()));
13979                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
13980                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
13981                                        + convertCoordinate(columnModel.getEndPosition()));
13982                        databaseElement.getColumns().add(columnElement);
13983                }
13984
13985                TableRelationRows relationRows = databaseModel.getRelationRows();
13986                if (relationRows.hasRelation()) {
13987                        column relationRowsElement = new column();
13988                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
13989                        relationRowsElement.setName(relationRows.getName());
13990                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
13991                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
13992                                                + convertCoordinate(relationRows.getEndPosition()));
13993                        }
13994                        relationRowsElement.setSource("system");
13995                        databaseElement.getColumns().add(relationRowsElement);
13996                }
13997        }
13998
13999        private void appendSchemaModel(dataflow dataflow, Table schemaModel) {
14000                table schemaElement = new table();
14001                schemaElement.setId(String.valueOf(schemaModel.getId()));
14002                if (!SQLUtil.isEmpty(schemaModel.getDatabase())) {
14003                        schemaElement.setDatabase(schemaModel.getDatabase());
14004                }
14005                if (!SQLUtil.isEmpty(schemaModel.getSchema())) {
14006                        schemaElement.setSchema(schemaModel.getSchema());
14007                }
14008                schemaElement.setServer(schemaModel.getServer());
14009                schemaElement.setName(schemaModel.getName());
14010                schemaElement.setType("schema");
14011                if (schemaModel.getFileType() != null) {
14012                        schemaElement.setFileType(SQLUtil.trimColumnStringQuote(schemaModel.getFileType()));
14013                }
14014
14015                if (schemaModel.getStartPosition() != null && schemaModel.getEndPosition() != null) {
14016                        schemaElement.setCoordinate(convertCoordinate(schemaModel.getStartPosition()) + ","
14017                                        + convertCoordinate(schemaModel.getEndPosition()));
14018                }
14019
14020                if (schemaModel.getProcesses() != null) {
14021                        List<String> processIds = new ArrayList<String>();
14022                        for (Process process : schemaModel.getProcesses()) {
14023                                processIds.add(String.valueOf(process.getId()));
14024                        }
14025                        schemaElement.setProcessIds(processIds);
14026                }
14027                dataflow.getSchemas().add(schemaElement);
14028
14029                List<TableColumn> columns = schemaModel.getColumns();
14030
14031                for (int j = 0; j < columns.size(); j++) {
14032                        TableColumn columnModel = (TableColumn) columns.get(j);
14033                        column columnElement = new column();
14034                        columnElement.setId(String.valueOf(columnModel.getId()));
14035                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
14036                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14037                                        + convertCoordinate(columnModel.getEndPosition()));
14038                        schemaElement.getColumns().add(columnElement);
14039                }
14040
14041                TableRelationRows relationRows = schemaModel.getRelationRows();
14042                if (relationRows.hasRelation()) {
14043                        column relationRowsElement = new column();
14044                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14045                        relationRowsElement.setName(relationRows.getName());
14046                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14047                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14048                                                + convertCoordinate(relationRows.getEndPosition()));
14049                        }
14050                        relationRowsElement.setSource("system");
14051                        schemaElement.getColumns().add(relationRowsElement);
14052                }
14053        }
14054
14055        private void appendPathModel(dataflow dataflow, Table pathModel) {
14056                table pathElement = new table();
14057                pathElement.setId(String.valueOf(pathModel.getId()));
14058                if (!SQLUtil.isEmpty(pathModel.getDatabase())) {
14059                        pathElement.setDatabase(pathModel.getDatabase());
14060                }
14061                if (!SQLUtil.isEmpty(pathModel.getSchema())) {
14062                        pathElement.setSchema(pathModel.getSchema());
14063                }
14064                pathElement.setServer(pathModel.getServer());
14065                pathElement.setName(pathModel.getName());
14066                pathElement.setType("path");
14067                if (pathModel.getFileFormat() != null) {
14068                        pathElement.setFileFormat(SQLUtil.trimColumnStringQuote(pathModel.getFileFormat()));
14069                }
14070
14071                if (pathModel.getStartPosition() != null && pathModel.getEndPosition() != null) {
14072                        pathElement.setCoordinate(convertCoordinate(pathModel.getStartPosition()) + ","
14073                                        + convertCoordinate(pathModel.getEndPosition()));
14074                }
14075
14076                if (pathModel.getProcesses() != null) {
14077                        List<String> processIds = new ArrayList<String>();
14078                        for (Process process : pathModel.getProcesses()) {
14079                                processIds.add(String.valueOf(process.getId()));
14080                        }
14081                        pathElement.setProcessIds(processIds);
14082                }
14083
14084                pathElement.setUri(pathModel.getName());
14085
14086                dataflow.getPaths().add(pathElement);
14087
14088                List<TableColumn> columns = pathModel.getColumns();
14089
14090                for (int j = 0; j < columns.size(); j++) {
14091                        TableColumn columnModel = (TableColumn) columns.get(j);
14092                        column columnElement = new column();
14093                        columnElement.setId(String.valueOf(columnModel.getId()));
14094                        columnElement.setName(SQLUtil.trimColumnStringQuote(columnModel.getName()));
14095                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14096                                        + convertCoordinate(columnModel.getEndPosition()));
14097                        pathElement.getColumns().add(columnElement);
14098                }
14099
14100                TableRelationRows relationRows = pathModel.getRelationRows();
14101                if (relationRows.hasRelation()) {
14102                        column relationRowsElement = new column();
14103                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14104                        relationRowsElement.setName(relationRows.getName());
14105                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14106                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14107                                                + convertCoordinate(relationRows.getEndPosition()));
14108                        }
14109                        relationRowsElement.setSource("system");
14110                        pathElement.getColumns().add(relationRowsElement);
14111                }
14112        }
14113
14114        private void appendVariableModel(dataflow dataflow, Table variableModel) {
14115                table variableElement = new table();
14116                variableElement.setId(String.valueOf(variableModel.getId()));
14117                if (!SQLUtil.isEmpty(variableModel.getDatabase())) {
14118                        variableElement.setDatabase(variableModel.getDatabase());
14119                }
14120                if (!SQLUtil.isEmpty(variableModel.getSchema())) {
14121                        variableElement.setSchema(variableModel.getSchema());
14122                }
14123                variableElement.setServer(variableModel.getServer());
14124                variableElement.setName(variableModel.getName());
14125                variableElement.setType("variable");
14126                variableElement.setParent(variableModel.getParent());
14127                if (variableModel.getSubType() != null) {
14128                        variableElement.setSubType(variableModel.getSubType().name());
14129                }
14130
14131                if (variableModel.getStartPosition() != null && variableModel.getEndPosition() != null) {
14132                        variableElement.setCoordinate(convertCoordinate(variableModel.getStartPosition()) + ","
14133                                        + convertCoordinate(variableModel.getEndPosition()));
14134                }
14135                dataflow.getVariables().add(variableElement);
14136
14137                List<TableColumn> columns = variableModel.getColumns();
14138
14139                if (containStarColumn(columns)) {
14140                        for (TableColumn column : columns) {
14141                                if (column.getName().endsWith("*")) {
14142                                        for (TableColumn starElement : columns) {
14143                                                if (starElement == column) {
14144                                                        continue;
14145                                                }
14146                                                TObjectName columnObject = starElement.getColumnObject();
14147                                                column.bindStarLinkColumn(columnObject);
14148                                        }
14149//                                      column.setShowStar(false);
14150                                }
14151                        }
14152                }
14153
14154                for (int j = 0; j < columns.size(); j++) {
14155                        TableColumn columnModel = columns.get(j);
14156                        if (columnModel.hasStarLinkColumn()) {
14157                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
14158                                for (int k = 0; k < starLinkColumnList.size(); k++) {
14159                                        column columnElement = new column();
14160                                        columnElement.setId(columnModel.getId() + "_" + k);
14161                                        String columnName = starLinkColumnList.get(k);
14162                                        if (containStarColumn(columns, columnName)) {
14163                                                continue;
14164                                        }
14165                                        columnElement.setName(columnName);
14166                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14167                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14168                                                                + convertCoordinate(columnModel.getEndPosition()));
14169                                        }
14170                                        variableElement.getColumns().add(columnElement);
14171                                }
14172
14173                                if (columnModel.isShowStar()) {
14174                                        column columnElement = new column();
14175                                        columnElement.setId(String.valueOf(columnModel.getId()));
14176                                        columnElement.setName(columnModel.getName());
14177                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14178                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14179                                                                + convertCoordinate(columnModel.getEndPosition()));
14180                                        }
14181                                        variableElement.getColumns().add(columnElement);
14182                                }
14183
14184                        } else {
14185                                column columnElement = new column();
14186                                columnElement.setId(String.valueOf(columnModel.getId()));
14187                                columnElement.setName(columnModel.getName());
14188                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14189                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14190                                                        + convertCoordinate(columnModel.getEndPosition()));
14191                                }
14192                                variableElement.getColumns().add(columnElement);
14193                        }
14194                }
14195
14196                TableRelationRows relationRows = variableModel.getRelationRows();
14197                if (relationRows.hasRelation()) {
14198                        column relationRowsElement = new column();
14199                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14200                        relationRowsElement.setName(relationRows.getName());
14201                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14202                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14203                                                + convertCoordinate(relationRows.getEndPosition()));
14204                        }
14205                        relationRowsElement.setSource("system");
14206                        variableElement.getColumns().add(relationRowsElement);
14207                }
14208        }
14209
14210        private void appendCursorModel(dataflow dataflow, Table cursorModel) {
14211                table cursorElement = new table();
14212                cursorElement.setId(String.valueOf(cursorModel.getId()));
14213                if (!SQLUtil.isEmpty(cursorModel.getDatabase())) {
14214                        cursorElement.setDatabase(cursorModel.getDatabase());
14215                }
14216                if (!SQLUtil.isEmpty(cursorModel.getSchema())) {
14217                        cursorElement.setSchema(cursorModel.getSchema());
14218                }
14219                cursorElement.setServer(cursorModel.getServer());
14220                cursorElement.setName(cursorModel.getName());
14221                cursorElement.setType("variable");
14222                if (cursorElement.getSubType() != null) {
14223                        cursorElement.setSubType(cursorModel.getSubType().name());
14224                }
14225
14226                if (cursorModel.getStartPosition() != null && cursorModel.getEndPosition() != null) {
14227                        cursorElement.setCoordinate(convertCoordinate(cursorModel.getStartPosition()) + ","
14228                                        + convertCoordinate(cursorModel.getEndPosition()));
14229                }
14230                dataflow.getVariables().add(cursorElement);
14231
14232                List<TableColumn> columns = cursorModel.getColumns();
14233
14234                if (containStarColumn(columns)) {
14235                        for (TableColumn column : columns) {
14236                                if (column.getName().endsWith("*")) {
14237                                        for (TableColumn starElement : columns) {
14238                                                if (starElement == column) {
14239                                                        continue;
14240                                                }
14241                                                TObjectName columnObject = starElement.getColumnObject();
14242                                                column.bindStarLinkColumn(columnObject);
14243                                        }
14244                                        column.setShowStar(false);
14245                                }
14246                        }
14247                }
14248
14249                for (int j = 0; j < columns.size(); j++) {
14250                        TableColumn columnModel = (TableColumn) columns.get(j);
14251                        if (columnModel.hasStarLinkColumn()) {
14252                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
14253                                for (int k = 0; k < starLinkColumnList.size(); k++) {
14254                                        column columnElement = new column();
14255                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
14256                                        String columnName = starLinkColumnList.get(k);
14257                                        if (containStarColumn(columns, columnName)) {
14258                                                continue;
14259                                        }
14260                                        columnElement.setName(columnName);
14261                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14262                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14263                                                                + convertCoordinate(columnModel.getEndPosition()));
14264                                        }
14265                                        cursorElement.getColumns().add(columnElement);
14266                                }
14267
14268                                if (columnModel.isShowStar()) {
14269                                        column columnElement = new column();
14270                                        columnElement.setId(String.valueOf(columnModel.getId()));
14271                                        columnElement.setName(columnModel.getName());
14272                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14273                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14274                                                                + convertCoordinate(columnModel.getEndPosition()));
14275                                        }
14276                                        cursorElement.getColumns().add(columnElement);
14277                                }
14278
14279                        } else {
14280                                column columnElement = new column();
14281                                columnElement.setId(String.valueOf(columnModel.getId()));
14282                                columnElement.setName(columnModel.getName());
14283                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14284                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14285                                                        + convertCoordinate(columnModel.getEndPosition()));
14286                                }
14287                                cursorElement.getColumns().add(columnElement);
14288                        }
14289                }
14290
14291                TableRelationRows relationRows = cursorModel.getRelationRows();
14292                if (relationRows.hasRelation()) {
14293                        column relationRowsElement = new column();
14294                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14295                        relationRowsElement.setName(relationRows.getName());
14296                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14297                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14298                                                + convertCoordinate(relationRows.getEndPosition()));
14299                        }
14300                        relationRowsElement.setSource("system");
14301                        cursorElement.getColumns().add(relationRowsElement);
14302                }
14303        }
14304
14305        private void appendErrors(dataflow dataflow) {
14306                List<ErrorInfo> errorInfos = this.getErrorMessages();
14307                if (metadataErrors != null) {
14308                        for (int i = 0; i < metadataErrors.size(); i++) {
14309                                errorInfos.add(i, metadataErrors.get(i));
14310                        }
14311                }
14312
14313                for (int i = 0; i < errorInfos.size(); ++i) {
14314                        ErrorInfo errorInfo = errorInfos.get(i);
14315                        error error = new error();
14316                        if (!SQLUtil.isEmpty(errorInfo.getErrorMessage())) {
14317                                error.setErrorMessage(errorInfo.getErrorMessage());
14318                        }
14319                        if (!SQLUtil.isEmpty(errorInfo.getErrorType())) {
14320                                error.setErrorType(errorInfo.getErrorType());
14321                        }
14322                        if (errorInfo.getStartPosition() != null && errorInfo.getEndPosition() != null) {
14323                                error.setCoordinate(convertCoordinate(errorInfo.getStartPosition()) + ","
14324                                                + convertCoordinate(errorInfo.getEndPosition()));
14325                        }
14326                        if (!SQLUtil.isEmpty(errorInfo.getFileName())) {
14327                                error.setFile(errorInfo.getFileName());
14328                        }
14329                        if (errorInfo.getOriginStartPosition() != null && errorInfo.getOriginEndPosition() != null) {
14330                                error.setOriginCoordinate(errorInfo.getOriginStartPosition() + "," + errorInfo.getOriginEndPosition());
14331                        }
14332                        dataflow.getErrors().add(error);
14333                }
14334        }
14335
14336        private void appendOraclePackages(dataflow dataflow) {
14337                List<OraclePackage> packages = this.modelManager.getOraclePackageModels();
14338
14339                for (int i = 0; i < packages.size(); ++i) {
14340                        OraclePackage model = packages.get(i);
14341                        oraclePackage oraclePackage = new oraclePackage();
14342                        oraclePackage.setId(String.valueOf(model.getId()));
14343                        if (!SQLUtil.isEmpty(model.getDatabase())) {
14344                                oraclePackage.setDatabase(model.getDatabase());
14345                        }
14346                        if (!SQLUtil.isEmpty(model.getSchema())) {
14347                                oraclePackage.setSchema(model.getSchema());
14348                        }
14349                        oraclePackage.setServer(model.getServer());
14350                        oraclePackage.setName(model.getName());
14351                        if (model.getType() != null) {
14352                                oraclePackage.setType(model.getType().name().replace("sst", ""));
14353                        }
14354                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
14355                                oraclePackage.setCoordinate(
14356                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
14357                        }
14358
14359                        dataflow.getPackages().add(oraclePackage);
14360
14361                        List<Argument> arguments = model.getArguments();
14362
14363                        for (int j = 0; j < arguments.size(); ++j) {
14364                                Argument argumentModel = (Argument) arguments.get(j);
14365                                argument argumentElement = new argument();
14366                                argumentElement.setId(String.valueOf(argumentModel.getId()));
14367                                argumentElement.setName(argumentModel.getName());
14368                                if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
14369                                        argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
14370                                                        + convertCoordinate(argumentModel.getEndPosition()));
14371                                }
14372
14373                                argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
14374                                argumentElement.setInout(argumentModel.getMode().name());
14375                                oraclePackage.getArguments().add(argumentElement);
14376                        }
14377
14378                        for (int j = 0; j < model.getProcedures().size(); j++) {
14379                                Procedure procedureModel = model.getProcedures().get(j);
14380                                procedure procedure = new procedure();
14381                                procedure.setId(String.valueOf(procedureModel.getId()));
14382                                if (!SQLUtil.isEmpty(procedureModel.getDatabase())) {
14383                                        procedure.setDatabase(procedureModel.getDatabase());
14384                                }
14385                                if (!SQLUtil.isEmpty(procedureModel.getSchema())) {
14386                                        procedure.setSchema(procedureModel.getSchema());
14387                                }
14388                                procedure.setServer(procedureModel.getServer());
14389                                procedure.setName(procedureModel.getName());
14390                                if (procedureModel.getType() != null) {
14391                                        procedure.setType(procedureModel.getType().name().replace("sst", ""));
14392                                }
14393                                if (procedureModel.getStartPosition() != null && procedureModel.getEndPosition() != null) {
14394                                        procedure.setCoordinate(convertCoordinate(procedureModel.getStartPosition()) + ","
14395                                                        + convertCoordinate(procedureModel.getEndPosition()));
14396                                }
14397
14398                                oraclePackage.getProcedures().add(procedure);
14399
14400                                List<Argument> procedureArguments = procedureModel.getArguments();
14401
14402                                for (int k = 0; k < procedureArguments.size(); ++k) {
14403                                        Argument argumentModel = (Argument) procedureArguments.get(k);
14404                                        argument argumentElement = new argument();
14405                                        argumentElement.setId(String.valueOf(argumentModel.getId()));
14406                                        argumentElement.setName(argumentModel.getName());
14407                                        if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
14408                                                argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
14409                                                                + convertCoordinate(argumentModel.getEndPosition()));
14410                                        }
14411
14412                                        argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
14413                                        argumentElement.setInout(argumentModel.getMode().name());
14414                                        procedure.getArguments().add(argumentElement);
14415                                }
14416                        }
14417                }
14418        }
14419
14420        private void appendProcedures(dataflow dataflow) {
14421                List<Procedure> procedures = this.modelManager.getProcedureModels();
14422
14423                for (int i = 0; i < procedures.size(); ++i) {
14424                        Procedure model = procedures.get(i);
14425                        if (model.getParentPackage() != null) {
14426                                continue;
14427                        }
14428                        procedure procedure = new procedure();
14429                        procedure.setId(String.valueOf(model.getId()));
14430                        if (!SQLUtil.isEmpty(model.getDatabase())) {
14431                                procedure.setDatabase(model.getDatabase());
14432                        }
14433                        if (!SQLUtil.isEmpty(model.getSchema())) {
14434                                procedure.setSchema(model.getSchema());
14435                        }
14436                        procedure.setServer(model.getServer());
14437                        procedure.setName(model.getName());
14438                        if (model.getType() != null) {
14439                                procedure.setType(model.getType().name().replace("sst", ""));
14440                        }
14441                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
14442                                procedure.setCoordinate(
14443                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
14444                        }
14445
14446                        dataflow.getProcedures().add(procedure);
14447
14448                        List<Argument> arguments = model.getArguments();
14449
14450                        for (int j = 0; j < arguments.size(); ++j) {
14451                                Argument argumentModel = (Argument) arguments.get(j);
14452                                argument argumentElement = new argument();
14453                                argumentElement.setId(String.valueOf(argumentModel.getId()));
14454                                argumentElement.setName(argumentModel.getName());
14455                                if (argumentModel.getStartPosition() != null && argumentModel.getEndPosition() != null) {
14456                                        argumentElement.setCoordinate(convertCoordinate(argumentModel.getStartPosition()) + ","
14457                                                        + convertCoordinate(argumentModel.getEndPosition()));
14458                                }
14459
14460                                argumentElement.setDatatype(argumentModel.getDataType().getDataTypeName());
14461                                argumentElement.setInout(argumentModel.getMode().name());
14462                                procedure.getArguments().add(argumentElement);
14463                        }
14464                }
14465        }
14466
14467        private void appendProcesses(dataflow dataflow) {
14468                List<Process> processes = this.modelManager.getProcessModels();
14469
14470                for (int i = 0; i < processes.size(); ++i) {
14471                        Process model = processes.get(i);
14472                        process process = new process();
14473                        process.setId(String.valueOf(model.getId()));
14474                        if (!SQLUtil.isEmpty(model.getDatabase())) {
14475                                process.setDatabase(model.getDatabase());
14476                        }
14477                        if (!SQLUtil.isEmpty(model.getSchema())) {
14478                                process.setSchema(model.getSchema());
14479                        }
14480                        process.setServer(model.getServer());
14481                        process.setName(getProcessName(model));
14482                        if (!SQLUtil.isEmpty(model.getProcedureName())) {
14483                                process.setProcedureName(model.getProcedureName());
14484                        }
14485                        if (model.getProcedureId() != null) {
14486                                process.setProcedureId(String.valueOf(model.getProcedureId()));
14487                        }
14488                        if (!SQLUtil.isEmpty(model.getQueryHashId())) {
14489                                process.setQueryHashId(model.getQueryHashId());
14490                        }
14491                        if (model.getGspObject() != null) {
14492                                process.setType(model.getGspObject().sqlstatementtype.name());
14493                        }
14494                        if (model.getStartPosition() != null && model.getEndPosition() != null) {
14495                                process.setCoordinate(
14496                                                convertCoordinate(model.getStartPosition()) + "," + convertCoordinate(model.getEndPosition()));
14497                        }
14498                        if (model.getTransforms() != null && !model.getTransforms().isEmpty()) {
14499                                for (Transform transformItem : model.getTransforms()) {
14500                                        process.addTransform(transformItem);
14501                                }
14502                        }
14503                        dataflow.getProcesses().add(process);
14504                }
14505        }
14506
14507        private void appendTables(dataflow dataflow) {
14508                List<TTable> tables = modelManager.getBaseTables();
14509                Map<String, table> tableMap = new HashMap<String, table>();
14510                Set<Long> tableModelIds = new HashSet<Long>();
14511                for (int i = 0; i < tables.size(); i++) {
14512                        Object model = modelManager.getModel(tables.get(i));
14513                        if (model instanceof Table) {
14514                                Table tableModel = (Table) model;
14515                                if(tableModelIds.contains(tableModel.getId())) {
14516                                        continue;
14517                                }
14518                                else {
14519                                        tableModelIds.add(tableModel.getId());
14520                                }
14521                                if (tableModel.isView()) {
14522                                        continue;
14523                                }
14524                                if (tableModel.isStage()) {
14525                                        appendStageModel(dataflow, tableModel);
14526                                        continue;
14527                                }
14528                                if (tableModel.isSequence()) {
14529                                        appendSequenceModel(dataflow, tableModel);
14530                                        continue;
14531                                }
14532                                if (tableModel.isDataSource()) {
14533                                        appendDataSourceModel(dataflow, tableModel);
14534                                        continue;
14535                                }
14536                                if (tableModel.isDatabase()) {
14537                                        appendDatabaseModel(dataflow, tableModel);
14538                                        continue;
14539                                }
14540                                if (tableModel.isSchema()) {
14541                                        appendSchemaModel(dataflow, tableModel);
14542                                        continue;
14543                                }
14544                                if (tableModel.isStream()) {
14545                                        appendStreamModel(dataflow, tableModel);
14546                                        continue;
14547                                }
14548                                if (tableModel.isPath()) {
14549                                        appendPathModel(dataflow, tableModel);
14550                                        continue;
14551                                }
14552                                if (tableModel.isVariable() && !tableModel.isCursor()) {
14553                                        appendVariableModel(dataflow, tableModel);
14554                                        continue;
14555                                }
14556                                if (tableModel.isCursor()) {
14557                                        appendCursorModel(dataflow, tableModel);
14558                                        continue;
14559                                }
14560                                if (tableModel.isConstant()) {
14561                                        appendConstantModel(dataflow, tableModel);
14562                                        continue;
14563                                }
14564                                if (!tableIds.contains(tableModel.getId())) {
14565                                        appendTableModel(dataflow, tableModel, tableMap);
14566                                        tableIds.add(tableModel.getId());
14567                                }
14568                        } else if (model instanceof QueryTable) {
14569                                QueryTable queryTable = (QueryTable) model;
14570                                if (!tableIds.contains(queryTable.getId())) {
14571                                        appendResultSet(dataflow, queryTable);
14572                                        tableIds.add(queryTable.getId());
14573                                }
14574                        }
14575                }
14576
14577                List<Table> tableNames = modelManager.getTablesByName();
14578                tableNames.addAll(modelManager.getDropTables());
14579                
14580                for (int i = 0; i < tableNames.size(); i++) {
14581                        Table tableModel = tableNames.get(i);
14582                        if(tableModelIds.contains(tableModel.getId())) {
14583                                continue;
14584                        }
14585                        else {
14586                                tableModelIds.add(tableModel.getId());
14587                        }
14588                        if (tableModel.isView()) {
14589                                continue;
14590                        }
14591                        if (tableModel.isDatabase()) {
14592                                appendDatabaseModel(dataflow, tableModel);
14593                                continue;
14594                        }
14595                        if (tableModel.isSchema()) {
14596                                appendSchemaModel(dataflow, tableModel);
14597                                continue;
14598                        }
14599                        if (tableModel.isStage()) {
14600                                appendStageModel(dataflow, tableModel);
14601                                continue;
14602                        }
14603                        if (tableModel.isSequence()) {
14604                                appendSequenceModel(dataflow, tableModel);
14605                                continue;
14606                        }
14607                        if (tableModel.isDataSource()) {
14608                                appendDataSourceModel(dataflow, tableModel);
14609                                continue;
14610                        }
14611                        if (tableModel.isStream()) {
14612                                appendStreamModel(dataflow, tableModel);
14613                                continue;
14614                        }
14615                        if (tableModel.isPath()) {
14616                                appendPathModel(dataflow, tableModel);
14617                                continue;
14618                        }
14619                        if (tableModel.isVariable()) {
14620                                appendVariableModel(dataflow, tableModel);
14621                                continue;
14622                        }
14623                        if (tableModel.isCursor()) {
14624                                appendCursorModel(dataflow, tableModel);
14625                                continue;
14626                        }
14627                        if (tableModel.isConstant()) {
14628                                appendConstantModel(dataflow, tableModel);
14629                                continue;
14630                        }
14631                        if (!tableIds.contains(tableModel.getId())) {
14632                                appendTableModel(dataflow, tableModel, tableMap);
14633                                tableIds.add(tableModel.getId());
14634                        }
14635                }
14636        }
14637
14638        private void appendConstantModel(dataflow dataflow, Table tableModel) {
14639                table constantElement = new table();
14640                constantElement.setId(String.valueOf(tableModel.getId()));
14641                if (!SQLUtil.isEmpty(tableModel.getDatabase())) {
14642                        constantElement.setDatabase(tableModel.getDatabase());
14643                }
14644                if (!SQLUtil.isEmpty(tableModel.getSchema())) {
14645                        constantElement.setSchema(tableModel.getSchema());
14646                }
14647                constantElement.setServer(tableModel.getServer());
14648                constantElement.setName(getConstantName(tableModel));
14649                constantElement.setType("constantTable");
14650
14651                if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) {
14652                        constantElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + ","
14653                                        + convertCoordinate(tableModel.getEndPosition()));
14654                }
14655                dataflow.getTables().add(constantElement);
14656
14657                List<TableColumn> columns = tableModel.getColumns();
14658                for (int j = 0; j < columns.size(); j++) {
14659                        TableColumn columnModel = (TableColumn) columns.get(j);
14660                        column columnElement = new column();
14661                        columnElement.setId(String.valueOf(columnModel.getId()));
14662                        columnElement.setName(columnModel.getName());
14663                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14664                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14665                                                + convertCoordinate(columnModel.getEndPosition()));
14666                        }
14667                        constantElement.getColumns().add(columnElement);
14668                }
14669        }
14670
14671        private void appendTableModel(dataflow dataflow, Table tableModel, Map<String, table> tableMap) {
14672                if(tableModel.getSubType() == SubType.unnest) {}
14673                table tableElement = new table();
14674                tableElement.setId(String.valueOf(tableModel.getId()));
14675                if (!SQLUtil.isEmpty(tableModel.getDatabase())) {
14676                        tableElement.setDatabase(tableModel.getDatabase());
14677                }
14678                if (!SQLUtil.isEmpty(tableModel.getSchema())) {
14679                        tableElement.setSchema(tableModel.getSchema());
14680                }
14681                tableElement.setServer(tableModel.getServer());
14682                tableElement.setName(tableModel.getName());
14683                tableElement.setDisplayName(tableModel.getDisplayName());
14684                tableElement.setStarStmt(tableModel.getStarStmt());
14685                if(tableModel.isFromDDL()) {
14686                        tableElement.setFromDDL(String.valueOf(tableModel.isFromDDL()));
14687                }
14688
14689                if (tableModel.isPseudo()) {
14690                        tableElement.setType("pseudoTable");
14691                } else {
14692                        tableElement.setType("table");
14693                }
14694
14695                if (tableModel.getSubType() != null) {
14696                        if (tableModel.getSubType() == SubType.unnest) {
14697                                tableElement.setType(SubType.unnest.name());
14698                        }
14699                        else {
14700                                tableElement.setSubType(tableModel.getSubType().name());
14701                        }
14702                }
14703                if (tableModel.getParent() != null) {
14704                        tableElement.setParent(tableModel.getParent());
14705                }
14706                if (tableModel.getAlias() != null && tableModel.getAlias().trim().length() > 0) {
14707                        tableElement.setAlias(tableModel.getAlias());
14708                }
14709                if (tableModel.getStartPosition() != null && tableModel.getEndPosition() != null) {
14710                        tableElement.setCoordinate(convertCoordinate(tableModel.getStartPosition()) + ","
14711                                        + convertCoordinate(tableModel.getEndPosition()));
14712                }
14713                if (tableModel.getProcesses() != null) {
14714                        List<String> processIds = new ArrayList<String>();
14715                        for (Process process : tableModel.getProcesses()) {
14716                                processIds.add(String.valueOf(process.getId()));
14717                        }
14718                        tableElement.setProcessIds(processIds);
14719                }
14720
14721                table oldTableElement = null;
14722                String tableFullName = DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getQualifiedTableName(tableElement));
14723                
14724                if(tableMap.containsKey(tableFullName)) {
14725                        oldTableElement = tableMap.get(tableFullName);
14726                }
14727                else {
14728                        tableMap.put(tableFullName, tableElement);
14729                }
14730                
14731                if (tableModel.getSubType() == SubType.unnest) {
14732                        dataflow.getResultsets().add(tableElement);
14733                } else {
14734                        dataflow.getTables().add(tableElement);
14735                }
14736
14737                List<TableColumn> columns = tableModel.getColumns();
14738
14739                if (containStarColumn(columns)) {
14740                        for (TableColumn column : columns) {
14741                                if (column.getName().endsWith("*")) {
14742                                        for (TableColumn starElement : columns) {
14743                                                if (starElement == column) {
14744                                                        continue;
14745                                                }
14746                                                if (starElement.isNotBindStarLinkColumn()) {
14747                                                        continue;
14748                                                }
14749                                                TObjectName columnObject = starElement.getColumnObject();
14750                                                column.bindStarLinkColumn(columnObject);
14751                                        }
14752                                        if (tableModel.isCreateTable() && column.isExpandStar()) {
14753                                                column.setShowStar(false);
14754                                        }
14755                                }
14756                        }
14757                }
14758
14759                for (int j = 0; j < columns.size(); j++) {
14760                        TableColumn columnModel = columns.get(j);
14761
14762                        if(oldTableElement != null){
14763                                if(!CollectionUtil.isEmpty(oldTableElement.getColumns())){
14764                                        for(column oldColumnElement: oldTableElement.getColumns()){
14765                                                if(oldColumnElement.getName().equalsIgnoreCase(columnModel.getName())){
14766                                                        if(columnModel.getDataType() == null && oldColumnElement.getDataType() != null){
14767                                                                columnModel.setDataType(oldColumnElement.getDataType());
14768                                                        }
14769                                                        if(columnModel.getPrimaryKey() == null && oldColumnElement.isPrimaryKey() != null){
14770                                                                columnModel.setPrimaryKey(oldColumnElement.isPrimaryKey());
14771                                                        }
14772                                                        if(columnModel.getIndexKey() == null && oldColumnElement.isIndexKey() != null){
14773                                                                columnModel.setIndexKey(oldColumnElement.isIndexKey());
14774                                                        }
14775                                                        if(columnModel.getUnqiueKey() == null && oldColumnElement.isUnqiueKey() != null){
14776                                                                columnModel.setUnqiueKey(oldColumnElement.isUnqiueKey());
14777                                                        }
14778                                                        if(columnModel.getForeignKey() == null && oldColumnElement.isForeignKey() != null){
14779                                                                columnModel.setForeignKey(oldColumnElement.isForeignKey());
14780                                                        }
14781
14782                                                        if(oldColumnElement.getDataType() == null && columnModel.getDataType() != null){
14783                                                                oldColumnElement.setDataType(columnModel.getDataType());
14784                                                        }
14785                                                        if(oldColumnElement.isPrimaryKey() == null && columnModel.getPrimaryKey() != null){
14786                                                                oldColumnElement.setPrimaryKey(columnModel.getPrimaryKey());
14787                                                        }
14788                                                        if(oldColumnElement.isIndexKey() == null && columnModel.getIndexKey() != null){
14789                                                                oldColumnElement.setIndexKey(columnModel.getIndexKey());
14790                                                        }
14791                                                        if(oldColumnElement.isUnqiueKey() == null && columnModel.getUnqiueKey() != null){
14792                                                                oldColumnElement.setUnqiueKey(columnModel.getUnqiueKey());
14793                                                        }
14794                                                        if(oldColumnElement.isForeignKey() == null && columnModel.getForeignKey() != null){
14795                                                                oldColumnElement.setForeignKey(columnModel.getForeignKey());
14796                                                        }
14797                                                        break;
14798                                                }
14799                                        }
14800                                }
14801
14802                        }
14803
14804                        if (!columnModel.isPseduo() && columnModel.hasStarLinkColumn() && !columnModel.isVariant()) {
14805                                List<String> starLinkColumnList = columnModel.getStarLinkColumnNames();
14806                                for (int k = 0; k < starLinkColumnList.size(); k++) {
14807                                        column columnElement = new column();
14808                                        columnElement.setId(String.valueOf(columnModel.getId()) + "_" + k);
14809                                        String columnName = starLinkColumnList.get(k);
14810                                        if (containStarColumn(columns, columnName)) {
14811                                                continue;
14812                                        }
14813                                        columnElement.setName(columnName);
14814                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14815                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14816                                                                + convertCoordinate(columnModel.getEndPosition()));
14817                                        }
14818                                        if (columnModel.getForeignKey()) {
14819                                                columnElement.setForeignKey(columnModel.getForeignKey());
14820                                        }
14821                                        if (columnModel.getIndexKey()) {
14822                                                columnElement.setIndexKey(columnModel.getIndexKey());
14823                                        }
14824                                        if (columnModel.getPrimaryKey()) {
14825                                                columnElement.setPrimaryKey(columnModel.getPrimaryKey());
14826                                        }
14827                                        if (columnModel.getUnqiueKey()) {
14828                                                columnElement.setUnqiueKey(columnModel.getUnqiueKey());
14829                                        }
14830                                        if (columnModel.getDataType() != null) {
14831                                                columnElement.setDataType(columnModel.getDataType());
14832                                        }
14833                                        tableElement.getColumns().add(columnElement);
14834                                }
14835                                if (columnModel.isShowStar()) {
14836                                        column columnElement = new column();
14837                                        columnElement.setId(String.valueOf(columnModel.getId()));
14838                                        columnElement.setName(columnModel.getName());
14839                                        if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14840                                                columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14841                                                                + convertCoordinate(columnModel.getEndPosition()));
14842                                        }
14843                                        if (columnModel.getForeignKey()) {
14844                                                columnElement.setForeignKey(columnModel.getForeignKey());
14845                                        }
14846                                        if (columnModel.getIndexKey()) {
14847                                                columnElement.setIndexKey(columnModel.getIndexKey());
14848                                        }
14849                                        if (columnModel.getPrimaryKey()) {
14850                                                columnElement.setPrimaryKey(columnModel.getPrimaryKey());
14851                                        }
14852                                        if (columnModel.getUnqiueKey()) {
14853                                                columnElement.setUnqiueKey(columnModel.getUnqiueKey());
14854                                        }
14855                                        if (columnModel.getDataType() != null) {
14856                                                columnElement.setDataType(columnModel.getDataType());
14857                                        }
14858                                        tableElement.getColumns().add(columnElement);
14859                                }
14860                        } else {
14861                                column columnElement = new column();
14862                                columnElement.setId(String.valueOf(columnModel.getId()));
14863                                columnElement.setName(columnModel.getName());
14864                                columnElement.setDisplayName(columnModel.getDisplayName());
14865                                if (columnModel.getStartPosition() != null && columnModel.getEndPosition() != null) {
14866                                        columnElement.setCoordinate(convertCoordinate(columnModel.getStartPosition()) + ","
14867                                                        + convertCoordinate(columnModel.getEndPosition()));
14868                                }
14869                                if (columnModel.isPseduo()) {
14870                                        columnElement.setSource("system");
14871                                }
14872                                if (columnModel.getForeignKey()) {
14873                                        columnElement.setForeignKey(columnModel.getForeignKey());
14874                                }
14875                                if (columnModel.getIndexKey()) {
14876                                        columnElement.setIndexKey(columnModel.getIndexKey());
14877                                }
14878                                if (columnModel.getPrimaryKey()) {
14879                                        columnElement.setPrimaryKey(columnModel.getPrimaryKey());
14880                                }
14881                                if (columnModel.getUnqiueKey()) {
14882                                        columnElement.setUnqiueKey(columnModel.getUnqiueKey());
14883                                }
14884                                if (columnModel.getDataType() != null) {
14885                                        columnElement.setDataType(columnModel.getDataType());
14886                                }
14887                                tableElement.getColumns().add(columnElement);
14888                        }
14889                }
14890
14891                TableRelationRows relationRows = tableModel.getRelationRows();
14892                if (relationRows.hasRelation()) {
14893                        column relationRowsElement = new column();
14894                        relationRowsElement.setId(String.valueOf(relationRows.getId()));
14895                        relationRowsElement.setName(relationRows.getName());
14896                        if (relationRows.getStartPosition() != null && relationRows.getEndPosition() != null) {
14897                                relationRowsElement.setCoordinate(convertCoordinate(relationRows.getStartPosition()) + ","
14898                                                + convertCoordinate(relationRows.getEndPosition()));
14899                        }
14900                        relationRowsElement.setSource("system");
14901                        tableElement.getColumns().add(relationRowsElement);
14902                }
14903        }
14904
14905        private boolean containStarColumn(List<TableColumn> columns, String qualifiedColumnName) {
14906                for (TableColumn tableColumn : columns) {
14907                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) {
14908                                return true;
14909                        }
14910                }
14911                return false;
14912        }
14913
14914        private TableColumn searchTableColumn(List<TableColumn> columns, String qualifiedColumnName) {
14915                for (TableColumn tableColumn : columns) {
14916                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()).equals(qualifiedColumnName)) {
14917                                return tableColumn;
14918                        }
14919                }
14920                return null;
14921        }
14922
14923        private boolean containStarColumn(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) {
14924                for (RelationshipElement element : elements) {
14925                        if (element.getElement() instanceof TableColumn) {
14926                                if (DlineageUtil.getIdentifierNormalColumnName(((TableColumn) element.getElement()).getName())
14927                                                .equals(qualifiedColumnName)) {
14928                                        return true;
14929                                }
14930                        } else if (element.getElement() instanceof ResultColumn) {
14931                                if (DlineageUtil.getIdentifierNormalColumnName(((ResultColumn) element.getElement()).getName())
14932                                                .equals(qualifiedColumnName)) {
14933                                        return true;
14934                                }
14935                        }
14936                }
14937                return false;
14938        }
14939
14940        /**
14941         * Returns true if there is a non-star source element matching the column name
14942         * whose parent (table/resultset) does NOT also contribute a star source in
14943         * the same relationship. This identifies "definitive" explicit sources like
14944         * subquery columns (e.g., "coalesce(...) as col_a") vs incidental references
14945         * (e.g., "aTab.id" where aTab.* is also a source).
14946         */
14947        private boolean hasDefinitiveNonStarSource(Collection<RelationshipElement<?>> elements, String qualifiedColumnName) {
14948                // First, collect parent IDs of all star (*) sources
14949                Set<Long> starSourceParentIds = new HashSet<Long>();
14950                for (RelationshipElement<?> element : elements) {
14951                        if (element.getElement() instanceof TableColumn) {
14952                                TableColumn tc = (TableColumn) element.getElement();
14953                                if ("*".equals(tc.getName()) && tc.getTable() != null) {
14954                                        starSourceParentIds.add(tc.getTable().getId());
14955                                }
14956                        } else if (element.getElement() instanceof ResultColumn) {
14957                                ResultColumn rc = (ResultColumn) element.getElement();
14958                                if ("*".equals(rc.getName()) && rc.getResultSet() != null) {
14959                                        starSourceParentIds.add(rc.getResultSet().getId());
14960                                }
14961                        }
14962                }
14963
14964                // Then check if any non-star source matching the column name has a parent
14965                // that does NOT also have a star source
14966                for (RelationshipElement<?> element : elements) {
14967                        if (element.getElement() instanceof TableColumn) {
14968                                TableColumn tc = (TableColumn) element.getElement();
14969                                if (!"*".equals(tc.getName())
14970                                                && DlineageUtil.getIdentifierNormalColumnName(tc.getName()).equals(qualifiedColumnName)) {
14971                                        if (tc.getTable() != null && !starSourceParentIds.contains(tc.getTable().getId())) {
14972                                                return true;
14973                                        }
14974                                }
14975                        } else if (element.getElement() instanceof ResultColumn) {
14976                                ResultColumn rc = (ResultColumn) element.getElement();
14977                                if (!"*".equals(rc.getName())
14978                                                && DlineageUtil.getIdentifierNormalColumnName(rc.getName()).equals(qualifiedColumnName)) {
14979                                        if (rc.getResultSet() != null && !starSourceParentIds.contains(rc.getResultSet().getId())) {
14980                                                return true;
14981                                        }
14982                                }
14983                        }
14984                }
14985                return false;
14986        }
14987
14988        private void analyzeSelectStmt(TSelectSqlStatement stmt) {
14989                if (!accessedSubqueries.contains(stmt)) {
14990                        accessedSubqueries.add(stmt);
14991                } else {
14992                        if (modelManager.getModel(stmt) != null) {
14993                                return;
14994                        }
14995                }
14996
14997                if (stmt.getParentStmt() == null && stmt.getIntoClause() == null && stmt.getIntoTableClause() == null) {
14998                        if(option.isIgnoreTopSelect() && (option.isIgnoreRecordSet() || option.isSimpleOutput())){
14999                                if(option.getAnalyzeMode() == null || option.getAnalyzeMode() == AnalyzeMode.dataflow){
15000                                        return;
15001                                }
15002                        }
15003                }
15004
15005                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
15006
15007                        // Iteratively analyze all descendant UNION branches before processing this node.
15008                        // Uses iterative post-order traversal to preserve the original left-right-self
15009                        // processing order, avoiding StackOverflow with deeply nested UNION trees.
15010                        {
15011                                Deque<TSelectSqlStatement> stack1 = new ArrayDeque<>();
15012                                List<TSelectSqlStatement> postOrder = new ArrayList<>();
15013                                stack1.push(stmt);
15014                                while (!stack1.isEmpty()) {
15015                                        TSelectSqlStatement node = stack1.pop();
15016                                        postOrder.add(node);
15017                                        if (node.getSetOperatorType() != ESetOperatorType.none) {
15018                                                // Push left first, then right, so that after reversal left comes first
15019                                                if (node.getLeftStmt() != null) stack1.push(node.getLeftStmt());
15020                                                if (node.getRightStmt() != null) stack1.push(node.getRightStmt());
15021                                        }
15022                                }
15023                                Collections.reverse(postOrder);
15024                                // Process all descendants in post-order, skip stmt itself (processed below)
15025                                for (int pi = 0; pi < postOrder.size() - 1; pi++) {
15026                                        TSelectSqlStatement node = postOrder.get(pi);
15027                                        if (!accessedStatements.contains(node)) {
15028                                                accessedStatements.add(node);
15029                                                analyzeSelectStmt(node);
15030                                        }
15031                                }
15032                        }
15033
15034                        stmtStack.push(stmt);
15035                        SelectSetResultSet resultSet = modelFactory.createSelectSetResultSet(stmt);
15036
15037                        ResultSet leftResultSetModel = (ResultSet) modelManager.getModel(stmt.getLeftStmt());
15038                        if (leftResultSetModel != null && leftResultSetModel != resultSet
15039                                        && !leftResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15040                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15041                                impactRelation.setEffectType(EffectType.select);
15042                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15043                                                leftResultSetModel.getRelationRows()));
15044                                impactRelation.setTarget(
15045                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
15046                        }
15047                        
15048                        ResultSet rightResultSetModel = (ResultSet) modelManager.getModel(stmt.getRightStmt());
15049                        if (rightResultSetModel != null && rightResultSetModel != resultSet
15050                                        && !rightResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15051                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15052                                impactRelation.setEffectType(EffectType.select);
15053                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15054                                                rightResultSetModel.getRelationRows()));
15055                                impactRelation.setTarget(
15056                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
15057                        }
15058                        
15059                        if ((leftResultSetModel != null && leftResultSetModel.isDetermined())
15060                                        || (rightResultSetModel != null && rightResultSetModel.isDetermined())) {
15061                                resultSet.setDetermined(true);
15062                        }
15063                        
15064                        if (resultSet.getColumns() == null || resultSet.getColumns().isEmpty()) {
15065                                if (getResultColumnList(stmt.getLeftStmt()) != null) {
15066                                        createSelectSetResultColumns(resultSet, stmt.getLeftStmt());
15067                                } else if (getResultColumnList(stmt.getRightStmt()) != null) {
15068                                        createSelectSetResultColumns(resultSet, stmt.getRightStmt());
15069                                }
15070                        }
15071
15072                        List<ResultColumn> columns = resultSet.getColumns();
15073                        for (int i = 0; i < columns.size(); i++) {
15074                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15075                                relation.setEffectType(EffectType.select);
15076                                relation.setTarget(new ResultColumnRelationshipElement(columns.get(i)));
15077
15078                                if (!stmt.getLeftStmt().isCombinedQuery()) {
15079                                        ResultSet sourceResultSet = (ResultSet) modelManager
15080                                                        .getModel(stmt.getLeftStmt().getResultColumnList());
15081                                        if (sourceResultSet!=null && sourceResultSet.getColumns().size() > i) {
15082                                                if (columns.get(i).getName().endsWith("*")) {
15083                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
15084                                                                relation.addSource(new ResultColumnRelationshipElement(column));
15085                                                        }
15086                                                } else {
15087                                                        relation.addSource(
15088                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
15089                                                }
15090                                        }
15091                                } else {
15092                                        ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getLeftStmt());
15093                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
15094                                                if (columns.get(i).getName().endsWith("*")) {
15095                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
15096                                                                relation.addSource(new ResultColumnRelationshipElement(column));
15097                                                        }
15098                                                } else {
15099                                                        relation.addSource(
15100                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
15101                                                }
15102                                        }
15103                                }
15104
15105                                if (!stmt.getRightStmt().isCombinedQuery()) {
15106                                        ResultSet sourceResultSet = (ResultSet) modelManager
15107                                                        .getModel(stmt.getRightStmt().getResultColumnList());
15108                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
15109                                                if (columns.get(i).getName().endsWith("*")) {
15110                                                        for (ResultColumn column : sourceResultSet.getColumns()) {
15111                                                                relation.addSource(new ResultColumnRelationshipElement(column));
15112                                                        }
15113                                                } else {
15114                                                        relation.addSource(
15115                                                                        new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
15116                                                }
15117                                        } else if (sourceResultSet != null) {
15118                                                for (ResultColumn column : sourceResultSet.getColumns()) {
15119                                                        if (column.hasStarLinkColumn()) {
15120                                                                relation.addSource(new ResultColumnRelationshipElement(column));
15121                                                        }
15122                                                }
15123                                        }
15124                                } else {
15125                                        ResultSet sourceResultSet = (ResultSet) modelManager.getModel(stmt.getRightStmt());
15126                                        if (sourceResultSet != null && sourceResultSet.getColumns().size() > i) {
15127                                                relation.addSource(new ResultColumnRelationshipElement(sourceResultSet.getColumns().get(i)));
15128                                        } else if (sourceResultSet != null) {
15129                                                for (ResultColumn column : sourceResultSet.getColumns()) {
15130                                                        if (column.hasStarLinkColumn()) {
15131                                                                relation.addSource(new ResultColumnRelationshipElement(column));
15132                                                        }
15133                                                }
15134                                        }
15135                                }
15136                        }
15137                        
15138                        analyzeSelectIntoClause(stmt);
15139                        
15140                        stmtStack.pop();
15141                } else {
15142
15143                        // handle hive stmt, issue_id I3SGZB
15144                        if (stmt.getHiveBodyList() != null && stmt.getHiveBodyList().size() > 0) {
15145                                stmtStack.push(stmt);
15146                                hiveFromTables = stmt.tables;
15147                                if (hiveFromTables != null) {
15148                                        for (int i = 0; i < hiveFromTables.size(); i++) {
15149                                                modelFactory.createTable(hiveFromTables.getTable(i));
15150                                        }
15151                                }
15152                                for (int i = 0; i < stmt.getHiveBodyList().size(); i++) {
15153                                        analyzeCustomSqlStmt(stmt.getHiveBodyList().get(i));
15154                                }
15155                                stmtStack.pop();
15156                                return;
15157                        }
15158                        
15159                        if (stmt.getTransformClause() != null) {
15160                                analyzeHiveTransformClause(stmt, stmt.getTransformClause());
15161                                return;
15162                        }
15163
15164                        if (stmt.getResultColumnList() == null) {
15165                                return;
15166                        }
15167
15168                        stmtStack.push(stmt);
15169
15170                        TTableList fromTables = stmt.tables;
15171                        if ((fromTables == null || fromTables.size() == 0)
15172                                        && (hiveFromTables != null && hiveFromTables.size() > 0)) {
15173                                fromTables = hiveFromTables;
15174                        }
15175
15176                        for (int i = 0; i < fromTables.size(); i++) {
15177                                TTable table = fromTables.getTable(i);
15178                                if (table.getLateralViewList() != null && !table.getLateralViewList().isEmpty()) {
15179                                        analyzeTableSubquery(table);
15180                                        analyzeLateralView(stmt, table, table.getLateralViewList());
15181                                        stmtStack.pop();
15182                                        return;
15183                                }
15184                                if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvpresto) {
15185                                        analyzeTableSubquery(table);
15186                                        analyzePrestoUnnest(stmt, table);
15187                                        stmtStack.pop();
15188                                        return;
15189                                }
15190                                if (table.getUnnestClause() != null && option.getVendor() == EDbVendor.dbvbigquery) {
15191                                        analyzeBigQueryUnnest(stmt, table);
15192                                }
15193                        }
15194                        
15195                        //用来获取 pivotedTable 对应的columns
15196                        TPivotedTable pivotedTable = null; 
15197                        if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
15198                                for (TJoin join : stmt.getJoins()) {
15199                                        if (join.getTable() != null && join.getTable().getPivotedTable() != null) {
15200                                                if (isUnPivotedTable(join.getTable().getPivotedTable())) {
15201                                                        analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable());
15202                                                        pivotedTable = join.getTable().getPivotedTable();
15203                                                } else {
15204                                                        analyzePivotedTable(stmt, join.getTable().getPivotedTable());
15205                                                        pivotedTable = join.getTable().getPivotedTable();
15206                                                }
15207                                        }
15208                                }
15209                        }
15210
15211                        for (int i = 0; i < fromTables.size(); i++) {
15212                                TTable table = fromTables.getTable(i);
15213
15214                                if (table.getFuncCall() != null) {
15215                                        TFunctionCall functionCall = table.getFuncCall();
15216                                        Procedure callee = modelManager.getProcedureByName(
15217                                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
15218                                        if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(functionCall))) {
15219                                                analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
15220                                                callee = modelManager.getProcedureByName(
15221                                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionCall)));
15222                                        }
15223
15224                                        if(callee!=null) {
15225                                                if (callee.getArguments() != null) {
15226                                                        for (int j = 0; j < callee.getArguments().size(); j++) {
15227                                                                Argument argument = callee.getArguments().get(j);
15228                                                                Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
15229                                                                if(variable!=null) {
15230                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
15231                                                                                Transform transform = new Transform();
15232                                                                                transform.setType(Transform.FUNCTION);
15233                                                                                transform.setCode(functionCall);
15234                                                                                variable.getColumns().get(0).setTransform(transform);
15235                                                                        }
15236                                                                        Process process = modelFactory.createProcess(functionCall);
15237                                                                        variable.addProcess(process);
15238                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionCall, j, process);
15239                                                                }
15240                                                        }
15241                                                }
15242                                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
15243                                                                .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
15244                                                if (functionTableModelObjs != null) {
15245                                                        modelManager.bindModel(table, functionTableModelObjs.iterator().next());
15246                                                }
15247                                                continue;
15248                                        } else {
15249                                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
15250                                                                .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
15251                                                if (functionTableModelObjs == null) {
15252//                                                      Procedure procedure = modelManager.getProcedureByName(DlineageUtil
15253//                                                                      .getIdentifierNormalTableName(table.getFuncCall().getFunctionName().toString()));
15254//                                                      if (procedure != null) {
15255                                                                createFunction(table.getFuncCall());
15256                                                                continue;
15257//                                                      }
15258                                                }
15259                                                if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof Table) {
15260                                                        Table functionTableModel = (Table) functionTableModelObjs.iterator().next();
15261                                                        if (functionTableModel.getColumns() != null) {
15262                                                                Table functionTable = modelFactory.createTableFromCreateDDL(table, true);
15263                                                                if (functionTable == functionTableModel)
15264                                                                        continue;
15265                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
15266                                                                        TableColumn column = modelFactory.createTableColumn(functionTable,
15267                                                                                        functionTableModel.getColumns().get(j).getColumnObject(), true);
15268                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15269                                                                        relation.setEffectType(EffectType.select);
15270                                                                        relation.setTarget(new TableColumnRelationshipElement(column));
15271                                                                        relation.addSource(
15272                                                                                        new TableColumnRelationshipElement(functionTableModel.getColumns().get(j)));
15273                                                                }
15274                                                        }
15275                                                } else if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) {
15276                                                        ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next();
15277                                                        if (functionTableModel.getColumns() != null) {
15278                                                                Table functionTable = modelFactory.createTableFromCreateDDL(table, true);
15279                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
15280                                                                        TParseTreeNode columnObj = functionTableModel.getColumns().get(j).getColumnObject();
15281                                                                        if (columnObj instanceof TObjectName) {
15282                                                                                TableColumn column = modelFactory.createTableColumn(functionTable,
15283                                                                                                (TObjectName) columnObj, true);
15284                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15285                                                                                relation.setEffectType(EffectType.select);
15286                                                                                relation.setTarget(new TableColumnRelationshipElement(column));
15287                                                                                relation.addSource(new ResultColumnRelationshipElement(
15288                                                                                                functionTableModel.getColumns().get(j)));
15289                                                                        } else if (columnObj instanceof TResultColumn) {
15290                                                                                TableColumn column = modelFactory.createTableColumn(functionTable,
15291                                                                                                (TResultColumn) columnObj);
15292                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15293                                                                                relation.setEffectType(EffectType.select);
15294                                                                                relation.setTarget(new TableColumnRelationshipElement(column));
15295                                                                                relation.addSource(new ResultColumnRelationshipElement(
15296                                                                                                functionTableModel.getColumns().get(j)));
15297                                                                        }
15298                                                                }
15299                                                        }
15300                                                }
15301                                        }
15302                                }
15303                                
15304                                if (table.getPartitionExtensionClause() != null
15305                                                && table.getPartitionExtensionClause().getKeyValues() != null) {
15306                                        TExpressionList values = table.getPartitionExtensionClause().getKeyValues();
15307                                        Table tableModel = modelFactory.createTable(table);
15308                                        for (TExpression value : values) {
15309                                                if (value.getExpressionType() == EExpressionType.simple_constant_t) {
15310                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15311                                                        impactRelation.setEffectType(EffectType.select);
15312                                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
15313                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable, value.getConstantOperand());
15314                                                        impactRelation.addSource(new TableColumnRelationshipElement(constantColumn));
15315                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
15316                                                                        tableModel.getRelationRows()));
15317                                                }
15318                                        }
15319                                }
15320
15321                                if (table.getSubquery() != null) {
15322                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15323                                        TSelectSqlStatement subquery = table.getSubquery();
15324                                        analyzeSelectStmt(subquery);
15325
15326                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
15327                                        if (resultSetModel != null && resultSetModel.isDetermined()) {
15328                                                queryTable.setDetermined(true);
15329                                        }
15330
15331                                        if (resultSetModel != null && resultSetModel != queryTable
15332                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15333                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15334                                                impactRelation.setEffectType(EffectType.select);
15335                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15336                                                                resultSetModel.getRelationRows()));
15337                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15338                                                                queryTable.getRelationRows()));
15339                                        }
15340
15341                                        if (resultSetModel != null && resultSetModel != queryTable
15342                                                        && queryTable.getTableObject().getAliasClause() != null
15343                                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
15344                                                for (int j = 0; j < queryTable.getColumns().size()
15345                                                                && j < resultSetModel.getColumns().size(); j++) {
15346                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15347                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
15348
15349                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
15350                                                        queryRalation.setEffectType(EffectType.select);
15351                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15352                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15353                                                }
15354                                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
15355                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
15356                                                                .getModel(subquery);
15357                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15358                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15359                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15360                                                                        sourceColumn);
15361                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15362                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
15363                                                        }
15364                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15365                                                        selectSetRalation.setEffectType(EffectType.select);
15366                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15367                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15368                                                }
15369                                        }
15370                                } else if (table.getOutputMerge() != null) {
15371                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15372                                        TMergeSqlStatement subquery = table.getOutputMerge();
15373                                        analyzeMergeStmt(subquery);
15374
15375                                        for (TResultColumn column : subquery.getOutputClause().getSelectItemList()) {
15376                                                modelFactory.createResultColumn(queryTable, column);
15377                                                analyzeResultColumn(column, EffectType.select);
15378                                        }
15379
15380                                        ResultSet resultSetModel = (ResultSet) modelManager
15381                                                        .getModel(subquery.getOutputClause().getSelectItemList());
15382
15383                                        if (resultSetModel != null && resultSetModel != queryTable
15384                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15385                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15386                                                impactRelation.setEffectType(EffectType.select);
15387                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15388                                                                resultSetModel.getRelationRows()));
15389                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15390                                                                queryTable.getRelationRows()));
15391                                        }
15392
15393                                        if (resultSetModel != null && resultSetModel != queryTable
15394                                                        && queryTable.getTableObject().getAliasClause() != null
15395                                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
15396                                                for (int j = 0; j < queryTable.getColumns().size()
15397                                                                && j < resultSetModel.getColumns().size(); j++) {
15398                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15399                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
15400
15401                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
15402                                                        queryRalation.setEffectType(EffectType.select);
15403                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15404                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15405                                                }
15406                                        }
15407                                } else if (table.getTableExpr() != null && table.getTableExpr().getSubQuery() != null) {
15408                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15409                                        TSelectSqlStatement subquery = table.getTableExpr().getSubQuery();
15410                                        analyzeSelectStmt(subquery);
15411
15412                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
15413
15414                                        if (resultSetModel != null && resultSetModel != queryTable
15415                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15416                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15417                                                impactRelation.setEffectType(EffectType.select);
15418                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15419                                                                resultSetModel.getRelationRows()));
15420                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15421                                                                queryTable.getRelationRows()));
15422                                        }
15423
15424                                        if (resultSetModel != null && resultSetModel != queryTable
15425                                                        && queryTable.getTableObject().getAliasClause() != null) {
15426                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
15427                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15428                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15429                                                                        sourceColumn);
15430
15431                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
15432                                                        queryRalation.setEffectType(EffectType.select);
15433                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15434                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15435                                                }
15436                                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
15437                                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
15438                                                                .getModel(subquery);
15439                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15440                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15441                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
15442                                                                        sourceColumn);
15443                                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15444                                                                targetColumn.bindStarLinkColumn(starLinkColumn);
15445                                                        }
15446                                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15447                                                        selectSetRalation.setEffectType(EffectType.select);
15448                                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15449                                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15450                                                }
15451                                        }
15452                                } else if (table.getCTE() != null) {
15453                                        QueryTable queryTable = modelFactory.createQueryTable(table);
15454
15455                                        TObjectNameList cteColumns = table.getCTE().getColumnList();
15456                                        if (cteColumns != null) {
15457                                                for (int j = 0; j < cteColumns.size(); j++) {
15458                                                        modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
15459                                                }
15460                                                queryTable.setDetermined(true);
15461                                        }
15462                                        TSelectSqlStatement subquery = table.getCTE().getSubquery();
15463                                        if (subquery != null && !stmtStack.contains(subquery) && subquery.getResultColumnList() != null) {
15464                                                analyzeSelectStmt(subquery);
15465
15466                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
15467                                                if (resultSetModel != null && resultSetModel != queryTable
15468                                                                && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
15469                                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
15470                                                        impactRelation.setEffectType(EffectType.select);
15471                                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15472                                                                        resultSetModel.getRelationRows()));
15473                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
15474                                                                        queryTable.getRelationRows()));
15475                                                }
15476
15477                                                if (subquery.getSetOperatorType() != ESetOperatorType.none) {
15478                                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
15479                                                                        .getModel(subquery);
15480                                                        int x = 0;
15481                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
15482                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
15483                                                                ResultColumn targetColumn = null;
15484                                                                if (cteColumns != null) {
15485                                                                        if (queryTable.getColumns().size() <= j) {
15486                                                                                for (int k = 0; k < queryTable.getColumns().size(); k++) {
15487                                                                                        if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName())
15488                                                                                                        || queryTable.getColumns().get(k).getName()
15489                                                                                                                        .equals(sourceColumn.getAlias())) {
15490                                                                                                targetColumn = queryTable.getColumns().get(k);
15491                                                                                        }
15492                                                                                }
15493                                                                        } else {
15494                                                                                if (x < j) {
15495                                                                                        x = j;
15496                                                                                }
15497                                                                                targetColumn = queryTable.getColumns().get(x);
15498                                                                                x++;
15499                                                                                if (resultSetModel.getColumns().get(j).getName().contains("*")
15500                                                                                                && x < cteColumns.size()) {
15501                                                                                        j--;
15502                                                                                }
15503                                                                        }
15504                                                                } else {
15505                                                                        targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
15506                                                                }
15507                                                                for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15508                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
15509                                                                }
15510                                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15511                                                                selectSetRalation.setEffectType(EffectType.select);
15512                                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15513                                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15514                                                        }
15515                                                        if (!queryTable.isDetermined()) {
15516                                                                queryTable.setDetermined(selectSetResultSetModel.isDetermined());
15517                                                        }
15518                                                } else {
15519                                                        int x = 0;
15520                                                        for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
15521                                                                ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
15522                                                                ResultColumn targetColumn = null;
15523                                                                if (cteColumns != null) {
15524                                                                        if (queryTable.getColumns().size() <= j) {
15525                                                                                for (int k = 0; k < queryTable.getColumns().size(); k++) {
15526                                                                                        if (queryTable.getColumns().get(k).getName().equals(sourceColumn.getName())
15527                                                                                                        || queryTable.getColumns().get(k).getName()
15528                                                                                                                        .equals(sourceColumn.getAlias())) {
15529                                                                                                targetColumn = queryTable.getColumns().get(k);
15530                                                                                        }
15531                                                                                }
15532                                                                        } else {
15533                                                                                if (x < j) {
15534                                                                                        x = j;
15535                                                                                }
15536                                                                                targetColumn = queryTable.getColumns().get(x);
15537                                                                                x++;
15538                                                                                if (resultSetModel.getColumns().get(j).getName().contains("*")
15539                                                                                                && x < cteColumns.size()) {
15540                                                                                        j--;
15541                                                                                }
15542                                                                        }
15543                                                                } else {
15544                                                                        targetColumn = modelFactory.createSelectSetResultColumn(queryTable, sourceColumn);
15545                                                                }
15546                                                                for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
15547                                                                        targetColumn.bindStarLinkColumn(starLinkColumn);
15548                                                                }
15549                                                                DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
15550                                                                selectSetRalation.setEffectType(EffectType.select);
15551                                                                selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
15552                                                                selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
15553                                                        }
15554                                                        if (!queryTable.isDetermined()) {
15555                                                                queryTable.setDetermined(resultSetModel.isDetermined());
15556                                                        }
15557                                                }
15558                                        } else if (table.getCTE().getUpdateStmt() != null) {
15559                                                analyzeCustomSqlStmt(table.getCTE().getUpdateStmt());
15560                                        } else if (table.getCTE().getInsertStmt() != null) {
15561                                                analyzeCustomSqlStmt(table.getCTE().getInsertStmt());
15562                                        } else if (table.getCTE().getDeleteStmt() != null) {
15563                                                analyzeCustomSqlStmt(table.getCTE().getDeleteStmt());
15564                                        }
15565                                } else if (table.getTableType().name().startsWith("open")) {
15566                                        continue;
15567                                } else if (table.getTableType() == ETableSource.jsonTable) {
15568                                        Table functionTable = modelFactory.createJsonTable(table);
15569                                        TJsonTable jsonTable = table.getJsonTable();
15570                                        TColumnDefinitionList definitions = jsonTable.getColumnDefinitions();
15571                                        if (definitions != null) {
15572                                                for (int j = 0; j < definitions.size(); j++) {
15573                                                        TableColumn column = modelFactory.createTableColumn(functionTable,
15574                                                                        definitions.getColumn(j).getColumnName(), true);
15575                                                        if (definitions.getColumn(j).getColumnPath() != null) {
15576                                                                column.setDisplayName(
15577                                                                                column.getName() + ":" + definitions.getColumn(j).getColumnPath());
15578                                                        }
15579                                                }
15580                                        } else {
15581                                                TObjectName keyColumn = new TObjectName();
15582                                                keyColumn.setString("key");
15583                                                modelFactory.createJsonTableColumn(functionTable, keyColumn);
15584                                                TObjectName valueColumn = new TObjectName();
15585                                                valueColumn.setString("value");
15586                                                modelFactory.createJsonTableColumn(functionTable, valueColumn);
15587                                                TObjectName typeColumn = new TObjectName();
15588                                                typeColumn.setString("type");
15589                                                modelFactory.createJsonTableColumn(functionTable, typeColumn);
15590                                        }
15591
15592                                        functionTable.setCreateTable(true);
15593                                        functionTable.setSubType(SubType.function);
15594                                        modelManager.bindCreateModel(table, functionTable);
15595
15596                                        if (jsonTable.getJsonExpression() == null) {
15597                                                ErrorInfo errorInfo = new ErrorInfo();
15598                                                errorInfo.setErrorType(ErrorInfo.ANALYZE_ERROR);
15599                                                errorInfo.setErrorMessage("Can't handle the json table: " + jsonTable.toString());
15600                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(jsonTable.getStartToken().lineNo,
15601                                                                jsonTable.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
15602                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(jsonTable.getEndToken().lineNo,
15603                                                                jsonTable.getEndToken().columnNo + jsonTable.getEndToken().getAstext().length(),
15604                                                                ModelBindingManager.getGlobalHash()));
15605                                                errorInfo.fillInfo(this);
15606                                                errorInfos.add(errorInfo);
15607                                        } else {
15608                                                String jsonName = jsonTable.getJsonExpression().toString();
15609                                                if (!jsonName.startsWith("@")) {
15610                                                        columnsInExpr visitor = new columnsInExpr();
15611                                                        jsonTable.getJsonExpression().inOrderTraverse(visitor);
15612                                                        List<TObjectName> objectNames = visitor.getObjectNames();
15613                                                        List<TParseTreeNode> functions = visitor.getFunctions();
15614                                                        List<TParseTreeNode> constants = visitor.getConstants();
15615                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15616
15617                                                        for (int j = 0; j < functionTable.getColumns().size(); j++) {
15618                                                                TableColumn tableColumn = functionTable.getColumns().get(j);
15619                                                                if (functions != null && !functions.isEmpty()) {
15620                                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
15621                                                                }
15622                                                                if (subquerys != null && !subquerys.isEmpty()) {
15623                                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
15624                                                                }
15625                                                                if (objectNames != null && !objectNames.isEmpty()) {
15626                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
15627                                                                }
15628                                                                if (constants != null && !constants.isEmpty()) {
15629                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
15630                                                                                        functions);
15631                                                                }
15632                                                        }
15633                                                } else {
15634                                                        TStatementList stmts = stmt.getGsqlparser().getSqlstatements();
15635                                                        for (int j = 0; j < stmts.size(); j++) {
15636                                                                TCustomSqlStatement item = stmts.get(j);
15637                                                                if (item instanceof TMssqlDeclare) {
15638                                                                        if (analyzeMssqlJsonDeclare((TMssqlDeclare) item, jsonName, functionTable)) {
15639                                                                                break;
15640                                                                        }
15641                                                                }
15642                                                        }
15643                                                }
15644                                        }
15645                                } else if (getTableLinkedColumns(table) != null && getTableLinkedColumns(table).size() > 0) {
15646                                        if (table.getTableType() == ETableSource.rowList && table.getRowList() != null
15647                                                        && table.getRowList().size() > 0) {
15648                                                Table tableModel = modelFactory.createTable(table);
15649                                                for (int j = 0; j < table.getRowList().size(); j++) {
15650                                                        TMultiTarget rowList = table.getRowList().getMultiTarget(j);
15651                                                        for (int k = 0; k < rowList.getColumnList().size(); k++) {
15652                                                                TResultColumn column = rowList.getColumnList().getResultColumn(k);
15653                                                                if (column.getFieldAttr() == null)
15654                                                                        continue;
15655                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel,
15656                                                                                column.getFieldAttr(), true);
15657
15658                                                                columnsInExpr visitor = new columnsInExpr();
15659                                                                column.getExpr().inOrderTraverse(visitor);
15660                                                                List<TObjectName> objectNames = visitor.getObjectNames();
15661                                                                List<TParseTreeNode> functions = visitor.getFunctions();
15662                                                                List<TParseTreeNode> constants = visitor.getConstants();
15663                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15664
15665                                                                if (functions != null && !functions.isEmpty()) {
15666                                                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.function);
15667                                                                }
15668                                                                if (subquerys != null && !subquerys.isEmpty()) {
15669                                                                        analyzeSubqueryDataFlowRelation(tableColumn, subquerys, EffectType.select);
15670                                                                }
15671                                                                if (objectNames != null && !objectNames.isEmpty()) {
15672                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select, functions);
15673                                                                }
15674                                                                if (constants != null && !constants.isEmpty()) {
15675                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
15676                                                                                        functions);
15677                                                                }
15678                                                        }
15679                                                }
15680                                        } else {
15681                                                if(table.getTableType() == ETableSource.pivoted_table) {
15682                                                        continue;
15683                                                }
15684                                                if (table.getTableType() == ETableSource.rowList) {
15685                                                        List<TResultColumnList> rowList = table.getValueClause().getRows();
15686                                                        
15687                                                        QueryTable tableModel = modelFactory.createQueryTable(table);
15688                                                        TAliasClause aliasClause = table.getAliasClause();
15689                                                        if (aliasClause != null && aliasClause.getColumns() != null) {
15690                                                                for (TObjectName column : aliasClause.getColumns()) {
15691                                                                        modelFactory.createResultColumn(tableModel, column, true);
15692                                                                }       
15693                                                        } else {        
15694                                                                int columnCount = rowList.get(0).size();
15695                                                                for (int j = 1; j <= columnCount; j++) {
15696                                                                        TObjectName columnName = new TObjectName();
15697                                                                        columnName.setString("column" + j);
15698                                                                        modelFactory.createResultColumn(tableModel, columnName, true);
15699                                                                }
15700                                                        }
15701                                                        tableModel.setDetermined(true);
15702                                                        
15703                                                        for (TResultColumnList resultColumnList : rowList) {
15704                                                                for (int j = 0; j < resultColumnList.size(); j++) {
15705                                                                        TResultColumn resultColumn = resultColumnList.getResultColumn(j);
15706                                                                        analyzeValueColumn(tableModel.getColumns().get(j), resultColumn, EffectType.select);
15707                                                                }
15708                                                        }
15709                                                        
15710                                                } else {
15711                                                        Table tableModel = modelFactory.createTable(table);
15712                                                        for (int j = 0; j < getTableLinkedColumns(table).size(); j++) {
15713                                                                TObjectName object = getTableLinkedColumns(table).getObjectName(j);
15714
15715                                                                if (object.getDbObjectType() == EDbObjectType.variable) {
15716                                                                        continue;
15717                                                                }
15718
15719                                                                if (object.getColumnNameOnly().startsWith("@")
15720                                                                                && (option.getVendor() == EDbVendor.dbvmssql
15721                                                                                                || option.getVendor() == EDbVendor.dbvazuresql)) {
15722                                                                        continue;
15723                                                                }
15724
15725                                                                if (object.getColumnNameOnly().startsWith(":")
15726                                                                                && (option.getVendor() == EDbVendor.dbvhana
15727                                                                                                || option.getVendor() == EDbVendor.dbvteradata)) {
15728                                                                        continue;
15729                                                                }
15730
15731                                                                if (isBuiltInFunctionName(object) && isFromFunction(object)) {
15732                                                                        continue;
15733                                                                }
15734
15735                                                                if (!"*".equals(getColumnName(object))) {
15736                                                                        if (isStructColumn(object)) {
15737
15738                                                                        } else {
15739                                                                                if (pivotedTable != null) {
15740                                                                                        ResultColumn resultColumn = getPivotedTableColumn(pivotedTable, object);
15741                                                                                        if (resultColumn != null) {
15742                                                                                                continue;
15743                                                                                        }
15744                                                                                }
15745                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object,
15746                                                                                                false);
15747                                                                                if(tableColumn == null) {
15748                                                                                        continue;
15749                                                                                }
15750                                                                                if (table.getUnnestClause() != null
15751                                                                                                && table.getUnnestClause().getArrayExpr() != null) {
15752                                                                                        columnsInExpr visitor = new columnsInExpr();
15753                                                                                        table.getUnnestClause().getArrayExpr().inOrderTraverse(visitor);
15754
15755                                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
15756                                                                                        List<TParseTreeNode> functions = visitor.getFunctions();
15757
15758                                                                                        if (functions != null && !functions.isEmpty()) {
15759                                                                                                analyzeFunctionDataFlowRelation(tableColumn, functions,
15760                                                                                                                EffectType.select);
15761
15762                                                                                        }
15763
15764                                                                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15765                                                                                        if (subquerys != null && !subquerys.isEmpty()) {
15766                                                                                                analyzeSubqueryDataFlowRelation(tableColumn, subquerys,
15767                                                                                                                EffectType.select);
15768                                                                                        }
15769
15770                                                                                        analyzeDataFlowRelation(tableColumn, objectNames, EffectType.select,
15771                                                                                                        functions);
15772
15773                                                                                        List<TParseTreeNode> constants = visitor.getConstants();
15774                                                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select,
15775                                                                                                        functions);
15776                                                                                }
15777                                                                        }
15778                                                                } else {
15779                                                                        boolean flag = false;
15780                                                                        for (TObjectName column : getTableLinkedColumns(table)) {
15781                                                                                if ("*".equals(getColumnName(column))) {
15782                                                                                        continue;
15783                                                                                }
15784                                                                                if (column.getLocation() != ESqlClause.where
15785                                                                                                && column.getLocation() != ESqlClause.joinCondition) {
15786                                                                                        flag = true;
15787                                                                                }
15788                                                                        }
15789                                                                        if (!flag) {
15790                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel, object,
15791                                                                                                false);
15792                                                                                if (tableColumn != null && !tableModel.hasSQLEnv()) {
15793                                                                                        tableColumn.setShowStar(true);
15794                                                                                }
15795                                                                        }
15796                                                                }
15797
15798                                                        }
15799                                                }
15800                                        }
15801                                }
15802                                else {
15803                                        modelFactory.createTable(table);
15804                                }
15805                        }
15806
15807                        if (pivotedTable!=null) {
15808                                for (TJoin join : stmt.getJoins()) {
15809                                        if (join.getTable() != null && join.getTable().getPivotedTable() != null) {
15810                                                if (isUnPivotedTable(join.getTable().getPivotedTable())) {
15811                                                        analyzeUnPivotedTable(stmt, join.getTable().getPivotedTable());
15812                                                } else {
15813                                                        analyzePivotedTable(stmt, join.getTable().getPivotedTable());
15814                                                }
15815                                                stmtStack.pop();
15816                                                return;
15817                                        }
15818                                }
15819                        }
15820
15821                        if (!stmt.isCombinedQuery()) {
15822                                Object queryModel = modelManager.getModel(stmt.getResultColumnList());
15823
15824                                if (queryModel == null) {
15825                                        TSelectSqlStatement parentStmt = getParentSetSelectStmt(stmt);
15826                                        if (isTopResultSet(stmt) || parentStmt == null) {
15827                                                ResultSet resultSetModel = modelFactory.createResultSet(stmt,
15828                                                                isTopResultSet(stmt) && isShowTopSelectResultSet() && stmt.getIntoClause() == null);
15829
15830                                                createPseudoImpactRelation(stmt, resultSetModel, EffectType.select);
15831
15832                                                boolean isDetermined = true;
15833                                                Map<String, AtomicInteger> keyMap = new HashMap<String, AtomicInteger>();
15834                                                Set<String> columnNames = new HashSet<String>();
15835                                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
15836                                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
15837
15838                                                        if (column.getExpr().getComparisonType() == EComparisonType.equals
15839                                                                        && column.getExpr().getLeftOperand().getObjectOperand() != null) {
15840                                                                TObjectName columnObject = column.getExpr().getLeftOperand().getObjectOperand();
15841
15842                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15843                                                                                columnObject);
15844                                                                if (columnObject.getDbObjectType() == EDbObjectType.variable) {
15845                                                                        Table variable = modelManager
15846                                                                                        .getTableByName(DlineageUtil.getTableFullName(columnObject.toString()));
15847                                                                        if (variable != null) {
15848                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15849                                                                                relation.setEffectType(EffectType.select);
15850                                                                                TableColumn columnModel = variable.getColumns().get(0);
15851                                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel));
15852                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
15853                                                                        } else {
15854                                                                                variable = modelFactory.createVariable(columnObject);
15855                                                                                variable.setCreateTable(true);
15856                                                                                variable.setSubType(SubType.record);
15857                                                                                TObjectName variableProperties = new TObjectName();
15858                                                                                variableProperties.setString("*");
15859                                                                                TableColumn variableProperty = modelFactory.createTableColumn(variable,
15860                                                                                                variableProperties, true);
15861                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
15862                                                                                relation.setEffectType(EffectType.select);
15863                                                                                relation.setTarget(new TableColumnRelationshipElement(variableProperty));
15864                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
15865                                                                        }
15866                                                                }
15867
15868                                                                columnsInExpr visitor = new columnsInExpr();
15869                                                                column.getExpr().getRightOperand().inOrderTraverse(visitor);
15870
15871                                                                List<TObjectName> objectNames = visitor.getObjectNames();
15872                                                                List<TParseTreeNode> functions = visitor.getFunctions();
15873
15874                                                                if (functions != null && !functions.isEmpty()) {
15875                                                                        analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.select);
15876
15877                                                                }
15878
15879                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
15880                                                                if (subquerys != null && !subquerys.isEmpty()) {
15881                                                                        analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.select);
15882                                                                }
15883
15884                                                                analyzeDataFlowRelation(resultColumn, objectNames, EffectType.select, functions);
15885
15886                                                                List<TParseTreeNode> constants = visitor.getConstants();
15887                                                                analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.select, functions);
15888                                                        } else {
15889                                                                if (column.getFieldAttr() != null && isStructColumn(column.getFieldAttr())) {
15890                                                                        Table table = modelFactory.createTable(column.getFieldAttr().getSourceTable());
15891                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
15892                                                                                TObjectName columnName = new TObjectName();
15893                                                                                if (table.getColumns().get(j).getName().equals(table.getAlias())) {
15894                                                                                        if (!SQLUtil.isEmpty(column.getColumnAlias())) {
15895                                                                                                columnName.setString(column.getColumnAlias());
15896                                                                                        } else {
15897                                                                                                columnName.setString(table.getColumns().get(j).getName());
15898                                                                                        }
15899                                                                                } else {
15900                                                                                        columnName.setString(
15901                                                                                                        table.getAlias() + "." + table.getColumns().get(j).getName());
15902                                                                                }
15903                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15904                                                                                                columnName);
15905                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
15906                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
15907                                                                                relationship.addSource(
15908                                                                                                new TableColumnRelationshipElement(table.getColumns().get(j)));
15909                                                                        }
15910                                                                } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.struct_t) {
15911                                                                        Function function = (Function) createFunction(column.getExpr().getFunctionCall());
15912                                                                        String functionName = getResultSetName(function);
15913                                                                        for (int j = 0; j < function.getColumns().size(); j++) {
15914                                                                                TObjectName columnName = new TObjectName();
15915                                                                                if (column.getAliasClause() != null) {
15916                                                                                        columnName.setString(column.getAliasClause() + "."
15917                                                                                                        + function.getColumns().get(j).getName());
15918                                                                                }
15919                                                                                else {
15920                                                                                        columnName.setString(functionName + "."
15921                                                                                                        + function.getColumns().get(j).getName());
15922                                                                                }
15923                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15924                                                                                                columnName);
15925                                                                                resultColumn.setStruct(true);
15926                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
15927                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
15928                                                                                relationship.addSource(
15929                                                                                                new ResultColumnRelationshipElement(function.getColumns().get(j)));
15930                                                                        }
15931                                                                } else if (column.getExpr().getFunctionCall() != null && column.getExpr().getFunctionCall().getFunctionType() == EFunctionType.array_t) {
15932                                                                        Function function = (Function) createFunction(column.getExpr().getFunctionCall());
15933                                                                        String functionName = getResultSetName(function);
15934                                                                        for (int j = 0; j < function.getColumns().size(); j++) {
15935                                                                                TObjectName columnName = new TObjectName();
15936                                                                                if (column.getAliasClause() != null) {
15937                                                                                        columnName.setString(column.getAliasClause() + "."
15938                                                                                                        + getColumnNameOnly(function.getColumns().get(j).getName()));
15939                                                                                }
15940                                                                                else {
15941                                                                                        columnName.setString(functionName + "."
15942                                                                                                        + getColumnNameOnly(function.getColumns().get(j).getName()));
15943                                                                                }
15944                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel,
15945                                                                                                columnName);
15946                                                                                resultColumn.setStruct(true);
15947                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
15948                                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
15949                                                                                relationship.addSource(
15950                                                                                                new ResultColumnRelationshipElement(function.getColumns().get(j)));
15951                                                                        }
15952                                                                } else if (column.getExpr().getExprList() != null && column.getExpr().getExpressionType() == EExpressionType.array_t) {
15953                                                                        if(column.getExpr().getObjectOperand()!=null) {
15954                                                                                TObjectName exprColumnName = column.getExpr().getObjectOperand();
15955                                                                                Table table = modelFactory.createTable(exprColumnName.getSourceTable());
15956                                                                                for (int z = 0; z < table.getColumns().size(); z++) {
15957                                                                                        TableColumn tableColumn = table.getColumns().get(z);
15958                                                                                        if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) {
15959                                                                                                TObjectName columnName = new TObjectName();
15960                                                                                                if (column.getAliasClause() != null) {
15961                                                                                                        columnName.setString(column.getAliasClause().toString());
15962                                                                                                } else {
15963                                                                                                        columnName
15964                                                                                                                        .setString(getColumnNameOnly(columnName.toString()));
15965                                                                                                }
15966                                                                                                ResultColumn resultColumn = modelFactory
15967                                                                                                                .createResultColumn(resultSetModel, columnName);
15968                                                                                                resultColumn.setStruct(true);
15969                                                                                                DataFlowRelationship relationship = modelFactory
15970                                                                                                                .createDataFlowRelation();
15971                                                                                                relationship.setTarget(
15972                                                                                                                new ResultColumnRelationshipElement(resultColumn));
15973                                                                                                relationship.addSource(new TableColumnRelationshipElement(
15974                                                                                                                tableColumn));
15975                                                                                        }
15976                                                                                }
15977                                                                        }
15978                                                                        else {
15979                                                                                for (int j = 0; j < column.getExpr().getExprList().size(); j++) {
15980                                                                                        TExpression expression = column.getExpr().getExprList().getExpression(j);
15981                                                                                        if(expression.getExpressionType() == EExpressionType.function_t) {
15982                                                                                                Function function = (Function)createFunction(expression.getFunctionCall());
15983                                                                                                String functionName = getResultSetName(function);
15984                                                                                                if (function != null && function.getColumns() != null) {
15985                                                                                                        for (int x = 0; x < function.getColumns().size(); x++) {
15986                                                                                                                TObjectName columnName = new TObjectName();
15987//                                                                                                              if (column.getAliasClause() != null) {
15988//                                                                                                                      columnName.setString(column.getAliasClause() + ".array."
15989//                                                                                                                                      + getColumnNameOnly(
15990//                                                                                                                                                      function.getColumns().get(x).getName()));
15991//                                                                                                              } else {
15992//                                                                                                                      columnName.setString(
15993//                                                                                                                                      functionName + ".array." + getColumnNameOnly(
15994//                                                                                                                                                      function.getColumns().get(x).getName()));
15995//                                                                                                              }
15996                                                                                                                if (column.getAliasClause() != null) {
15997                                                                                                                        columnName.setString(column.getAliasClause() + "."
15998                                                                                                                                        + getColumnNameOnly(
15999                                                                                                                                        function.getColumns().get(x).getName()));
16000                                                                                                                } else {
16001                                                                                                                        columnName.setString(
16002                                                                                                                                        functionName + "." + getColumnNameOnly(
16003                                                                                                                                                        function.getColumns().get(x).getName()));
16004                                                                                                                }
16005                                                                                                                ResultColumn resultColumn = modelFactory
16006                                                                                                                                .createResultColumn(resultSetModel, columnName);
16007                                                                                                                resultColumn.setStruct(true);
16008                                                                                                                DataFlowRelationship relationship = modelFactory
16009                                                                                                                                .createDataFlowRelation();
16010                                                                                                                relationship.setTarget(
16011                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
16012                                                                                                                relationship.addSource(new ResultColumnRelationshipElement(
16013                                                                                                                                function.getColumns().get(x)));
16014                                                                                                        }
16015                                                                                                }
16016                                                                                        }
16017                                                                                        else if(expression.getExpressionType() == EExpressionType.simple_object_name_t) {
16018                                                                                                TObjectName exprColumnName = expression.getObjectOperand();
16019                                                                                                Table table = modelFactory.createTable(exprColumnName.getSourceTable());
16020                                                                                                for (int z = 0; z < table.getColumns().size(); z++) {
16021                                                                                                        TableColumn tableColumn = table.getColumns().get(z);
16022                                                                                                        if(getColumnName(exprColumnName.toString()).equals(getColumnName(tableColumn.getName()))) {
16023                                                                                                                TObjectName columnName = new TObjectName();
16024                                                                                                                if (column.getAliasClause() != null) {
16025                                                                                                                        columnName.setString(column.getAliasClause().toString());
16026                                                                                                                } else {
16027                                                                                                                        columnName
16028                                                                                                                                        .setString(getColumnNameOnly(columnName.toString()));
16029                                                                                                                }
16030                                                                                                                ResultColumn resultColumn = modelFactory
16031                                                                                                                                .createResultColumn(resultSetModel, columnName);
16032                                                                                                                resultColumn.setStruct(true);
16033                                                                                                                DataFlowRelationship relationship = modelFactory
16034                                                                                                                                .createDataFlowRelation();
16035                                                                                                                relationship.setTarget(
16036                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
16037                                                                                                                relationship.addSource(new TableColumnRelationshipElement(
16038                                                                                                                                tableColumn));
16039                                                                                                        }
16040                                                                                                }
16041                                                                                        }
16042                                                                                }
16043                                                                        }
16044                                                                } else {
16045                                                                        if ("*".equals(column.getColumnNameOnly())) {
16046                                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
16047                                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
16048                                                                                if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) {
16049                                                                                        for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) {
16050                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
16051                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
16052                                                                                        }
16053                                                                                }
16054                                                                                
16055                                                                                TObjectName columnObject = column.getFieldAttr();
16056                                                                                List<TTable> sourceTables = columnObject.getSourceTableList();
16057                                                                                if (sourceTables != null && !sourceTables.isEmpty()) {
16058                                                                                        boolean[] determine = new boolean[sourceTables.size()];
16059                                                                                        for (int k = 0; k < sourceTables.size(); k++) {
16060                                                                                                TTable sourceTable = sourceTables.get(k);
16061                                                                                                Object tableModel = modelManager.getModel(sourceTable);
16062                                                                                                if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
16063                                                                                                        Table table = (Table) tableModel;
16064                                                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
16065                                                                                                                TableColumn tableColumn = table.getColumns().get(j);
16066                                                                                                                if (column.getExceptColumnList() != null) {
16067                                                                                                                        boolean except = false;
16068                                                                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
16069                                                                                                                                if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) {
16070                                                                                                                                        except = true;
16071                                                                                                                                        break;
16072                                                                                                                                }
16073                                                                                                                        }
16074                                                                                                                        if (!except && tableColumn.isStruct()) {
16075                                                                                                                                List<String> names = SQLUtil
16076                                                                                                                                                .parseNames(tableColumn.getName());
16077                                                                                                                                for (String name : names) {
16078                                                                                                                                        for (TObjectName objectName : column
16079                                                                                                                                                        .getExceptColumnList()) {
16080                                                                                                                                                if (getColumnName(objectName.toString())
16081                                                                                                                                                                .equals(getColumnName(name))) {
16082                                                                                                                                                        except = true;
16083                                                                                                                                                        break;
16084                                                                                                                                                }
16085                                                                                                                                        }
16086                                                                                                                                        if (except) {
16087                                                                                                                                                break;
16088                                                                                                                                        }
16089                                                                                                                                }
16090                                                                                                                        }
16091                                                                                                                        if(except){
16092                                                                                                                                continue;
16093                                                                                                                        }
16094                                                                                                                }
16095                                                                                                                
16096                                                                                                                if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
16097                                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
16098                                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
16099                                                                                                                        Transform transform = new Transform();
16100                                                                                                                        transform.setType(Transform.EXPRESSION);
16101                                                                                                                        TObjectName expression = new TObjectName();
16102                                                                                                                        expression.setString(expr.first);
16103                                                                                                                transform.setCode(expression);
16104                                                                                                                        resultColumn.setTransform(transform);
16105                                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
16106                                                                                                                }
16107                                                                                                                else {
16108                                                                                                                        String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName());
16109                                                                                                                        //bigquery
16110                                                                                                                        boolean exist = false;
16111                                                                                                                        if (!columnName.matches("(?i)f\\d+_")) {
16112                                                                                                                                if (!keyMap.containsKey(columnName)) {
16113                                                                                                                                        keyMap.put(columnName, new AtomicInteger(0));
16114                                                                                                                                } else {
16115                                                                                                                                        while (columnNames.contains(columnName)) {
16116                                                                                                                                                if(columnName.indexOf("*") == -1 && stmt.toString().matches("(?is).*using\\s*\\(\\s*"+columnName+"\\s*\\).*")) {
16117                                                                                                                                                        exist = true;
16118                                                                                                                                                        break;
16119                                                                                                                                                } else if (keyMap.containsKey(columnName)) {
16120                                                                                                                                                        int index = keyMap.get(columnName)
16121                                                                                                                                                                        .incrementAndGet();
16122                                                                                                                                                        columnName = columnName + index;
16123                                                                                                                                                }
16124                                                                                                                                        }
16125                                                                                                                                }
16126                                                                                                                                columnNames.add(columnName);
16127                                                                                                                        }
16128                                                                                                                        if (exist) {
16129                                                                                                                                String targetColumn = columnName;
16130                                                                                                                                DataFlowRelationship relation = modelFactory
16131                                                                                                                                                .createDataFlowRelation();
16132                                                                                                                                relation.setEffectType(EffectType.select);
16133                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(
16134                                                                                                                                                resultSetModel.getColumns().stream()
16135                                                                                                                                                                .filter(t -> t.getName()
16136                                                                                                                                                                                .equalsIgnoreCase(targetColumn))
16137                                                                                                                                                                .findFirst().get()));
16138                                                                                                                                relation.addSource(new TableColumnRelationshipElement(
16139                                                                                                                                                tableColumn));
16140                                                                                                                                continue;
16141                                                                                                                        }
16142                                                                                                                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
16143                                                                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) {
16144                                                                                                                                columnName = tableColumn.getName();
16145                                                                                                                        }
16146                                                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName);
16147                                                                                                                        resultColumn.setStruct(tableColumn.isStruct());
16148                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16149                                                                                                                        relation.setEffectType(EffectType.select);
16150                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16151                                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
16152                                                                                                                }
16153                                                                                                        }
16154                                                                                                        determine[k] = true;
16155                                                                                                        continue;
16156                                                                                                }
16157                                                                                                else if (tableModel instanceof ResultSet && ((ResultSet) tableModel).isDetermined()) {
16158                                                                                                        ResultSet table = (ResultSet) tableModel;
16159                                                                                                        for (int j = 0; j < table.getColumns().size(); j++) {
16160                                                                                                                ResultColumn tableColumn = table.getColumns().get(j);
16161                                                                                                                if (column.getExceptColumnList() != null) {
16162                                                                                                                        boolean except = false;
16163                                                                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
16164                                                                                                                                if(getColumnName(objectName.toString()).equals(getColumnName(tableColumn.getName()))) {
16165                                                                                                                                        except = true;
16166                                                                                                                                        break;
16167                                                                                                                                }
16168                                                                                                                        }
16169                                                                                                                        if (!except && tableColumn.isStruct()) {
16170                                                                                                                                List<String> names = SQLUtil
16171                                                                                                                                                .parseNames(tableColumn.getName());
16172                                                                                                                                for (String name : names) {
16173                                                                                                                                        for (TObjectName objectName : column
16174                                                                                                                                                        .getExceptColumnList()) {
16175                                                                                                                                                if (getColumnName(objectName.toString())
16176                                                                                                                                                                .equals(getColumnName(name))) {
16177                                                                                                                                                        except = true;
16178                                                                                                                                                        break;
16179                                                                                                                                                }
16180                                                                                                                                        }
16181                                                                                                                                        if (except) {
16182                                                                                                                                                break;
16183                                                                                                                                        }
16184                                                                                                                                }
16185                                                                                                                        }
16186                                                                                                                        if(except){
16187                                                                                                                                continue;
16188                                                                                                                        }
16189                                                                                                                }
16190                                                                                                                if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
16191                                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
16192                                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
16193                                                                                                                        Transform transform = new Transform();
16194                                                                                                                        transform.setType(Transform.EXPRESSION);
16195                                                                                                                        TObjectName expression = new TObjectName();
16196                                                                                                                        expression.setString(expr.first);
16197                                                                                                                transform.setCode(expression);
16198                                                                                                                        resultColumn.setTransform(transform);
16199                                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
16200                                                                                                                }
16201                                                                                                                else if(tableColumn.getRefColumnName()!=null) {
16202                                                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, tableColumn.getRefColumnName());
16203                                                                                                                        if(tableColumn.isStruct()) {
16204                                                                                                                                resultColumn.setStruct(true);
16205                                                                                                                        }
16206                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16207                                                                                                                        relation.setEffectType(EffectType.select);
16208                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16209                                                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16210                                                                                                                }
16211                                                                                                                else {
16212                                                                                                                        String columnName = DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName());
16213                                                                                                                        //bigquery
16214                                                                                                                        if (!columnName.matches("(?i)f\\d+_")) {
16215                                                                                                                                if (!keyMap.containsKey(columnName)) {
16216                                                                                                                                        keyMap.put(columnName, new AtomicInteger(0));
16217                                                                                                                                } else {
16218                                                                                                                                        while (columnNames.contains(columnName)) {
16219                                                                                                                                                int index = keyMap.get(columnName)
16220                                                                                                                                                                .incrementAndGet();
16221                                                                                                                                                columnName = columnName + index;
16222                                                                                                                                        }
16223                                                                                                                                }
16224                                                                                                                                columnNames.add(columnName);
16225                                                                                                                        }
16226                                                                                                                        if (DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
16227                                                                                                                                        .equalsIgnoreCase(DlineageUtil.getIdentifierNormalColumnName(columnName))) {
16228                                                                                                                                columnName = tableColumn.getName();
16229                                                                                                                        }
16230                                                                                                                        if (modelManager.getModel(column) instanceof ResultColumn) {
16231                                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16232                                                                                                                                relation.setEffectType(EffectType.select);
16233                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement((ResultColumn)modelManager.getModel(column)));
16234                                                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16235                                                                                                                        }
16236                                                                                                                        else {
16237                                                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(resultSetModel, column, columnName);
16238                                                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16239                                                                                                                                relation.setEffectType(EffectType.select);
16240                                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16241                                                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16242                                                                                                                        }
16243                                                                                                                }
16244                                                                                                        }
16245                                                                                                        determine[k] = true;
16246                                                                                                        continue;
16247                                                                                                }
16248                                                                                                else {
16249                                                                                                        ResultColumn resultColumn = modelFactory
16250                                                                                                                        .createResultColumn(resultSetModel, column);
16251                                                                                                        if (tableModel instanceof Function) {
16252                                                                                                
16253                                                                                                        } else {
16254                                                                                                                TObjectName[] columns = modelManager
16255                                                                                                                                .getTableColumns(sourceTable);
16256                                                                                                                for (int j = 0; j < columns.length; j++) {
16257                                                                                                                        TObjectName columnName = columns[j];
16258                                                                                                                        if (columnName == null
16259                                                                                                                                        || "*".equals(getColumnName(columnName))) {
16260                                                                                                                                continue;
16261                                                                                                                        }
16262                                                                                                                        if (isStructColumn(columnName)) {
16263                                                                                                                                continue;
16264                                                                                                                        }
16265
16266                                                                                                                        resultColumn.bindStarLinkColumn(columnName);
16267                                                                                                                        if (column.getExceptColumnList() != null) {
16268                                                                                                                                for (TObjectName objectName : column
16269                                                                                                                                                .getExceptColumnList()) {
16270                                                                                                                                        resultColumn.unbindStarLinkColumn(objectName);
16271                                                                                                                                }
16272                                                                                                                        }
16273                                                                                                                }
16274                                                                                                                if (tableModel instanceof ResultSet) {
16275                                                                                                                        ResultSet queryTable = (ResultSet) tableModel;
16276                                                                                                                        if (!containStarColumn(queryTable)) {
16277                                                                                                                                resultColumn.setShowStar(false);
16278                                                                                                                        }
16279                                                                                                                }
16280                                                                                                                if (tableModel instanceof Table) {
16281                                                                                                                        Table table = (Table) tableModel;
16282                                                                                                                        if (table.isCreateTable()) {
16283                                                                                                                                resultColumn.setShowStar(false);
16284                                                                                                                        }
16285                                                                                                                }
16286                                                                                                        }
16287                                                                                                }
16288                                                                                        }
16289                                                                                        if(!Arrays.toString(determine).contains("false")) {
16290                                                                                                continue;
16291                                                                                        }
16292                                                                                } else {
16293                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
16294                                                                                        TTableList tables = stmt.getTables();
16295                                                                                        for (int k = 0; k < tables.size(); k++) {
16296                                                                                                TTable table = tables.getTable(k);
16297                                                                                                TObjectName[] columns = modelManager.getTableColumns(table);
16298                                                                                                for (int j = 0; j < columns.length; j++) {
16299                                                                                                        TObjectName columnName = columns[j];
16300                                                                                                        if (columnName == null) {
16301                                                                                                                continue;
16302                                                                                                        }
16303                                                                                                        if ("*".equals(getColumnName(columnName))) {
16304                                                                                                                if (modelManager.getModel(table) instanceof Table) {
16305                                                                                                                        Table tableModel = (Table) modelManager.getModel(table);
16306                                                                                                                        if (tableModel != null
16307                                                                                                                                        && !tableModel.getColumns().isEmpty()) {
16308                                                                                                                                for (TableColumn item : tableModel.getColumns()) {
16309                                                                                                                                        resultColumn
16310                                                                                                                                                        .bindStarLinkColumn(item.getColumnObject());
16311                                                                                                                                        if (table.getSubquery() == null
16312                                                                                                                                                        && table.getCTE() == null
16313                                                                                                                                                        && !tableModel.isCreateTable()) {
16314                                                                                                                                                resultColumn.setShowStar(true);
16315                                                                                                                                        }
16316                                                                                                                                }
16317                                                                                                                        }
16318                                                                                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
16319                                                                                                                        QueryTable tableModel = (QueryTable) modelManager
16320                                                                                                                                        .getModel(table);
16321                                                                                                                        if (tableModel != null
16322                                                                                                                                        && !tableModel.getColumns().isEmpty()) {
16323                                                                                                                                for (ResultColumn item : tableModel.getColumns()) {
16324                                                                                                                                        if (item.hasStarLinkColumn()) {
16325                                                                                                                                                for (TObjectName starLinkColumn : item
16326                                                                                                                                                                .getStarLinkColumnList()) {
16327                                                                                                                                                        resultColumn
16328                                                                                                                                                                        .bindStarLinkColumn(starLinkColumn);
16329                                                                                                                                                }
16330                                                                                                                                        } else if (item
16331                                                                                                                                                        .getColumnObject() instanceof TObjectName) {
16332                                                                                                                                                resultColumn.bindStarLinkColumn(
16333                                                                                                                                                                (TObjectName) item.getColumnObject());
16334                                                                                                                                        } else if (item
16335                                                                                                                                                        .getColumnObject() instanceof TResultColumn) {
16336                                                                                                                                                TResultColumn queryTableColumn = (TResultColumn) item
16337                                                                                                                                                                .getColumnObject();
16338                                                                                                                                                TObjectName tableColumnObject = queryTableColumn
16339                                                                                                                                                                .getFieldAttr();
16340                                                                                                                                                if (tableColumnObject != null) {
16341                                                                                                                                                        resultColumn.bindStarLinkColumn(
16342                                                                                                                                                                        tableColumnObject);
16343                                                                                                                                                } else if (queryTableColumn
16344                                                                                                                                                                .getAliasClause() != null) {
16345                                                                                                                                                        resultColumn.bindStarLinkColumn(
16346                                                                                                                                                                        queryTableColumn.getAliasClause()
16347                                                                                                                                                                                        .getAliasName());
16348                                                                                                                                                }
16349                                                                                                                                        }
16350                                                                                                                                }
16351                                                                                                                        }
16352                                                                                                                }
16353                                                                                                                continue;
16354                                                                                                        }
16355                                                                                                        resultColumn.bindStarLinkColumn(columnName);
16356                                                                                                }
16357                                                                                        }
16358                                                                                }
16359                                                                                isDetermined = false;
16360                                                                        }
16361                                                                        else {
16362                                                                                if(column.getAliasClause()!=null && column.getAliasClause().getColumns()!=null) {
16363                                                                                        for(TObjectName aliasColumn: column.getAliasClause().getColumns()) {
16364                                                                                                modelFactory.createResultColumn(resultSetModel, aliasColumn);
16365                                                                                        }
16366                                                                                }
16367                                                                                else {
16368                                                                                        modelFactory.createResultColumn(resultSetModel, column);
16369                                                                                }
16370                                                                        }
16371                                                                        analyzeResultColumn(column, EffectType.select);
16372                                                                }
16373                                                        }
16374                                                }
16375                                                if (isDetermined) {
16376                                                        resultSetModel.setDetermined(isDetermined);
16377                                                }
16378                                        }
16379
16380                                        TSelectSqlStatement parent = getParentSetSelectStmt(stmt);
16381                                        if (parent != null && parent.getSetOperatorType() != ESetOperatorType.none) {
16382                                                ResultSet resultSetModel = modelFactory.createResultSet(stmt, false);
16383                                                if(queryModel == null) {
16384                                                        queryModel = resultSetModel;
16385                                                } 
16386
16387                                                createPseudoImpactRelation(stmt, resultSetModel, EffectType.select);
16388
16389                                                boolean isDetermined = true;
16390                                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
16391                                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
16392                                                        if ("*".equals(column.getColumnNameOnly())) {
16393                                                                
16394                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
16395                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
16396                                                                if(column.getReplaceExprAsIdentifiers()!=null && column.getReplaceExprAsIdentifiers().size()>0) {
16397                                                                        for(TReplaceExprAsIdentifier replace: column.getReplaceExprAsIdentifiers()) {
16398                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(column.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
16399                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
16400                                                                        }
16401                                                                }
16402                                                                
16403                                                                TObjectName columnObject = column.getFieldAttr();
16404                                                                TTable sourceTable = columnObject.getSourceTable();
16405                                                                if (sourceTable != null) {
16406                                                                        Object tableModel = modelManager.getModel(sourceTable);
16407                                                                        if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
16408                                                                                Table table = (Table) tableModel;
16409                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16410                                                                                        TableColumn tableColumn = table.getColumns().get(j);
16411                                                                                        if (column.getExceptColumnList() != null) {
16412                                                                                                boolean except = false;
16413                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16414                                                                                                        if (getColumnName(objectName.toString())
16415                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16416                                                                                                                except = true;
16417                                                                                                                break;
16418                                                                                                        }
16419                                                                                                }
16420                                                                                                if (!except && tableColumn.isStruct()) {
16421                                                                                                        List<String> names = SQLUtil
16422                                                                                                                        .parseNames(tableColumn.getName());
16423                                                                                                        for (String name : names) {
16424                                                                                                                for (TObjectName objectName : column
16425                                                                                                                                .getExceptColumnList()) {
16426                                                                                                                        if (getColumnName(objectName.toString())
16427                                                                                                                                        .equals(getColumnName(name))) {
16428                                                                                                                                except = true;
16429                                                                                                                                break;
16430                                                                                                                        }
16431                                                                                                                }
16432                                                                                                                if (except) {
16433                                                                                                                        break;
16434                                                                                                                }
16435                                                                                                        }
16436                                                                                                }
16437                                                                                                if (except) {
16438                                                                                                        continue;
16439                                                                                                }
16440                                                                                        }
16441                                                                                        
16442                                                                                        if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
16443                                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
16444                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
16445                                                                                                Transform transform = new Transform();
16446                                                                                                transform.setType(Transform.EXPRESSION);
16447                                                                                                TObjectName expression = new TObjectName();
16448                                                                                                expression.setString(expr.first);
16449                                                                                        transform.setCode(expression);
16450                                                                                                resultColumn.setTransform(transform);
16451                                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
16452                                                                                        }
16453                                                                                        else {
16454                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16455                                                                                                                resultSetModel, column, tableColumn.getName());
16456                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16457                                                                                                relation.setEffectType(EffectType.select);
16458                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16459                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
16460                                                                                        }
16461                                                                                }
16462                                                                                continue;
16463                                                                        } else if (tableModel instanceof ResultSet
16464                                                                                        && ((ResultSet) tableModel).isDetermined()) {
16465                                                                                ResultSet table = (ResultSet) tableModel;
16466                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16467                                                                                        ResultColumn tableColumn = table.getColumns().get(j);
16468                                                                                        if (column.getExceptColumnList() != null) {
16469                                                                                                boolean except = false;
16470                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16471                                                                                                        if (getColumnName(objectName.toString())
16472                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16473                                                                                                                except = true;
16474                                                                                                                break;
16475                                                                                                        }
16476                                                                                                }
16477                                                                                                if (!except && tableColumn.isStruct()) {
16478                                                                                                        List<String> names = SQLUtil
16479                                                                                                                        .parseNames(tableColumn.getName());
16480                                                                                                        for (String name : names) {
16481                                                                                                                for (TObjectName objectName : column
16482                                                                                                                                .getExceptColumnList()) {
16483                                                                                                                        if (getColumnName(objectName.toString())
16484                                                                                                                                        .equals(getColumnName(name))) {
16485                                                                                                                                except = true;
16486                                                                                                                                break;
16487                                                                                                                        }
16488                                                                                                                }
16489                                                                                                                if (except) {
16490                                                                                                                        break;
16491                                                                                                                }
16492                                                                                                        }
16493                                                                                                }
16494                                                                                                if (except) {
16495                                                                                                        continue;
16496                                                                                                }
16497                                                                                        }
16498                                                                                        
16499                                                                                        if (replaceAsIdentifierMap.containsKey(tableColumn.getName())) {
16500                                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableColumn.getName());
16501                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, replaceColumnMap.get(tableColumn.getName()));
16502                                                                                                Transform transform = new Transform();
16503                                                                                                transform.setType(Transform.EXPRESSION);
16504                                                                                                TObjectName expression = new TObjectName();
16505                                                                                                expression.setString(expr.first);
16506                                                                                        transform.setCode(expression);
16507                                                                                                resultColumn.setTransform(transform);
16508                                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
16509                                                                                        }
16510                                                                                        else if (tableColumn.getRefColumnName() != null) {
16511                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16512                                                                                                                (ResultSet)queryModel, column, tableColumn.getRefColumnName());
16513                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16514                                                                                                relation.setEffectType(EffectType.select);
16515                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16516                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16517                                                                                        } else {
16518                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16519                                                                                                                resultSetModel, column, tableColumn.getName());
16520                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16521                                                                                                relation.setEffectType(EffectType.select);
16522                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16523                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16524                                                                                        }
16525                                                                                }
16526                                                                                continue;
16527                                                                        }
16528                                                                        else {
16529                                                                                isDetermined = false;
16530                                                                        }
16531                                                                }
16532                                                                
16533                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
16534                                                                
16535                                                                if (columnObject.getTableToken() != null && sourceTable != null) {
16536                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
16537                                                                        for (int j = 0; j < columns.length; j++) {
16538                                                                                TObjectName columnName = columns[j];
16539                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
16540                                                                                        continue;
16541                                                                                }
16542                                                                                resultColumn.bindStarLinkColumn(columnName);
16543                                                                        }
16544
16545                                                                        if (modelManager.getModel(sourceTable) instanceof Table) {
16546                                                                                Table tableModel = (Table) modelManager.getModel(sourceTable);
16547                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16548                                                                                        for (TableColumn item : tableModel.getColumns()) {
16549                                                                                                if ("*".equals(getColumnName(item.getColumnObject()))) {
16550                                                                                                        continue;
16551                                                                                                }
16552                                                                                                resultColumn.bindStarLinkColumn(item.getColumnObject());
16553                                                                                        }
16554                                                                                }
16555                                                                        } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
16556                                                                                QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
16557                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16558                                                                                        for (ResultColumn item : tableModel.getColumns()) {
16559                                                                                                if (item.hasStarLinkColumn()) {
16560                                                                                                        for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
16561                                                                                                                if ("*".equals(getColumnName(starLinkColumn))) {
16562                                                                                                                        continue;
16563                                                                                                                }
16564                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
16565                                                                                                        }
16566                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
16567                                                                                                        TObjectName starLinkColumn = (TObjectName) item.getColumnObject();
16568                                                                                                        if ("*".equals(getColumnName(starLinkColumn))) {
16569                                                                                                                continue;
16570                                                                                                        }
16571                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
16572                                                                                                }
16573                                                                                        }
16574                                                                                }
16575                                                                        }
16576
16577                                                                } else {
16578                                                                        TTableList tables = stmt.getTables();
16579                                                                        for (int k = 0; k < tables.size(); k++) {
16580                                                                                TTable table = tables.getTable(k);
16581                                                                                TObjectName[] columns = modelManager.getTableColumns(table);
16582                                                                                for (int j = 0; j < columns.length; j++) {
16583                                                                                        TObjectName columnName = columns[j];
16584                                                                                        if (columnName == null) {
16585                                                                                                continue;
16586                                                                                        }
16587                                                                                        if ("*".equals(getColumnName(columnName))) {
16588                                                                                                if (modelManager.getModel(table) instanceof Table) {
16589                                                                                                        Table tableModel = (Table) modelManager.getModel(table);
16590                                                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16591                                                                                                                for (TableColumn item : tableModel.getColumns()) {
16592                                                                                                                        resultColumn.bindStarLinkColumn(item.getColumnObject());
16593                                                                                                                }
16594                                                                                                        }
16595                                                                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
16596                                                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(table);
16597                                                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16598                                                                                                                for (ResultColumn item : tableModel.getColumns()) {
16599                                                                                                                        if (item.hasStarLinkColumn()) {
16600                                                                                                                                for (TObjectName starLinkColumn : item
16601                                                                                                                                                .getStarLinkColumnList()) {
16602                                                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
16603                                                                                                                                }
16604                                                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
16605                                                                                                                                resultColumn.bindStarLinkColumn(
16606                                                                                                                                                (TObjectName) item.getColumnObject());
16607                                                                                                                        } else if (item
16608                                                                                                                                        .getColumnObject() instanceof TResultColumn) {
16609                                                                                                                                TResultColumn queryTableColumn = (TResultColumn) item
16610                                                                                                                                                .getColumnObject();
16611                                                                                                                                TObjectName tableColumnObject = queryTableColumn
16612                                                                                                                                                .getFieldAttr();
16613                                                                                                                                if (tableColumnObject != null) {
16614                                                                                                                                        resultColumn.bindStarLinkColumn(tableColumnObject);
16615                                                                                                                                } else if (queryTableColumn.getAliasClause() != null) {
16616                                                                                                                                        resultColumn.bindStarLinkColumn(queryTableColumn
16617                                                                                                                                                        .getAliasClause().getAliasName());
16618                                                                                                                                }
16619                                                                                                                        }
16620                                                                                                                }
16621                                                                                                        }
16622                                                                                                }
16623
16624                                                                                                continue;
16625                                                                                        }
16626                                                                                        resultColumn.bindStarLinkColumn(columnName);
16627                                                                                }
16628                                                                        }
16629                                                                }
16630                                                        }
16631                                                        else {
16632                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSetModel, column);
16633                                                        }
16634                                                        analyzeResultColumn(column, EffectType.select);
16635
16636                                                }
16637                                                
16638                                                resultSetModel.setDetermined(isDetermined);
16639                                        }
16640                                } else {
16641                                        for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
16642                                                TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
16643
16644                                                if (!(queryModel instanceof ResultSet)) {
16645                                                        continue;
16646                                                }
16647                                                
16648                                                ResultSet resultSetModel = (ResultSet)queryModel;
16649                                                        
16650                                                if ("*".equals(column.getColumnNameOnly())) {
16651                                                        TObjectName columnObject = column.getFieldAttr();
16652                                                        TTable sourceTable = columnObject.getSourceTable();
16653                                                        if (column.toString().indexOf(".") == -1 && stmt.getTables().size() > 1) {
16654                                                                sourceTable = null;
16655                                                        }
16656                                                        if (sourceTable != null) {
16657                                                                {
16658                                                                        Object tableModel = modelManager.getModel(sourceTable);
16659                                                                        if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
16660                                                                                Table table = (Table) tableModel;
16661                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16662                                                                                        TableColumn tableColumn = table.getColumns().get(j);
16663                                                                                        if (column.getExceptColumnList() != null) {
16664                                                                                                boolean except = false;
16665                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16666                                                                                                        if (getColumnName(objectName.toString())
16667                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16668                                                                                                                except = true;
16669                                                                                                                break;
16670                                                                                                        }
16671                                                                                                }
16672                                                                                                if (!except && tableColumn.isStruct()) {
16673                                                                                                        List<String> names = SQLUtil
16674                                                                                                                        .parseNames(tableColumn.getName());
16675                                                                                                        for (String name : names) {
16676                                                                                                                for (TObjectName objectName : column
16677                                                                                                                                .getExceptColumnList()) {
16678                                                                                                                        if (getColumnName(objectName.toString())
16679                                                                                                                                        .equals(getColumnName(name))) {
16680                                                                                                                                except = true;
16681                                                                                                                                break;
16682                                                                                                                        }
16683                                                                                                                }
16684                                                                                                                if (except) {
16685                                                                                                                        break;
16686                                                                                                                }
16687                                                                                                        }
16688                                                                                                }
16689                                                                                                if (except) {
16690                                                                                                        continue;
16691                                                                                                }
16692                                                                                        }
16693                                                                                        ResultColumn resultColumn = modelFactory.createStarResultColumn(
16694                                                                                                        resultSetModel, column, tableColumn.getName());
16695                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16696                                                                                        relation.setEffectType(EffectType.select);
16697                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16698                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
16699                                                                                }
16700                                                                                if(stmt.getResultColumnList().size() == 1) {
16701                                                                                        resultSetModel.setDetermined(true);
16702                                                                                }
16703                                                                                else {
16704                                                                                        int starCount = 0;
16705                                                                                        for (int j = 0; j < stmt.getResultColumnList().size(); j++) {
16706                                                                                                if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly()
16707                                                                                                                .endsWith("*")) {
16708                                                                                                        starCount += 1;
16709                                                                                                }
16710                                                                                        }
16711                                                                                        if (starCount <= 1) {
16712                                                                                                resultSetModel.setDetermined(true);
16713                                                                                        }
16714                                                                                }
16715                                                                                continue;
16716                                                                        } else if (tableModel instanceof ResultSet
16717                                                                                        && ((ResultSet) tableModel).isDetermined()) {
16718                                                                                ResultSet table = (ResultSet) tableModel;
16719                                                                                for (int j = 0; j < table.getColumns().size(); j++) {
16720                                                                                        ResultColumn tableColumn = table.getColumns().get(j);
16721                                                                                        if (column.getExceptColumnList() != null) {
16722                                                                                                boolean except = false;
16723                                                                                                for (TObjectName objectName : column.getExceptColumnList()) {
16724                                                                                                        if (getColumnName(objectName.toString())
16725                                                                                                                        .equals(getColumnName(tableColumn.getName()))) {
16726                                                                                                                except = true;
16727                                                                                                                break;
16728                                                                                                        }
16729                                                                                                }
16730                                                                                                if (!except && tableColumn.isStruct()) {
16731                                                                                                        List<String> names = SQLUtil
16732                                                                                                                        .parseNames(tableColumn.getName());
16733                                                                                                        for (String name : names) {
16734                                                                                                                for (TObjectName objectName : column
16735                                                                                                                                .getExceptColumnList()) {
16736                                                                                                                        if (getColumnName(objectName.toString())
16737                                                                                                                                        .equals(getColumnName(name))) {
16738                                                                                                                                except = true;
16739                                                                                                                                break;
16740                                                                                                                        }
16741                                                                                                                }
16742                                                                                                                if (except) {
16743                                                                                                                        break;
16744                                                                                                                }
16745                                                                                                        }
16746                                                                                                }
16747                                                                                                if (except) {
16748                                                                                                        continue;
16749                                                                                                }
16750                                                                                        }
16751                                                                                        if (tableColumn.getRefColumnName() != null) {
16752                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16753                                                                                                                (ResultSet)queryModel, column, tableColumn.getRefColumnName());
16754                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16755                                                                                                relation.setEffectType(EffectType.select);
16756                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16757                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16758                                                                                        } else {
16759                                                                                                ResultColumn resultColumn = modelFactory.createStarResultColumn(
16760                                                                                                                resultSetModel, column, tableColumn.getName());
16761                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
16762                                                                                                relation.setEffectType(EffectType.select);
16763                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
16764                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
16765                                                                                        }
16766                                                                                }
16767                                                                                if(stmt.getResultColumnList().size() == 1) {
16768                                                                                        resultSetModel.setDetermined(true);
16769                                                                                }
16770                                                                                else {
16771                                                                                        int starCount = 0;
16772                                                                                        for (int j = 0; j < stmt.getResultColumnList().size(); j++) {
16773                                                                                                if (stmt.getResultColumnList().getResultColumn(j).getColumnNameOnly()
16774                                                                                                                .endsWith("*")) {
16775                                                                                                        starCount += 1;
16776                                                                                                }
16777                                                                                        }
16778                                                                                        if (starCount <= 1) {
16779                                                                                                resultSetModel.setDetermined(true);
16780                                                                                        }
16781                                                                                }
16782                                                                                continue;
16783                                                                        }
16784                                                                }
16785                                                                
16786                                                                ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
16787                                                                if (modelManager.getModel(sourceTable) instanceof Table) {
16788                                                                        Table tableModel = (Table) modelManager.getModel(sourceTable);
16789                                                                        if (tableModel != null) {
16790                                                                                modelFactory.createTableColumn(tableModel, columnObject, false);
16791                                                                        }
16792                                                                        TObjectName[] columns = modelManager.getTableColumns(sourceTable);
16793                                                                        for (int j = 0; j < columns.length; j++) {
16794                                                                                TObjectName columnName = columns[j];
16795                                                                                if (columnName == null || "*".equals(getColumnName(columnName))) {
16796                                                                                        continue;
16797                                                                                }
16798                                                                                resultColumn.bindStarLinkColumn(columnName);
16799                                                                        }
16800
16801                                                                        if (tableModel.getColumns() != null) {
16802                                                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
16803                                                                                        TableColumn tableColumn = tableModel.getColumns().get(j);
16804                                                                                        TObjectName columnName = tableColumn.getColumnObject();
16805                                                                                        if (columnName == null || "*".equals(getColumnName(columnName))) {
16806                                                                                                continue;
16807                                                                                        }
16808                                                                                        resultColumn.bindStarLinkColumn(columnName);
16809                                                                                }
16810                                                                        }
16811                                                                } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
16812                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
16813                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16814                                                                                for (ResultColumn item : tableModel.getColumns()) {
16815                                                                                        if (item.hasStarLinkColumn()) {
16816                                                                                                for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
16817                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
16818                                                                                                }
16819                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
16820                                                                                                resultColumn.bindStarLinkColumn((TObjectName) item.getColumnObject());
16821                                                                                        } else if (item.getColumnObject() instanceof TResultColumn) {
16822                                                                                                TResultColumn queryTableColumn = (TResultColumn) item.getColumnObject();
16823                                                                                                TObjectName tableColumnObject = queryTableColumn.getFieldAttr();
16824                                                                                                if (tableColumnObject != null) {
16825                                                                                                        resultColumn.bindStarLinkColumn(tableColumnObject);
16826                                                                                                } else if (queryTableColumn.getAliasClause() != null) {
16827                                                                                                        resultColumn.bindStarLinkColumn(
16828                                                                                                                        queryTableColumn.getAliasClause().getAliasName());
16829                                                                                                }
16830                                                                                        }
16831                                                                                }
16832                                                                        }
16833                                                                }
16834                                                        } else {
16835                                                                ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
16836                                                                TTableList tables = stmt.getTables();
16837                                                                for (int k = 0; k < tables.size(); k++) {
16838                                                                        TTable table = tables.getTable(k);
16839                                                                        TObjectName[] columns = modelManager.getTableColumns(table);
16840                                                                        for (int j = 0; j < columns.length; j++) {
16841                                                                                TObjectName columnName = columns[j];
16842                                                                                if (columnName == null) {
16843                                                                                        continue;
16844                                                                                }
16845                                                                                if ("*".equals(getColumnName(columnName))) {
16846                                                                                        if (modelManager.getModel(table) instanceof Table) {
16847                                                                                                Table tableModel = (Table) modelManager.getModel(table);
16848                                                                                                if (tableModel != null) {
16849                                                                                                        modelFactory.createTableColumn(tableModel, columnName, false);
16850                                                                                                }
16851                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16852                                                                                                        for (int z = 0; z < tableModel.getColumns().size(); z++) {
16853                                                                                                                resultColumn.bindStarLinkColumn(
16854                                                                                                                                tableModel.getColumns().get(z).getColumnObject());
16855                                                                                                        }
16856                                                                                                }
16857                                                                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
16858                                                                                                QueryTable tableModel = (QueryTable) modelManager.getModel(table);
16859                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
16860                                                                                                        for (ResultColumn item : tableModel.getColumns()) {
16861                                                                                                                if (item.hasStarLinkColumn()) {
16862                                                                                                                        for (TObjectName starLinkColumn : item
16863                                                                                                                                        .getStarLinkColumnList()) {
16864                                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
16865                                                                                                                        }
16866                                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
16867                                                                                                                        resultColumn.bindStarLinkColumn(
16868                                                                                                                                        (TObjectName) item.getColumnObject());
16869                                                                                                                } else if (item.getColumnObject() instanceof TResultColumn) {
16870                                                                                                                        TResultColumn queryTableColumn = (TResultColumn) item
16871                                                                                                                                        .getColumnObject();
16872                                                                                                                        TObjectName tableColumnObject = queryTableColumn
16873                                                                                                                                        .getFieldAttr();
16874                                                                                                                        if (tableColumnObject != null) {
16875                                                                                                                                resultColumn.bindStarLinkColumn(tableColumnObject);
16876                                                                                                                        } else if (queryTableColumn.getAliasClause() != null) {
16877                                                                                                                                resultColumn.bindStarLinkColumn(queryTableColumn
16878                                                                                                                                                .getAliasClause().getAliasName());
16879                                                                                                                        }
16880                                                                                                                }
16881                                                                                                        }
16882                                                                                                }
16883                                                                                        }
16884                                                                                        continue;
16885                                                                                }
16886                                                                                resultColumn.bindStarLinkColumn(columnName);
16887                                                                        }
16888                                                                }
16889                                                        }
16890                                                }
16891                                                else {
16892                                                        ResultColumn resultColumn  = modelFactory.createResultColumn(resultSetModel, column);   
16893                                                }
16894                                                
16895                                                analyzeResultColumn(column, EffectType.select);
16896
16897                                        }
16898                                        
16899                                        if (queryModel instanceof ResultSet) {
16900                                                boolean isDetermined = true;
16901                                                ResultSet resultSet = (ResultSet) queryModel;
16902                                                for (ResultColumn column : resultSet.getColumns()) {
16903                                                        if (column.getName().endsWith("*")) {
16904                                                                isDetermined = false;
16905                                                                break;
16906                                                        }
16907                                                }
16908                                                if (isDetermined) {
16909                                                        resultSet.setDetermined(isDetermined);
16910                                                }
16911                                        }
16912                                }
16913                        }
16914
16915                
16916                        analyzeSelectIntoClause(stmt);
16917                
16918
16919                        if (stmt.getJoins() != null && stmt.getJoins().size() > 0) {
16920                                for (int i = 0; i < stmt.getJoins().size(); i++) {
16921                                        TJoin join = stmt.getJoins().getJoin(i);
16922                                        ResultSet topResultSet = (ResultSet) modelManager.getModel(stmt);
16923                                        if (join.getJoinItems() != null && join.getJoinItems().size() > 0) {
16924                                                for (int k = 0; k < join.getJoinItems().size(); k++) {
16925                                                        TTable table = join.getJoinItems().getJoinItem(k).getTable();
16926                                                        if (table != null && table.getSubquery() != null) {
16927                                                                
16928                                                                ResultSet joinResultSet = (ResultSet) modelManager.getModel(table.getSubquery());
16929                                                                for (int x = 0; x < joinResultSet.getColumns().size(); x++) {
16930                                                                        ResultColumn sourceColumn = joinResultSet.getColumns().get(x);
16931                                                                        ResultColumn resultColumn = matchResultColumn(topResultSet.getColumns(),
16932                                                                                        sourceColumn);
16933                                                                        if (resultColumn != null
16934                                                                                        && resultColumn.getColumnObject() instanceof TResultColumn) {
16935                                                                                TResultColumn column = (TResultColumn) resultColumn.getColumnObject();
16936                                                                                if (column.getAliasClause() == null && column.getFieldAttr() != null) {
16937                                                                                        TObjectName resultObject = column.getFieldAttr();
16938                                                                                        if (resultObject.getSourceTable() == null
16939                                                                                                        || resultObject.getSourceTable().equals(table)) {
16940                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
16941                                                                                                                .createDataFlowRelation();
16942                                                                                                combinedQueryRelation.setEffectType(EffectType.select);
16943                                                                                                combinedQueryRelation
16944                                                                                                                .setTarget(new ResultColumnRelationshipElement(resultColumn));
16945                                                                                                combinedQueryRelation
16946                                                                                                                .addSource(new ResultColumnRelationshipElement(sourceColumn));
16947                                                                                        }
16948                                                                                }
16949                                                                        }
16950                                                                }
16951                                                        }
16952                                                        
16953                                                        if(join.getJoinItems().getJoinItem(k).getJoin()!=null) {
16954                                                                analyzeJoin(join.getJoinItems().getJoinItem(k).getJoin(), EffectType.select);
16955                                                        }
16956                                                }
16957                                        }
16958                                        analyzeJoin(join, EffectType.select);
16959                                }
16960                        }
16961
16962                        if (stmt.getWhereClause() != null) {
16963                                TExpression expr = stmt.getWhereClause().getCondition();
16964                                if (expr != null) {
16965                                        analyzeFilterCondition(null, expr, null, JoinClauseType.where, EffectType.select);
16966                                }
16967                        }
16968
16969                        stmtStack.pop();
16970                }
16971        }
16972
16973        protected TObjectNameList getTableLinkedColumns(TTable table) {
16974                if(structObjectMap.containsKey(table)) {
16975                        return structObjectMap.get(table);
16976                }
16977                return table.getLinkedColumns();
16978        }
16979
16980        protected boolean isTopResultSet(TSelectSqlStatement stmt) {
16981                TCustomSqlStatement parent = stmt.getParentStmt();
16982                if (parent == null)
16983                        return true;
16984                if (parent instanceof TMssqlReturn) {
16985                        return true;
16986                }
16987                if (parent instanceof TReturnStmt) {
16988                        return true;
16989                }
16990                if (parent instanceof TCommonBlock) {
16991                        TCommonBlock block = (TCommonBlock) parent;
16992                        if (block.getStatements() != null) {
16993                                for (int i = 0; i < block.getStatements().size(); i++) {
16994                                        TCustomSqlStatement child = block.getStatements().get(i);
16995                                        if(stmt == child) {
16996                                                return true;
16997                                        }
16998                                }
16999                        }
17000                }
17001                if (parent instanceof TMssqlBlock) {
17002                        TMssqlBlock block = (TMssqlBlock) parent;
17003                        if (block.getStatements() != null) {
17004                                for (int i = 0; i < block.getStatements().size(); i++) {
17005                                        TCustomSqlStatement child = block.getStatements().get(i);
17006                                        if(stmt == child) {
17007                                                return true;
17008                                        }
17009                                }
17010                        }
17011                }
17012                if (parent instanceof TStoredProcedureSqlStatement) {
17013                        TStoredProcedureSqlStatement block = (TStoredProcedureSqlStatement) parent;
17014                        if (block.getStatements() != null) {
17015                                for (int i = 0; i < block.getStatements().size(); i++) {
17016                                        TCustomSqlStatement child = block.getStatements().get(i);
17017                                        if(child == stmt) {
17018                                                return true;
17019                                        }
17020                                        if (child instanceof TReturnStmt) {
17021                                                TReturnStmt returnStmt = (TReturnStmt) child;
17022                                                if (returnStmt.getStatements() != null) {
17023                                                        for (int j = 0; j < returnStmt.getStatements().size(); j++) {
17024                                                                TCustomSqlStatement child1 = returnStmt.getStatements().get(j);
17025                                                                if(child1 == stmt) {
17026                                                                        return true;
17027                                                                }
17028                                                        }
17029                                                }
17030                                        }
17031                                        if (child instanceof TMssqlReturn) {
17032                                                TMssqlReturn returnStmt = (TMssqlReturn) child;
17033                                                if (returnStmt.getStatements() != null) {
17034                                                        for (int j = 0; j < returnStmt.getStatements().size(); j++) {
17035                                                                TCustomSqlStatement child1 = returnStmt.getStatements().get(j);
17036                                                                if(child1 == stmt) {
17037                                                                        return true;
17038                                                                }
17039                                                        }
17040                                                }
17041                                        }
17042                                }
17043                        }
17044                }
17045                return false;
17046        }
17047
17048        protected void analyzeTableSubquery(TTable table) {
17049                if(table.getSubquery()!=null) {
17050                        QueryTable queryTable = modelFactory.createQueryTable(table);
17051                        TSelectSqlStatement subquery = table.getSubquery();
17052                        analyzeSelectStmt(subquery);
17053
17054                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
17055
17056                        if (resultSetModel != null && resultSetModel != queryTable
17057                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
17058                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
17059                                impactRelation.setEffectType(EffectType.select);
17060                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
17061                                                resultSetModel.getRelationRows()));
17062                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
17063                                                queryTable.getRelationRows()));
17064                        }
17065
17066                        if (resultSetModel != null && resultSetModel != queryTable
17067                                        && queryTable.getTableObject().getAliasClause() != null
17068                                        && queryTable.getTableObject().getAliasClause().getColumns() != null) {
17069                                for (int j = 0; j < queryTable.getColumns().size()
17070                                                && j < resultSetModel.getColumns().size(); j++) {
17071                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
17072                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
17073
17074                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
17075                                        queryRalation.setEffectType(EffectType.select);
17076                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
17077                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
17078                                }
17079                        } else if (subquery.getSetOperatorType() != ESetOperatorType.none) {
17080                                SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
17081                                                .getModel(subquery);
17082                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
17083                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
17084                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
17085                                                        sourceColumn);
17086                                        for (TObjectName starLinkColumn : sourceColumn.getStarLinkColumnList()) {
17087                                                targetColumn.bindStarLinkColumn(starLinkColumn);
17088                                        }
17089                                        DataFlowRelationship selectSetRalation = modelFactory.createDataFlowRelation();
17090                                        selectSetRalation.setEffectType(EffectType.select);
17091                                        selectSetRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
17092                                        selectSetRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
17093                                }
17094                        }
17095                }
17096        }
17097
17098        private ResultColumn getPivotedTableColumn(TPivotedTable pivotedTable, TObjectName columnName) {
17099                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
17100                if (pivotedTable.getPivotClause() != null) {
17101                        pivotClauses.add(pivotedTable.getPivotClause());
17102                }
17103                if (pivotedTable.getPivotClauseList() != null) {
17104                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
17105                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
17106                        }
17107                }
17108                for (TPivotClause clause : pivotClauses) {
17109                        Object model = modelManager.getModel(clause);
17110                        if (model instanceof PivotedTable) {
17111                                PivotedTable pivotedTableModel = (PivotedTable) model;
17112                                if (pivotedTableModel.getColumns() != null) {
17113                                        for (ResultColumn column : pivotedTableModel.getColumns()) {
17114                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
17115                                                                getColumnName(SQLUtil.trimColumnStringQuote(column.getName())))) {
17116                                                        return column;
17117                                                }
17118                                        }
17119                                }
17120                        }
17121                }
17122                return null;
17123        }
17124
17125        private void analyzeHiveTransformClause(TSelectSqlStatement stmt, THiveTransformClause transformClause) {
17126                Table mapSourceTable = null;
17127                QueryTable mapQueryTable = null;
17128                if(stmt.getTables()!=null) {
17129                        for(int i=0;i<stmt.getTables().size();i++) {
17130                                TTable table = stmt.getTables().getTable(i);
17131                                if (table.getSubquery() != null) {
17132                                        if (transformClause.getTransformType() == ETransformType.ettReduce) {
17133                                                mapQueryTable = modelFactory.createQueryTable(table);
17134                                        }
17135                                        analyzeSelectStmt(table.getSubquery());
17136                                }
17137                                else {
17138                                        mapSourceTable = modelFactory.createTable(table);
17139                                }
17140                        }
17141                }
17142                
17143                if (transformClause.getTransformType() == ETransformType.ettReduce) {
17144                        modelFactory.createResultSet(stmt, false);
17145                }
17146                
17147                List<TableColumn> mapTableColumns = new ArrayList<TableColumn>();
17148                List<ResultColumn> mapResultSetColumns = new ArrayList<ResultColumn>();
17149                List<ResultColumn> redueResultSetColumns = new ArrayList<ResultColumn>();
17150                
17151                if(transformClause.getExpressionList()!=null) {
17152                        for(TExpression expression: transformClause.getExpressionList()) {
17153                                if(expression.getObjectOperand()!=null) {
17154                                        if (transformClause.getTransformType() == ETransformType.ettMap || transformClause.getTransformType() == ETransformType.ettSelect) {
17155                                                if (mapSourceTable != null) {
17156                                                        TableColumn tableColumn = modelFactory.createTableColumn(mapSourceTable,
17157                                                                        expression.getObjectOperand(), false);
17158                                                        if (tableColumn != null) {
17159                                                                mapTableColumns.add(tableColumn);
17160                                                        }
17161                                                }
17162                                        }
17163                                        else if (transformClause.getTransformType() == ETransformType.ettReduce) {
17164                                                if (mapQueryTable != null) {
17165                                                        ResultColumn resultColumn = modelFactory.createResultColumn(mapQueryTable,
17166                                                                        expression.getObjectOperand(), false);
17167                                                        if (resultColumn != null) {
17168                                                                mapResultSetColumns.add(resultColumn);
17169                                                        }
17170                                                }
17171                                        }
17172                                }
17173                        }
17174                }
17175                
17176                if (transformClause.getAliasClause() != null) {
17177                        Object model = modelManager.getModel(stmt);
17178                        if (model instanceof ResultSet) {
17179                                ResultSet result = (ResultSet) model;
17180                                if (result!=null && transformClause.getAliasClause().getColumns() != null) {
17181                                        for (TObjectName column : transformClause.getAliasClause().getColumns()) {
17182                                                ResultColumn resultColumn = modelFactory.createResultColumn(result, column);
17183                                                if (resultColumn != null) {
17184                                                        if (transformClause.getTransformType() == ETransformType.ettMap 
17185                                                                        || transformClause.getTransformType() == ETransformType.ettSelect) {
17186                                                                mapResultSetColumns.add(resultColumn);
17187                                                        }
17188                                                        else if (transformClause.getTransformType() == ETransformType.ettReduce) {
17189                                                                redueResultSetColumns.add(resultColumn);
17190                                                        }
17191                                                }
17192                                        }
17193                                }
17194                        }
17195                }
17196                
17197                if (transformClause.getTransformType() == ETransformType.ettMap 
17198                                || transformClause.getTransformType() == ETransformType.ettSelect) {
17199                        if (!mapTableColumns.isEmpty() && !mapResultSetColumns.isEmpty()) {
17200                                for (ResultColumn resultColumn : mapResultSetColumns) {
17201                                        for (TableColumn tableColumn : mapTableColumns) {
17202                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17203                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17204                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17205                                                relation.setEffectType(EffectType.select);
17206                                        }
17207                                }
17208                        }
17209                }
17210                else if (transformClause.getTransformType() == ETransformType.ettReduce) {
17211                        if (!redueResultSetColumns.isEmpty() && !mapResultSetColumns.isEmpty()) {
17212                                for (ResultColumn reduceResultColumn : redueResultSetColumns) {
17213                                        for (ResultColumn mapResultColumn : mapResultSetColumns) {
17214                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17215                                                relation.setTarget(new ResultColumnRelationshipElement(reduceResultColumn));
17216                                                relation.addSource(new ResultColumnRelationshipElement(mapResultColumn));
17217                                                relation.setEffectType(EffectType.select);
17218                                        }
17219                                }
17220                        }
17221                }
17222        }
17223
17224        protected boolean isStructColumn(TObjectName columnName) {
17225                return columnName.getSourceTable() != null && columnName.getSourceTable().getAliasClause() != null
17226                                && columnName.getSourceTable().getUnnestClause() != null
17227                                && DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
17228                                                getColumnName(columnName.getSourceTable().getAliasClause().getAliasName()));
17229        }
17230
17231        private TObjectName getObjectName(ResultColumn column) {
17232                if (column.getColumnObject() instanceof TResultColumn) {
17233                        TResultColumn resultColumn = (TResultColumn) column.getColumnObject();
17234                        if (resultColumn.getAliasClause() != null && resultColumn.getAliasClause().getAliasName() != null) {
17235                                return resultColumn.getAliasClause().getAliasName();
17236                        }
17237                        if (resultColumn.getFieldAttr() != null) {
17238                                return resultColumn.getFieldAttr();
17239                        }
17240                        if (resultColumn.getExpr() != null
17241                                        && resultColumn.getExpr().getExpressionType() == EExpressionType.simple_object_name_t) {
17242                                return resultColumn.getExpr().getObjectOperand();
17243                        }
17244                } else if (column.getColumnObject() instanceof TObjectName) {
17245                        return (TObjectName) column.getColumnObject();
17246                }
17247                return null;
17248        }
17249
17250        private boolean isShowTopSelectResultSet() {
17251                if (option.isSimpleOutput() && !option.isSimpleShowTopSelectResultSet())
17252                        return false;
17253                return true;
17254        }
17255
17256        private void analyzeSelectIntoClause(TSelectSqlStatement stmt) {
17257                if (stmt.getParentStmt() instanceof TSelectSqlStatement) {
17258                        return;
17259                }
17260                
17261                TableColumn oracleIntoTableColumn = null;
17262                
17263                TIntoClause intoClause = stmt.getIntoClause();
17264                
17265                TSelectSqlStatement leftStmt = DlineageUtil.getLeftStmt(stmt);
17266                
17267                if (intoClause == null && leftStmt != null) {
17268                        intoClause = leftStmt.getIntoClause();
17269                }
17270                
17271                if (intoClause != null) {
17272                        List<TObjectName> tableNames = new ArrayList<TObjectName>();
17273                        if (intoClause.getExprList() != null) {
17274                                for (int j = 0; j < intoClause.getExprList().size(); j++) {
17275                                        TObjectName tableName = intoClause.getExprList().getExpression(j).getObjectOperand();
17276                                        if (tableName != null) {
17277                                                if (tableName.toString().startsWith(":") && option.getVendor() == EDbVendor.dbvoracle
17278                                                                && tableName.getDbObjectType() == EDbObjectType.column) {
17279                                                        TObjectName tableAlias = new TObjectName();
17280                                                        tableAlias.setString(tableName.getTableString());
17281                                                        tableNames.add(tableAlias);
17282                                                        TTable sourceTable = tableName.getSourceTable();
17283                                                        Table sourceTableModel = modelFactory.createTable(sourceTable, tableAlias);
17284                                                        oracleIntoTableColumn = modelFactory.createTableColumn(sourceTableModel, tableName, true);
17285                                                } else {
17286                                                        if (tableName != null) {
17287                                                                tableNames.add(tableName);
17288                                                        }
17289                                                }
17290                                        }
17291                                        else if(intoClause.getExprList().getExpression(j).getFunctionCall()!=null) {
17292                                                TObjectName variableName = intoClause.getExprList().getExpression(j).getFunctionCall().getFunctionName();
17293                                                tableNames.add(variableName);
17294                                                Variable variable = modelFactory.createVariable(variableName);
17295                                                variable.setSubType(SubType.record);
17296                                                TObjectName variableProperties = new TObjectName();
17297                                                variableProperties.setString("*");
17298                                                modelFactory.createTableColumn(variable, variableProperties, true);
17299                                        }
17300                                }
17301                        } else if (intoClause.getVariableList() != null) {
17302                                for (int j = 0; j < intoClause.getVariableList().size(); j++) {
17303                                        TObjectName tableName = intoClause.getVariableList().getObjectName(j);
17304                                        if (tableName != null) {
17305                                                tableNames.add(tableName);
17306                                        }
17307                                }
17308                        } else if (intoClause.getIntoName() != null) {
17309                                tableNames.add(intoClause.getIntoName());
17310                        }
17311
17312                        ResultSet queryModel = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
17313                        if (stmt.getSetOperatorType() != ESetOperatorType.none) {
17314                                queryModel = (ResultSet) modelManager.getModel(stmt);
17315                        }
17316                        for (int j = 0; j < tableNames.size(); j++) {
17317                                TObjectName tableName = tableNames.get(j);
17318                                if (tableName.getColumnNameOnly().startsWith("@")
17319                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
17320                                        continue;
17321                                }
17322
17323                                if (tableName.getColumnNameOnly().startsWith(":")
17324                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
17325                                        continue;
17326                                }
17327
17328                                Table tableModel;
17329                                TableColumn variableColumn = null;
17330
17331                                if (tableName.getDbObjectType() == EDbObjectType.variable) {
17332                                        if (tableName.toString().indexOf(".") != -1) {
17333                                                List<String> splits = SQLUtil.parseNames(tableName.toString());
17334                                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
17335                                        } else {
17336                                                tableModel = modelFactory.createVariable(tableName);
17337                                        }
17338                                        if (tableModel.getSubType() == null) {
17339                                                tableModel.setSubType(SubType.record);
17340                                        }
17341                                        if(tableModel.getColumns() == null || tableModel.getColumns().isEmpty()) {
17342                                                TObjectName variableProperties = new TObjectName();
17343                                                variableProperties.setString("*");
17344                                                variableColumn = modelFactory.createTableColumn(tableModel, variableProperties, true);
17345                                        }
17346                                } else {
17347                                        tableModel = modelFactory.createTableByName(tableName);
17348                                }
17349                                
17350                                if (queryModel instanceof ResultSet && (stmt.getWhereClause() != null || hasJoin(stmt))) {
17351                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
17352                                        impactRelation.setEffectType(EffectType.insert);
17353                                        impactRelation.addSource(
17354                                                        new RelationRowsRelationshipElement<ResultSetRelationRows>(((ResultSet)queryModel).getRelationRows()));
17355                                        impactRelation.setTarget(
17356                                                        new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
17357                                }
17358                                
17359                                Process process = modelFactory.createProcess(stmt);
17360                                tableModel.addProcess(process);
17361                                
17362                                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
17363                                        for (ResultColumn resultColumn : queryModel.getColumns()) {
17364                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17365                                                                resultColumn.getName());
17366
17367                                                if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
17368                                                                && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
17369                                                        TSQLSchema schema = sqlenv
17370                                                                        .getSQLSchema(tableModel.getDatabase() + "." + tableModel.getSchema(), true);
17371                                                        if (schema != null) {
17372                                                                TSQLTable tempTable = schema
17373                                                                                .createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
17374                                                                tempTable.addColumn(tableColumn.getName());
17375                                                        }
17376                                                }
17377
17378                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17379                                                relation.setEffectType(EffectType.insert);
17380                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17381                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17382                                                relation.setProcess(process);
17383                                        }
17384                                        
17385                                        tableModel.setDetermined(queryModel.isDetermined());
17386                                        if(queryModel.isDetermined() && DlineageUtil.isTempTable(tableModel, option.getVendor())) {
17387                                                tableModel.setCreateTable(true, false);
17388                                        }
17389                                        return;
17390                                }
17391
17392                                boolean isDetermined = true;
17393                                for (int i = 0; i < stmt.getResultColumnList().size(); i++) {
17394                                        if (tableNames.size() > 1 && tableName.getDbObjectType() == EDbObjectType.variable) {
17395                                                if (i != j) {
17396                                                        continue;
17397                                                }
17398                                        }
17399                                        TResultColumn column = stmt.getResultColumnList().getResultColumn(i);
17400
17401                                        if ("*".equals(column.getColumnNameOnly()) && column.getFieldAttr() != null
17402                                                        && column.getFieldAttr().getSourceTable() != null) {
17403                                                Object model = modelManager.getModel(column);
17404                                                if(model instanceof LinkedHashMap) {
17405                                                        LinkedHashMap<String, ResultColumn> columns = (LinkedHashMap<String, ResultColumn>)model;
17406                                                        for(String key: columns.keySet()) {
17407                                                                ResultColumn sourceColumn = columns.get(key);
17408                                                                TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17409                                                                                sourceColumn.getName());
17410                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17411                                                                relation.setEffectType(EffectType.insert);
17412                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17413                                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
17414                                                                relation.setProcess(process);
17415                                                        }
17416                                                }
17417                                                else if(model instanceof ResultColumn) {
17418                                                        isDetermined = false;
17419                                                        ResultColumn resultColumn = (ResultColumn) model;
17420                                                        List<TObjectName> columns = resultColumn.getStarLinkColumnList();
17421                                                        if (columns.size() > 0) {
17422                                                                for (int k = 0; k < columns.size(); k++) {
17423        
17424                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17425                                                                                        columns.get(k));
17426        
17427                                                                        if (DlineageUtil.isTempTable(tableModel, option.getVendor()) && sqlenv != null
17428                                                                                        && tableModel.getDatabase() != null && tableModel.getSchema() != null) {
17429                                                                                TSQLSchema schema = sqlenv.getSQLSchema(
17430                                                                                                tableModel.getDatabase() + "." + tableModel.getSchema(), true);
17431                                                                                if (schema != null) {
17432                                                                                        TSQLTable tempTable = schema.createTable(DlineageUtil.getSimpleTableName(tableModel.getName()));
17433                                                                                        tempTable.addColumn(tableColumn.getName());
17434                                                                                }
17435                                                                        }
17436        
17437                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17438                                                                        relation.setEffectType(EffectType.insert);
17439                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17440                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17441                                                                        relation.setProcess(process);
17442                                                                }
17443                                                                if (resultColumn.isShowStar()) {
17444                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17445                                                                                        column.getFieldAttr());
17446                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17447                                                                        relation.setEffectType(EffectType.insert);
17448                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17449                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17450                                                                        relation.setProcess(process);
17451                                                                }
17452                                                        } else {
17453                                                                TObjectName columnObject = column.getFieldAttr();
17454                                                                if (column.getAliasClause() != null) {
17455                                                                        columnObject = column.getAliasClause().getAliasName();
17456                                                                }
17457                                                                if (columnObject != null) {
17458                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17459                                                                                        columnObject);
17460                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17461                                                                        relation.setEffectType(EffectType.insert);
17462                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17463                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17464                                                                        relation.setProcess(process);
17465                                                                } else if (!SQLUtil.isEmpty(column.getColumnAlias())) {
17466                                                                        TableColumn tableColumn = modelFactory.createInsertTableColumn(tableModel,
17467                                                                                        column.getAliasClause().getAliasName());
17468                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17469                                                                        relation.setEffectType(EffectType.insert);
17470                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17471                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17472                                                                        relation.setProcess(process);
17473                                                                }
17474                                                        }
17475                                                }
17476                                        } else {
17477                                                ResultColumn resultColumn = null;
17478
17479                                                if (queryModel instanceof QueryTable) {
17480                                                        resultColumn = (ResultColumn) modelManager.getModel(column);
17481                                                } else if (queryModel instanceof ResultSet) {
17482                                                        resultColumn = (ResultColumn) modelManager.getModel(column);
17483                                                } else {
17484                                                        continue;
17485                                                }
17486
17487                                                if (resultColumn == null && column.getAliasClause() != null) {
17488                                                        resultColumn = (ResultColumn) modelManager.getModel(column.getAliasClause().getAliasName());
17489                                                }
17490
17491                                                if (resultColumn != null) {
17492                                                        TObjectName columnObject = column.getFieldAttr();
17493                                                        if (column.getAliasClause() != null) {
17494                                                                columnObject = column.getAliasClause().getAliasName();
17495                                                        }
17496                                                        TableColumn tableColumn = null;
17497                                                        if (columnObject != null) {
17498                                                                if (tableModel.isVariable()) {
17499                                                                        if (variableColumn != null) {
17500                                                                                tableColumn = variableColumn;
17501                                                                        } else {
17502                                                                                tableColumn = tableModel.getColumns().get(0);
17503                                                                        }
17504                                                                } 
17505                                                                else if (oracleIntoTableColumn != null) {
17506                                                                        tableColumn = oracleIntoTableColumn;
17507                                                                }
17508                                                                else {
17509                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel, columnObject);
17510                                                                        if (containStarColumn(queryModel)) {
17511                                                                                tableColumn.notBindStarLinkColumn(true);
17512                                                                        }
17513                                                                }
17514                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17515                                                                relation.setEffectType(EffectType.insert);
17516                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17517                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17518                                                                relation.setProcess(process);
17519                                                        } else if (!SQLUtil.isEmpty(column.getColumnAlias())) {
17520                                                                if (tableModel.isVariable()) {
17521                                                                        if (variableColumn != null) {
17522                                                                                tableColumn = variableColumn;
17523                                                                        } else {
17524                                                                                tableColumn = tableModel.getColumns().get(0);
17525                                                                        }
17526                                                                } else {
17527                                                                        tableColumn = modelFactory.createInsertTableColumn(tableModel,
17528                                                                                        column.getAliasClause().getAliasName());
17529                                                                }
17530                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17531                                                                relation.setEffectType(EffectType.insert);
17532                                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17533                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17534                                                                relation.setProcess(process);
17535                                                        } else {
17536                                                                if (tableModel.isVariable()) {
17537                                                                        if (variableColumn != null) {
17538                                                                                tableColumn = variableColumn;
17539                                                                        } else {
17540                                                                                tableColumn = tableModel.getColumns().get(0);
17541                                                                        }
17542                                                                }
17543                                                                if (tableColumn != null) {
17544                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17545                                                                        relation.setEffectType(EffectType.insert);
17546                                                                        relation.setTarget(new TableColumnRelationshipElement(tableColumn));
17547                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17548                                                                        relation.setProcess(process);
17549                                                                }
17550                                                        }
17551                                                }
17552                                        }
17553                                }
17554                                tableModel.setDetermined(isDetermined);
17555                                if(isDetermined && DlineageUtil.isTempTable(tableModel, option.getVendor())) {
17556                                        tableModel.setCreateTable(true, false);
17557                                }
17558                        }
17559                }
17560        }
17561
17562        private boolean isUnPivotedTable(TPivotedTable pivotedTable) {
17563                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
17564                        return pivotedTable.getPivotClauseList().getElement(0).getType() == TPivotClause.unpivot;
17565                } else {
17566                        TPivotClause pivotClause = pivotedTable.getPivotClause();
17567                        return pivotClause.getType() == TPivotClause.unpivot;
17568                }
17569        }
17570
17571        private void analyzeUnPivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) {
17572                List<Object> tables = new ArrayList<Object>();
17573                Set<Object> pivotedColumns = new HashSet<Object>();
17574                TTable fromTable = pivotedTable.getTableSource();
17575                Object table = modelManager.getModel(fromTable);
17576                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
17577                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
17578                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
17579                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
17580                        }
17581                } else {
17582                        TPivotClause pivotClause = pivotedTable.getPivotClause();
17583                        pivotClauses.add(pivotClause);
17584                }
17585
17586                for (int y = 0; y < pivotClauses.size(); y++) {
17587                        TPivotClause pivotClause = pivotClauses.get(y);
17588                        PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause);
17589                        pivotTable.setUnpivoted(true);
17590
17591                        if (pivotClause.getValueColumnList() != null) {
17592                                for (int j = 0; j < pivotClause.getValueColumnList().size(); j++) {
17593                                        modelFactory.createResultColumn(pivotTable, pivotClause.getValueColumnList().getObjectName(j));
17594                                }
17595                        }
17596                        if (pivotClause.getPivotColumnList() != null) {
17597                                for (int j = 0; j < pivotClause.getPivotColumnList().size(); j++) {
17598                                        modelFactory.createResultColumn(pivotTable, pivotClause.getPivotColumnList().getObjectName(j));
17599                                }
17600                        }
17601                        if (pivotClause.getUnpivotInClause()!=null && pivotClause.getUnpivotInClause().getItems() != null) {
17602                                for (int j = 0; j < pivotClause.getUnpivotInClause().getItems().size(); j++) {
17603                                        TObjectName columnName = pivotClause.getUnpivotInClause().getItems().getElement(j).getColumn();
17604                                        if (columnName != null) {
17605                                                if (table instanceof QueryTable) {
17606                                                        for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
17607                                                                if (getColumnName(columnName)
17608                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17609                                                                        for (ResultColumn resultColumn : pivotTable.getColumns()) {
17610                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17611                                                                                relation.setEffectType(EffectType.select);
17612                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17613                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17614                                                                                pivotedColumns.add(tableColumn);
17615                                                                        }
17616                                                                        break;
17617                                                                }
17618                                                        }
17619                                                } else if (table instanceof Table) {
17620                                                        for (TableColumn tableColumn : ((Table) table).getColumns()) {
17621                                                                if (getColumnName(columnName)
17622                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17623                                                                        for (ResultColumn resultColumn : pivotTable.getColumns()) {
17624                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17625                                                                                relation.setEffectType(EffectType.select);
17626                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17627                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17628                                                                                pivotedColumns.add(tableColumn);
17629                                                                        }
17630                                                                        break;
17631                                                                }
17632                                                        }
17633                                                }
17634                                        } else {
17635                                                TObjectNameList columnNames = pivotClause.getUnpivotInClause().getItems().getElement(j)
17636                                                                .getColumnList();
17637                                                for (TObjectName columnName1 : columnNames) {
17638                                                        if (table instanceof QueryTable) {
17639                                                                for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
17640                                                                        if (getColumnName(columnName1).equals(
17641                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17642                                                                                for (ResultColumn resultColumn : pivotTable.getColumns()) {
17643                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17644                                                                                        relation.setEffectType(EffectType.select);
17645                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17646                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17647                                                                                        pivotedColumns.add(tableColumn);
17648                                                                                }
17649                                                                                break;
17650                                                                        }
17651                                                                }
17652                                                        } else if (table instanceof Table) {
17653                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17654                                                                        if (getColumnName(columnName1).equals(
17655                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17656                                                                                for (ResultColumn resultColumn : pivotTable.getColumns()) {
17657                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17658                                                                                        relation.setEffectType(EffectType.select);
17659                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17660                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17661                                                                                        pivotedColumns.add(tableColumn);
17662                                                                                }
17663                                                                                break;
17664                                                                        }
17665                                                                }
17666                                                        }
17667                                                }
17668                                        }
17669                                }
17670                        }
17671                        tables.add(pivotTable);
17672                        tables.add(table);
17673                }
17674
17675                ResultSet resultSet = modelFactory.createResultSet(stmt,
17676                                isTopResultSet(stmt) && isShowTopSelectResultSet());
17677                TResultColumnList columnList = stmt.getResultColumnList();
17678                for (int i = 0; i < columnList.size(); i++) {
17679                        TResultColumn column = columnList.getResultColumn(i);
17680                        ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
17681                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
17682                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
17683                                if (columnObject.getFieldAttr() != null) {
17684                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
17685                                                resultColumn.setShowStar(false);
17686                                                int index = 0;
17687                                                for (int k = 0; k < tables.size(); k++) {
17688                                                        Object tableItem = tables.get(k);
17689                                                        if (tableItem instanceof ResultSet) {
17690                                                                for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) {
17691                                                                        ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
17692                                                                        if (pivotedColumns.contains(tableColumn)) {
17693                                                                                continue;
17694                                                                        }
17695                                                                        if (tableColumn.getColumnObject() instanceof TObjectName) {
17696                                                                                resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject());
17697                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17698                                                                                relation.setEffectType(EffectType.select);
17699                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17700                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17701                                                                        } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
17702                                                                                if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
17703                                                                                        if (tableColumn.hasStarLinkColumn()) {
17704                                                                                                for (int z = 0; z < tableColumn.getStarLinkColumnList().size(); z++) {
17705                                                                                                        ResultColumn resultColumn1 = modelFactory.createResultColumn(
17706                                                                                                                        (ResultSet) tableItem,
17707                                                                                                                        tableColumn.getStarLinkColumnList().get(z));
17708                                                                                                        DataFlowRelationship relation = modelFactory
17709                                                                                                                        .createDataFlowRelation();
17710                                                                                                        relation.setEffectType(EffectType.select);
17711                                                                                                        relation.setTarget(
17712                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
17713                                                                                                        relation.addSource(
17714                                                                                                                        new ResultColumnRelationshipElement(resultColumn1));
17715                                                                                                        tableColumn.getStarLinkColumns().remove(
17716                                                                                                                        getColumnName(tableColumn.getStarLinkColumnList().get(z)));
17717                                                                                                        z--;
17718                                                                                                }
17719                                                                                        } else {
17720                                                                                                resultColumn.bindStarLinkColumn(
17721                                                                                                                ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr());
17722                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17723                                                                                                relation.setEffectType(EffectType.select);
17724                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr()));
17725                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17726                                                                                        }
17727                                                                                } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) {
17728                                                                                        TExpression expr = ((TResultColumn) tableColumn.getColumnObject())
17729                                                                                                        .getExpr();
17730                                                                                        if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
17731                                                                                                TObjectName columnName = new TObjectName();
17732                                                                                                columnName.setString(expr.toString());
17733                                                                                                resultColumn.bindStarLinkColumn(columnName);
17734                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17735                                                                                                relation.setEffectType(EffectType.select);
17736                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, columnName));
17737                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17738                                                                                        }
17739                                                                                }
17740                                                                        }
17741                                                                }
17742                                                        } else if (tableItem instanceof Table) {
17743                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17744                                                                        if (pivotedColumns.contains(tableColumn)) {
17745                                                                                continue;
17746                                                                        }
17747                                                                        resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(), index);
17748                                                                        index++;
17749                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17750                                                                        relation.setEffectType(EffectType.select);
17751                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
17752                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
17753                                                                }
17754                                                        }
17755                                                }
17756                                        } else {
17757                                                for (int k = 0; k < tables.size(); k++) {
17758                                                        Object tableItem = tables.get(k);
17759                                                        if (tableItem instanceof ResultSet) {
17760                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
17761                                                                        if (getColumnName(columnObject.getFieldAttr()).equals(
17762                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17763                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17764                                                                                relation.setEffectType(EffectType.select);
17765                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17766                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17767                                                                                break;
17768                                                                        }
17769                                                                }
17770                                                        } else if (tableItem instanceof Table) {
17771                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
17772                                                                        if (getColumnName(columnObject.getFieldAttr()).equals(
17773                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17774                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17775                                                                                relation.setEffectType(EffectType.select);
17776                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17777                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17778                                                                                break;
17779                                                                        }
17780                                                                }
17781                                                        }
17782                                                }
17783                                        }
17784                                } else if (columnObject.getExpr() != null) {
17785                                        analyzeResultColumn(column, EffectType.select);
17786                                }
17787                        }
17788                }
17789        }
17790
17791        private void analyzePivotedTable(TSelectSqlStatement stmt, TPivotedTable pivotedTable) {
17792                List<Object> tables = new ArrayList<Object>();
17793                Set<Object> pivotedColumns = new HashSet<Object>();
17794                TTable fromTable = pivotedTable.getTableSource();
17795                Object table = modelManager.getModel(fromTable);
17796                if(table == null && fromTable.getSubquery()!=null) {
17797                        table = modelFactory.createQueryTable(fromTable);
17798                        TSelectSqlStatement subquery = fromTable.getSubquery();
17799                        analyzeSelectStmt(subquery);
17800                }
17801                List<TPivotClause> pivotClauses = new ArrayList<TPivotClause>();
17802                if (pivotedTable.getPivotClauseList() != null && pivotedTable.getPivotClauseList().size() > 0) {
17803                        for (int i = 0; i < pivotedTable.getPivotClauseList().size(); i++) {
17804                                pivotClauses.add(pivotedTable.getPivotClauseList().getElement(i));
17805                        }
17806                } else {
17807                        TPivotClause pivotClause = pivotedTable.getPivotClause();
17808                        pivotClauses.add(pivotClause);
17809                }
17810
17811                for (int y = 0; y < pivotClauses.size(); y++) {
17812                        TPivotClause pivotClause = pivotClauses.get(y);
17813                        List<TFunctionCall> functionCalls = new ArrayList<TFunctionCall>();
17814                        if (pivotClause.getAggregation_function() != null || pivotClause.getAggregation_function_list() != null) {
17815                                if (pivotClause.getAggregation_function() != null) {
17816                                        functionCalls.add((TFunctionCall) pivotClause.getAggregation_function());
17817                                } else if (pivotClause.getAggregation_function_list() != null) {
17818                                        for (int i = 0; i < pivotClause.getAggregation_function_list().size(); i++) {
17819                                                functionCalls.add((TFunctionCall) pivotClause.getAggregation_function_list().getResultColumn(i)
17820                                                                .getExpr().getFunctionCall());
17821                                        }
17822                                }
17823
17824                                if (functionCalls.isEmpty()) {
17825                                        return;
17826                                }
17827
17828                                if (pivotClause.getPivotColumnList() == null) {
17829                                        return;
17830                                }
17831
17832                                if (pivotClause.getPivotInClause() == null) {
17833                                        return;
17834                                }
17835
17836                                for (int x = 0; x < functionCalls.size(); x++) {
17837                                        TFunctionCall functionCall = functionCalls.get(x);
17838                                        Function function = modelFactory.createFunction(functionCall);
17839                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
17840                                                        ((TFunctionCall) functionCall).getFunctionName());
17841
17842                                        List<TExpression> expressions = new ArrayList<TExpression>();
17843                                        getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall);
17844
17845                                        for (int j = 0; j < expressions.size(); j++) {
17846                                                columnsInExpr visitor = new columnsInExpr();
17847                                                expressions.get(j).inOrderTraverse(visitor);
17848                                                List<TObjectName> objectNames = visitor.getObjectNames();
17849                                                if (objectNames == null) {
17850                                                        continue;
17851                                                }
17852                                                for (TObjectName columnName : objectNames) {
17853                                                        if (table instanceof QueryTable) {
17854                                                                for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) {
17855                                                                        boolean find = false;
17856                                                                        ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i);
17857                                                                        if (tableColumn.hasStarLinkColumn()) {
17858                                                                                for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) {
17859                                                                                        TObjectName objectName = tableColumn.getStarLinkColumnList().get(k);
17860                                                                                        if (getColumnName(columnName).equals(getColumnName(objectName))) {
17861                                                                                                ResultColumn resultColumn = modelFactory
17862                                                                                                                .createResultColumn((QueryTable) table, objectName);
17863                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17864                                                                                                relation.setEffectType(EffectType.select);
17865                                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17866                                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17867                                                                                                pivotedColumns.add(resultColumn);
17868                                                                                                tableColumn.getStarLinkColumns()
17869                                                                                                                .remove(DlineageUtil.getColumnName(objectName));
17870                                                                                                find = true;
17871                                                                                                break;
17872                                                                                        }
17873                                                                                }
17874                                                                        } else if (getColumnName(columnName).equals(
17875                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17876                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17877                                                                                relation.setEffectType(EffectType.select);
17878                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17879                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17880                                                                                pivotedColumns.add(tableColumn);
17881                                                                                find = true;
17882                                                                                break;
17883                                                                        } 
17884                                                                        
17885                                                                        if (!find && tableColumn.getName().endsWith("*")) {
17886                                                                                QueryTable queryTable = (QueryTable)table;
17887                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(queryTable, columnName);
17888                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17889                                                                                relation.setEffectType(EffectType.select);
17890                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17891                                                                                relation.addSource(new ResultColumnRelationshipElement(resultColumn));
17892                                                                                tableColumn.bindStarLinkColumn(columnName);
17893                                                                        }
17894                                                                }
17895                                                        } else if (table instanceof Table) {
17896                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17897                                                                        if (getColumnName(columnName).equals(
17898                                                                                        DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
17899                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17900                                                                                relation.setEffectType(EffectType.select);
17901                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17902                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17903                                                                                pivotedColumns.add(tableColumn);
17904                                                                                break;
17905                                                                        }
17906                                                                }
17907                                                        }
17908                                                }
17909                                        }
17910
17911                                        PivotedTable pivotTable = modelFactory.createPivotdTable(pivotClause);
17912                                        pivotTable.setUnpivoted(false);
17913
17914                                        if (pivotClause.getPivotInClause().getItems() != null) {
17915                                                for (int j = 0; j < pivotClause.getPivotInClause().getItems().size(); j++) {
17916                                                        ResultColumn resultColumn = null;
17917                                                        if (pivotClause.getAggregation_function_list() != null
17918                                                                        && pivotClause.getAggregation_function_list().size() > 1) {
17919                                                                TResultColumn functionColumn = pivotClause.getAggregation_function_list()
17920                                                                                .getResultColumn(x);
17921                                                                TObjectName tableColumn = new TObjectName();
17922                                                                if (option.getVendor() == EDbVendor.dbvbigquery) {
17923                                                                        tableColumn.setString(getResultColumnString(functionColumn) + "_"
17924                                                                                        + SQLUtil.trimColumnStringQuote(getResultColumnString(
17925                                                                                                        pivotClause.getPivotInClause().getItems().getResultColumn(j))));
17926                                                                }
17927                                                                else {
17928                                                                        tableColumn.setString(SQLUtil
17929                                                                                        .trimColumnStringQuote(getResultColumnString(
17930                                                                                                        pivotClause.getPivotInClause().getItems().getResultColumn(j)))
17931                                                                                        + "_" + getResultColumnString(functionColumn));
17932                                                                }
17933                                                                resultColumn = modelFactory.createResultColumn(pivotTable, tableColumn);
17934                                                        } else {
17935                                                                resultColumn = modelFactory.createSelectSetResultColumn(pivotTable,
17936                                                                                pivotClause.getPivotInClause().getItems().getResultColumn(j), j);
17937                                                        }
17938                                                        {
17939                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17940                                                                relation.setEffectType(EffectType.select);
17941                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17942                                                                relation.addSource(new ResultColumnRelationshipElement(column));
17943                                                        }
17944                                                        {
17945                                                                for (TObjectName columnName : pivotClause.getPivotColumnList()) {
17946                                                                        if (table instanceof QueryTable) {
17947                                                                                for (int i = 0; i < ((QueryTable) table).getColumns().size(); i++) {
17948                                                                                        ResultColumn tableColumn = ((QueryTable) table).getColumns().get(i);
17949                                                                                        if (tableColumn.hasStarLinkColumn()) {
17950                                                                                                for (int k = 0; k < tableColumn.getStarLinkColumnList().size(); k++) {
17951                                                                                                        TObjectName objectName = tableColumn.getStarLinkColumnList().get(k);
17952                                                                                                        if (getColumnName(columnName).equals(getColumnName(objectName))) {
17953                                                                                                                ResultColumn resultColumn1 = modelFactory
17954                                                                                                                                .createResultColumn((QueryTable) table, objectName);
17955                                                                                                                DataFlowRelationship relation = modelFactory
17956                                                                                                                                .createDataFlowRelation();
17957                                                                                                                relation.setEffectType(EffectType.select);
17958                                                                                                                relation.setTarget(new ResultColumnRelationshipElement(column));
17959                                                                                                                relation.addSource(
17960                                                                                                                                new ResultColumnRelationshipElement(resultColumn1));
17961                                                                                                                pivotedColumns.add(resultColumn1);
17962                                                                                                                tableColumn.getStarLinkColumns()
17963                                                                                                                                .remove(DlineageUtil.getColumnName(objectName));
17964                                                                                                                break;
17965                                                                                                        }
17966                                                                                                }
17967                                                                                        } else if (getColumnName(columnName).equals(DlineageUtil
17968                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17969                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17970                                                                                                relation.setEffectType(EffectType.select);
17971                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17972                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
17973                                                                                                pivotedColumns.add(tableColumn);
17974                                                                                                break;
17975                                                                                        }
17976                                                                                }
17977                                                                        } else if (table instanceof Table) {
17978                                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
17979                                                                                        if (getColumnName(columnName).equals(DlineageUtil
17980                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
17981                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
17982                                                                                                relation.setEffectType(EffectType.select);
17983                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
17984                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
17985                                                                                                pivotedColumns.add(tableColumn);
17986                                                                                                break;
17987                                                                                        }
17988                                                                                }
17989                                                                        }
17990                                                                }
17991                                                        }
17992                                                }
17993                                        } else if (pivotClause.getPivotInClause().getSubQuery() != null) {
17994                                                TSelectSqlStatement subquery = pivotClause.getPivotInClause().getSubQuery();
17995                                                analyzeSelectStmt(subquery);
17996                                                ResultSet selectSetResultSetModel = (ResultSet) modelManager.getModel(subquery);
17997                                                for (int j = 0; j < subquery.getResultColumnList().size(); j++) {
17998                                                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(pivotTable,
17999                                                                        subquery.getResultColumnList().getResultColumn(j), j);
18000                                                        {
18001                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18002                                                                relation.setEffectType(EffectType.select);
18003                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18004                                                                relation.addSource(new ResultColumnRelationshipElement(column));
18005                                                                relation.addSource(new ResultColumnRelationshipElement(
18006                                                                                selectSetResultSetModel.getColumns().get(j)));
18007                                                        }
18008                                                        {
18009                                                                for (TObjectName columnName : pivotClause.getPivotColumnList()) {
18010                                                                        if (table instanceof QueryTable) {
18011                                                                                for (ResultColumn tableColumn : ((QueryTable) table).getColumns()) {
18012                                                                                        if (getColumnName(columnName).equals(DlineageUtil
18013                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
18014                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18015                                                                                                relation.setEffectType(EffectType.select);
18016                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18017                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18018                                                                                                pivotedColumns.add(tableColumn);
18019                                                                                                break;
18020                                                                                        }
18021                                                                                }
18022                                                                        } else if (table instanceof Table) {
18023                                                                                for (TableColumn tableColumn : ((Table) table).getColumns()) {
18024                                                                                        if (getColumnName(columnName).equals(DlineageUtil
18025                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
18026                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18027                                                                                                relation.setEffectType(EffectType.select);
18028                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18029                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18030                                                                                                pivotedColumns.add(tableColumn);
18031                                                                                                break;
18032                                                                                        }
18033                                                                                }
18034                                                                        }
18035                                                                }
18036                                                        }
18037                                                }
18038                                        }
18039                                        tables.add(pivotTable);
18040                                        tables.add(table);
18041                                }
18042                        }
18043                }
18044
18045                TPivotClause pivotClause = pivotClauses.get(0);
18046                boolean hasAlias = pivotClause.getAliasClause() != null && pivotClause.getAliasClause().getColumns() != null
18047                                && pivotClause.getAliasClause().getColumns().size() > 0;
18048                if (hasAlias) {
18049                        Alias alias = modelFactory.createAlias(pivotClause.getAliasClause());
18050                        List<TObjectName> aliasColumns = new ArrayList<TObjectName>();
18051                        int index = 0;
18052                        for (int k = 0; k < tables.size(); k++) {
18053                                Object tableItem = tables.get(k);
18054                                if (tableItem instanceof ResultSet) {
18055                                        for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
18056                                                if (pivotedColumns.contains(tableColumn)) {
18057                                                        continue;
18058                                                }
18059                                                if (tableColumn.getColumnObject() instanceof TObjectName) {
18060                                                        aliasColumns.add((TObjectName) tableColumn.getColumnObject());
18061                                                } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
18062                                                        if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
18063                                                                aliasColumns.add(((TResultColumn) tableColumn.getColumnObject()).getFieldAttr());
18064                                                        } else {
18065                                                                TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr();
18066                                                                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
18067                                                                        TObjectName columnName = new TObjectName();
18068                                                                        columnName.setString(expr.toString());
18069                                                                        aliasColumns.add(columnName);
18070                                                                }
18071                                                        }
18072                                                }
18073                                        }
18074                                } else if (tableItem instanceof Table) {
18075                                        for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18076                                                if (pivotedColumns.contains(tableColumn)) {
18077                                                        continue;
18078                                                }
18079                                                aliasColumns.add(index, (TObjectName) tableColumn.getColumnObject());
18080                                                index++;
18081                                        }
18082                                }
18083                        }
18084
18085                        IndexedLinkedHashMap<String, ResultColumn> aliasColumnMap = new IndexedLinkedHashMap<String, ResultColumn>();
18086                        int diffCount = pivotClause.getAliasClause().getColumns().size() -  aliasColumns.size();
18087                        for (int k = 0; k < pivotClause.getAliasClause().getColumns().size(); k++) {
18088                                if (pivotClause.getAliasClause().getColumns().size() > aliasColumns.size()) {
18089                                        if (k < diffCount) {
18090                                                continue;
18091                                        }
18092                                        ResultColumn resultColumn = modelFactory.createResultColumn(alias,
18093                                                        pivotClause.getAliasClause().getColumns().getObjectName(k));
18094                                        if ((k - diffCount) < aliasColumns.size()) {
18095                                                aliasColumnMap.put(aliasColumns.get(k - diffCount).toString(), resultColumn);
18096                                        }
18097                                } else {
18098                                        ResultColumn resultColumn = modelFactory.createResultColumn(alias,
18099                                                        pivotClause.getAliasClause().getColumns().getObjectName(k));
18100                                        if (k < aliasColumns.size()) {
18101                                                aliasColumnMap.put(aliasColumns.get(k).toString(), resultColumn);
18102                                        }
18103                                }
18104                        }
18105
18106                        for (int k = 0; k < tables.size(); k++) {
18107                                Object tableItem = tables.get(k);
18108                                if (tableItem instanceof ResultSet) {
18109                                        int resultColumnSize = ((ResultSet) tableItem).getColumns().size();
18110                                        for (int x = 0; x < resultColumnSize; x++) {
18111                                                ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
18112                                                if (pivotedColumns.contains(tableColumn)) {
18113                                                        continue;
18114                                                }
18115                                                if (tableColumn.getColumnObject() instanceof TObjectName) {
18116                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18117                                                        relation.setEffectType(EffectType.select);
18118                                                        relation.setTarget(new ResultColumnRelationshipElement(
18119                                                                        aliasColumnMap.get(tableColumn.getColumnObject().toString())));
18120                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18121                                                } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
18122                                                        if (((TResultColumn) tableColumn.getColumnObject()).getFieldAttr() != null) {
18123                                                                ResultColumn targetColumn = aliasColumnMap.get(
18124                                                                                ((TResultColumn) tableColumn.getColumnObject()).getFieldAttr().toString());
18125                                                                if(targetColumn == null) {
18126                                                                        continue;
18127                                                                }
18128                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18129                                                                relation.setEffectType(EffectType.select);
18130                                                                relation.setTarget(new ResultColumnRelationshipElement(targetColumn));
18131                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18132                                                        } else if (((TResultColumn) tableColumn.getColumnObject()).getExpr() != null) {
18133                                                                TExpression expr = ((TResultColumn) tableColumn.getColumnObject()).getExpr();
18134                                                                if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
18135                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18136                                                                        relation.setEffectType(EffectType.select);
18137                                                                        ResultColumn targetColumn = (ResultColumn) aliasColumnMap
18138                                                                                        .getValueAtIndex(aliasColumnMap.size() - resultColumnSize + x);
18139                                                                        relation.setTarget(new ResultColumnRelationshipElement(targetColumn));
18140                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18141                                                                }
18142                                                        }
18143                                                }
18144                                        }
18145                                } else if (tableItem instanceof Table) {
18146                                        for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18147                                                if (pivotedColumns.contains(tableColumn)) {
18148                                                        continue;
18149                                                }
18150                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18151                                                relation.setEffectType(EffectType.select);
18152                                                relation.setTarget(new ResultColumnRelationshipElement(
18153                                                                aliasColumnMap.get(tableColumn.getColumnObject().toString())));
18154                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18155                                        }
18156                                }
18157                        }
18158
18159                        ResultSet resultSet = modelFactory.createResultSet(stmt,
18160                                        isTopResultSet(stmt) && isShowTopSelectResultSet());
18161                        TResultColumnList columnList = stmt.getResultColumnList();
18162                        for (int i = 0; i < columnList.size(); i++) {
18163                                TResultColumn column = columnList.getResultColumn(i);
18164                                ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
18165                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
18166                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
18167                                        if (columnObject.getFieldAttr() != null) {
18168                                                if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
18169                                                        resultColumn.setShowStar(false);
18170                                                        for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
18171                                                                resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject());
18172                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18173                                                                relation.setEffectType(EffectType.select);
18174                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
18175                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18176                                                        }
18177                                                } else {
18178                                                        for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
18179                                                                if (getColumnName(columnObject.getFieldAttr())
18180                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18181                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18182                                                                        relation.setEffectType(EffectType.select);
18183                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18184                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18185                                                                        break;
18186                                                                }
18187                                                        }
18188                                                }
18189                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
18190                                                        .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
18191                                                for (ResultColumn tableColumn : ((ResultSet) alias).getColumns()) {
18192                                                        if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand())
18193                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18194                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18195                                                                relation.setEffectType(EffectType.select);
18196                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18197                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18198                                                                break;
18199                                                        }
18200                                                }
18201                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
18202                                                        .getExpressionType() == EExpressionType.function_t) {
18203                                                Function function = (Function) createFunction(columnObject.getExpr().getFunctionCall());
18204                                                for (ResultColumn arg : function.getColumns()) {
18205                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18206                                                        relation.setEffectType(EffectType.select);
18207                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18208                                                        relation.addSource(new ResultColumnRelationshipElement(arg));
18209                                                }
18210                                        }
18211                                }
18212                        }
18213                } else {
18214                        ResultSet resultSet = modelFactory.createResultSet(stmt, isTopResultSet(stmt));
18215                        TResultColumnList columnList = stmt.getResultColumnList();
18216                        for (int i = 0; i < columnList.size(); i++) {
18217                                TResultColumn column = columnList.getResultColumn(i);
18218                                ResultColumn resultColumn = modelFactory.createAndBindingSelectSetResultColumn(resultSet, column, i);
18219                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
18220                                        boolean fromFunction = false;
18221                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
18222                                        TObjectName resultColumnFieldAttr = columnObject.getFieldAttr();
18223                                        List<TObjectName> resultColumnNames = new ArrayList<TObjectName>();
18224                                        if (resultColumnFieldAttr != null) {
18225                                                resultColumnNames.add(resultColumnFieldAttr);
18226                                        } else if (columnObject.getExpr() != null
18227                                                        && column.getExpr().getExpressionType() == EExpressionType.function_t) {
18228                                                extractFunctionObjectNames(column.getExpr().getFunctionCall(), resultColumnNames);
18229                                                fromFunction = true;
18230                                        }
18231                                        
18232                                        if (!resultColumnNames.isEmpty()) {
18233                                                for (TObjectName resultColumnName : resultColumnNames) {
18234                                                        if ("*".equals(getColumnName(resultColumnName))) {
18235                                                                resultColumn.setShowStar(false);
18236                                                                int index = 0;
18237                                                                for (int k = 0; k < tables.size(); k++) {
18238                                                                        Object tableItem = tables.get(k);
18239                                                                        if (tableItem instanceof ResultSet && !(tableItem instanceof QueryTable)) {
18240                                                                                for (int x = 0; x < ((ResultSet) tableItem).getColumns().size(); x++) {
18241                                                                                        ResultColumn tableColumn = ((ResultSet) tableItem).getColumns().get(x);
18242                                                                                        if (pivotedColumns.contains(tableColumn)) {
18243                                                                                                continue;
18244                                                                                        }
18245                                                                                        if (tableColumn.getColumnObject() instanceof TObjectName) {
18246                                                                                                resultColumn.bindStarLinkColumn(
18247                                                                                                                (TObjectName) tableColumn.getColumnObject());
18248                                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18249                                                                                                relation.setEffectType(EffectType.select);
18250                                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
18251                                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18252                                                                                        } else if (tableColumn.getColumnObject() instanceof TResultColumn) {
18253                                                                                                if (((TResultColumn) tableColumn.getColumnObject())
18254                                                                                                                .getFieldAttr() != null) {
18255                                                                                                        if (tableColumn.hasStarLinkColumn()) {
18256                                                                                                                for (int z = 0; z < tableColumn.getStarLinkColumnList()
18257                                                                                                                                .size(); z++) {
18258                                                                                                                        ResultColumn resultColumn1 = modelFactory
18259                                                                                                                                        .createResultColumn((ResultSet) tableItem,
18260                                                                                                                                                        tableColumn.getStarLinkColumnList().get(z));
18261                                                                                                                        DataFlowRelationship relation = modelFactory
18262                                                                                                                                        .createDataFlowRelation();
18263                                                                                                                        relation.setEffectType(EffectType.select);
18264                                                                                                                        relation.setTarget(
18265                                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
18266                                                                                                                        relation.addSource(
18267                                                                                                                                        new ResultColumnRelationshipElement(resultColumn1));
18268                                                                                                                        tableColumn.getStarLinkColumns().remove(getColumnName(
18269                                                                                                                                        tableColumn.getStarLinkColumnList().get(z)));
18270                                                                                                                        z--;
18271                                                                                                                }
18272                                                                                                        } else {
18273                                                                                                                resultColumn.bindStarLinkColumn(
18274                                                                                                                                ((TResultColumn) tableColumn.getColumnObject())
18275                                                                                                                                                .getFieldAttr());
18276                                                                                                                DataFlowRelationship relation = modelFactory
18277                                                                                                                                .createDataFlowRelation();
18278                                                                                                                relation.setEffectType(EffectType.select);
18279                                                                                                                relation.setTarget(
18280                                                                                                                                new ResultColumnRelationshipElement(resultColumn, ((TResultColumn) tableColumn.getColumnObject())
18281                                                                                                                                                .getFieldAttr()));
18282                                                                                                                relation.addSource(
18283                                                                                                                                new ResultColumnRelationshipElement(tableColumn));
18284                                                                                                        }
18285                                                                                                } else if (((TResultColumn) tableColumn.getColumnObject())
18286                                                                                                                .getExpr() != null) {
18287                                                                                                        TExpression expr = ((TResultColumn) tableColumn.getColumnObject())
18288                                                                                                                        .getExpr();
18289                                                                                                        if (expr.getExpressionType() == EExpressionType.simple_constant_t) {
18290                                                                                                                TObjectName columnName = new TObjectName();
18291                                                                                                                columnName.setString(expr.toString());
18292                                                                                                                resultColumn.bindStarLinkColumn(columnName);
18293                                                                                                                DataFlowRelationship relation = modelFactory
18294                                                                                                                                .createDataFlowRelation();
18295                                                                                                                relation.setEffectType(EffectType.select);
18296                                                                                                                relation.setTarget(
18297                                                                                                                                new ResultColumnRelationshipElement(resultColumn, columnName));
18298                                                                                                                relation.addSource(
18299                                                                                                                                new ResultColumnRelationshipElement(tableColumn));
18300                                                                                                        }
18301                                                                                                }
18302                                                                                        }
18303                                                                                }
18304                                                                        } else if (tableItem instanceof Table) {
18305                                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18306                                                                                        if (pivotedColumns.contains(tableColumn)) {
18307                                                                                                continue;
18308                                                                                        }
18309                                                                                        resultColumn.bindStarLinkColumn((TObjectName) tableColumn.getColumnObject(),
18310                                                                                                        index);
18311                                                                                        index++;
18312                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18313                                                                                        relation.setEffectType(EffectType.select);
18314                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, (TObjectName) tableColumn.getColumnObject()));
18315                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18316                                                                                }
18317                                                                        } else if (tableItem instanceof QueryTable) {
18318                                                                                for (ResultColumn tableColumn : ((QueryTable) tableItem).getColumns()) {
18319                                                                                        if (pivotedColumns.contains(tableColumn)) {
18320                                                                                                continue;
18321                                                                                        }
18322                                                                                        TObjectName column1 = new TObjectName();
18323                                                                                        column1.setString(tableColumn.getName());
18324                                                                                        resultColumn.bindStarLinkColumn(column1, index);
18325                                                                                        index++;
18326                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18327                                                                                        relation.setEffectType(EffectType.select);
18328                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, column1));
18329                                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn), false);
18330                                                                                }
18331                                                                        }
18332                                                                }
18333                                                        } else {
18334                                                                ResultColumn pivotedTableColumn = getPivotedTableColumn(pivotedTable, resultColumnName);
18335                                                                        if (pivotedTableColumn != null) {
18336                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18337                                                                                relation.setEffectType(EffectType.select);
18338                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18339                                                                                relation.addSource(new ResultColumnRelationshipElement(pivotedTableColumn));
18340                                                                        } else {
18341                                                                                for (int k = 0; k < tables.size(); k++) {
18342                                                                                        Object tableItem = tables.get(k);
18343                                                                                        if (tableItem instanceof ResultSet) {
18344                                                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
18345                                                                                                        if (DlineageUtil
18346                                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()).equals(getColumnName(resultColumnName))) {
18347                                                                                                                if (fromFunction) {
18348                                                                                                                        Function function = (Function)createPivotedFunction(column.getExpr().getFunctionCall(), tableColumn);
18349                                                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18350                                                                                                                        relation.setEffectType(EffectType.select);
18351                                                                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18352                                                                                                                        if (function.getColumns() != null && !function.getColumns().isEmpty()) {
18353                                                                                                                                for (ResultColumn functionColumn : function.getColumns()) {
18354                                                                                                                                        relation.addSource(new ResultColumnRelationshipElement(functionColumn));
18355                                                                                                                                }
18356                                                                                                                        }
18357                                                                                                                } else {
18358                                                                                                                        DataFlowRelationship relation = modelFactory
18359                                                                                                                                        .createDataFlowRelation();
18360                                                                                                                        relation.setEffectType(EffectType.select);
18361                                                                                                                        relation.setTarget(
18362                                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
18363                                                                                                                        relation.addSource(
18364                                                                                                                                        new ResultColumnRelationshipElement(tableColumn));
18365                                                                                                                }
18366                                                                                                                break;
18367                                                                                                        }
18368                                                                                                }
18369                                                                                        } else if (tableItem instanceof Table) {
18370                                                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18371                                                                                                        if (getColumnName(resultColumnName).equals(DlineageUtil
18372                                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
18373                                                                                                                DataFlowRelationship relation = modelFactory
18374                                                                                                                                .createDataFlowRelation();
18375                                                                                                                relation.setEffectType(EffectType.select);
18376                                                                                                                relation.setTarget(
18377                                                                                                                                new ResultColumnRelationshipElement(resultColumn));
18378                                                                                                                relation.addSource(
18379                                                                                                                                new TableColumnRelationshipElement(tableColumn));
18380                                                                                                                break;
18381                                                                                                        }
18382                                                                                                }
18383                                                                                        }
18384                                                                                }
18385                                                                        }
18386                                                                }
18387                                                }
18388                                        } else if (columnObject.getExpr() != null && columnObject.getExpr()
18389                                                        .getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
18390                                                for (int k = 0; k < tables.size(); k++) {
18391                                                        Object tableItem = tables.get(k);
18392                                                        if (tableItem instanceof ResultSet) {
18393                                                                for (ResultColumn tableColumn : ((ResultSet) tableItem).getColumns()) {
18394                                                                        if (columnObject.getExpr().getRightOperand().getObjectOperand() != null
18395                                                                                        && getColumnName(
18396                                                                                                        columnObject.getExpr().getRightOperand().getObjectOperand())
18397                                                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(
18398                                                                                                                                        tableColumn.getName()))) {
18399                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18400                                                                                relation.setEffectType(EffectType.select);
18401                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18402                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18403                                                                                break;
18404                                                                        } else if (columnObject.getExpr().getRightOperand()
18405                                                                                        .getExpressionType() == EExpressionType.function_t) {
18406                                                                                List<TExpression> expressions = new ArrayList<TExpression>();
18407                                                                                getFunctionExpressions(expressions, new ArrayList<TExpression>(),
18408                                                                                                columnObject.getExpr().getRightOperand().getFunctionCall());
18409                                                                                for (int j = 0; j < expressions.size(); j++) {
18410                                                                                        columnsInExpr visitor = new columnsInExpr();
18411                                                                                        expressions.get(j).inOrderTraverse(visitor);
18412                                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
18413                                                                                        if (objectNames == null) {
18414                                                                                                continue;
18415                                                                                        }
18416                                                                                        for (TObjectName columnName : objectNames) {
18417                                                                                                if (getColumnName(columnName).equals(DlineageUtil
18418                                                                                                                .getIdentifierNormalColumnName(tableColumn.getName()))) {
18419                                                                                                        DataFlowRelationship relation = modelFactory
18420                                                                                                                        .createDataFlowRelation();
18421                                                                                                        relation.setEffectType(EffectType.select);
18422                                                                                                        relation.setTarget(
18423                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
18424                                                                                                        relation.addSource(
18425                                                                                                                        new ResultColumnRelationshipElement(tableColumn));
18426                                                                                                        break;
18427                                                                                                }
18428                                                                                        }
18429                                                                                }
18430                                                                        }
18431                                                                }
18432                                                        } else if (tableItem instanceof Table) {
18433                                                                for (TableColumn tableColumn : ((Table) tableItem).getColumns()) {
18434                                                                        if (getColumnName(columnObject.getExpr().getRightOperand().getObjectOperand())
18435                                                                                        .equals(DlineageUtil
18436                                                                                                        .getIdentifierNormalColumnName(tableColumn.getName()))) {
18437                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18438                                                                                relation.setEffectType(EffectType.select);
18439                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18440                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18441                                                                                break;
18442                                                                        }
18443                                                                }
18444                                                        }
18445                                                }
18446                                        }
18447                                }
18448                        }
18449                }
18450
18451                analyzeSelectIntoClause(stmt);
18452        }
18453
18454        private Function createPivotedFunction(TFunctionCall functionCall, ResultColumn sourceColumn) {
18455                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
18456                ResultColumn column = modelFactory.createFunctionResultColumn(function,
18457                                ((TFunctionCall) functionCall).getFunctionName());
18458                if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) {
18459                        // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP
18460                        // COUNT特殊处理,不和参数关联
18461                        if (option.isShowCountTableColumn()) {
18462                                analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn);
18463                        }
18464                } else {
18465                        analyzePivotedFunctionArgumentsDataFlowRelation(column, functionCall, sourceColumn);
18466                        Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function));
18467                        if (functionTableModelObjs!=null && functionTableModelObjs.iterator().next() instanceof ResultSet) {
18468                                ResultSet functionTableModel = (ResultSet) functionTableModelObjs.iterator().next();
18469                                if (functionTableModel.getColumns() != null) {
18470                                        for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
18471                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18472                                                        relation.setEffectType(EffectType.select);
18473                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18474                                                        relation.addSource(new ResultColumnRelationshipElement(
18475                                                                        functionTableModel.getColumns().get(j)));
18476                                        }
18477                                }
18478                        }
18479                }
18480                return function;
18481        }
18482
18483        private void analyzePivotedFunctionArgumentsDataFlowRelation(ResultColumn column, TFunctionCall functionCall,
18484                        ResultColumn sourceColumn) {
18485                List<TExpression> directExpressions = new ArrayList<TExpression>();
18486                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18487
18488                getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
18489
18490                for (int j = 0; j < directExpressions.size(); j++) {
18491                        columnsInExpr visitor = new columnsInExpr();
18492                        directExpressions.get(j).inOrderTraverse(visitor);
18493
18494                        List<TObjectName> objectNames = visitor.getObjectNames();
18495                        List<TParseTreeNode> constants = visitor.getConstants();
18496
18497                        if (objectNames != null) {
18498                                for (TObjectName name : objectNames) {
18499                                        if (DlineageUtil.compareColumnIdentifier(name.toString(), sourceColumn.getName())) {
18500                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18501                                                relation.setEffectType(EffectType.select);
18502                                                relation.setTarget(new ResultColumnRelationshipElement(column));
18503                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
18504                                        }
18505                                }
18506                        }
18507                        if (constants != null) {
18508                                for (TParseTreeNode name : constants) {
18509                                        if (name.toString().equals(sourceColumn.getName())) {
18510                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18511                                                relation.setEffectType(EffectType.select);
18512                                                relation.setTarget(new ResultColumnRelationshipElement(column));
18513                                                relation.addSource(new ResultColumnRelationshipElement(sourceColumn));
18514                                        }
18515                                }
18516                        }
18517                }
18518        }
18519        
18520        private void extractFunctionObjectNames(TFunctionCall functionCall, List<TObjectName> resultColumnNames) {
18521                List<TExpression> directExpressions = new ArrayList<TExpression>();
18522                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
18523
18524                getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
18525
18526                for (int j = 0; j < directExpressions.size(); j++) {
18527                        columnsInExpr visitor = new columnsInExpr();
18528                        directExpressions.get(j).inOrderTraverse(visitor);
18529
18530                        List<TObjectName> objectNames = visitor.getObjectNames();
18531                        List<TParseTreeNode> functions = visitor.getFunctions();
18532                        List<TParseTreeNode> constants = visitor.getConstants(); 
18533
18534                        if (objectNames != null) {
18535                                resultColumnNames.addAll(objectNames);
18536                        }
18537                        
18538                        if (constants != null) {
18539                                for(TParseTreeNode item: constants) {
18540                                        if(item instanceof TConstant && ((TConstant) item).getLiteralType().getText().equals(ELiteralType.string_et.getText())) {
18541                                                TObjectName object = new TObjectName();
18542                                                object.setString(item.toString());
18543                                                resultColumnNames.add(object);
18544                                        }
18545                                }
18546                        }
18547
18548                        if (functions != null && !functions.isEmpty()) {
18549                                for (TParseTreeNode function : functions) {
18550                                        if (function instanceof TFunctionCall) {
18551                                                extractFunctionObjectNames((TFunctionCall) function, resultColumnNames);
18552                                        }
18553                                }
18554                        }
18555                }
18556        }
18557
18558        private String getResultColumnString(TResultColumn resultColumn) {
18559                if (resultColumn.getAliasClause() != null) {
18560                        return resultColumn.getAliasClause().toString();
18561                }
18562                return resultColumn.toString();
18563        }
18564
18565        private void analyzeBigQueryUnnest(TSelectSqlStatement stmt, TTable table) {
18566                Table unnestTable = modelFactory.createTableFromCreateDDL(table, false, getTempTableName(table));
18567                unnestTable.setSubType(SubType.unnest);
18568                TUnnestClause clause = table.getUnnestClause();
18569                TExpression arrayExpr = clause.getArrayExpr();
18570                if (arrayExpr == null){
18571                        if (clause.getColumns() != null) {
18572                                for (TObjectName column : clause.getColumns()) {
18573                                        if (clause.getDerivedColumnList() != null) {
18574                                                unnestTable.setCreateTable(true);
18575                                                for (int i = 0; i < clause.getDerivedColumnList().size(); i++) {
18576                                                        TObjectName columnName = new TObjectName();
18577                                                        columnName.setString(column.getColumnNameOnly() + "."
18578                                                                        + clause.getDerivedColumnList().getObjectName(i).getColumnNameOnly());
18579                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true);
18580                                                        List<TObjectName> columns = new ArrayList<TObjectName>();
18581                                                        columns.add(column);
18582                                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18583                                                }
18584                                        }
18585                                        else {
18586                                                unnestTable.setCreateTable(true);
18587                                                boolean find = false;
18588                                                if (column.getSourceTable() != null && modelManager.getModel(column.getSourceTable()) instanceof Table) {
18589                                                        Table sourceTable = (Table)modelManager.getModel(column.getSourceTable());
18590                                                        if(sourceTable!=null) {
18591                                                                for(TableColumn tableColumn: sourceTable.getColumns()) {
18592                                                                        if(tableColumn.isStruct()) {
18593                                                                                List<String> names = SQLUtil.parseNames(tableColumn.getName());
18594                                                                                if (names.get(0).equalsIgnoreCase(column.getColumnNameOnly())) {
18595                                                                                        TObjectName columnName = new TObjectName();
18596                                                                                        columnName.setString(tableColumn.getName());
18597                                                                                        TableColumn unnestTableColumn = modelFactory.createTableColumn(unnestTable,
18598                                                                                                        columnName, true);
18599                                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18600                                                                                        relation.setEffectType(EffectType.select);
18601                                                                                        relation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
18602                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18603                                                                                        find = true;
18604                                                                                }
18605                                                                        }
18606                                                                }
18607                                                        }
18608                                                }
18609                                                if (!find) {
18610                                                        TObjectName colName = column;
18611                                                        if (table.getAliasClause() != null && table.getAliasClause().getAliasName() != null) {
18612                                                                colName = table.getAliasClause().getAliasName();
18613                                                        }
18614                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, colName, true);
18615                                                        List<TObjectName> columns = new ArrayList<TObjectName>();
18616                                                        columns.add(column);
18617                                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18618                                                }
18619                                        }
18620                                }
18621                        }
18622                        return;
18623                }
18624                List<TExpression> expressions = new ArrayList<TExpression>();
18625                TExpressionList values = arrayExpr.getExprList();
18626                if (values == null) {
18627                        expressions.add(arrayExpr);
18628                }
18629                else {
18630                        for(TExpression value: values) {
18631                                expressions.add(value);
18632                        }
18633                }
18634                for (TExpression value : expressions) {
18635                        unnestTable.setCreateTable(true);
18636                        if (value.getExpressionType() == EExpressionType.simple_object_name_t) {
18637                                if (table.getAliasClause() != null) {
18638                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18639                                                        table.getAliasClause().getAliasName(), true);
18640                                        columnsInExpr visitor = new columnsInExpr();
18641                                        value.inOrderTraverse(visitor);
18642                                        List<TObjectName> columns = visitor.getObjectNames();
18643                                        analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18644                                } else {
18645                                        TResultColumnList resultColumnList = stmt.getResultColumnList();
18646                                        for (int i = 0; i < resultColumnList.size(); i++) {
18647                                                TObjectName firstColumn = new TObjectName();
18648                                                firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly());
18649                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18650                                                columnsInExpr visitor = new columnsInExpr();
18651                                                value.inOrderTraverse(visitor);
18652                                                List<TObjectName> columns = visitor.getObjectNames();
18653                                                analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18654                                        }
18655                                }
18656                        } else if (value.getExpressionType() == EExpressionType.function_t) {
18657                                if (table.getAliasClause() != null) {
18658                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18659                                                        table.getAliasClause().getAliasName(), true);
18660                                        columnsInExpr visitor = new columnsInExpr();
18661                                        value.inOrderTraverse(visitor);
18662                                        List<TParseTreeNode> functions = visitor.getFunctions();
18663                                        analyzeFunctionDataFlowRelation(tableColumn, functions, EffectType.select, null);
18664                                } else {
18665                                        TResultColumnList resultColumnList = stmt.getResultColumnList();
18666                                        for (int i = 0; i < resultColumnList.size(); i++) {
18667                                                TObjectName firstColumn = new TObjectName();
18668                                                firstColumn.setString(resultColumnList.getResultColumn(0).getColumnNameOnly());
18669                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18670                                                columnsInExpr visitor = new columnsInExpr();
18671                                                value.inOrderTraverse(visitor);
18672                                                List<TObjectName> columns = visitor.getObjectNames();
18673                                                analyzeDataFlowRelation(tableColumn, columns, EffectType.select, null);
18674                                        }
18675                                }
18676                        } else if (value.getExpressionType() == EExpressionType.simple_constant_t) {
18677                                if (table.getAliasClause() != null) {
18678                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18679                                                        table.getAliasClause().getAliasName(), true);
18680                                        columnsInExpr visitor = new columnsInExpr();
18681                                        value.inOrderTraverse(visitor);
18682                                        List<TParseTreeNode> constants = visitor.getConstants();
18683                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18684                                } else {
18685                                        TObjectName firstColumn = new TObjectName();
18686                                        firstColumn.setString("f0_");
18687                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18688                                        columnsInExpr visitor = new columnsInExpr();
18689                                        value.inOrderTraverse(visitor);
18690                                        List<TParseTreeNode> constants = visitor.getConstants();
18691                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18692                                }
18693                        } else if (value.getExpressionType() == EExpressionType.list_t) {
18694                                if (arrayExpr.getTypeName() != null && arrayExpr.getTypeName().getColumnDefList() != null) {
18695                                        for (int i = 0; i < arrayExpr.getTypeName().getColumnDefList().size(); i++) {
18696                                                TColumnDefinition column = arrayExpr.getTypeName().getColumnDefList().getColumn(i);
18697                                                if (column != null && column.getColumnName() != null) {
18698                                                        TableColumn tableColumn = modelFactory.createTableColumn(unnestTable,
18699                                                                        column.getColumnName(), true);
18700                                                        columnsInExpr visitor = new columnsInExpr();
18701                                                        value.getExprList().getExpression(i).inOrderTraverse(visitor);
18702                                                        List<TParseTreeNode> constants = visitor.getConstants();
18703                                                        analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18704                                                }
18705                                        }
18706                                } else {
18707                                        for (int i = 0; i < value.getExprList().size(); i++) {
18708                                                TObjectName firstColumn = new TObjectName();
18709                                                firstColumn.setString("f" + i + "_");
18710                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, firstColumn, true);
18711                                                columnsInExpr visitor = new columnsInExpr();
18712                                                value.getExprList().getExpression(i).inOrderTraverse(visitor);
18713                                                List<TParseTreeNode> constants = visitor.getConstants();
18714                                                analyzeConstantDataFlowRelation(tableColumn, constants, EffectType.select, null);
18715                                        }
18716                                }
18717                        } else if (value.getExpressionType() == EExpressionType.subquery_t) {
18718                                analyzeSelectStmt(value.getSubQuery());
18719                                ResultSet resultSet = (ResultSet) modelManager.getModel(value.getSubQuery());
18720                                if (resultSet != null) {
18721                                        for (int i = 0; i < resultSet.getColumns().size(); i++) {
18722                                                TObjectName columnName =  new TObjectName();
18723                                                if(resultSet.getColumns().get(i).getAlias()!=null) {
18724                                                        columnName.setString(resultSet.getColumns().get(i).getAlias());
18725                                                }
18726                                                else {
18727                                                        columnName.setString(getColumnName(resultSet.getColumns().get(i).getName()));
18728                                                }
18729                                                TableColumn tableColumn = modelFactory.createTableColumn(unnestTable, columnName, true);
18730                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18731                                                relation.setEffectType(EffectType.select);
18732                                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
18733                                                relation.addSource(
18734                                                                new ResultColumnRelationshipElement(resultSet.getColumns().get(i)));
18735                                        }
18736                                }
18737                        }
18738                }
18739        }
18740
18741        private void analyzePrestoUnnest(TSelectSqlStatement stmt, TTable table) {
18742                List<Table> tables = new ArrayList<Table>();
18743                TTable targetTable = stmt.getTables().getTable(0);
18744                Table stmtTable = modelFactory.createTable(targetTable);
18745                Object sourceTable = null;
18746                if (targetTable.getSubquery() != null) {
18747                        analyzeSelectStmt(targetTable.getSubquery());
18748                        if (targetTable.getSubquery().isCombinedQuery()) {
18749                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(targetTable.getSubquery());
18750                                sourceTable = sourceResultSet;
18751                        } else if (targetTable.getSubquery().getResultColumnList() != null) {
18752                                ResultSet sourceResultSet = (ResultSet) modelManager
18753                                                .getModel(targetTable.getSubquery().getResultColumnList());
18754                                sourceTable = sourceResultSet;
18755                        } else if (targetTable.getSubquery().getValueClause() != null) {
18756                                List<TResultColumnList> rowList = targetTable.getSubquery().getValueClause().getRows();
18757                                if (rowList != null && rowList.size() > 0) {
18758                                        Table valuesTable = modelFactory.createTableByName("Values-Table", true);
18759                                        int columnCount = rowList.get(0).size();
18760                                        for (int j = 1; j <= columnCount; j++) {
18761                                                TObjectName columnName = new TObjectName();
18762                                                TResultColumn columnObject = rowList.get(0).getResultColumn(j - 1);
18763                                                if (columnObject.getExpr().getExpressionType() == EExpressionType.typecast_t) {
18764                                                        columnName.setString(columnObject.getExpr().getLeftOperand().toString());
18765                                                } else {
18766                                                        columnName.setString(columnObject.getExpr().toString());
18767                                                }
18768                                                modelFactory.createTableColumn(valuesTable, columnName, true);
18769                                        }
18770                                        valuesTable.setCreateTable(true);
18771                                        valuesTable.setSubType(SubType.values_table);
18772                                        sourceTable = valuesTable;
18773                                }
18774                        }
18775                }
18776                tables.add(stmtTable);
18777                Table unnestTable = modelFactory.createTable(table);
18778                unnestTable.setSubType(SubType.unnest);
18779                tables.add(unnestTable);
18780                if (table.getAliasClause() != null && table.getAliasClause().getColumns() != null
18781                                && table.getUnnestClause().getColumns() != null) {
18782                        int unnestTableSize = table.getUnnestClause().getColumns().size();
18783                        for (int i = 0; i < table.getAliasClause().getColumns().size(); i++) {
18784                                TableColumn sourceColumn = null;
18785                                if (unnestTableSize > i) {
18786                                        sourceColumn = modelFactory.createTableColumn(stmtTable,
18787                                                        table.getUnnestClause().getColumns().getObjectName(i), true);
18788                                        if (sourceTable instanceof Table) {
18789                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18790                                                relation.setEffectType(EffectType.select);
18791                                                relation.setTarget(new TableColumnRelationshipElement(sourceColumn));
18792                                                relation.addSource(
18793                                                                new TableColumnRelationshipElement(((Table) sourceTable).getColumns().get(i)));
18794                                        } else if (sourceTable instanceof ResultSet) {
18795                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18796                                                relation.setEffectType(EffectType.select);
18797                                                relation.setTarget(new TableColumnRelationshipElement(sourceColumn));
18798                                                relation.addSource(
18799                                                                new ResultColumnRelationshipElement(((ResultSet) sourceTable).getColumns().get(i)));
18800                                        }
18801                                } else {
18802                                        sourceColumn = modelFactory.createTableColumn(stmtTable,
18803                                                        table.getUnnestClause().getColumns().getObjectName(unnestTableSize - 1), true);
18804                                }
18805                                TableColumn targetColumn = modelFactory.createTableColumn(unnestTable,
18806                                                table.getAliasClause().getColumns().getObjectName(i), true);
18807                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18808                                relation.setEffectType(EffectType.select);
18809                                relation.setTarget(new TableColumnRelationshipElement(targetColumn));
18810                                relation.addSource(new TableColumnRelationshipElement(sourceColumn));
18811                        }
18812                }
18813
18814                ResultSet resultSet = modelFactory.createResultSet(stmt,
18815                                isTopResultSet(stmt) && isShowTopSelectResultSet());
18816                TResultColumnList columnList = stmt.getResultColumnList();
18817                for (int i = 0; i < columnList.size(); i++) {
18818                        TResultColumn column = columnList.getResultColumn(i);
18819                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
18820                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
18821                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
18822                                if (columnObject.getFieldAttr() != null) {
18823                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
18824                                                for (int k = 0; k < tables.size(); k++) {
18825                                                        Table tableItem = tables.get(k);
18826                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18827                                                                resultColumn.bindStarLinkColumn(tableColumn.getColumnObject());
18828                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18829                                                                relation.setEffectType(EffectType.select);
18830                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject()));
18831                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
18832                                                        }
18833                                                }
18834                                        } else {
18835                                                boolean match = false;
18836                                                for (int k = 0; k < tables.size(); k++) {
18837                                                        Table tableItem = tables.get(k);
18838                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18839                                                                if (getColumnName(columnObject.getFieldAttr())
18840                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18841                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18842                                                                        relation.setEffectType(EffectType.select);
18843                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18844                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18845                                                                        match = true;
18846                                                                }
18847                                                        }
18848                                                }
18849                                                if (!match) {
18850                                                        TableColumn tableColumn = modelFactory.createTableColumn(stmtTable,
18851                                                                        columnObject.getFieldAttr(), false);
18852                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18853                                                        relation.setEffectType(EffectType.select);
18854                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
18855                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18856                                                }
18857                                        }
18858                                }
18859                        }
18860                }
18861        }
18862
18863        private void analyzeLateralView(TSelectSqlStatement stmt, TTable table, ArrayList<TLateralView> lateralViews) {
18864                List<Object> tables = new ArrayList<Object>();
18865                Object stmtTable = null;
18866                if(table.getSubquery()!=null) {
18867                        stmtTable = modelFactory.createQueryTable(table);
18868                        tables.add(stmtTable);
18869                }
18870                else {
18871                        stmtTable = modelFactory.createTable(table);
18872                        tables.add(stmtTable);
18873                }
18874                for (int i = 0; i < lateralViews.size(); i++) {
18875                        TLateralView lateralView = lateralViews.get(i);
18876                        TFunctionCall functionCall = lateralView.getUdtf();
18877                        List<TExpression> expressions = new ArrayList<TExpression>();
18878                        if (functionCall == null) {
18879                                continue;
18880                        }
18881                        Function function = modelFactory.createFunction(functionCall);
18882                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
18883                                        ((TFunctionCall) functionCall).getFunctionName());
18884
18885                        Table lateralTable = null;
18886                        if (lateralView.getTableAlias() != null) {
18887                                lateralTable = modelFactory.createTableByName(lateralView.getTableAlias().getAliasName(), true);
18888                        } else {
18889                                lateralTable = modelFactory.createTableByName(functionCall.toString(), true);
18890                        }
18891
18892                        for (int j = 0; j < lateralView.getColumnAliasList().size(); j++) {
18893                                TObjectName viewColumn = lateralView.getColumnAliasList().getObjectName(j);
18894                                TableColumn tableColumn = modelFactory.createTableColumn(lateralTable, viewColumn, true);
18895
18896                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18897                                relation.setEffectType(EffectType.select);
18898                                relation.setTarget(new TableColumnRelationshipElement(tableColumn));
18899                                relation.addSource(new ResultColumnRelationshipElement(column));
18900                        }
18901
18902                        getFunctionExpressions(expressions, new ArrayList<TExpression>(), functionCall);
18903                        for (int j = 0; j < expressions.size(); j++) {
18904                                columnsInExpr visitor = new columnsInExpr();
18905                                expressions.get(j).inOrderTraverse(visitor);
18906                                List<TObjectName> objectNames = visitor.getObjectNames();
18907                                if (objectNames == null) {
18908                                        continue;
18909                                }
18910                                for (TObjectName columnName : objectNames) {
18911                                        boolean match = false;
18912                                        for (int k = 0; k < tables.size(); k++) {
18913                                                Object item = tables.get(k);
18914                                                if(item instanceof Table) {
18915                                                        Table tableItem = (Table)item;
18916                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
18917                                                                if (getColumnName(columnName)
18918                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18919                                                                        match = true;
18920                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18921                                                                        relation.setEffectType(EffectType.select);
18922                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18923                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18924                                                                }
18925                                                        }
18926                                                }
18927                                                else {
18928                                                        ResultSet tableItem = (ResultSet)item;
18929                                                        for (ResultColumn tableColumn : tableItem.getColumns()) {
18930                                                                if (getColumnName(columnName)
18931                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
18932                                                                        match = true;
18933                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18934                                                                        relation.setEffectType(EffectType.select);
18935                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18936                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18937                                                                }
18938                                                        }
18939                                                }
18940                                        }
18941                                        if (!match) {
18942                                                if(stmtTable instanceof Table) {
18943                                                        TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable, columnName, false);
18944                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18945                                                        relation.setEffectType(EffectType.select);
18946                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18947                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
18948                                                }
18949                                                else {
18950                                                        ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable, columnName, false);
18951                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18952                                                        relation.setEffectType(EffectType.select);
18953                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18954                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
18955                                                }
18956                                        }
18957                                }
18958                                List<TParseTreeNode> constants = visitor.getConstants();
18959                                if (!constants.isEmpty()) {
18960                                        if (option.isShowConstantTable()) {
18961                                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
18962                                                for (TParseTreeNode constant : constants) {
18963                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
18964                                                        relation.setEffectType(EffectType.select);
18965                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
18966                                                        if (constant instanceof TConstant) {
18967                                                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
18968                                                                                (TConstant) constant);
18969                                                                relation.addSource(new ConstantRelationshipElement(constantColumn));
18970                                                        } else if (constant instanceof TObjectName) {
18971                                                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
18972                                                                                (TObjectName) constant, false);
18973                                                                relation.addSource(new ConstantRelationshipElement(constantColumn));
18974                                                        }
18975                                                }
18976                                        }
18977                                }
18978                                
18979                                List<TParseTreeNode> functions = visitor.getFunctions();
18980                                if (functions != null && !functions.isEmpty()) {
18981                                        analyzeFunctionDataFlowRelation(column, functions, EffectType.function);
18982                                }
18983                        }
18984                        tables.add(lateralTable);
18985                }
18986
18987                ResultSet resultSet = modelFactory.createResultSet(stmt,
18988                                isTopResultSet(stmt) && isShowTopSelectResultSet());
18989                TResultColumnList columnList = stmt.getResultColumnList();
18990                for (int i = 0; i < columnList.size(); i++) {
18991                        TResultColumn column = columnList.getResultColumn(i);
18992                        ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
18993                        if (resultColumn.getColumnObject() instanceof TResultColumn) {
18994                                TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
18995                                if (columnObject.getFieldAttr() != null) {
18996                                        if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
18997                                                for (int k = 0; k < tables.size(); k++) {
18998                                                        Object item = tables.get(k);
18999                                                        if(item instanceof Table) {
19000                                                                Table tableItem = (Table)item;
19001                                                                for (TableColumn tableColumn : tableItem.getColumns()) {
19002                                                                        resultColumn.bindStarLinkColumn(tableColumn.getColumnObject());
19003                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19004                                                                        relation.setEffectType(EffectType.select);
19005                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, tableColumn.getColumnObject()));
19006                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
19007                                                                }
19008                                                        }
19009                                                        else {
19010                                                                ResultSet tableItem = (ResultSet)item;
19011                                                                for (ResultColumn tableColumn : tableItem.getColumns()) {
19012                                                                        TObjectName linkColumn = new TObjectName();
19013                                                                        linkColumn.setString(tableColumn.getName());
19014                                                                        resultColumn.bindStarLinkColumn(linkColumn);
19015                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19016                                                                        relation.setEffectType(EffectType.select);
19017                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn, linkColumn));
19018                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19019                                                                }
19020                                                        }
19021                                                }
19022                                        } else {
19023                                                boolean match = false;
19024                                                for (int k = 0; k < tables.size(); k++) {
19025                                                        Object item = tables.get(k);
19026                                                        if(item instanceof Table) {
19027                                                                Table tableItem = (Table)item;
19028                                                                for (TableColumn tableColumn : tableItem.getColumns()) {
19029                                                                        if (getColumnName(columnObject.getFieldAttr())
19030                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
19031                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19032                                                                                relation.setEffectType(EffectType.select);
19033                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19034                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
19035                                                                                match = true;
19036                                                                        }
19037                                                                }
19038                                                        }
19039                                                        else {
19040                                                                ResultSet tableItem = (ResultSet)item;
19041                                                                for (ResultColumn tableColumn : tableItem.getColumns()) {
19042                                                                        if (getColumnName(columnObject.getFieldAttr())
19043                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
19044                                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19045                                                                                relation.setEffectType(EffectType.select);
19046                                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19047                                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19048                                                                                match = true;
19049                                                                        }
19050                                                                }
19051                                                        }
19052                                                }
19053                                                if (!match) {
19054                                                        if(stmtTable instanceof Table) {
19055                                                                TableColumn tableColumn = modelFactory.createTableColumn((Table)stmtTable,
19056                                                                                columnObject.getFieldAttr(), false);
19057                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19058                                                                relation.setEffectType(EffectType.select);
19059                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19060                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
19061                                                        }
19062                                                        else {
19063                                                                ResultColumn tableColumn = modelFactory.createResultColumn((ResultSet)stmtTable,
19064                                                                                columnObject.getFieldAttr(), false);
19065                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19066                                                                relation.setEffectType(EffectType.select);
19067                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19068                                                                relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19069                                                        }
19070                                                }
19071                                        }
19072                                }
19073                                else if (columnObject.getExpr() != null
19074                                                && columnObject.getExpr().getExpressionType() == EExpressionType.function_t) {
19075                                        analyzeResultColumn(column, EffectType.select);
19076                                        for (int k = 0; k < tables.size(); k++) {
19077                                                Object item = tables.get(k);
19078                                                if (item instanceof Table) {
19079                                                        Table tableItem = (Table) item;
19080                                                        for (TableColumn tableColumn : tableItem.getColumns()) {
19081                                                                if (getColumnName(resultColumn.getName()).equals(
19082                                                                                DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
19083                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19084                                                                        relation.setEffectType(EffectType.select);
19085                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19086                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
19087                                                                }
19088                                                        }
19089                                                } else {
19090                                                        ResultSet tableItem = (ResultSet) item;
19091                                                        for (ResultColumn tableColumn : tableItem.getColumns()) {
19092                                                                if (getColumnName(resultColumn.getName()).equals(
19093                                                                                DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName()))) {
19094                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19095                                                                        relation.setEffectType(EffectType.select);
19096                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
19097                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
19098                                                                }
19099                                                        }
19100                                                }
19101                                        }
19102                                }
19103                        }
19104                }
19105        }
19106
19107        private boolean isFromFunction(TObjectName object) {
19108
19109                Stack<TParseTreeNode> nodes = object.getStartToken().getNodesStartFromThisToken();
19110                if (nodes != null) {
19111                        for (int i = 0; i < nodes.size(); i++) {
19112                                if (nodes.get(i) instanceof TFunctionCall) {
19113                                        return true;
19114                                }
19115                        }
19116                }
19117                return false;
19118        }
19119
19120        private TResultColumnList getResultColumnList(TSelectSqlStatement stmt) {
19121                // Iterative DFS (left-first) to find the first non-combined query's result column list.
19122                // Avoids StackOverflow with deeply nested UNION trees.
19123                Deque<TSelectSqlStatement> stack = new ArrayDeque<>();
19124                stack.push(stmt);
19125                while (!stack.isEmpty()) {
19126                        TSelectSqlStatement current = stack.pop();
19127                        if (current.isCombinedQuery()) {
19128                                // Push right first so left is processed first (stack is LIFO)
19129                                if (current.getRightStmt() != null) stack.push(current.getRightStmt());
19130                                if (current.getLeftStmt() != null) stack.push(current.getLeftStmt());
19131                        } else {
19132                                if (current.getResultColumnList() != null) {
19133                                        return current.getResultColumnList();
19134                                }
19135                        }
19136                }
19137                return null;
19138        }
19139
19140        private void createPseudoImpactRelation(TCustomSqlStatement stmt, ResultSet resultSetModel, EffectType effectType) {
19141                if (stmt.getTables() != null) {
19142                        for (int i = 0; i < stmt.getTables().size(); i++) {
19143                                TTable table = stmt.getTables().getTable(i);
19144                                if (modelManager.getModel(table) instanceof ResultSet) {
19145                                        ResultSet tableModel = (ResultSet) modelManager.getModel(table);
19146                                        if (tableModel != resultSetModel && !tableModel.getRelationRows().getHoldRelations().isEmpty()) {
19147                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
19148                                                impactRelation.setEffectType(effectType);
19149                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19150                                                                tableModel.getRelationRows()));
19151                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19152                                                                resultSetModel.getRelationRows()));
19153                                        }
19154                                } else if (modelManager.getModel(table) instanceof Table) {
19155                                        Table tableModel = (Table) modelManager.getModel(table);
19156                                        if (!tableModel.getRelationRows().getHoldRelations().isEmpty()) {
19157                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
19158                                                impactRelation.setEffectType(effectType);
19159                                                impactRelation.addSource(
19160                                                                new RelationRowsRelationshipElement<TableRelationRows>(tableModel.getRelationRows()));
19161                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19162                                                                resultSetModel.getRelationRows()));
19163                                        }
19164                                }
19165                        }
19166                }
19167        }
19168
19169        private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions,
19170                        EffectType effectType) {
19171                for (int i = 0; i < functions.size(); i++) {
19172                        TParseTreeNode functionCall = functions.get(i);
19173                        if (functionCall instanceof TFunctionCall) {
19174                                String functionName = DlineageUtil.getIdentifierNormalTableName(
19175                                                DlineageUtil.getFunctionNameWithArgNum((TFunctionCall) functionCall));
19176                                Procedure procedure = modelManager.getProcedureByName(functionName);
19177                                if (procedure != null) {
19178                                        String procedureParent = getProcedureParentName(stmtStack.peek());
19179                                        if (procedureParent != null) {
19180                                                Procedure caller = modelManager
19181                                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
19182                                                if (caller != null) {
19183                                                        CallRelationship callRelation = modelFactory.createCallRelation();
19184                                                        callRelation.setCallObject(functionCall);
19185                                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
19186                                                        callRelation.addSource(new ProcedureRelationshipElement(procedure));
19187                                                        if (isBuiltInFunctionName(((TFunctionCall)functionCall).getFunctionName())||isKeyword(((TFunctionCall)functionCall).getFunctionName())) {
19188                                                                callRelation.setBuiltIn(true);
19189                                                        }
19190                                                }
19191                                        }
19192                                        if (procedure.getProcedureObject() instanceof TCreateFunctionStmt) {
19193                                                TCreateFunctionStmt createFunction = (TCreateFunctionStmt)procedure.getProcedureObject();
19194                                                TTypeName dataType = createFunction.getReturnDataType();
19195                                                if (dataType!=null && dataType.getTypeOfList() != null && dataType.getTypeOfList().getColumnDefList() != null) {
19196                                                        Object modelObject = modelManager.getModel(gspObject);
19197                                                        if(modelObject instanceof ResultColumn) {
19198                                                                ResultColumn resultColumn = (ResultColumn)modelObject;
19199                                                                ResultSet resultSet = resultColumn.getResultSet();
19200                                                                for (int j = 0; j < dataType.getTypeOfList().getColumnDefList().size(); j++) {
19201                                                                        TObjectName columnName = new TObjectName();
19202                                                                        if( dataType.getDataType() == EDataType.array_t) {
19203//                                                                              columnName.setString(resultColumn.getName() + ".array."
19204//                                                                                              + dataType.getTypeOfList().getColumnDefList().getColumn(j)
19205//                                                                                                              .getColumnName().getColumnNameOnly());
19206                                                                                columnName.setString(resultColumn.getName() + "."
19207                                                                                                + dataType.getTypeOfList().getColumnDefList().getColumn(j)
19208                                                                                                .getColumnName().getColumnNameOnly());
19209                                                                        }
19210                                                                        else {
19211                                                                                columnName.setString(resultColumn.getName() + "."
19212                                                                                                + dataType.getTypeOfList().getColumnDefList().getColumn(j)
19213                                                                                                                .getColumnName().getColumnNameOnly());
19214                                                                        }
19215                                                                        ResultColumn sturctColumn = modelFactory.createResultColumn(resultSet, columnName,
19216                                                                                        true);
19217                                                                        sturctColumn.setStruct(true);
19218                                                                        Function sourceFunction = (Function)createFunction(functionCall);
19219                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19220                                                                        relation.setEffectType(effectType);
19221                                                                        relation.setTarget(new ResultColumnRelationshipElement(sturctColumn));
19222                                                                        if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) {
19223                                                                                for (ResultColumn column : sourceFunction.getColumns()) {
19224                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
19225                                                                                }
19226                                                                        }
19227                                                                }
19228                                                                resultSet.getColumns().remove(resultColumn);
19229                                                        }
19230                                                        return;
19231                                                }
19232                                        }
19233                                }
19234                        }
19235                        
19236                        if(gspObject instanceof TResultColumn) {
19237                                TResultColumn resultColumn = (TResultColumn)gspObject;
19238                                if(resultColumn.getAliasClause()!=null && resultColumn.getAliasClause().getColumns()!=null) {
19239                                        for(TObjectName columnName: resultColumn.getAliasClause().getColumns()) {
19240                                                analyzeFunctionDataFlowRelation(columnName, Arrays.asList(functionCall), effectType, null);
19241                                        }
19242                                        return;
19243                                }
19244                        }
19245                        analyzeFunctionDataFlowRelation(gspObject, Arrays.asList(functionCall), effectType, null);
19246                }
19247        }
19248
19249        private void analyzeFunctionDataFlowRelation(Object gspObject, List<TParseTreeNode> functions,
19250                        EffectType effectType, Process process) {
19251
19252                Object modelObject = modelManager.getModel(gspObject);
19253                if (modelObject == null) {
19254                        if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) {
19255                                modelObject = gspObject;
19256                        }
19257                }
19258
19259                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19260                relation.setEffectType(effectType);
19261                relation.setProcess(process);
19262
19263                if (modelObject instanceof ResultColumn) {
19264                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
19265
19266                } else if (modelObject instanceof TableColumn) {
19267                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
19268
19269                } else {
19270                        throw new UnsupportedOperationException();
19271                }
19272
19273                for (int i = 0; i < functions.size(); i++) {
19274                        TParseTreeNode functionCall = functions.get(i);
19275
19276                        if (functionCall instanceof TFunctionCall) {
19277                                TFunctionCall call = (TFunctionCall) functionCall;
19278                                Procedure callee = modelManager.getProcedureByName(
19279                                                DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call)));
19280                                if (callee == null && procedureDDLMap.containsKey(DlineageUtil.getFunctionNameWithArgNum(call))) {
19281                                        analyzeCustomSqlStmt(procedureDDLMap.get(DlineageUtil.getFunctionNameWithArgNum(call)));
19282                                        callee = modelManager.getProcedureByName(
19283                                                        DlineageUtil.getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(call)));
19284                                }
19285
19286                                if (callee != null) {
19287                                        String procedureParent = getProcedureParentName(stmtStack.peek());
19288                                        if (procedureParent != null) {
19289                                                Procedure caller = modelManager
19290                                                                .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
19291                                                if (caller != null) {
19292                                                        CallRelationship callRelation = modelFactory.createCallRelation();
19293                                                        callRelation.setCallObject(functionCall);
19294                                                        callRelation.setTarget(new ProcedureRelationshipElement(caller));
19295                                                        callRelation.addSource(new ProcedureRelationshipElement(callee));
19296                                                        if (isBuiltInFunctionName(call.getFunctionName()) || isKeyword(call.getFunctionName())) {
19297                                                                callRelation.setBuiltIn(true);
19298                                                        }
19299                                                }
19300                                        }
19301                                        if (callee.getArguments() != null) {
19302                                                for (int j = 0; j < callee.getArguments().size(); j++) {
19303                                                        Argument argument = callee.getArguments().get(j);
19304                                                        Variable variable = modelFactory.createVariable(callee, argument.getName(), false);
19305                                                        if(variable!=null) {
19306                                                                if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
19307                                                                        Transform transform = new Transform();
19308                                                                        transform.setType(Transform.FUNCTION);
19309                                                                        transform.setCode(call);
19310                                                                        variable.getColumns().get(0).setTransform(transform);
19311                                                                }
19312                                                                Process callProcess = modelFactory.createProcess(call);
19313                                                                variable.addProcess(callProcess);
19314                                                                analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), call, j, callProcess);
19315                                                        }
19316                                                }
19317                                        }
19318                                        Set<Object> functionTableModelObjs = modelManager.getFunctionTable(DlineageUtil
19319                                                        .getIdentifierNormalTableName(call.getFunctionName().toString()));
19320                                        if (functionTableModelObjs != null) {
19321                                                modelManager.bindModel(call, functionTableModelObjs.iterator().next());
19322                                                for (Object functionTableModelObj : functionTableModelObjs) {
19323                                                        if (functionTableModelObj instanceof ResultSet) {
19324                                                                ResultSet resultSet = (ResultSet) functionTableModelObj;
19325                                                                for (ResultColumn column : resultSet.getColumns()) {
19326                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
19327                                                                }
19328                                                        }
19329                                                }
19330                                        }
19331                                        continue;
19332                                }
19333                        }
19334
19335
19336                        Object functionModel = createFunction(functionCall);
19337                        if (functionModel instanceof Function) {
19338                                Function sourceFunction = (Function)functionModel;
19339                                if (sourceFunction.getColumns() != null && !sourceFunction.getColumns().isEmpty()) {
19340                                        for (ResultColumn column : sourceFunction.getColumns()) {
19341                                                relation.addSource(new ResultColumnRelationshipElement(column));
19342                                        }
19343                                }
19344                                else if (functionCall instanceof TFunctionCall) {
19345                                        relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager
19346                                                        .getModel(((TFunctionCall) functionCall).getFunctionName())));
19347                                } else if (functionCall instanceof TCaseExpression) {
19348                                        relation.addSource(new ResultColumnRelationshipElement((FunctionResultColumn) modelManager
19349                                                        .getModel(((TCaseExpression) functionCall).getWhenClauseItemList())));
19350                                }
19351                                
19352                                if (sourceFunction != null && !sourceFunction.getRelationRows().getHoldRelations().isEmpty()) {
19353                                        boolean find = false;
19354                                        if (modelObject instanceof ResultColumn) {
19355                                                ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows();
19356                                                if(targetRelationRows.hasRelation()) {
19357                                                        for(Relationship relationship: targetRelationRows.getHoldRelations()) {
19358                                                                if(relationship.getSources().contains(sourceFunction.getRelationRows())) {
19359                                                                        find = true;
19360                                                                        break;
19361                                                                }
19362                                                        }
19363                                                }
19364                                        }
19365                                        else if (modelObject instanceof TableColumn) {
19366                                                TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows();
19367                                                if(targetRelationRows.hasRelation()) {
19368                                                        for(Relationship relationship: targetRelationRows.getHoldRelations()) {
19369                                                                if(relationship.getSources().contains(sourceFunction.getRelationRows())) {
19370                                                                        find = true;
19371                                                                        break;
19372                                                                }
19373                                                        }
19374                                                }
19375                                        }
19376                                        
19377                                        if (!find) {
19378                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
19379                                                impactRelation.setEffectType(EffectType.select);
19380                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19381                                                                sourceFunction.getRelationRows()));
19382                                                if (modelObject instanceof ResultColumn) {
19383                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19384                                                                        ((ResultColumn) modelObject).getResultSet().getRelationRows()));
19385                                                } else if (modelObject instanceof TableColumn) {
19386                                                        impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
19387                                                                        ((TableColumn) modelObject).getTable().getRelationRows()));
19388                                                }
19389                                        }
19390                                }
19391                        } else if (functionModel instanceof Table) {
19392                                TFunctionCall call = (TFunctionCall) functionCall;
19393                                String functionName = call.getFunctionName().toString();
19394                                boolean flag = false;
19395                                if (functionName.indexOf(".") != -1) {
19396                                        String columnName = functionName.substring(functionName.indexOf(".") + 1);
19397                                        for (TableColumn tableColumn : ((Table) functionModel).getColumns()) {
19398                                                if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) {
19399                                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
19400                                                        relation.addSource(element);
19401                                                        flag = true;
19402                                                        break;
19403                                                }
19404                                        }
19405                                }
19406
19407                                if (!flag) {
19408                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
19409                                                        ((TFunctionCall) functionCall));
19410                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
19411                                        relation.addSource(element);
19412                                }
19413                        }
19414                }
19415
19416        }
19417
19418        private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys,
19419                        EffectType effectType) {
19420                analyzeSubqueryDataFlowRelation(gspObject, subquerys, effectType, null);
19421        }
19422
19423        private void analyzeSubqueryDataFlowRelation(Object gspObject, List<TSelectSqlStatement> subquerys,
19424                        EffectType effectType, Process process) {
19425
19426                Object modelObject = modelManager.getModel(gspObject);
19427                if (modelObject == null) {
19428                        if (gspObject instanceof ResultColumn || gspObject instanceof TableColumn) {
19429                                modelObject = gspObject;
19430                        }
19431                }
19432
19433                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19434                relation.setEffectType(effectType);
19435                relation.setProcess(process);
19436
19437                if (modelObject instanceof ResultColumn) {
19438                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
19439
19440                } else if (modelObject instanceof TableColumn) {
19441                        relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
19442
19443                } else {
19444                        throw new UnsupportedOperationException();
19445                }
19446
19447                for (int i = 0; i < subquerys.size(); i++) {
19448                        TSelectSqlStatement subquery = subquerys.get(i);
19449                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
19450                        if (resultSetModel != null && resultSetModel.getColumns() != null) {
19451                                for (ResultColumn column : resultSetModel.getColumns()) {
19452                                        relation.addSource(new ResultColumnRelationshipElement(column));
19453                                }
19454                        }
19455                        
19456                        if (resultSetModel != null && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
19457                                boolean find = false;
19458                                if (modelObject instanceof ResultColumn) {
19459                                        ResultSetRelationRows targetRelationRows = ((ResultColumn) modelObject).getResultSet().getRelationRows();
19460                                        if(targetRelationRows.hasRelation()) {
19461                                                for(Relationship relationship: targetRelationRows.getHoldRelations()) {
19462                                                        if(relationship.getSources().contains(resultSetModel.getRelationRows())) {
19463                                                                find = true;
19464                                                                break;
19465                                                        }
19466                                                }
19467                                        }
19468                                }
19469                                else if (modelObject instanceof TableColumn) {
19470                                        TableRelationRows targetRelationRows = ((TableColumn) modelObject).getTable().getRelationRows();
19471                                        if(targetRelationRows.hasRelation()) {
19472                                                for(Relationship relationship: targetRelationRows.getHoldRelations()) {
19473                                                        if(relationship.getSources().contains(resultSetModel.getRelationRows())) {
19474                                                                find = true;
19475                                                                break;
19476                                                        }
19477                                                }
19478                                        }
19479                                }
19480                                
19481                                if (!find) {
19482                                        ImpactRelationship impactRelation = modelFactory.createImpactRelation();
19483                                        impactRelation.setEffectType(EffectType.select);
19484                                        impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19485                                                        resultSetModel.getRelationRows()));
19486                                        if (modelObject instanceof ResultColumn) {
19487                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
19488                                                                ((ResultColumn) modelObject).getResultSet().getRelationRows()));
19489                                        } else if (modelObject instanceof TableColumn) {
19490                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
19491                                                                ((TableColumn) modelObject).getTable().getRelationRows()));
19492                                        }
19493                                }
19494                        }
19495                }
19496
19497        }
19498
19499        private Object createFunction(TParseTreeNode functionCall) {
19500                if (functionCall instanceof TFunctionCall) {
19501                        TFunctionCall functionObj = (TFunctionCall) functionCall;
19502                        if (!isBuiltInFunctionName(functionObj.getFunctionName())) {
19503                                TCustomSqlStatement stmt = stmtStack.peek();
19504                                String procedureParent = getProcedureParentName(stmt);
19505                                if (procedureParent != null) {
19506                                        Procedure procedureCallee = modelManager.getProcedureByName(DlineageUtil
19507                                                        .getIdentifierNormalTableName(DlineageUtil.getFunctionNameWithArgNum(functionObj)));
19508                                        if (procedureCallee != null) {
19509                                                if (procedureParent != null) {
19510                                                        Procedure caller = modelManager
19511                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
19512                                                        if (caller != null) {
19513                                                                CallRelationship callRelation = modelFactory.createCallRelation();
19514                                                                callRelation.setCallObject(functionCall);
19515                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
19516                                                                callRelation.addSource(new ProcedureRelationshipElement(procedureCallee));
19517                                                                if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){
19518                                                                        callRelation.setBuiltIn(true);
19519                                                                }
19520                                                        }
19521                                                }
19522                                                if (procedureCallee.getArguments() != null) {
19523                                                        for (int j = 0; j < procedureCallee.getArguments().size(); j++) {
19524                                                                Argument argument = procedureCallee.getArguments().get(j);
19525                                                                Variable variable = modelFactory.createVariable(procedureCallee, argument.getName(), false);
19526                                                                if(variable!=null) {
19527                                                                        if (argument.getMode() == EParameterMode.out || argument.getMode() == EParameterMode.output) {
19528                                                                                Transform transform = new Transform();
19529                                                                                transform.setType(Transform.FUNCTION);
19530                                                                                transform.setCode(functionObj);
19531                                                                                variable.getColumns().get(0).setTransform(transform);
19532                                                                        }
19533                                                                        Process process = modelFactory.createProcess(functionObj);
19534                                                                        variable.addProcess(process);
19535                                                                        analyzeFunctionArgumentsDataFlowRelation(variable.getColumns().get(0), functionObj, j, process);
19536                                                                }
19537                                                        }
19538                                                }
19539                                        } else {
19540                                                TFunctionCall call = (TFunctionCall)functionCall;
19541                                                String functionName = call.getFunctionName().toString();
19542                                                if (functionName.indexOf(".") != -1) {
19543                                                        Table functionTable = modelManager
19544                                                                        .getTableByName(functionName.substring(0, functionName.indexOf(".")));
19545                                                        if (functionTable != null) {
19546                                                                String columnName = functionName.substring(functionName.indexOf(".") + 1);
19547                                                                for (TableColumn tableColumn : functionTable.getColumns()) {
19548                                                                        if (getColumnName(tableColumn.getName()).equalsIgnoreCase(columnName)) {
19549                                                                                return functionTable;
19550                                                                        }
19551                                                                }
19552                                                        }
19553                                                }
19554                                                Function function = modelFactory.createFunction(call);
19555                                                if (procedureParent != null) {
19556                                                        Procedure caller = modelManager
19557                                                                        .getProcedureByName(DlineageUtil.getIdentifierNormalTableName(procedureParent));
19558                                                        if (caller != null) {
19559                                                                CallRelationship callRelation = modelFactory.createCallRelation();
19560                                                                callRelation.setCallObject(functionCall);
19561                                                                callRelation.setTarget(new ProcedureRelationshipElement(caller));
19562                                                                callRelation.addSource(new FunctionRelationshipElement(function));
19563                                                                if(isBuiltInFunctionName(functionObj.getFunctionName()) || isKeyword(functionObj.getFunctionName())){
19564                                                                        callRelation.setBuiltIn(true);
19565                                                                }
19566                                                        }
19567                                                }
19568                                        }
19569                                }
19570                        } else if (isConstantFunction(functionObj.getFunctionName())
19571                                        && (functionObj.getArgs() == null || functionObj.getArgs().size() == 0)) {
19572                                if (option.isShowConstantTable()) {
19573                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
19574                                        modelFactory.createTableColumn(constantTable, functionObj);
19575                                        return constantTable;
19576                                } else {
19577                                        return null;
19578                                }
19579                        }  
19580                        
19581                        if (functionObj.getFunctionType() == EFunctionType.struct_t) {
19582                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
19583                                if(functionObj instanceof TTableFunction) {
19584                                        TTableFunction tableFunction = (TTableFunction) functionObj;
19585                                        if (tableFunction.getFieldValues() != null) {
19586                                                for (int i = 0; i < tableFunction.getFieldValues().size(); i++) {
19587                                                        TResultColumn resultColumn = tableFunction.getFieldValues().getResultColumn(i);
19588                                                        if (resultColumn.getAliasClause() != null) {
19589                                                                ResultColumn column = modelFactory.createFunctionResultColumn(function,
19590                                                                                resultColumn.getAliasClause().getAliasName());
19591                                                                columnsInExpr visitor = new columnsInExpr();
19592                                                                resultColumn.getExpr().inOrderTraverse(visitor);
19593                                                                List<TObjectName> objectNames = visitor.getObjectNames();
19594                                                                List<TParseTreeNode> functions = visitor.getFunctions();
19595                                                                if (functions != null && !functions.isEmpty()) {
19596                                                                        analyzeFunctionDataFlowRelation(column, functions, EffectType.function);
19597                                                                }
19598                                                                List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19599                                                                if (subquerys != null && !subquerys.isEmpty()) {
19600                                                                        analyzeSubqueryDataFlowRelation(column, subquerys, EffectType.function);
19601                                                                }
19602                                                                analyzeDataFlowRelation(column, objectNames, EffectType.function, functions);
19603                                                                List<TParseTreeNode> constants = visitor.getConstants();
19604                                                                analyzeConstantDataFlowRelation(column, constants, EffectType.function, functions);
19605                                                        } else if (resultColumn.getFieldAttr() != null) {
19606                                                                ResultColumn column = modelFactory.createFunctionResultColumn(function,
19607                                                                                resultColumn.getFieldAttr());
19608                                                                analyzeDataFlowRelation(column, Arrays.asList(resultColumn.getFieldAttr()), EffectType.function, null);
19609                                                        } else if (resultColumn.getExpr() != null) {
19610                                                                if (resultColumn.getExpr().getFunctionCall() != null) {
19611                                                                        Function resultColumnFunction = (Function) createFunction(
19612                                                                                        resultColumn.getExpr().getFunctionCall());
19613                                                                        String functionName = getResultSetName(function);
19614                                                                        for (int j = 0; j < resultColumnFunction.getColumns().size(); j++) {
19615                                                                                TObjectName columnName = new TObjectName();
19616                                                                                if (resultColumn.getAliasClause() != null) {
19617                                                                                        columnName.setString(resultColumn.getAliasClause() + "." + getColumnNameOnly(
19618                                                                                                        resultColumnFunction.getColumns().get(j).getName()));
19619                                                                                } else {
19620                                                                                        columnName.setString(functionName + "." + getColumnNameOnly(
19621                                                                                                        resultColumnFunction.getColumns().get(j).getName()));
19622                                                                                }
19623                                                                                ResultColumn functionResultColumn = modelFactory.createResultColumn(function,
19624                                                                                                columnName);
19625                                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
19626                                                                                relationship.setTarget(new ResultColumnRelationshipElement(functionResultColumn));
19627                                                                                relationship.addSource(new ResultColumnRelationshipElement(
19628                                                                                                resultColumnFunction.getColumns().get(j)));
19629                                                                        }
19630                                                                }
19631                                                                else if (resultColumn.getExpr().getCaseExpression() != null) {
19632                                                                        function = modelFactory.createFunction(resultColumn.getExpr().getCaseExpression());
19633                                                                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
19634                                                                                        ((TCaseExpression) resultColumn.getExpr().getCaseExpression()).getWhenClauseItemList());
19635                                                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19636                                                                }
19637                                                        }
19638                                                }
19639                                                return function;
19640                                        }
19641                                }
19642                                else if(functionObj instanceof TFunctionCall) {
19643                                        
19644                                }
19645                        }
19646                        
19647                        if (functionObj.getFunctionType() == EFunctionType.array_t || functionObj.getFunctionType() == EFunctionType.array_agg_t) {
19648                                Function function = modelFactory.createFunction((TFunctionCall) functionCall);
19649                                if(functionObj.getArgs()!=null) {
19650                                        if(functionObj.getArgs().getExpression(0).getSubQuery()!=null) {
19651                                                TSelectSqlStatement stmt = functionObj.getArgs().getExpression(0).getSubQuery();
19652                                                analyzeSelectStmt(stmt);
19653                                                ResultSet resultset = (ResultSet) modelManager.getModel(stmt);
19654                                                for (int i = 0; i < resultset.getColumns().size(); i++) {
19655                                                        ResultColumn sourceColumn = resultset.getColumns().get(i);
19656                                                        TObjectName columnName = new TObjectName();
19657                                                        columnName.setString(sourceColumn.getName());
19658                                                        ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function,
19659                                                                        columnName);
19660                                                        DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
19661                                                        relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
19662                                                        relationship.addSource(
19663                                                                        new ResultColumnRelationshipElement(sourceColumn));
19664                                                }
19665                                                return function;
19666                                        }
19667                                        else if (functionObj.getArgs().getExpression(0).getExpressionType() == EExpressionType.function_t) {
19668                                                Object functionTableModelObj = createFunction(functionObj.getArgs().getExpression(0).getFunctionCall());
19669                                                if (functionTableModelObj instanceof ResultSet) {
19670                                                        ResultSet resultset = (ResultSet) functionTableModelObj;
19671                                                        for (int i = 0; i < resultset.getColumns().size(); i++) {
19672                                                                ResultColumn sourceColumn = resultset.getColumns().get(i);
19673                                                                TObjectName columnName = new TObjectName();
19674                                                                columnName.setString(sourceColumn.getName());
19675                                                                ResultColumn resultColumn = modelFactory.createFunctionResultColumn(function, columnName);
19676                                                                DataFlowRelationship relationship = modelFactory.createDataFlowRelation();
19677                                                                relationship.setTarget(new ResultColumnRelationshipElement(resultColumn));
19678                                                                relationship.addSource(new ResultColumnRelationshipElement(sourceColumn));
19679                                                        }
19680                                                        return function;
19681                                                }
19682                                        }
19683                                }
19684                        }
19685                        
19686                        Function function = modelFactory.createFunction((TFunctionCall) functionCall);
19687                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
19688                                        ((TFunctionCall) functionCall).getFunctionName());
19689                        if ("COUNT".equalsIgnoreCase(((TFunctionCall) functionCall).getFunctionName().toString())) {
19690                                // @see https://e.gitee.com/gudusoft/issues/list?issue=I40NUP
19691                                // COUNT特殊处理,不和参数关联
19692                                if (option.isShowCountTableColumn()) {
19693                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19694                                }
19695                        } else {
19696                                boolean isCustomFunction = analyzeCustomFunctionCall((TFunctionCall)functionCall);
19697//                              if(!isCustomFunction) 
19698                                {
19699                                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19700                                }
19701                                Set<Object> functionTableModelObjs = modelManager.getFunctionTable(getIdentifiedFunctionName(function));
19702                                if(functionTableModelObjs!=null) {
19703                                        for(Object functionTableModelObj: functionTableModelObjs) {
19704                                                if (functionTableModelObj instanceof ResultSet) {
19705                                                        ResultSet functionTableModel = (ResultSet) functionTableModelObj;
19706                                                        if (functionTableModel.getColumns() != null) {
19707                                                                for (int j = 0; j < functionTableModel.getColumns().size(); j++) {
19708                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
19709                                                                        relation.setEffectType(EffectType.select);
19710                                                                        relation.setTarget(new ResultColumnRelationshipElement(column));
19711                                                                        relation.addSource(new ResultColumnRelationshipElement(
19712                                                                                        functionTableModel.getColumns().get(j)));
19713                                                                }
19714                                                        }
19715                                                }
19716                                        }
19717                                }
19718                        }
19719                        return function;
19720                } else if (functionCall instanceof TCaseExpression) {
19721                        Function function = modelFactory.createFunction((TCaseExpression) functionCall);
19722                        ResultColumn column = modelFactory.createFunctionResultColumn(function,
19723                                        ((TCaseExpression) functionCall).getWhenClauseItemList());
19724                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19725                        return function;
19726                } else if (functionCall instanceof TObjectName) {
19727                        Function function = modelFactory.createFunction((TObjectName) functionCall);
19728                        TObjectName columnName = new TObjectName();
19729                        columnName.setString(function.getFunctionName());
19730                        ResultColumn column = modelFactory.createResultColumn(function,
19731                                        columnName);
19732                        analyzeFunctionArgumentsDataFlowRelation(column, functionCall);
19733                        return function;
19734                }
19735                return null;
19736        }
19737
19738        protected String getIdentifiedFunctionName(Function function) {
19739                return DlineageUtil.getIdentifierNormalFunctionName(function.getFunctionName());
19740        }
19741        
19742        private boolean isConstantFunction(TObjectName functionName) {
19743                boolean result = CONSTANT_BUILTIN_FUNCTIONS.contains(functionName.toString().toUpperCase());
19744                if (result) {
19745                        return true;
19746                }
19747                return false;
19748        }
19749
19750        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TParseTreeNode gspObject) {
19751                List<TExpression> directExpressions = new ArrayList<TExpression>();
19752                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19753                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19754                if (gspObject instanceof TFunctionCall) {
19755                        TFunctionCall functionCall = (TFunctionCall) gspObject;
19756                        getFunctionExpressions(directExpressions, indirectExpressions, functionCall);
19757                } else if (gspObject instanceof TCaseExpression) {
19758                        TCaseExpression expr = (TCaseExpression) gspObject;
19759                        TExpression inputExpr = expr.getInput_expr();
19760                        if (inputExpr != null) {
19761                                if(option.isShowCaseWhenAsDirect()){
19762                                        directExpressions.add(inputExpr);
19763                                }
19764                                else {
19765                                        conditionExpressions.add(inputExpr);
19766                                }
19767                        }
19768                        TExpression defaultExpr = expr.getElse_expr();
19769                        if (defaultExpr != null) {
19770                                directExpressions.add(defaultExpr);
19771                        }
19772                        TWhenClauseItemList list = expr.getWhenClauseItemList();
19773                        for (int i = 0; i < list.size(); i++) {
19774                                TWhenClauseItem element = list.getWhenClauseItem(i);
19775                                if(option.isShowCaseWhenAsDirect()){
19776                                        directExpressions.add(element.getComparison_expr());
19777                                }
19778                                else {
19779                                        conditionExpressions.add(element.getComparison_expr());
19780                                }
19781                                directExpressions.add(element.getReturn_expr());
19782                        }
19783                }
19784
19785                for (int j = 0; j < directExpressions.size(); j++) {
19786                        columnsInExpr visitor = new columnsInExpr();
19787                        directExpressions.get(j).inOrderTraverse(visitor);
19788
19789                        List<TObjectName> objectNames = visitor.getObjectNames();
19790                        List<TParseTreeNode> functions = visitor.getFunctions();
19791
19792                        if (functions != null && !functions.isEmpty()) {
19793                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19794                        }
19795
19796                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19797                        if (subquerys != null && !subquerys.isEmpty()) {
19798                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19799                        }
19800
19801                        analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19802
19803                        List<TParseTreeNode> constants = visitor.getConstants();
19804                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19805                }
19806
19807                conditionExpressions.addAll(indirectExpressions);
19808                for (int j = 0; j < conditionExpressions.size(); j++) {
19809                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19810                }
19811        }
19812        
19813        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TCallStatement callStatment, int argumentIndex, Process process) {
19814                List<TExpression> directExpressions = new ArrayList<TExpression>();
19815                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19816                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19817
19818                getFunctionExpressions(directExpressions, indirectExpressions, callStatment, argumentIndex);
19819
19820                for (int j = 0; j < directExpressions.size(); j++) {
19821                        columnsInExpr visitor = new columnsInExpr();
19822                        directExpressions.get(j).inOrderTraverse(visitor);
19823
19824                        List<TObjectName> objectNames = visitor.getObjectNames();
19825                        List<TParseTreeNode> functions = visitor.getFunctions();
19826
19827                        if (functions != null && !functions.isEmpty()) {
19828                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19829                        }
19830
19831                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19832                        if (subquerys != null && !subquerys.isEmpty()) {
19833                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19834                        }
19835
19836                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19837                        if (relation != null) {
19838                                relation.setProcess(process);
19839                        }
19840
19841                        List<TParseTreeNode> constants = visitor.getConstants();
19842                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19843                }
19844
19845                conditionExpressions.addAll(indirectExpressions);
19846                for (int j = 0; j < conditionExpressions.size(); j++) {
19847                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19848                }
19849        }
19850
19851        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TFunctionCall functionCall, int argumentIndex, Process process) {
19852                List<TExpression> directExpressions = new ArrayList<TExpression>();
19853                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19854                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19855
19856                getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentIndex);
19857
19858                for (int j = 0; j < directExpressions.size(); j++) {
19859                        columnsInExpr visitor = new columnsInExpr();
19860                        directExpressions.get(j).inOrderTraverse(visitor);
19861
19862                        List<TObjectName> objectNames = visitor.getObjectNames();
19863                        List<TParseTreeNode> functions = visitor.getFunctions();
19864
19865                        if (functions != null && !functions.isEmpty()) {
19866                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19867                        }
19868
19869                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19870                        if (subquerys != null && !subquerys.isEmpty()) {
19871                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19872                        }
19873
19874                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19875                        if (relation != null) {
19876                                relation.setProcess(process);
19877                        }
19878
19879                        List<TParseTreeNode> constants = visitor.getConstants();
19880                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19881                }
19882
19883                conditionExpressions.addAll(indirectExpressions);
19884                for (int j = 0; j < conditionExpressions.size(); j++) {
19885                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19886                }
19887        }
19888
19889        private void analyzeFunctionArgumentsDataFlowRelation(Object resultColumn, TMssqlExecute functionCall, String argumentName, int argumentIndex, Process process) {
19890                List<TExpression> directExpressions = new ArrayList<TExpression>();
19891                List<TExpression> indirectExpressions = new ArrayList<TExpression>();
19892                List<TExpression> conditionExpressions = new ArrayList<TExpression>();
19893
19894                getFunctionExpressions(directExpressions, indirectExpressions, functionCall, argumentName, argumentIndex);
19895
19896                for (int j = 0; j < directExpressions.size(); j++) {
19897                        columnsInExpr visitor = new columnsInExpr();
19898                        directExpressions.get(j).inOrderTraverse(visitor);
19899
19900                        List<TObjectName> objectNames = visitor.getObjectNames();
19901                        List<TParseTreeNode> functions = visitor.getFunctions();
19902
19903                        if (functions != null && !functions.isEmpty()) {
19904                                analyzeFunctionDataFlowRelation(resultColumn, functions, EffectType.function);
19905                        }
19906
19907                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
19908                        if (subquerys != null && !subquerys.isEmpty()) {
19909                                analyzeSubqueryDataFlowRelation(resultColumn, subquerys, EffectType.function);
19910                        }
19911
19912                        DataFlowRelationship relation = analyzeDataFlowRelation(resultColumn, objectNames, EffectType.function, functions);
19913                        if (relation != null) {
19914                                relation.setProcess(process);
19915                        }
19916
19917                        List<TParseTreeNode> constants = visitor.getConstants();
19918                        analyzeConstantDataFlowRelation(resultColumn, constants, EffectType.function, functions);
19919                }
19920
19921                conditionExpressions.addAll(indirectExpressions);
19922                for (int j = 0; j < conditionExpressions.size(); j++) {
19923                        analyzeFilterCondition(resultColumn, conditionExpressions.get(j), null, null, EffectType.function);
19924                }
19925        }
19926
19927
19928        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
19929                        TFunctionCall functionCall) {
19930                if (functionCall.getArgs() != null) {
19931                        for (int k = 0; k < functionCall.getArgs().size(); k++) {
19932                                TExpression expr = functionCall.getArgs().getExpression(k);
19933                                if(FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(),  functionCall.getArgs().size(), k)) {
19934                                        directExpressions.add(expr);
19935                                }
19936                                if(FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(),  functionCall.getArgs().size(), k)) {
19937                                        indirectExpressions.add(expr);
19938                                }
19939                        }
19940                }
19941                if (functionCall.getXMLElementValueExprList() != null) {
19942                        for (int k = 0; k < functionCall.getXMLElementValueExprList().size(); k++) {
19943                                TExpression expr = functionCall.getXMLElementValueExprList().getResultColumn(k).getExpr();
19944                                directExpressions.add(expr);
19945                        }
19946                }
19947                if (functionCall.getTrimArgument() != null) {
19948                        TTrimArgument args = functionCall.getTrimArgument();
19949                        TExpression expr = args.getStringExpression();
19950                        if (expr != null) {
19951                                directExpressions.add(expr);
19952                        }
19953                        expr = args.getTrimCharacter();
19954                        if (expr != null) {
19955                                directExpressions.add(expr);
19956                        }
19957                }
19958
19959                if (functionCall.getAgainstExpr() != null) {
19960                        directExpressions.add(functionCall.getAgainstExpr());
19961                }
19962//              if (functionCall.getBetweenExpr() != null) {
19963//                      directExpressions.add(functionCall.getBetweenExpr());
19964//              }
19965                if (functionCall.getExpr1() != null) {
19966                        directExpressions.add(functionCall.getExpr1());
19967                }
19968                if (functionCall.getExpr2() != null) {
19969                        directExpressions.add(functionCall.getExpr2());
19970                }
19971                if (functionCall.getExpr3() != null) {
19972                        directExpressions.add(functionCall.getExpr3());
19973                }
19974                if (functionCall.getParameter() != null) {
19975                        directExpressions.add(functionCall.getParameter());
19976                }
19977                if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getPartitionClause() != null) {
19978                        TExpressionList args = functionCall.getWindowDef().getPartitionClause().getExpressionList();
19979                        if (args != null) {
19980                                for (int k = 0; k < args.size(); k++) {
19981                                        TExpression expr = args.getExpression(k);
19982                                        if (expr != null) {
19983                                                indirectExpressions.add(expr);
19984                                        }
19985                                }
19986                        }
19987                }
19988                if (functionCall.getWindowDef() != null && functionCall.getWindowDef().getOrderBy() != null) {
19989                        TOrderByItemList orderByList = functionCall.getWindowDef().getOrderBy().getItems();
19990                        for (int i = 0; i < orderByList.size(); i++) {
19991                                TOrderByItem element = orderByList.getOrderByItem(i);
19992                                TExpression expression = element.getSortKey();
19993                                indirectExpressions.add(expression);
19994                        }
19995                }
19996                if (functionCall.getWithinGroup() != null && functionCall.getWithinGroup().getOrderBy() != null) {
19997                        TOrderByItemList orderByList = functionCall.getWithinGroup().getOrderBy().getItems();
19998                        for (int i = 0; i < orderByList.size(); i++) {
19999                                TOrderByItem element = orderByList.getOrderByItem(i);
20000                                TExpression expression = element.getSortKey();
20001                                indirectExpressions.add(expression);
20002                        }
20003                }
20004                if (functionCall.getCallTarget() != null) {
20005                        directExpressions.add(functionCall.getCallTarget().getExpr());
20006                }
20007                if (functionCall.getFieldValues() != null) {
20008                        for (int k = 0; k < functionCall.getFieldValues().size(); k++) {
20009                                TExpression expr = functionCall.getFieldValues().getResultColumn(k).getExpr();
20010                                directExpressions.add(expr);
20011                        }
20012                }
20013                if (functionCall instanceof TJsonObjectFunction) {
20014                        TJsonObjectFunction jsonObject = (TJsonObjectFunction)functionCall;
20015                        for (int k = 0; k < jsonObject.getKeyValues().size(); k++) {
20016                                TExpression expr = jsonObject.getKeyValues().get(k).getValue();
20017                                directExpressions.add(expr);
20018                        }
20019                }
20020        }
20021
20022        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
20023                                                                                TFunctionCall functionCall, int argumentIndex) {
20024                if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) {
20025                        TExpression expr = functionCall.getArgs().getExpression(argumentIndex);
20026                        if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) {
20027                                directExpressions.add(expr);
20028                        }
20029                        if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getFunctionName().toString(), functionCall.getArgs().size(), argumentIndex)) {
20030                                indirectExpressions.add(expr);
20031                        }
20032                }
20033        }
20034        
20035        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
20036                        TCallStatement functionCall, int argumentIndex) {
20037                if (functionCall.getArgs() != null && argumentIndex < functionCall.getArgs().size()) {
20038                        TExpression expr = functionCall.getArgs().getExpression(argumentIndex);
20039                        if (FunctionUtility.isDirectRelation(option.getVendor(), functionCall.getRoutineName().toString(),
20040                                        functionCall.getArgs().size(), argumentIndex)) {
20041                                directExpressions.add(expr);
20042                        }
20043                        if (FunctionUtility.isIndirectRelation(option.getVendor(), functionCall.getRoutineName().toString(),
20044                                        functionCall.getArgs().size(), argumentIndex)) {
20045                                indirectExpressions.add(expr);
20046                        }
20047                }
20048        }
20049
20050        private void getFunctionExpressions(List<TExpression> directExpressions, List<TExpression> indirectExpressions,
20051                                                                                TMssqlExecute functionCall, String argumentName, int argumentIndex) {
20052                if (functionCall.getParameters() != null) {
20053                        for (int i = 0; i < functionCall.getParameters().size(); i++) {
20054                                TExecParameter param = functionCall.getParameters().getExecParameter(i);
20055                                if (param.getParameterName() != null) {
20056                                        if (DlineageUtil.compareColumnIdentifier(param.getParameterName().toString(), argumentName)) {
20057                                                TExpression expr = param.getParameterValue();
20058                                                directExpressions.add(expr);
20059                                        }
20060                                } else if (i == argumentIndex) {
20061                                        TExpression expr = param.getParameterValue();
20062                                        directExpressions.add(expr);
20063                                }
20064                        }
20065                }
20066        }
20067
20068        private void analyzeJoin(TJoin join, EffectType effectType) {
20069                if (join.getJoinItems() != null) {
20070                        for (int j = 0; j < join.getJoinItems().size(); j++) {
20071                                TJoinItem joinItem = join.getJoinItems().getJoinItem(j);
20072                                TExpression expr = joinItem.getOnCondition();
20073                                if (expr != null) {
20074                                        analyzeFilterCondition(null, expr, joinItem.getJoinType(), JoinClauseType.on, effectType);
20075                                }
20076                        }
20077                }
20078
20079                if (join.getJoin() != null) {
20080                        analyzeJoin(join.getJoin(), effectType);
20081                }
20082        }
20083
20084        private TSelectSqlStatement getParentSetSelectStmt(TSelectSqlStatement stmt) {
20085                TCustomSqlStatement parent = stmt.getParentStmt();
20086                if (parent == null)
20087                        return null;
20088                if (parent.getStatements() != null) {
20089                        for (int i = 0; i < parent.getStatements().size(); i++) {
20090                                TCustomSqlStatement temp = parent.getStatements().get(i);
20091                                if (temp instanceof TSelectSqlStatement) {
20092                                        TSelectSqlStatement select = (TSelectSqlStatement) temp;
20093                                        if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt)
20094                                                return select;
20095                                }
20096                        }
20097                }
20098                if (parent instanceof TSelectSqlStatement) {
20099                        TSelectSqlStatement select = (TSelectSqlStatement) parent;
20100                        if (select.getLeftStmt() == stmt || select.getRightStmt() == stmt)
20101                                return select;
20102                }
20103                return null;
20104        }
20105
20106        private void createSelectSetResultColumns(SelectSetResultSet resultSet, TSelectSqlStatement stmt) {
20107                if (stmt.getSetOperatorType() != ESetOperatorType.none) {
20108                        createSelectSetResultColumns(resultSet, stmt.getLeftStmt());
20109                } else {
20110                        TResultColumnList columnList = stmt.getResultColumnList();
20111                        ResultSet subqueryResultSet = (ResultSet) modelManager.getModel(columnList);
20112                        if(subqueryResultSet!=null && subqueryResultSet.isDetermined()) {
20113                                for (int j = 0; j < subqueryResultSet.getColumns().size(); j++) {
20114                                        ResultColumn tableColumn = subqueryResultSet.getColumns().get(j);
20115                                        if (tableColumn.getRefColumnName() != null) {
20116                                                TObjectName columnName = new TObjectName();
20117                                                columnName.setString(tableColumn.getRefColumnName());
20118                                                modelFactory.createDeterminedResultColumn(
20119                                                                resultSet, columnName);
20120                                        } else {
20121                                                TObjectName columnName = new TObjectName();
20122                                                columnName.setString(tableColumn.getName());
20123                                                modelFactory.createDeterminedResultColumn(
20124                                                                resultSet, columnName);
20125                                        }
20126                                }
20127                                resultSet.setDetermined(true);
20128                                return;
20129                        }
20130                        
20131                        boolean isDetermined = true;
20132                        for (int i = 0; i < columnList.size(); i++) {
20133                                TResultColumn column = columnList.getResultColumn(i);
20134                                
20135                                if ("*".equals(column.getColumnNameOnly())) {
20136                                        TObjectName columnObject = column.getFieldAttr();
20137                                        TTable sourceTable = columnObject.getSourceTable();
20138                                        if (sourceTable != null) {
20139                                                Object tableModel = modelManager.getModel(sourceTable);
20140                                                if (tableModel instanceof Table && ((Table) tableModel).isCreateTable()) {
20141                                                        Table table = (Table) tableModel;
20142                                                        for (int j = 0; j < table.getColumns().size(); j++) {
20143                                                                TableColumn tableColumn = table.getColumns().get(j);
20144                                                                if (column.getExceptColumnList() != null) {
20145                                                                        boolean except = false;
20146                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
20147                                                                                if (getColumnName(objectName.toString())
20148                                                                                                .equals(getColumnName(tableColumn.getName()))) {
20149                                                                                        except = true;
20150                                                                                        break;
20151                                                                                }
20152                                                                        }
20153                                                                        if (!except && tableColumn.isStruct()) {
20154                                                                                List<String> names = SQLUtil
20155                                                                                                .parseNames(tableColumn.getName());
20156                                                                                for (String name : names) {
20157                                                                                        for (TObjectName objectName : column
20158                                                                                                        .getExceptColumnList()) {
20159                                                                                                if (getColumnName(objectName.toString())
20160                                                                                                                .equals(getColumnName(name))) {
20161                                                                                                        except = true;
20162                                                                                                        break;
20163                                                                                                }
20164                                                                                        }
20165                                                                                        if (except) {
20166                                                                                                break;
20167                                                                                        }
20168                                                                                }
20169                                                                        }
20170                                                                        if (except) {
20171                                                                                continue;
20172                                                                        }
20173                                                                }
20174                                                                TObjectName columnName = new TObjectName();
20175                                                                columnName.setString(tableColumn.getName());
20176                                                                ResultColumn resultColumn = modelFactory.createResultColumn(
20177                                                                                resultSet, columnName);
20178                                                                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
20179                                                                relation.setEffectType(EffectType.select);
20180                                                                relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
20181                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
20182                                                        }
20183                                                        continue;
20184                                                } else if (tableModel instanceof ResultSet
20185                                                                && ((ResultSet) tableModel).isDetermined()) {
20186                                                        ResultSet table = (ResultSet) tableModel;
20187                                                        for (int j = 0; j < table.getColumns().size(); j++) {
20188                                                                ResultColumn tableColumn = table.getColumns().get(j);
20189                                                                if (column.getExceptColumnList() != null) {
20190                                                                        boolean except = false;
20191                                                                        for (TObjectName objectName : column.getExceptColumnList()) {
20192                                                                                if (getColumnName(objectName.toString())
20193                                                                                                .equals(getColumnName(tableColumn.getName()))) {
20194                                                                                        except = true;
20195                                                                                        break;
20196                                                                                }
20197                                                                        }
20198                                                                        if (!except && tableColumn.isStruct()) {
20199                                                                                List<String> names = SQLUtil
20200                                                                                                .parseNames(tableColumn.getName());
20201                                                                                for (String name : names) {
20202                                                                                        for (TObjectName objectName : column
20203                                                                                                        .getExceptColumnList()) {
20204                                                                                                if (getColumnName(objectName.toString())
20205                                                                                                                .equals(getColumnName(name))) {
20206                                                                                                        except = true;
20207                                                                                                        break;
20208                                                                                                }
20209                                                                                        }
20210                                                                                        if (except) {
20211                                                                                                break;
20212                                                                                        }
20213                                                                                }
20214                                                                        }
20215                                                                        if (except) {
20216                                                                                continue;
20217                                                                        }
20218                                                                }
20219                                                                if (tableColumn.getRefColumnName() != null) {
20220                                                                        TObjectName columnName = new TObjectName();
20221                                                                        columnName.setString(tableColumn.getRefColumnName());
20222                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(
20223                                                                                        resultSet, columnName);
20224                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
20225                                                                        relation.setEffectType(EffectType.select);
20226                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
20227                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
20228                                                                } else {
20229                                                                        TObjectName columnName = new TObjectName();
20230                                                                        columnName.setString(tableColumn.getName());
20231                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(
20232                                                                                        resultSet, columnName);
20233                                                                        DataFlowRelationship relation = modelFactory.createDataFlowRelation();
20234                                                                        relation.setEffectType(EffectType.select);
20235                                                                        relation.setTarget(new ResultColumnRelationshipElement(resultColumn));
20236                                                                        relation.addSource(new ResultColumnRelationshipElement(tableColumn));
20237                                                                }
20238                                                        }
20239                                                        continue;
20240                                                }
20241                                                else {
20242                                                        isDetermined = false;
20243                                                }
20244                                        }
20245                                }
20246                                        
20247                                ResultColumn resultColumn = modelFactory.createSelectSetResultColumn(resultSet, column, i);
20248
20249                                if (resultColumn.getColumnObject() instanceof TResultColumn) {
20250                                        TResultColumn columnObject = (TResultColumn) resultColumn.getColumnObject();
20251                                        if (columnObject.getFieldAttr() != null) {
20252                                                if ("*".equals(getColumnName(columnObject.getFieldAttr()))) {
20253                                                        TObjectName fieldAttr = columnObject.getFieldAttr();
20254                                                        TTable sourceTable = fieldAttr.getSourceTable();
20255                                                        if (fieldAttr.getTableToken() != null && sourceTable != null) {
20256                                                                TObjectName[] columns = modelManager.getTableColumns(sourceTable);
20257                                                                for (int j = 0; j < columns.length; j++) {
20258                                                                        TObjectName columnName = columns[j];
20259                                                                        if (columnName == null) {
20260                                                                                continue;
20261                                                                        }
20262                                                                        if ("*".equals(getColumnName(columnName))) {
20263                                                                                continue;
20264                                                                        }
20265                                                                        resultColumn.bindStarLinkColumn(columnName);
20266                                                                }
20267
20268                                                                if (modelManager.getModel(sourceTable) instanceof Table) {
20269                                                                        Table tableModel = (Table) modelManager.getModel(sourceTable);
20270                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
20271                                                                                for (int z = 0; z < tableModel.getColumns().size(); z++) {
20272                                                                                        if ("*".equals(
20273                                                                                                        getColumnName(tableModel.getColumns().get(z).getColumnObject()))) {
20274                                                                                                continue;
20275                                                                                        }
20276                                                                                        resultColumn.bindStarLinkColumn(
20277                                                                                                        tableModel.getColumns().get(z).getColumnObject());
20278                                                                                }
20279                                                                        }
20280                                                                } else if (modelManager.getModel(sourceTable) instanceof QueryTable) {
20281                                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(sourceTable);
20282                                                                        if (tableModel != null && !tableModel.getColumns().isEmpty()) {
20283                                                                                for (ResultColumn item : tableModel.getColumns()) {
20284                                                                                        if (item.hasStarLinkColumn()) {
20285                                                                                                for (TObjectName starLinkColumn : item.getStarLinkColumnList()) {
20286                                                                                                        if ("*".equals(getColumnName(starLinkColumn))) {
20287                                                                                                                continue;
20288                                                                                                        }
20289                                                                                                        resultColumn.bindStarLinkColumn(starLinkColumn);
20290                                                                                                }
20291                                                                                        } else if (item.getColumnObject() instanceof TObjectName) {
20292                                                                                                TObjectName starLinkColumn = (TObjectName) item.getColumnObject();
20293                                                                                                if ("*".equals(getColumnName(starLinkColumn))) {
20294                                                                                                        continue;
20295                                                                                                }
20296                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
20297                                                                                        }
20298                                                                                }
20299                                                                        }
20300                                                                }
20301
20302                                                        } else {
20303                                                                TTableList tables = stmt.getTables();
20304                                                                for (int k = 0; k < tables.size(); k++) {
20305                                                                        TTable tableElement = tables.getTable(k);
20306                                                                        TObjectName[] columns = modelManager.getTableColumns(tableElement);
20307                                                                        for (int j = 0; j < columns.length; j++) {
20308                                                                                TObjectName columnName = columns[j];
20309                                                                                if (columnName == null) {
20310                                                                                        continue;
20311                                                                                }
20312                                                                                if ("*".equals(getColumnName(columnName))) {
20313                                                                                        if (modelManager.getModel(tableElement) instanceof Table) {
20314                                                                                                Table tableModel = (Table) modelManager.getModel(tableElement);
20315                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
20316                                                                                                        for (int z = 0; z < tableModel.getColumns().size(); z++) {
20317                                                                                                                resultColumn.bindStarLinkColumn(
20318                                                                                                                                tableModel.getColumns().get(z).getColumnObject());
20319                                                                                                        }
20320                                                                                                }
20321                                                                                        } else if (modelManager.getModel(tableElement) instanceof QueryTable) {
20322                                                                                                QueryTable tableModel = (QueryTable) modelManager
20323                                                                                                                .getModel(tableElement);
20324                                                                                                if (tableModel != null && !tableModel.getColumns().isEmpty()) {
20325                                                                                                        for (ResultColumn item : tableModel.getColumns()) {
20326                                                                                                                if (item.hasStarLinkColumn()) {
20327                                                                                                                        for (TObjectName starLinkColumn : item
20328                                                                                                                                        .getStarLinkColumnList()) {
20329                                                                                                                                resultColumn.bindStarLinkColumn(starLinkColumn);
20330                                                                                                                        }
20331                                                                                                                } else if (item.getColumnObject() instanceof TObjectName) {
20332                                                                                                                        resultColumn.bindStarLinkColumn(
20333                                                                                                                                        (TObjectName) item.getColumnObject());
20334                                                                                                                }
20335                                                                                                        }
20336                                                                                                }
20337                                                                                        }
20338                                                                                        continue;
20339                                                                                }
20340                                                                                resultColumn.bindStarLinkColumn(columnName);
20341                                                                        }
20342                                                                }
20343                                                        }
20344                                                }
20345                                        }
20346                                }
20347                                
20348                                resultSet.setDetermined(isDetermined);
20349                        }
20350                }
20351        }
20352
20353        private void analyzeResultColumn(TResultColumn column, EffectType effectType) {
20354                TExpression expression = column.getExpr();
20355                if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
20356                        expression = expression.getRightOperand();
20357                }
20358
20359                if (expression.getExpressionType() == EExpressionType.array_t) {
20360                        if (expression.getExprList() != null) {
20361                                for (TExpression expr : expression.getExprList()) {
20362                                        columnsInExpr visitor = new columnsInExpr();
20363                                        expr.inOrderTraverse(visitor);
20364                                        List<TObjectName> objectNames = visitor.getObjectNames();
20365
20366                                        List<TParseTreeNode> functions = visitor.getFunctions();
20367
20368                                        if (functions != null && !functions.isEmpty()) {
20369                                                analyzeFunctionDataFlowRelation(column, functions, effectType);
20370                                        }
20371
20372                                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
20373                                        if (subquerys != null && !subquerys.isEmpty()) {
20374                                                analyzeSubqueryDataFlowRelation(column, subquerys, effectType);
20375                                        }
20376
20377                                        analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions);
20378
20379                                        List<TParseTreeNode> constants = visitor.getConstants();
20380                                        Object columnObject = modelManager.getModel(column);
20381                                        analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions);
20382
20383                                        analyzeRecordSetRelation(functions, effectType);
20384                                        // analyzeResultColumnImpact( column, effectType, functions);
20385                                }
20386                        }
20387                        else {
20388                                List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
20389                                TConstant constant = new TConstant();
20390                                constant.setString(expression.toString());
20391                                constants.add(constant);
20392                                Object columnObject = modelManager.getModel(column);
20393                                analyzeConstantDataFlowRelation(columnObject, constants, effectType, null);
20394                        }
20395                } else {
20396                        columnsInExpr visitor = new columnsInExpr();
20397                        expression.inOrderTraverse(visitor);
20398                        List<TObjectName> objectNames = visitor.getObjectNames();
20399
20400                        List<TParseTreeNode> functions = visitor.getFunctions();
20401
20402                        if (functions != null && !functions.isEmpty()) {
20403                                analyzeFunctionDataFlowRelation(column, functions, effectType);
20404                        }
20405
20406                        List<TSelectSqlStatement> subquerys = visitor.getSubquerys();
20407                        if (subquerys != null && !subquerys.isEmpty()) {
20408                                analyzeSubqueryDataFlowRelation(column, subquerys, effectType);
20409                        }
20410
20411                        analyzeDataFlowRelation(column, objectNames, column.getExceptColumnList(), effectType, functions);
20412
20413                        List<TParseTreeNode> constants = visitor.getConstants();
20414                        Object columnObject = modelManager.getModel(column);
20415                        analyzeConstantDataFlowRelation(columnObject, constants, effectType, functions);
20416
20417                        analyzeRecordSetRelation(functions, effectType);
20418                        // analyzeResultColumnImpact( column, effectType, functions);
20419                }
20420        }
20421        
20422        
20423        private void analyzeValueColumn(Object object, TResultColumn column, EffectType effectType) {
20424                TExpression expression = column.getExpr();
20425                if (expression.getExpressionType() == EExpressionType.sqlserver_proprietary_column_alias_t) {
20426                        expression = expression.getRightOperand();
20427                }
20428
20429                if (expression.getExpressionType() == EExpressionType.array_t) {
20430                        if (expression.getExprList() != null) {
20431                                for (TExpression expr : expression.getExprList()) {
20432                                        columnsInExpr visitor = new columnsInExpr();
20433                                        expr.inOrderTraverse(visitor);
20434                                        List<TObjectName> objectNames = visitor.getObjectNames();
20435                                        analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null);
20436                                        List<TParseTreeNode> constants = visitor.getConstants();
20437                                        analyzeConstantDataFlowRelation(object, constants, effectType, null);
20438                                }
20439                        }
20440                        else {
20441                                List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
20442                                TConstant constant = new TConstant();
20443                                constant.setString(expression.toString());
20444                                constants.add(constant);
20445                                Object columnObject = modelManager.getModel(column);
20446                                analyzeConstantDataFlowRelation(object, constants, effectType, null);
20447                        }
20448                } else {
20449                        columnsInExpr visitor = new columnsInExpr();
20450                        expression.inOrderTraverse(visitor);
20451                        List<TObjectName> objectNames = visitor.getObjectNames();
20452                        analyzeDataFlowRelation(object, objectNames, column.getExceptColumnList(), effectType, null, null);
20453                        List<TParseTreeNode> constants = visitor.getConstants();
20454                        analyzeConstantDataFlowRelation(object, constants, effectType, null);           }
20455        }
20456
20457        private void analyzeTableColumn(TableColumn tableColumn, TFunctionCall functionCall, EffectType effectType) {
20458                List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>();
20459                functions.add(functionCall);
20460
20461                if (functions != null && !functions.isEmpty()) {
20462                        analyzeFunctionDataFlowRelation(tableColumn, functions, effectType);
20463                }
20464
20465                analyzeRecordSetRelation(functions, effectType);
20466        }
20467
20468        private void analyzeRecordSetRelation(List<TParseTreeNode> functions, EffectType effectType) {
20469                if (functions == null || functions.size() == 0)
20470                        return;
20471
20472                List<TFunctionCall> aggregateFunctions = new ArrayList<TFunctionCall>();
20473                for (TParseTreeNode function : functions) {
20474                        if (function instanceof TFunctionCall && isAggregateFunction((TFunctionCall) function)) {
20475                                aggregateFunctions.add((TFunctionCall) function);
20476                        }
20477                }
20478
20479                if (aggregateFunctions.size() == 0)
20480                        return;
20481
20482                for (int i = 0; i < aggregateFunctions.size(); i++) {
20483                        TFunctionCall function = aggregateFunctions.get(i);
20484
20485                        TCustomSqlStatement stmt = stmtStack.peek();
20486                        if (stmt instanceof TSelectSqlStatement) {
20487                                TSelectSqlStatement select = (TSelectSqlStatement) stmt;
20488                                if (select.getGroupByClause() != null) {
20489                                        TGroupByItemList groupByList = select.getGroupByClause().getItems();
20490                                        for (int j = 0; j < groupByList.size(); j++) {
20491                                                TGroupByItem groupBy = groupByList.getGroupByItem(j);
20492                                                TExpression expr = groupBy.getExpr();
20493                                                analyzeAggregate(function, expr);
20494                                        }
20495
20496                                        if (select.getGroupByClause().getHavingClause() != null) {
20497                                                analyzeAggregate(function, select.getGroupByClause().getHavingClause());
20498                                        }
20499                                        // if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString()))
20500                                        {
20501                                                analyzeAggregate(function, null);
20502                                        }
20503                                } else {
20504                                        analyzeAggregate(function, null);
20505                                }
20506                        }
20507                }
20508        }
20509
20510        private void analyzeDataFlowRelation(TParseTreeNode gspObject, List<TObjectName> objectNames,
20511                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions) {
20512                Object columnObject = modelManager.getModel(gspObject);
20513                analyzeDataFlowRelation(columnObject, objectNames, exceptColumnList, effectType, functions, null);
20514        }
20515
20516        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType,
20517                        List<TParseTreeNode> functions) {
20518                return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, null);
20519        }
20520        
20521        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames, EffectType effectType,
20522                        List<TParseTreeNode> functions, Process process) {
20523                return analyzeDataFlowRelation(modelObject, objectNames, null, effectType, functions, process);
20524        }
20525
20526        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames,
20527                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process) {
20528                return analyzeDataFlowRelation(modelObject, objectNames, exceptColumnList, effectType, functions, process, null);
20529        }
20530        
20531        private DataFlowRelationship analyzeDataFlowRelation(Object modelObject, List<TObjectName> objectNames,
20532                        TObjectNameList exceptColumnList, EffectType effectType, List<TParseTreeNode> functions, Process process, Integer valueIndex) {
20533                if (objectNames == null || objectNames.size() == 0)
20534                        return null;
20535
20536                boolean isStar = false;
20537                boolean showStar = false;
20538
20539                DataFlowRelationship relation = modelFactory.createDataFlowRelation();
20540                relation.setEffectType(effectType);
20541                relation.setProcess(process);
20542
20543                if (functions != null && !functions.isEmpty()) {
20544                        relation.setFunction(getFunctionName(functions.get(0)));
20545                }
20546
20547                int columnIndex = -1;
20548
20549                boolean isOut = false;
20550
20551                if (modelObject instanceof ResultColumn) {
20552                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
20553
20554                        if ("*".equals(((ResultColumn) modelObject).getName())) {
20555                                isStar = true;
20556                                showStar = ((ResultColumn) modelObject).isShowStar();
20557                        }
20558
20559                        if (((ResultColumn) modelObject).getResultSet() != null) {
20560                                columnIndex = ((ResultColumn) modelObject).getResultSet().getColumns().indexOf(modelObject);
20561                        }
20562                } else if (modelObject instanceof TableColumn) {
20563                        Table table  = ((TableColumn) modelObject).getTable();
20564                        if(table.getSubType() == SubType.out && isNotInProcedure(table)){
20565                                isOut = true;
20566                                relation.addSource(new TableColumnRelationshipElement((TableColumn) modelObject));
20567                        }
20568                        else {
20569                                relation.setTarget(new TableColumnRelationshipElement((TableColumn) modelObject));
20570                        }
20571
20572                        if ("*".equals(((TableColumn) modelObject).getName())) {
20573                                isStar = true;
20574                        }
20575
20576                        if (((TableColumn) modelObject).getTable() != null) {
20577                                columnIndex = ((TableColumn) modelObject).getTable().getColumns().indexOf(modelObject);
20578                        }
20579                } else {
20580                        throw new UnsupportedOperationException();
20581                }
20582
20583                for (int i = 0; i < objectNames.size(); i++) {
20584                        TObjectName columnName = objectNames.get(i);
20585                        if (columnName.toString().indexOf(".") == -1 && isConstant(columnName)) {
20586                                boolean isConstant = true;
20587                                if (columnName.getSourceTable() != null) {
20588                                        Table tableModel = modelManager.getTableByName(
20589                                                        DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString()));
20590                                        if (tableModel != null && tableModel.getColumns() != null) {
20591                                                for (int j = 0; j < tableModel.getColumns().size(); j++) {
20592                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
20593                                                                        getColumnName(tableModel.getColumns().get(j).getName()))) {
20594                                                                isConstant = false;
20595                                                                break;
20596                                                        }
20597                                                }
20598                                        }
20599                                }
20600
20601                                if (isConstant) {
20602                                        if (option.isShowConstantTable()) {
20603                                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
20604                                                TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false);
20605                                                if(tableColumn!=null) {
20606                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20607                                                }
20608                                        }
20609                                        continue;
20610                                }
20611                        }
20612                        if (columnName.getDbObjectType() == EDbObjectType.variable) {
20613                                boolean find = false;
20614                                List<String> segments = SQLUtil.parseNames(columnName.toString());
20615                                if (segments.size() == 1) {
20616                                        Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString()));
20617                                        if (variable != null) {
20618                                                TableColumn columnModel = variable.getColumns().get(0);
20619                                                if(variable.getColumns().size()>0){
20620                                                        TableColumn matchColumn = matchColumn(variable.getColumns(), columnName);
20621                                                        if(matchColumn!=null){
20622                                                                columnModel = matchColumn;
20623                                                        }
20624                                                }
20625                                                if(isOut){
20626                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20627                                                }
20628                                                else {
20629                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20630                                                }
20631                                                find = true;
20632                                        } else {
20633                                                if (columnName.toString().matches("\\$\\d+")) {
20634                                                        TCustomSqlStatement stmt = stmtStack.peek();
20635                                                        Procedure procedure = modelManager
20636                                                                        .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt)));
20637                                                        if(procedure!=null) {
20638                                                                Variable cursorVariable = modelFactory.createVariable(procedure.getArguments().get(Integer.valueOf(columnName.toString().replace("$", "")) - 1).getName());
20639                                                                if (isOut) {
20640                                                                        relation.setTarget(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
20641                                                                } else {
20642                                                                        relation.addSource(new TableColumnRelationshipElement(cursorVariable.getColumns().get(0)));
20643                                                                }
20644                                                        }
20645                                                } else {
20646                                                        Variable cursorVariable = modelFactory.createVariable(columnName);
20647                                                        cursorVariable.setCreateTable(true);
20648                                                        cursorVariable.setSubType(SubType.record);
20649                                                        TableColumn variableProperty = null;
20650                                                        if(cursorVariable.getColumns() == null || cursorVariable.getColumns().isEmpty()) {
20651                                variableProperty = modelFactory.createTableColumn(cursorVariable, columnName,
20652                                        true);
20653                            }
20654                                                        else{
20655                                                                variableProperty = cursorVariable.getColumns().get(0);
20656                                                        }
20657                                                        if (isOut) {
20658                                                                relation.setTarget(new TableColumnRelationshipElement(variableProperty));
20659                                                        } else {
20660                                                                relation.addSource(new TableColumnRelationshipElement(variableProperty));
20661                                                        }
20662                                                }
20663                                                find = true;
20664                                        }
20665                                } else if (option.getVendor() == EDbVendor.dbvoracle && columnName.getTableToken()!=null) {
20666                                        Variable cursorVariable = modelFactory
20667                                                        .createVariable(columnName.getTableToken().toString());
20668
20669                                        TObjectName variableColumnName = new TObjectName();
20670                                        variableColumnName.setString(segments.get(segments.size() - 1));
20671
20672                                        if (cursorVariable.getColumns() != null) {
20673                                                for (int j = 0; j < cursorVariable.getColumns().size(); j++) {
20674                                                        if (getColumnName(variableColumnName)
20675                                                                        .equals(getColumnName(cursorVariable.getColumns().get(j).getColumnObject()))) {
20676                                                                TableColumn columnModel = cursorVariable.getColumns().get(j);
20677                                                                if (isOut) {
20678                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20679                                                                } else {
20680                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20681                                                                }
20682                                                                find = true;
20683                                                        }
20684                                                }
20685                                        }
20686
20687                                        if (!find) {
20688                                                TableColumn variableColumn = new TableColumn(cursorVariable, variableColumnName);
20689                                                cursorVariable.addColumn(variableColumn);
20690                                                if (isOut) {
20691                                                        relation.setTarget(new TableColumnRelationshipElement(variableColumn));
20692                                                } else {
20693                                                        relation.addSource(new TableColumnRelationshipElement(variableColumn));
20694                                                }
20695                                        }
20696                                } else {
20697                                        Table variable = modelManager
20698                                                        .getTableByName(DlineageUtil.getTableFullName(segments.get(segments.size() - 2)));
20699                                        if (variable != null) {
20700                                                for (int j = 0; j < variable.getColumns().size(); j++) {
20701                                                        if (getColumnName(columnName)
20702                                                                        .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) {
20703                                                                TableColumn columnModel = variable.getColumns().get(j);
20704                                                                if (isOut) {
20705                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20706                                                                } else {
20707                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20708                                                                }
20709                                                                find = true;
20710                                                        }
20711                                                }
20712                                        }
20713                                }
20714                                if (!find) {
20715                                        TCustomSqlStatement stmt = stmtStack.peek();
20716                                        if (getProcedureParentName(stmt) != null) {
20717                                                Procedure procedure = modelManager
20718                                                                .getProcedureByName(DlineageUtil.getTableFullName(getProcedureParentName(stmt)));
20719                                                if (procedure != null && procedure.getArguments() != null) {
20720                                                        for (Argument argument : procedure.getArguments()) {
20721                                                                if (DlineageUtil.getTableFullName(argument.getName())
20722                                                                                .equals(DlineageUtil.getTableFullName(columnName.toString()))) {
20723                                                                        relation.addSource(new ArgumentRelationshipElement(argument));
20724                                                                }
20725                                                        }
20726                                                }
20727                                        }
20728                                }
20729                                continue;
20730                        }
20731                        
20732                        // Handle sequence pseudocolumn syntax (sequence.NEXTVAL or sequence.CURRVAL)
20733                        // Used by Oracle, Snowflake, and accepted by other vendors for compatibility
20734                        if(("NEXTVAL".equalsIgnoreCase(columnName.getColumnNameOnly()) || "CURRVAL".equalsIgnoreCase(columnName.getColumnNameOnly()))){
20735                                List<String> segments = SQLUtil.parseNames(columnName.toString());
20736                                if (segments.size() > 1) {
20737                                        segments.remove(segments.size()-1);
20738                                        Table table = modelFactory.createTableByName(SQLUtil.mergeSegments(segments, 0), true);
20739                                        table.setSequence(true);
20740                                        TableColumn seqCursor = modelFactory.createTableColumn(table, columnName, true);
20741                                        relation.addSource(new TableColumnRelationshipElement(seqCursor));
20742                                        continue;
20743                                }
20744                        }
20745
20746                        {
20747                                if (columnName.getSourceTable() != null) {
20748
20749                                }
20750                                else {
20751                                        Table variable = modelManager.getTableByName(DlineageUtil.getTableFullName(columnName.toString()));
20752                                        if (variable == null) {
20753                                                variable = modelManager
20754                                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getTableString()));
20755                                                if (variable != null && variable.isCursor()) {
20756                                                        TableColumn variableColumn = modelFactory.createInsertTableColumn(variable, columnName);
20757                                                        if (variableColumn != null) {
20758                                                                if(isOut){
20759                                                                        relation.setTarget(new TableColumnRelationshipElement(variableColumn));
20760                                                                }
20761                                                                else {
20762                                                                        relation.addSource(new TableColumnRelationshipElement(variableColumn));
20763                                                                }
20764                                                        } else {
20765                                                                if(isOut){
20766                                                                        relation.setTarget(new TableColumnRelationshipElement(variable.getColumns().get(0)));
20767                                                                }
20768                                                                else {
20769                                                                        relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0)));
20770                                                                }
20771                                                        }
20772                                                        continue;
20773                                                }
20774                                        } else if (variable.isVariable() || variable.isCursor()) {
20775                                                TableColumn columnModel = variable.getColumns().get(0);
20776                                                if (valueIndex != null) {
20777                                                        if(isOut){
20778                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel, valueIndex));
20779                                                        }
20780                                                        else {
20781                                                                relation.addSource(new TableColumnRelationshipElement(columnModel, valueIndex));
20782                                                        }
20783                                                } else {
20784                                                        if(isOut){
20785                                                                relation.setTarget(new TableColumnRelationshipElement(columnModel));
20786                                                        }
20787                                                        else {
20788                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
20789                                                        }
20790                                                }
20791                                                continue;
20792                                        }
20793                                }
20794                        }
20795                        
20796                        if (columnName.getColumnNameOnly().startsWith("@")
20797                                        && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
20798                                continue;
20799                        }
20800
20801                        if (columnName.getColumnNameOnly().startsWith(":")
20802                                        && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
20803                                Table variable = modelManager
20804                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getColumnNameOnly().replace(":", "")));
20805                                if (variable != null) {
20806                                        for (int j = 0; j < variable.getColumns().size(); j++) {
20807                                                if (getColumnName(columnName).replace(":", "")
20808                                                                .equals(getColumnName(variable.getColumns().get(j).getColumnObject()))) {
20809                                                        TableColumn columnModel = variable.getColumns().get(j);
20810                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20811                                                }
20812                                        }
20813                                }
20814                                continue;
20815                        }
20816
20817                        boolean linkedFirstTable = false;
20818                        
20819                        TCustomSqlStatement stmt = stmtStack.peek();
20820                        TTableList tableList = stmt.tables;
20821                        if ((tableList == null || tableList.size() == 0) && (hiveFromTables != null && hiveFromTables.size() > 0)) {
20822                                tableList = hiveFromTables;
20823                        }
20824
20825                        List<TTable> tables = new ArrayList<TTable>();
20826                        {
20827                                TTable table = columnName.getSourceTable();
20828
20829                                // 针对CursorVariable特殊处理
20830                                if (columnName.getTableToken() != null) {
20831
20832                                        Table tableModel = null;
20833                                        if (table != null && modelManager.getModel(table) instanceof Table) {
20834                                                tableModel = (Table) modelManager.getModel(table);
20835                                        }
20836
20837                                        if (tableModel == null) {
20838                                                tableModel = modelManager
20839                                                                .getTableByName(DlineageUtil.getTableFullName(columnName.getTableToken().toString()));
20840                                        }
20841
20842                                        if (tableModel == null) {
20843                                                TCustomSqlStatement currentStmt = ModelBindingManager.getGlobalStmtStack().peek();
20844                                                String procedureName = DlineageUtil.getProcedureParentName(currentStmt);
20845                                                String variableString = columnName.getTableToken().toString();
20846                                                if (variableString.startsWith(":")) {
20847                                                        variableString = variableString.substring(variableString.indexOf(":") + 1);
20848                                                }
20849                                                if (!SQLUtil.isEmpty(procedureName)) {
20850                                                        variableString = procedureName + "." + SQLUtil.getIdentifierNormalTableName(variableString);
20851                                                }
20852
20853                                                if (modelManager
20854                                                                .getTableByName(DlineageUtil.getTableFullName(variableString)) instanceof Variable) {
20855                                                        tableModel = modelManager.getTableByName(DlineageUtil.getTableFullName(variableString));
20856                                                }
20857                                        }
20858
20859                                        if (tableModel != null) {
20860
20861                                                if (table == null) {
20862                                                        table = tableModel.getTableObject();
20863                                                }
20864
20865                                                if (tableModel.isVariable()) {
20866                                                        if (!isStar && "*".equals(getColumnName(columnName))) {
20867                                                                TObjectName[] columns = modelManager.getTableColumns(table);
20868                                                                for (int j = 0; j < columns.length; j++) {
20869                                                                        TObjectName objectName = columns[j];
20870                                                                        if (objectName == null || "*".equals(getColumnName(objectName))) {
20871                                                                                continue;
20872                                                                        }
20873                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName,
20874                                                                                        false);
20875                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20876                                                                }
20877                                                        } else {
20878                                                                if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) {
20879
20880                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
20881                                                                                TableColumn columnModel = tableModel.getColumns().get(j);
20882                                                                                if (exceptColumnList != null) {
20883                                                                                        boolean flag = false;
20884                                                                                        for (TObjectName objectName : exceptColumnList) {
20885                                                                                                if (getColumnName(objectName)
20886                                                                                                                .equals(getColumnName(columnModel.getColumnObject()))) {
20887                                                                                                        flag = true;
20888                                                                                                        break;
20889                                                                                                }
20890                                                                                        }
20891                                                                                        if (flag) {
20892                                                                                                continue;
20893                                                                                        }
20894                                                                                }
20895                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
20896                                                                        }
20897
20898                                                                        if (isStar && showStar) {
20899                                                                                TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20900                                                                                                false);
20901                                                                                if (columnModel == null) {
20902                                                                                        if (tableModel.isCreateTable()) {
20903                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
20904                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
20905                                                                                                        relation.setShowStarRelation(true);
20906                                                                                                }
20907                                                                                        }
20908                                                                                } else {
20909                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20910                                                                                        relation.setShowStarRelation(true);
20911                                                                                }
20912                                                                        }
20913                                                                } else {
20914                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
20915                                                                                        false);
20916                                                                        
20917                                                                        if(columnModel == null && containStarColumn(tableModel.getColumns())){
20918                                                                                columnModel = getStarColumn(tableModel.getColumns());
20919                                                                                if (columnModel != null && tableModel.getSubType() == SubType.record_type) {
20920                                                                                        if(!"*".equals(getColumnName(columnName))){
20921                                                                                                columnModel.bindStarLinkColumn(columnName);
20922                                                                                        }
20923                                                                                }
20924                                                                        }
20925                                                                        
20926                                                                        if (columnModel == null) {
20927                                                                                continue;
20928                                                                        }
20929                                                                        if (columnModel.hasStarLinkColumn()) {
20930                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel,
20931                                                                                                columnModel.getStarLinkColumnNames()
20932                                                                                                                .indexOf(DlineageUtil.getColumnName(columnName))));
20933                                                                        } else {
20934                                                                                if (isOut) {
20935                                                                                        relation.setTarget(new TableColumnRelationshipElement(columnModel));
20936                                                                                } else {
20937                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
20938                                                                                }
20939                                                                        }
20940                                                                        if (columnName.getSourceTable() != null
20941                                                                                        && columnName.getSourceTable().getTableType() == ETableSource.function) {
20942                                                                                analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(),
20943                                                                                                effectType);
20944                                                                        }
20945                                                                }
20946                                                        }
20947                                                        continue;
20948                                                }
20949                                        }
20950                                }
20951
20952                                if (table == null) {
20953                                        table = modelManager.getTable(stmt, columnName);
20954                                }
20955
20956                                if (table == null) {
20957                                        if (columnName.getTableToken() != null || !"*".equals(getColumnName(columnName))) {
20958                                                table = columnName.getSourceTable();
20959                                        }
20960                                        
20961                                        if (table == null && !SQLUtil.isEmpty(columnName.getTableString())) {
20962                                                table = modelManager.getTableFromColumn(columnName);
20963                                        }
20964                                }
20965
20966                                if (table == null) {
20967                                        if (tableList != null) {
20968                                                for (int j = 0; j < tableList.size(); j++) {
20969                                                        if (table != null)
20970                                                                break;
20971
20972                                                        TTable tTable = tableList.getTable(j);
20973                                                        if (tTable.getTableType().name().startsWith("open")) {
20974                                                                continue;
20975                                                        }
20976
20977                                                        if (getTableLinkedColumns(tTable) != null && getTableLinkedColumns(tTable).size() > 0) {
20978                                                                for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) {
20979                                                                        TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z);
20980                                                                        if ("*".equals(getColumnName(refer)))
20981                                                                                continue;
20982                                                                        // For BigQuery struct field access, match base column name from FieldPath
20983                                                                        String structFullName = getStructFieldFullName(columnName);
20984                                                                        if (structFullName != null) {
20985                                                                                String baseName = getStructFieldBaseName(columnName);
20986                                                                                if (baseName != null && DlineageUtil.getIdentifierNormalColumnName(getColumnName(refer))
20987                                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(baseName))) {
20988                                                                                        table = tTable;
20989                                                                                        break;
20990                                                                                }
20991                                                                        }
20992                                                                        if (getColumnName(refer).equals(getColumnName(columnName))) {
20993                                                                                table = tTable;
20994                                                                                break;
20995                                                                        }
20996                                                                }
20997                                                        }
20998
20999                                                        if (tTable.getLinkTable() != null) {
21000                                                                tTable = tTable.getLinkTable();
21001                                                                for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) {
21002                                                                        TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z);
21003                                                                        if ("*".equals(getColumnName(refer)))
21004                                                                                continue;
21005                                                                        if (getColumnName(refer).equals(getColumnName(columnName))) {
21006                                                                                table = tTable;
21007                                                                                break;
21008                                                                        }
21009                                                                }
21010                                                        }
21011
21012                                                        if (table != null)
21013                                                                break;
21014
21015                                                        if (columnName.getTableToken() != null && (columnName.getTableToken().getAstext()
21016                                                                        .equalsIgnoreCase(tTable.getName())
21017                                                                        || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) {
21018                                                                table = tTable;
21019                                                                break;
21020                                                        }
21021                                                }
21022                                        }
21023
21024                                        if (table == null) {
21025                                                for (int j = 0; j < tableList.size(); j++) {
21026                                                        if (table != null)
21027                                                                break;
21028
21029                                                        TTable tTable = tableList.getTable(j);
21030                                                        Object model = ModelBindingManager.get().getModel(tTable);
21031                                                        if (model instanceof Table) {
21032                                                                Table tableModel = (Table) model;
21033                                                                for (int z = 0; tableModel.getColumns() != null
21034                                                                                && z < tableModel.getColumns().size(); z++) {
21035                                                                        TableColumn refer = tableModel.getColumns().get(z);
21036                                                                        if (getColumnName(refer.getName()).equals(getColumnName(columnName))) {
21037                                                                                table = tTable;
21038                                                                                break;
21039                                                                        }
21040                                                                        if (refer.hasStarLinkColumn()) {
21041                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
21042                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
21043                                                                                                table = tTable;
21044                                                                                                break;
21045                                                                                        }
21046                                                                                }
21047                                                                        }
21048                                                                }
21049                                                        } else if (model instanceof QueryTable) {
21050                                                                QueryTable tableModel = (QueryTable) model;
21051                                                                for (int z = 0; tableModel.getColumns() != null
21052                                                                                && z < tableModel.getColumns().size(); z++) {
21053                                                                        ResultColumn refer = tableModel.getColumns().get(z);
21054                                                                        // Try FieldPath-based matching first
21055                                                                        String structFullName = getStructFieldFullName(columnName);
21056                                                                        if (structFullName != null) {
21057                                                                                String baseName = getStructFieldBaseName(columnName);
21058                                                                                if (baseName != null && DlineageUtil.getIdentifierNormalColumnName(refer.getName())
21059                                                                                                .equals(DlineageUtil.getIdentifierNormalColumnName(baseName))) {
21060                                                                                        table = tTable;
21061                                                                                        break;
21062                                                                                }
21063                                                                        }
21064                                                                        List<String> splits = SQLUtil.parseNames(columnName.toString());
21065                                                                        if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
21066                                                                                if (DlineageUtil.getIdentifierNormalColumnName(refer.getName())
21067                                                                                                .equals(DlineageUtil
21068                                                                                                                .getIdentifierNormalColumnName(getColumnName(splits.get(0))))) {
21069                                                                                        table = tTable;
21070                                                                                        break;
21071                                                                                }
21072                                                                        }
21073                                                                        else if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals(
21074                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
21075                                                                                table = tTable;
21076                                                                                break;
21077                                                                        }
21078                                                                        if (refer.hasStarLinkColumn()) {
21079                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
21080                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
21081                                                                                                table = tTable;
21082                                                                                                break;
21083                                                                                        }
21084                                                                                }
21085                                                                        }
21086                                                                }
21087                                                        }
21088                                                }
21089                                        }
21090                                }
21091
21092                                if (columnName.getTableToken() == null && "*".equals(getColumnName(columnName))) {
21093                                        if (!hasJoin(stmt)) {
21094                                                tables.add(table);
21095                                        } else {
21096                                                for (int j = 0; j < tableList.size(); j++) {
21097                                                        tables.add(tableList.getTable(j));
21098                                                }
21099                                        }
21100                                } else if (table != null) {
21101                                        tables.add(table);
21102                                }
21103
21104                                // 此处特殊处理,多表关联无法找到 column 所属的 Table, tTable.getLinkedColumns
21105                                // 也找不到,退而求其次采用第一个表
21106
21107                                if (stmt.getParentStmt() != null && isApplyJoin(stmt.getParentStmt())
21108                                                && (tableList != null && tableList.size() > 0)) {
21109                                        stmt = stmt.getParentStmt();
21110                                        TTable applyTable = tableList.getTable(0);
21111                                        if (modelManager.getModel(table) == null) {
21112                                                modelFactory.createTable(applyTable);
21113                                        }
21114                                }
21115
21116                                if (columnName.toString().indexOf(".")==-1 && isConstant(columnName)) {
21117                                        boolean isConstant = true;
21118                                        if (columnName.getSourceTable() != null) {
21119                                                Table tableModel = modelManager.getTableByName(
21120                                                                DlineageUtil.getTableFullName(columnName.getSourceTable().getTableName().toString()));
21121                                                if (tableModel != null && tableModel.getColumns() != null) {
21122                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
21123                                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
21124                                                                                getColumnName(tableModel.getColumns().get(j).getName()))) {
21125                                                                        isConstant = false;
21126                                                                        break;
21127                                                                }
21128                                                        }
21129                                                }
21130                                        }
21131
21132                                        if (isConstant) {
21133                                                if (option.isShowConstantTable()) {
21134                                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
21135                                                        TableColumn tableColumn = modelFactory.createTableColumn(constantTable, columnName, false);
21136                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
21137                                                }
21138                                                continue;
21139                                        }
21140                                }
21141
21142                                if (tableList != null && tableList.size() != 0 && tables.size() == 0
21143                                                && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) {
21144                                        if (modelManager.getModel(stmt) instanceof ResultSet) {
21145                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt);
21146                                                boolean find = false;
21147                                                for (ResultColumn resultColumn : resultSetModel.getColumns()) {
21148                                                        if(resultColumn.equals(modelObject)) {
21149                                                                continue;
21150                                                        }
21151                                                        if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) {
21152                                                                if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) {
21153                                                                        if (resultColumn.getColumnObject() != null) {
21154                                                                                int startToken = resultColumn.getColumnObject().getStartToken().posinlist;
21155                                                                                int endToken = resultColumn.getColumnObject().getEndToken().posinlist;
21156                                                                                if (columnName.getStartToken().posinlist >= startToken
21157                                                                                                && columnName.getEndToken().posinlist <= endToken) {
21158                                                                                        continue;
21159                                                                                }
21160                                                                        }
21161                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
21162                                                                        find = true;
21163                                                                        break;
21164                                                                }
21165                                                        }
21166                                                }
21167                                                if (find) {
21168                                                        continue;
21169                                                }
21170                                        }
21171                                        
21172                                        TObjectName pseudoTableName = new TObjectName();
21173                                        // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl)
21174                                        // Otherwise fall back to default pseudo table name
21175                                        String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName);
21176                                        pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column");
21177                                        Table pseudoTable = modelFactory.createTableByName(pseudoTableName);
21178                                        pseudoTable.setPseudo(true);
21179                                        TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true);
21180
21181                                        // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col),
21182                                        // add the pseudo table column as source
21183                                        if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) {
21184                                                if (isOut) {
21185                                                        relation.setTarget(new TableColumnRelationshipElement(pseudoTableColumn));
21186                                                } else {
21187                                                        relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn));
21188                                                }
21189                                        }
21190
21191                                        if (isLinkOrphanColumnToFirstTable()) {
21192                                                TTable orphanTable = tableList.getTable(0);
21193                                                tables.add(orphanTable);
21194                                                Object tableModel = modelManager.getModel(orphanTable);
21195                                                if (tableModel == null) {
21196                                                        if(orphanTable.getSubquery()!=null) {
21197                                                                QueryTable queryTable = modelFactory.createQueryTable(orphanTable);
21198                                                                TSelectSqlStatement subquery = orphanTable.getSubquery();
21199                                                                analyzeSelectStmt(subquery);
21200                                                        }
21201                                                        else {
21202                                                                tableModel = modelFactory.createTable(orphanTable);
21203                                                        }
21204                                                }
21205                                                if (tableModel instanceof Table) {
21206                                                        TableColumn orphanColum = modelFactory.createTableColumn((Table) tableModel, columnName, false);
21207                                                        if(orphanColum!=null) {
21208                                                                ErrorInfo errorInfo = new ErrorInfo();
21209                                                                errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN);
21210                                                                errorInfo.setErrorMessage("Link orphan column [" + columnName.toString()
21211                                                                                + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]");
21212                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo,
21213                                                                                columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
21214                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo,
21215                                                                                columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(),
21216                                                                                ModelBindingManager.getGlobalHash()));
21217                                                                errorInfo.fillInfo(this);
21218                                                                errorInfos.add(errorInfo);
21219                                                        }
21220                                                        if (orphanTable.getSubquery() != null) {
21221                                                                TSelectSqlStatement subquery = orphanTable.getSubquery();
21222                                                                if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) {
21223                                                                        TTable subqueryTable = subquery.getTables().getTable(0);
21224                                                                        Object sourceTable = modelManager.getModel(subqueryTable);
21225                                                                        if(sourceTable instanceof Table) {
21226                                                                                modelFactory.createTableColumn((Table) sourceTable, columnName, false);
21227                                                                        }
21228                                                                        else if(sourceTable instanceof ResultSet) {
21229                                                                                modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false);
21230                                                                        }
21231                                                                }
21232                                                        }
21233                                                        else if (orphanTable.getCTE()!=null && orphanTable.getCTE().getSubquery() != null) {
21234                                                                TSelectSqlStatement subquery = orphanTable.getCTE().getSubquery();
21235                                                                if (subquery.getResultColumnList().toString().endsWith("*") && subquery.getTables().size() == 1) {
21236                                                                        TTable subqueryTable = subquery.getTables().getTable(0);
21237                                                                        Object sourceTable = modelManager.getModel(subqueryTable);
21238                                                                        if(sourceTable instanceof Table) {
21239                                                                                modelFactory.createTableColumn((Table) sourceTable, columnName, false);
21240                                                                        }
21241                                                                        else if(sourceTable instanceof ResultSet) {
21242                                                                                modelFactory.createResultColumn((ResultSet) sourceTable, columnName, false);
21243                                                                        }
21244                                                                }
21245                                                        }
21246                                                }
21247                                                
21248                                                linkedFirstTable = true;
21249                                        }
21250                                }
21251                        }
21252
21253                        for (int k = 0; k < tables.size(); k++) {
21254                                TTable table = tables.get(k);
21255                                if (table != null) {
21256                                        Object object = modelManager.getModel(table);
21257                                        if(object instanceof PivotedTable) {
21258                                                TPivotClause clause = (TPivotClause)((PivotedTable)object).getGspObject();
21259                                                if(clause.getAliasClause()!=null) {
21260                                                        object = modelManager.getModel(clause.getAliasClause());
21261                                                }
21262                                        }
21263                                        if (object == null && table.getTableType() == ETableSource.objectname) {
21264                                                if (table.getCTE() != null) {
21265                                                        QueryTable queryTable = modelFactory.createQueryTable(table);
21266                                                        TSelectSqlStatement subquery = table.getCTE().getSubquery();
21267                                                        analyzeSelectStmt(subquery);
21268                                                        ResultSet resultSetModel = (ResultSet) modelManager.getModel(subquery);
21269
21270                                                        if (resultSetModel != null && resultSetModel != queryTable
21271                                                                        && !resultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
21272                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
21273                                                                impactRelation.setEffectType(EffectType.select);
21274                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21275                                                                                resultSetModel.getRelationRows()));
21276                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21277                                                                                queryTable.getRelationRows()));
21278                                                        }
21279
21280                                                        if (resultSetModel != null && resultSetModel != queryTable) {
21281                                                                for (int j = 0; j < resultSetModel.getColumns().size(); j++) {
21282                                                                        ResultColumn sourceColumn = resultSetModel.getColumns().get(j);
21283                                                                        ResultColumn targetColumn = modelFactory.createSelectSetResultColumn(queryTable,
21284                                                                                        sourceColumn);
21285
21286                                                                        DataFlowRelationship queryRalation = modelFactory.createDataFlowRelation();
21287                                                                        queryRalation.setEffectType(EffectType.select);
21288                                                                        queryRalation.setTarget(new ResultColumnRelationshipElement(targetColumn));
21289                                                                        queryRalation.addSource(new ResultColumnRelationshipElement(sourceColumn));
21290                                                                }
21291                                                        }
21292                                                        
21293                                                        object = queryTable;
21294                                                        
21295                                                } else {
21296                                                        object = modelFactory.createTable(table);
21297                                                }
21298                                        }
21299                                        if (object instanceof Function) {
21300                                                relation.addSource(new ResultColumnRelationshipElement(((Function)object).getColumns().get(0)));
21301                                                continue;
21302                                        } else if (object instanceof ResultSet && !(object instanceof QueryTable)) {
21303                                                //Object tableModel = modelManager.getModel(columnName.getSourceTable());
21304                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
21305                                                                (ResultSet)object);
21306                                                if(table.getTableType() == ETableSource.function && !relation.getSources().isEmpty()) {
21307                                                        relation.getSources().stream().reduce((first, second) -> second).get().addTransform(Transform.FUNCTION, table);
21308                                                }
21309                                                continue;
21310                                        }
21311                                        else if (object instanceof Table) {
21312                                                Table tableModel = (Table) modelManager.getModel(table);
21313                                                if (tableModel != null) {
21314                                                        if (!isStar && "*".equals(getColumnName(columnName))) {
21315                                                                TObjectName[] columns = modelManager.getTableColumns(table);
21316                                                                for (int j = 0; j < columns.length; j++) {
21317                                                                        TObjectName objectName = columns[j];
21318                                                                        if (objectName == null || ("*".equals(getColumnName(objectName)) && tableModel.isDetermined())) {
21319                                                                                continue;
21320                                                                        }
21321                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, objectName,
21322                                                                                        false);
21323                                                                        if(columnModel == null) {
21324                                                                                continue;
21325                                                                        }
21326                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
21327                                                                }
21328                                                        } else {
21329                                                                if ("*".equals(getColumnName(columnName)) && !tableModel.getColumns().isEmpty()) {
21330                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21331                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
21332                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
21333                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
21334                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
21335                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
21336                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
21337                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
21338                                                                                        }
21339                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21340                                                                                        if(tableModel.isDetermined()) {
21341                                                                                                resultSet.getColumns().clear();
21342                                                                                        }
21343                                                                                }
21344                                                                        }
21345                                                                        
21346                                                                        for (int j = 0; j < tableModel.getColumns().size(); j++) {
21347                                                                                TableColumn columnModel = tableModel.getColumns().get(j);
21348                                                                                if (exceptColumnList != null) {
21349                                                                                        boolean flag = false;
21350                                                                                        for (TObjectName objectName : exceptColumnList) {
21351                                                                                                if (getColumnName(objectName)
21352                                                                                                                .equals(getColumnName(columnModel.getColumnObject()))) {
21353                                                                                                        flag = true;
21354                                                                                                        break;
21355                                                                                                }
21356                                                                                        }
21357                                                                                        if (flag) {
21358                                                                                                continue;
21359                                                                                        }
21360                                                                                }
21361                                                                                
21362                                                                                if (replaceAsIdentifierMap.containsKey(tableModel.getColumns().get(j).getName())) {
21363                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(tableModel.getColumns().get(j).getName());
21364                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21365                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(tableModel.getColumns().get(j).getName()));
21366                                                                                        Transform transform = new Transform();
21367                                                                                        transform.setType(Transform.EXPRESSION);
21368                                                                                        TObjectName expression = new TObjectName();
21369                                                                                        expression.setString(expr.first);
21370                                                                                transform.setCode(expression);
21371                                                                                        resultColumn.setTransform(transform);
21372                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
21373                                                                                } else {
21374                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
21375                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
21376                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
21377                                                                                                                columnModel.getColumnObject());
21378                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
21379                                                                                                relation1.setEffectType(effectType);
21380                                                                                                relation1.setProcess(process);
21381                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
21382                                                                                                relation1.addSource(new TableColumnRelationshipElement(columnModel));
21383                                                                                        }
21384                                                                                        else {
21385                                                                                                relation.addSource(
21386                                                                                                        new TableColumnRelationshipElement(columnModel));
21387                                                                                        }
21388                                                                                }
21389                                                                        }
21390
21391                                                                        if (isStar && showStar) {
21392                                                                                TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
21393                                                                                                false);
21394                                                                                if (columnModel == null) {
21395                                                                                        if(tableModel.isCreateTable()) {
21396                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
21397                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
21398                                                                                                        relation.setShowStarRelation(true);
21399                                                                                                }
21400                                                                                        }
21401                                                                                } else {
21402                                                                                        relation.addSource(new TableColumnRelationshipElement(columnModel));
21403                                                                                        relation.setShowStarRelation(true);
21404                                                                                }
21405                                                                        }
21406                                                                } else {
21407                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName,
21408                                                                                        false);
21409                                                                        if(columnModel == null) {
21410                                                                                if(tableModel.isCreateTable()) {
21411                                                                                        boolean flag = false;
21412                                                                                        // Try FieldPath-based matching first for BigQuery/Redshift struct fields
21413                                                                                        String structFullName = getStructFieldFullName(columnName);
21414                                                                                        if (structFullName != null && !flag) {
21415                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
21416                                                                                                        if (tableColumn.isStruct()
21417                                                                                                                && DlineageUtil.getIdentifierNormalColumnName(tableColumn.getName())
21418                                                                                                                        .equals(DlineageUtil.getIdentifierNormalColumnName(structFullName))) {
21419                                                                                                                relation.addSource(new TableColumnRelationshipElement(tableColumn));
21420                                                                                                                flag = true;
21421                                                                                                                if (modelObject instanceof ResultColumn) {
21422                                                                                                                        ((ResultColumn) modelObject).setStruct(true);
21423                                                                                                                } else if (modelObject instanceof TableColumn) {
21424                                                                                                                        ((TableColumn) modelObject).setStruct(true);
21425                                                                                                                }
21426                                                                                                                break;
21427                                                                                                        }
21428                                                                                                }
21429                                                                                        }
21430                                                                                        if (ModelBindingManager.getGlobalVendor() == EDbVendor.dbvbigquery || ModelBindingManager.getGlobalVendor() == EDbVendor.dbvredshift) {
21431                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
21432                                                                                                        if(tableColumn.isStruct()) {
21433                                                                                                                List<String> names = SQLUtil.parseNames(tableColumn.getName());
21434                                                                                                                if (modelObject instanceof TableColumn) {
21435                                                                                                                        TableColumn targetColumn = (TableColumn) modelObject;
21436                                                                                                                        if (targetColumn.isStruct()) {
21437                                                                                                                                List<String> targetNames = SQLUtil
21438                                                                                                                                                .parseNames(targetColumn.getName());
21439                                                                                                                                if (!getColumnName(targetNames.get(0))
21440                                                                                                                                                .equals(getColumnName(names.get(0)))) {
21441                                                                                                                                        continue;
21442                                                                                                                                }
21443                                                                                                                        }
21444                                                                                                                }
21445                                                                                                                else if (modelObject instanceof ResultColumn) {
21446                                                                                                                        ResultColumn targetColumn = (ResultColumn) modelObject;
21447                                                                                                                        if (targetColumn.isStruct()) {
21448                                                                                                                                List<String> targetNames = SQLUtil
21449                                                                                                                                                .parseNames(targetColumn.getName());
21450                                                                                                                                if (!getColumnName(targetNames.get(0))
21451                                                                                                                                                .equals(getColumnName(names.get(0)))) {
21452                                                                                                                                        continue;
21453                                                                                                                                }
21454                                                                                                                        }
21455                                                                                                                }
21456                                                                                                                for(String name: names) {
21457                                                                                                                        if (getColumnName(name)
21458                                                                                                                                        .equals(getColumnName(modelObject.toString()))) {
21459                                                                                                                                relation.addSource(
21460                                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21461                                                                                                                                flag = true;
21462                                                                                                                                if (modelObject instanceof ResultColumn) {
21463                                                                                                                                        ((ResultColumn)modelObject).setStruct(true);
21464                                                                                                                                }
21465                                                                                                                                else if (modelObject instanceof TableColumn) {
21466                                                                                                                                        ((TableColumn)modelObject).setStruct(true);
21467                                                                                                                                }
21468                                                                                                                                break;
21469                                                                                                                        }
21470                                                                                                                }
21471
21472                                                                                                                if (!flag && tableModel.getColumns().size() == 1 && tableModel
21473                                                                                                                                .getColumns().get(0).getSourceColumn() != null) {
21474                                                                                                                        TableColumn sourceColumn = tableModel
21475                                                                                                                                        .getColumns().get(0).getSourceColumn();
21476                                                                                                                        Table sourceTable = sourceColumn.getTable();
21477                                                                                                                        TObjectName sourceColumnName = new TObjectName();
21478                                                                                                                        sourceColumnName.setString(sourceColumn.getName() + "."
21479                                                                                                                                        + columnName.getColumnNameOnly());
21480                                                                                                                        TableColumn sourceTableColumn = modelFactory.createTableColumn(sourceTable, sourceColumnName, true);
21481                                                                                                                        relation.addSource(
21482                                                                                                                                        new TableColumnRelationshipElement(sourceTableColumn));
21483                                                                                                                        flag = true;
21484                                                                                                                        break;
21485                                                                                                                }
21486                                                                                                        }
21487                                                                                                        else if (getColumnName(tableColumn.getName())
21488                                                                                                                        .equals(getColumnName(modelObject.toString()))) {
21489                                                                                                                relation.addSource(
21490                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21491                                                                                                                flag = true;
21492                                                                                                                break;
21493                                                                                                        }
21494                                                                                                }
21495                                                                                                if (modelObject instanceof TableColumn) {
21496                                                                                                        TableColumn column = (TableColumn) modelObject;
21497                                                                                                        for (TableColumn tableColumn : tableModel.getColumns()) {
21498                                                                                                                if (tableColumn.getColumnIndex() == null) {
21499                                                                                                                        continue;
21500                                                                                                                }
21501                                                                                                                if (tableColumn.getName().toLowerCase()
21502                                                                                                                                .indexOf(column.getName().toLowerCase()) == -1
21503                                                                                                                                && tableColumn.getName().toLowerCase()
21504                                                                                                                                                .indexOf(column.getColumnObject().toString()
21505                                                                                                                                                                .toLowerCase()) == -1) {
21506                                                                                                                        continue;
21507                                                                                                                }
21508                                                                                                                flag = true;
21509                                                                                                                relation.addSource(
21510                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21511                                                                                                                relation.setShowStarRelation(true);
21512                                                                                                        }
21513                                                                                                        if (flag)
21514                                                                                                                break;
21515
21516                                                                                                } else if (modelObject instanceof ResultColumn) {
21517                                                                                                        ResultColumn column = (ResultColumn) modelObject;
21518                                                                                                        for (TableColumn tableColumn : tableModel.getColumns()) {
21519                                                                                                                if (tableColumn.getColumnIndex() == null) {
21520                                                                                                                        continue;
21521                                                                                                                }
21522                                                                                                                if (tableColumn.getName().toLowerCase()
21523                                                                                                                                .indexOf(column.getName().toLowerCase()) == -1
21524                                                                                                                                && tableColumn.getName().toLowerCase()
21525                                                                                                                                                .indexOf(column.getColumnObject().toString()
21526                                                                                                                                                                .toLowerCase()) == -1) {
21527                                                                                                                        continue;
21528                                                                                                                }
21529                                                                                                                flag = true;
21530                                                                                                                relation.addSource(
21531                                                                                                                                new TableColumnRelationshipElement(tableColumn));
21532                                                                                                                relation.setShowStarRelation(true);
21533                                                                                                        }
21534                                                                                                        if (flag)
21535                                                                                                                break;
21536
21537                                                                                                }
21538                                                                                        }
21539                                                                                        if (!flag 
21540                                                                                                        && (isStar 
21541                                                                                                                        || getColumnName(columnName).equals(getColumnName(tableModel.getName()))
21542                                                                                                                        || getColumnName(columnName).equals(getColumnName(tableModel.getAlias())))) {
21543                                                                                                for (TableColumn tableColumn : tableModel.getColumns()) {
21544                                                                                                        relation.addSource(new TableColumnRelationshipElement(tableColumn));
21545                                                                                                        relation.setShowStarRelation(true);
21546                                                                                                }
21547                                                                                        }
21548                                                                                }
21549                                                                        }
21550                                                                        else {
21551                                                                                if (linkedFirstTable || columnModel.getCandidateParents() != null) {
21552                                                                                        if (columnName.getCandidateTables() != null
21553                                                                                                        && columnName.getCandidateTables().size() > 1) {
21554                                                                                                List<Object> candidateParents = new ArrayList<Object>();
21555                                                                                                for(TTable tableItem: columnName.getCandidateTables()) {
21556                                                                                                        Object model = modelManager.getModel(tableItem);
21557                                                                                                        if(model!=null) {
21558                                                                                                                candidateParents.add(model);
21559                                                                                                        }
21560                                                                                                }
21561                                                                                                if (candidateParents.size() > 1) {
21562                                                                                                        columnModel.setCandidateParents(candidateParents);
21563                                                                                                }
21564                                                                                        }
21565                                                                                }
21566                                                                                relation.addSource(new TableColumnRelationshipElement(columnModel));
21567                                                                                relation.setShowStarRelation(true);
21568                                                                                if(modelObject instanceof TableColumn) {
21569                                                                                        TableColumn targetTableColumn = (TableColumn)modelObject;
21570                                                                                        if(targetTableColumn.getTable().getSubType() == SubType.unnest && targetTableColumn.getTable().getColumns().size() == 1) {
21571                                                                                                targetTableColumn.setSourceColumn(columnModel);
21572                                                                                                targetTableColumn.setStruct(true);
21573                                                                                        }
21574                                                                                }
21575                                                                                if (columnName.getSourceTable() != null
21576                                                                                                && columnName.getSourceTable().getTableType() == ETableSource.function) {
21577                                                                                        analyzeTableColumn(columnModel, columnName.getSourceTable().getFuncCall(),
21578                                                                                                        effectType);
21579                                                                                }
21580                                                                        }
21581                                                                }
21582                                                        }
21583                                                }
21584                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
21585                                                QueryTable queryTable = (QueryTable) modelManager.getModel(table);
21586
21587                                                TObjectNameList cteColumns = null;
21588                                                TSelectSqlStatement subquery = null;
21589                                                if (queryTable.getTableObject().getCTE() != null) {
21590                                                        subquery = queryTable.getTableObject().getCTE().getSubquery();
21591                                                        cteColumns = queryTable.getTableObject().getCTE().getColumnList();
21592                                                } else if (queryTable.getTableObject().getAliasClause() != null
21593                                                                && queryTable.getTableObject().getAliasClause().getColumns() != null) {
21594
21595                                                } else if (queryTable.getTableObject().getTableExpr() != null
21596                                                                && queryTable.getTableObject().getTableExpr().getSubQuery() != null) {
21597                                                        subquery = queryTable.getTableObject().getTableExpr().getSubQuery();
21598                                                } else {
21599                                                        subquery = queryTable.getTableObject().getSubquery();
21600                                                }
21601
21602                                                if (cteColumns != null) {
21603                                                        for (int j = 0; j < cteColumns.size(); j++) {
21604                                                                modelFactory.createResultColumn(queryTable, cteColumns.getObjectName(j));
21605                                                        }
21606                                                }
21607
21608                                                if (subquery != null && subquery.isCombinedQuery()) {
21609                                                        SelectSetResultSet selectSetResultSetModel = (SelectSetResultSet) modelManager
21610                                                                        .getModel(subquery);
21611
21612                                                        if (selectSetResultSetModel != null
21613                                                                        && !selectSetResultSetModel.getRelationRows().getHoldRelations().isEmpty()) {
21614                                                                ImpactRelationship impactRelation = modelFactory.createImpactRelation();
21615                                                                impactRelation.setEffectType(EffectType.select);
21616                                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21617                                                                                selectSetResultSetModel.getRelationRows()));
21618                                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
21619                                                                                queryTable.getRelationRows()));
21620                                                        }
21621
21622                                                        if (selectSetResultSetModel != null) {
21623                                                                if (getColumnName(columnName).equals("*")) {
21624                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21625                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
21626                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
21627                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
21628                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
21629                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
21630                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
21631                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
21632                                                                                        }
21633                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21634                                                                                        if(selectSetResultSetModel.isDetermined()) {
21635                                                                                                resultSet.getColumns().clear();
21636                                                                                        }
21637                                                                                }
21638                                                                        }
21639                                                                        
21640                                                                        
21641                                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
21642                                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
21643                                                                                if (cteColumns != null) {
21644                                                                                        if (j < cteColumns.size()) {
21645                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
21646
21647                                                                                                if (exceptColumnList != null) {
21648                                                                                                        boolean flag = false;
21649                                                                                                        for (TObjectName objectName : exceptColumnList) {
21650                                                                                                                if (getColumnName(objectName)
21651                                                                                                                                .equals(getColumnName(targetColumn.getName()))) {
21652                                                                                                                        flag = true;
21653                                                                                                                        break;
21654                                                                                                                }
21655                                                                                                        }
21656                                                                                                        if (flag) {
21657                                                                                                                continue;
21658                                                                                                        }
21659                                                                                                }
21660
21661                                                                                                if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
21662                                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
21663                                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21664                                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
21665                                                                                                        Transform transform = new Transform();
21666                                                                                                        transform.setType(Transform.EXPRESSION);
21667                                                                                                        TObjectName expression = new TObjectName();
21668                                                                                                        expression.setString(expr.first);
21669                                                                                                transform.setCode(expression);
21670                                                                                                        resultColumn.setTransform(transform);
21671                                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
21672                                                                                                } else {
21673                                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
21674                                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
21675                                                                                                                TObjectName resultColumnName = new TObjectName();
21676                                                                                                                resultColumnName.setString(targetColumn.getName());
21677                                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
21678                                                                                                                                resultColumnName);
21679                                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
21680                                                                                                                relation1.setEffectType(effectType);
21681                                                                                                                relation1.setProcess(process);
21682                                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
21683                                                                                                                relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
21684                                                                                                        }
21685                                                                                                        else {
21686                                                                                                                relation.addSource(
21687                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21688                                                                                                        }
21689                                                                                                }
21690                                                                                                
21691                                                                                        }
21692                                                                                } else {
21693                                                                                        ResultColumn targetColumn = modelFactory
21694                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21695
21696                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21697                                                                                                        .createDataFlowRelation();
21698                                                                                        combinedQueryRelation.setEffectType(effectType);
21699                                                                                        combinedQueryRelation
21700                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
21701                                                                                        combinedQueryRelation
21702                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
21703
21704                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21705                                                                                }
21706                                                                        }
21707                                                                        break;
21708                                                                } else {
21709                                                                        boolean flag = false;
21710
21711                                                                        for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
21712                                                                                ResultColumn sourceColumn = selectSetResultSetModel
21713                                                                                                .getColumns().get(j);
21714                                                                                List<String> splits = SQLUtil.parseNames(columnName.toString());        
21715                                                                                if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
21716                                                                                        if (getColumnName(sourceColumn.getName())
21717                                                                                                        .equalsIgnoreCase(getColumnName(splits.get(0)))
21718                                                                                                        || getColumnName(sourceColumn.getName())
21719                                                                                                                        .equalsIgnoreCase(getColumnName(splits.get(1)))) {
21720                                                                                                ResultColumn targetColumn = modelFactory
21721                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
21722
21723                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
21724                                                                                                                .createDataFlowRelation();
21725                                                                                                combinedQueryRelation.setEffectType(effectType);
21726                                                                                                combinedQueryRelation.setTarget(
21727                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21728                                                                                                combinedQueryRelation.addSource(
21729                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
21730
21731                                                                                                relation.addSource(
21732                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21733                                                                                                flag = true;
21734                                                                                                break;
21735                                                                                        }
21736                                                                                }
21737                                                                                else if (getColumnName(sourceColumn.getName())
21738                                                                                                .equalsIgnoreCase(getColumnName(columnName))) {
21739                                                                                        ResultColumn targetColumn = modelFactory
21740                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21741
21742                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21743                                                                                                        .createDataFlowRelation();
21744                                                                                        combinedQueryRelation.setEffectType(effectType);
21745                                                                                        combinedQueryRelation
21746                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
21747                                                                                        combinedQueryRelation
21748                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
21749
21750                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21751                                                                                        flag = true;
21752                                                                                        break;
21753                                                                                }
21754                                                                                else if (sourceColumn instanceof SelectSetResultColumn && ((SelectSetResultColumn)sourceColumn).getAliasSet().size() > 1) {
21755                                                                                        for (String alias : ((SelectSetResultColumn)sourceColumn).getAliasSet()) {
21756                                                                                                if (getColumnName(alias).equalsIgnoreCase(getColumnName(columnName))) {
21757                                                                                                        ResultColumn targetColumn = modelFactory
21758                                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21759
21760                                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21761                                                                                                                        .createDataFlowRelation();
21762                                                                                                        combinedQueryRelation.setEffectType(effectType);
21763                                                                                                        combinedQueryRelation.setTarget(
21764                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21765                                                                                                        combinedQueryRelation.addSource(
21766                                                                                                                        new ResultColumnRelationshipElement(sourceColumn));
21767
21768                                                                                                        relation.addSource(
21769                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21770                                                                                                        flag = true;
21771                                                                                                        break;
21772                                                                                                }
21773                                                                                        }
21774                                                                                        if (flag) {
21775                                                                                                break;
21776                                                                                        }
21777                                                                                }
21778                                                                        }
21779
21780                                                                        if (flag) {
21781                                                                                break;
21782                                                                        } else if (columnIndex != -1) {
21783                                                                                for (int j = 0; j < selectSetResultSetModel.getColumns().size(); j++) {
21784                                                                                        ResultColumn sourceColumn = selectSetResultSetModel.getColumns().get(j);
21785                                                                                        if (!sourceColumn.getStarLinkColumns().isEmpty()) {
21786                                                                                                if (cteColumns != null) {
21787                                                                                                        if (j < cteColumns.size()) {
21788                                                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
21789                                                                                                                relation.addSource(
21790                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21791                                                                                                        }
21792                                                                                                } 
21793                                                                                                else {
21794                                                                                                        if(sourceColumn.hasStarLinkColumn()) {
21795                                                                                                                for (TObjectName linkColumn : sourceColumn.getStarLinkColumnList()) {
21796                                                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
21797                                                                                                                                ResultColumn targetColumn = modelFactory
21798                                                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
21799
21800                                                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
21801                                                                                                                                                .createDataFlowRelation();
21802                                                                                                                                combinedQueryRelation.setEffectType(effectType);
21803                                                                                                                                combinedQueryRelation.setTarget(
21804                                                                                                                                                new ResultColumnRelationshipElement(targetColumn, linkColumn));
21805                                                                                                                                combinedQueryRelation.addSource(
21806                                                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
21807
21808                                                                                                                                relation.addSource(
21809                                                                                                                                                new ResultColumnRelationshipElement(targetColumn, linkColumn));
21810                                                                                                                                flag = true;
21811                                                                                                                                break;
21812                                                                                                                        }
21813                                                                                                                }
21814                                                                                                        }
21815                                                                                                        
21816                                                                                                        if(!flag) {
21817                                                                                                                ResultColumn targetColumn = modelFactory
21818                                                                                                                                .createSelectSetResultColumn(queryTable, sourceColumn);
21819
21820                                                                                                                DataFlowRelationship combinedQueryRelation = modelFactory
21821                                                                                                                                .createDataFlowRelation();
21822                                                                                                                combinedQueryRelation.setEffectType(effectType);
21823                                                                                                                combinedQueryRelation.setTarget(
21824                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21825                                                                                                                combinedQueryRelation.addSource(
21826                                                                                                                                new ResultColumnRelationshipElement(sourceColumn));
21827
21828                                                                                                                relation.addSource(
21829                                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21830                                                                                                        }
21831                                                                                                }
21832                                                                                                flag = true;
21833                                                                                                break;
21834                                                                                        }
21835                                                                                }
21836                                                                        }
21837
21838                                                                        if (flag) {
21839                                                                                break;
21840                                                                        } else if (columnIndex < selectSetResultSetModel.getColumns().size()
21841                                                                                        && columnIndex != -1) {
21842                                                                                ResultColumn sourceColumn = selectSetResultSetModel.getColumns()
21843                                                                                                .get(columnIndex);
21844                                                                                if (cteColumns != null) {
21845                                                                                        boolean flag1 = false;
21846                                                                                        for (ResultColumn targetColumn : queryTable.getColumns()) {
21847                                                                                                if (getColumnName(targetColumn.getName())
21848                                                                                                                .equalsIgnoreCase(getColumnName(columnName))) {
21849                                                                                                        relation.addSource(
21850                                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21851                                                                                                        flag1 = true;
21852                                                                                                        break;
21853                                                                                                }
21854                                                                                        }
21855                                                                                        if (!flag1 && columnIndex < cteColumns.size()){
21856                                                                                                ResultColumn targetColumn = queryTable.getColumns()
21857                                                                                                                .get(columnIndex);
21858                                                                                                relation.addSource(
21859                                                                                                                new ResultColumnRelationshipElement(targetColumn));
21860                                                                                        }
21861                                                                                } else {
21862                                                                                        ResultColumn targetColumn = modelFactory
21863                                                                                                        .createSelectSetResultColumn(queryTable, sourceColumn);
21864
21865                                                                                        DataFlowRelationship combinedQueryRelation = modelFactory
21866                                                                                                        .createDataFlowRelation();
21867                                                                                        combinedQueryRelation.setEffectType(effectType);
21868                                                                                        combinedQueryRelation
21869                                                                                                        .setTarget(new ResultColumnRelationshipElement(targetColumn));
21870                                                                                        combinedQueryRelation
21871                                                                                                        .addSource(new ResultColumnRelationshipElement(sourceColumn));
21872
21873                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21874                                                                                }
21875                                                                                flag = true;
21876                                                                                break;
21877                                                                        }
21878
21879                                                                        if (flag) {
21880                                                                                break;
21881                                                                        }
21882                                                                }
21883                                                        } else if (cteColumns != null) {
21884                                                                if (getColumnName(columnName).equals("*")) {
21885                                                                        Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21886                                                                        Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
21887                                                                        if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
21888                                                                                TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
21889                                                                                if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
21890                                                                                        for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
21891                                                                                                replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
21892                                                                                                replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
21893                                                                                        }
21894                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21895                                                                                        
21896                                                                                        if (columnName.getSourceColumn() != null) {
21897                                                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21898                                                                                                if (model instanceof ResultColumn && ((ResultColumn)model).getResultSet().isDetermined()) {
21899                                                                                                        resultSet.getColumns().clear();
21900                                                                                                }
21901                                                                                        } else if (columnName.getSourceTable() != null) {
21902                                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
21903                                                                                                if (tableModel instanceof Table && ((Table)tableModel).isDetermined()) {
21904                                                                                                        resultSet.getColumns().clear();
21905                                                                                                }
21906                                                                                        }
21907                                                                                }
21908                                                                        }
21909                                                                        
21910                                                                        for (int j = 0; j < cteColumns.size(); j++) {
21911                                                                                ResultColumn targetColumn = queryTable.getColumns().get(j);
21912
21913                                                                                if (exceptColumnList != null) {
21914                                                                                        boolean flag = false;
21915                                                                                        for (TObjectName objectName : exceptColumnList) {
21916                                                                                                if (getColumnName(objectName)
21917                                                                                                                .equals(getColumnName(targetColumn.getName()))) {
21918                                                                                                        flag = true;
21919                                                                                                        break;
21920                                                                                                }
21921                                                                                        }
21922                                                                                        if (flag) {
21923                                                                                                continue;
21924                                                                                        }
21925                                                                                }
21926
21927                                                                                if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
21928                                                                                        Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
21929                                                                                        ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
21930                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
21931                                                                                        Transform transform = new Transform();
21932                                                                                        transform.setType(Transform.EXPRESSION);
21933                                                                                        TObjectName expression = new TObjectName();
21934                                                                                        expression.setString(expr.first);
21935                                                                                transform.setCode(expression);
21936                                                                                        resultColumn.setTransform(transform);
21937                                                                                        analyzeResultColumnExpressionRelation(resultColumn, expr.second);
21938                                                                                } else {
21939                                                                                        if(!replaceAsIdentifierMap.isEmpty()) {
21940                                                                                                ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
21941                                                                                                TObjectName resultColumnName = new TObjectName();
21942                                                                                                resultColumnName.setString(targetColumn.getName());
21943                                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
21944                                                                                                                resultColumnName);
21945                                                                                                DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
21946                                                                                                relation1.setEffectType(effectType);
21947                                                                                                relation1.setProcess(process);
21948                                                                                                relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
21949                                                                                                relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
21950                                                                                        }
21951                                                                                        else {
21952                                                                                                relation.addSource(
21953                                                                                                        new ResultColumnRelationshipElement(targetColumn));
21954                                                                                        }
21955                                                                                }
21956                                                                        }
21957                                                                        break;
21958                                                                } else {
21959                                                                        boolean flag = false;
21960
21961                                                                        for (int j = 0; j < cteColumns.size(); j++) {
21962                                                                                TObjectName sourceColumn = cteColumns.getObjectName(j);
21963
21964                                                                                if (getColumnName(sourceColumn).equalsIgnoreCase(getColumnName(columnName))) {
21965                                                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
21966
21967                                                                                        relation.addSource(new ResultColumnRelationshipElement(targetColumn));
21968                                                                                        flag = true;
21969                                                                                        break;
21970                                                                                }
21971                                                                        }
21972
21973                                                                        if (flag) {
21974                                                                                break;
21975                                                                        }
21976                                                                }
21977                                                        }
21978
21979                                                        if (columnName.getSourceColumn() != null) {
21980                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
21981                                                                if (model instanceof ResultColumn) {
21982                                                                        ResultColumn resultColumn = (ResultColumn) model;
21983                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
21984                                                                }
21985                                                        } else if (columnName.getSourceTable() != null) {
21986                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
21987                                                                if (tableModel instanceof Table) {
21988                                                                        Object model = modelManager
21989                                                                                        .getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName));
21990                                                                        if (model instanceof TableColumn) {
21991                                                                                relation.addSource(new TableColumnRelationshipElement((TableColumn) model));
21992                                                                        }
21993                                                                }
21994                                                        }
21995                                                } else {
21996                                                        List<ResultColumn> columns = queryTable.getColumns();
21997                                                        if (getColumnName(columnName).equals("*")) {
21998                                                                Map<String, Pair<String, TExpression>> replaceAsIdentifierMap = new HashMap<String, Pair<String, TExpression>>();
21999                                                                Map<String, TObjectName> replaceColumnMap = new HashMap<String, TObjectName>();
22000                                                                if(modelObject instanceof ResultColumn && ((ResultColumn)modelObject).getColumnObject() instanceof TResultColumn) {
22001                                                                        TResultColumn resultColumn =  (TResultColumn )((ResultColumn)modelObject).getColumnObject();
22002                                                                        if(resultColumn.getReplaceExprAsIdentifiers()!=null && resultColumn.getReplaceExprAsIdentifiers().size()>0) {
22003                                                                                for(TReplaceExprAsIdentifier replace: resultColumn.getReplaceExprAsIdentifiers()) {
22004                                                                                        replaceAsIdentifierMap.put(replace.getIdentifier().toString(), new Pair<String, TExpression>(resultColumn.getExpr().getExceptReplaceClause().toString(), replace.getExpr()));
22005                                                                                        replaceColumnMap.put(replace.getIdentifier().toString(), replace.getIdentifier());
22006                                                                                }
22007                                                                                ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
22008                                                                                if(queryTable.isDetermined()) {
22009                                                                                        resultSet.getColumns().clear();
22010                                                                                }
22011                                                                        }
22012                                                                }
22013                                                                
22014                                                                int index = 0;
22015                                                                for (int j = 0; j < queryTable.getColumns().size(); j++) {
22016                                                                        ResultColumn targetColumn = queryTable.getColumns().get(j);
22017                                                                        if (exceptColumnList != null) {
22018                                                                                boolean flag = false;
22019                                                                                for (TObjectName objectName : exceptColumnList) {
22020                                                                                        if (getColumnName(objectName)
22021                                                                                                        .equals(getColumnName(targetColumn.getName()))) {
22022                                                                                                flag = true;
22023                                                                                                break;
22024                                                                                        }
22025                                                                                }
22026                                                                                if (flag) {
22027                                                                                        continue;
22028                                                                                }
22029                                                                        }
22030                                                                        
22031                                                                        if (replaceAsIdentifierMap.containsKey(targetColumn.getName())) {
22032                                                                                Pair<String, TExpression> expr = replaceAsIdentifierMap.get(targetColumn.getName());
22033                                                                                ResultSet resultSet = ((ResultColumn)modelObject).getResultSet();
22034                                                                                ResultColumn resultColumn = modelFactory.createResultColumn(resultSet, replaceColumnMap.get(targetColumn.getName()));
22035                                                                                Transform transform = new Transform();
22036                                                                                transform.setType(Transform.EXPRESSION);
22037                                                                                TObjectName expression = new TObjectName();
22038                                                                                expression.setString(expr.first);
22039                                                                        transform.setCode(expression);
22040                                                                                resultColumn.setTransform(transform);
22041                                                                                analyzeResultColumnExpressionRelation(resultColumn, expr.second);
22042                                                                        } else {
22043                                                                                if(!replaceAsIdentifierMap.isEmpty()) {
22044                                                                                        ResultSet resultSet = ((ResultColumn) modelObject).getResultSet();
22045                                                                                        TObjectName resultColumnName = new TObjectName();
22046                                                                                        resultColumnName.setString(targetColumn.getName());
22047                                                                                        ResultColumn resultColumn = modelFactory.createResultColumn(resultSet,
22048                                                                                                        resultColumnName);
22049                                                                                        DataFlowRelationship relation1 = modelFactory.createDataFlowRelation();
22050                                                                                        relation1.setEffectType(effectType);
22051                                                                                        relation1.setProcess(process);
22052                                                                                        relation1.setTarget(new ResultColumnRelationshipElement(resultColumn));
22053                                                                                        relation1.addSource(new ResultColumnRelationshipElement(targetColumn));
22054                                                                                }
22055                                                                                else {
22056                                                                                        relation.addSource(
22057                                                                                                new ResultColumnRelationshipElement(targetColumn));
22058                                                                                }
22059                                                                        }
22060                                                                        index++;
22061                                                                }
22062                                                        } else {
22063                                                                if (table.getCTE() != null) {
22064                                                                        
22065                                                                        if (modelObject instanceof TableColumn) {
22066                                                                                Table modelTable = ((TableColumn) modelObject).getTable();
22067                                                                                if (modelTable.getSubType() == SubType.unnest) {
22068                                                                                        boolean find = false;
22069                                                                                        for (k = 0; k < columns.size(); k++) {
22070                                                                                                ResultColumn column = columns.get(k);
22071                                                                                                if (column.isStruct()) {
22072                                                                                                        List<String> names = SQLUtil.parseNames(column.getName());
22073                                                                                                        for (String name : names) {
22074                                                                                                                if (getColumnName(name).equals(getColumnName(columnName))) {
22075                                                                                                                        DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation();
22076                                                                                                                        unnestRelation.setEffectType(effectType);
22077                                                                                                                        unnestRelation.setProcess(process);
22078                                                                                                                        unnestRelation.addSource(new ResultColumnRelationshipElement(
22079                                                                                                                                        column, columnName));
22080                                                                                                                        TObjectName unnestTableColumnName = new TObjectName();
22081                                                                                                                        unnestTableColumnName.setString(names.get(names.size()-1));
22082                                                                                                                        TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true);
22083                                                                                                                        unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
22084                                                                                                                        find = true;
22085                                                                                                                }
22086                                                                                                        }
22087                                                                                                        List<String> names1 = SQLUtil.parseNames(column.getName());
22088                                                                                                        if (names.size() == 1 && names1.size() >= 1) {
22089                                                                                                                for (String name : names1) {
22090                                                                                                                        if (getColumnName(name)
22091                                                                                                                                        .equals(getColumnName(column.getName()))) {
22092                                                                                                                                DataFlowRelationship unnestRelation = modelFactory.createDataFlowRelation();
22093                                                                                                                                unnestRelation.setEffectType(effectType);
22094                                                                                                                                unnestRelation.setProcess(process);
22095                                                                                                                                unnestRelation.addSource(new ResultColumnRelationshipElement(
22096                                                                                                                                                column, columnName));
22097                                                                                                                                TObjectName unnestTableColumnName = new TObjectName();
22098                                                                                                                                unnestTableColumnName.setString(names1.get(names.size()-1));
22099                                                                                                                                TableColumn unnestTableColumn = modelFactory.createTableColumn(modelTable, unnestTableColumnName, true);
22100                                                                                                                                unnestRelation.setTarget(new TableColumnRelationshipElement(unnestTableColumn));
22101                                                                                                                                find = true;
22102                                                                                                                        }
22103                                                                                                                }
22104                                                                                                        }
22105                                                                                                }
22106                                                                                        }
22107                                                                                        if (find) {
22108                                                                                                modelTable.getColumns().remove(modelObject);
22109                                                                                                break;
22110                                                                                        }
22111                                                                                }
22112                                                                        }
22113                                                                        
22114                                                                        for (k = 0; k < columns.size(); k++) {
22115                                                                                ResultColumn column = columns.get(k);
22116                                                                                if ("*".equals(column.getName())) {
22117                                                                                        if (!containsStarColumn(column, columnName)) {
22118                                                                                                column.bindStarLinkColumn(columnName);
22119                                                                                        }
22120                                                                                        relation.addSource(new ResultColumnRelationshipElement(column, columnName));
22121                                                                                } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
22122                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
22123                                                                                        if (!column.equals(modelObject)) {
22124                                                                                                relation.addSource(
22125                                                                                                                new ResultColumnRelationshipElement(column, columnName));
22126                                                                                        }
22127                                                                                        break;
22128                                                                                } else if(column.isStruct()) {
22129                                                                                        List<String> names = SQLUtil.parseNames(column.getName());
22130                                                                                        for(String name: names) {
22131                                                                                                if (getColumnName(name)
22132                                                                                                                .equals(getColumnName(columnName))) {
22133                                                                                                        relation.addSource(
22134                                                                                                                        new ResultColumnRelationshipElement(column, columnName));
22135                                                                                                }
22136                                                                                        }
22137                                                                                        List<String> names1 = SQLUtil.parseNames(column.getName());
22138                                                                                        if (names.size() == 1 && names1.size() >= 1) {
22139                                                                                                for(String name: names1) {
22140                                                                                                        if (getColumnName(name)
22141                                                                                                                        .equals(getColumnName(column.getName()))) {
22142                                                                                                                relation.addSource(
22143                                                                                                                                new ResultColumnRelationshipElement(column, columnName));
22144                                                                                                        }
22145                                                                                                }
22146                                                                                        }
22147                                                                                }
22148                                                                        }
22149                                                                } else if (table.getAliasClause() != null
22150                                                                                && table.getAliasClause().getColumns() != null) {
22151                                                                        for (k = 0; k < columns.size(); k++) {
22152                                                                                ResultColumn column = columns.get(k);
22153                                                                                List<String> splits = SQLUtil.parseNames(columnName.toString());        
22154                                                                                if ("*".equals(column.getName())) {
22155                                                                                        if (!containsStarColumn(column, columnName)) {
22156                                                                                                column.bindStarLinkColumn(columnName);
22157                                                                                        }
22158                                                                                        relation.addSource(new ResultColumnRelationshipElement(column, columnName));
22159                                                                                } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
22160                                                                                        if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)),
22161                                                                                                        DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
22162                                                                                                if (!column.equals(modelObject)) {
22163                                                                                                        relation.addSource(new ResultColumnRelationshipElement(column,
22164                                                                                                                        columnName));
22165                                                                                                }
22166                                                                                                break;
22167                                                                                        }
22168                                                                                } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
22169                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
22170                                                                                        if (!column.equals(modelObject)) {
22171                                                                                                relation.addSource(
22172                                                                                                                new ResultColumnRelationshipElement(column, columnName));
22173                                                                                        }
22174                                                                                        break;
22175                                                                                }
22176                                                                        }
22177                                                                } else if (table.getSubquery() != null || (table.getTableExpr() != null
22178                                                                                && table.getTableExpr().getSubQuery() != null)) {
22179                                                                        TSelectSqlStatement select = table.getSubquery();
22180                                                                        if (select == null) {
22181                                                                                select = table.getTableExpr().getSubQuery();
22182                                                                        }
22183                                                                        if (columnName.getSourceTable() != null) {
22184                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
22185                                                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
22186                                                                                                tableModel);
22187                                                                        } else if (columnName.getObjectToken() != null
22188                                                                                        && !SQLUtil.isEmpty(table.getAliasName())) {
22189                                                                                if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(),
22190                                                                                                table.getAliasName())) {
22191                                                                                        Object tableModel = modelManager.getModel(table);
22192                                                                                        appendResultColumnRelationSource(modelObject, relation, columnIndex,
22193                                                                                                        columnName, tableModel);
22194                                                                                }
22195                                                                        } else if(columns!=null) {
22196                                                                                for (k = 0; k < columns.size(); k++) {
22197                                                                                        ResultColumn column = columns.get(k);
22198                                                                                        List<String> splits = SQLUtil.parseNames(columnName.toString());        
22199                                                                                        if ("*".equals(column.getName())) {
22200                                                                                                if (!containsStarColumn(column, columnName)) {
22201                                                                                                        column.bindStarLinkColumn(columnName);
22202                                                                                                }
22203                                                                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
22204                                                                                        } else if (splits.size() > 1 && EDbVendor.dbvbigquery == getOption().getVendor()) {
22205                                                                                                if (DlineageUtil.compareColumnIdentifier(getColumnName(splits.get(0)),
22206                                                                                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
22207                                                                                                        if (!column.equals(modelObject)) {
22208                                                                                                                relation.addSource(new ResultColumnRelationshipElement(column,
22209                                                                                                                                columnName));
22210                                                                                                        }
22211                                                                                                        break;
22212                                                                                                }
22213                                                                                        } else if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
22214                                                                                                        DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
22215                                                                                                if (!column.equals(modelObject)) {
22216                                                                                                        relation.addSource(
22217                                                                                                                        new ResultColumnRelationshipElement(column, columnName));
22218                                                                                                }
22219                                                                                                break;
22220                                                                                        }
22221                                                                                }
22222                                                                        }
22223                                                                } else if (table.getOutputMerge() != null) {
22224                                                                        if (columnName.getSourceColumn() != null) {
22225                                                                                Object model = modelManager.getModel(columnName.getSourceColumn());
22226                                                                                if (model instanceof ResultColumn) {
22227                                                                                        ResultColumn resultColumn = (ResultColumn) model;
22228                                                                                        if ("*".equals(resultColumn.getName())
22229                                                                                                        && !containsStarColumn(resultColumn, columnName)) {
22230                                                                                                resultColumn.bindStarLinkColumn(columnName);
22231                                                                                        }
22232                                                                                        relation.addSource(
22233                                                                                                        new ResultColumnRelationshipElement(resultColumn, columnName));
22234                                                                                }
22235                                                                        } else if (columnName.getSourceTable() != null) {
22236                                                                                Object tableModel = modelManager.getModel(columnName.getSourceTable());
22237                                                                                appendResultColumnRelationSource(modelObject, relation, columnIndex, columnName,
22238                                                                                                tableModel);
22239                                                                        } else if (columnName.getObjectToken() != null
22240                                                                                        && !SQLUtil.isEmpty(table.getAliasName())) {
22241                                                                                if (DlineageUtil.compareTableIdentifier(columnName.getObjectToken().toString(),
22242                                                                                                table.getAliasName())) {
22243                                                                                        Object tableModel = modelManager.getModel(table);
22244                                                                                        appendResultColumnRelationSource(modelObject, relation, columnIndex,
22245                                                                                                        columnName, tableModel);
22246                                                                                }
22247                                                                        }
22248                                                                }
22249                                                        }
22250                                                }
22251                                        }
22252                                }
22253                        }
22254                        if (relation.getSources().size() == 0 && isKeyword(columnName)) {
22255                                Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
22256                                TableColumn constantColumn = modelFactory.createTableColumn(constantTable, columnName, true);
22257                                relation.addSource(new ConstantRelationshipElement(constantColumn));
22258                        }
22259
22260                        if (relation.getSources().size() > 0) {
22261                                for (RelationshipElement<?> sourceItem: relation.getSources()) {
22262                                        Object source = sourceItem.getElement();
22263                                        ImpactRelationship impactRelation = null;
22264                                        if (source instanceof ResultColumn
22265                                                        && !((ResultColumn) source).getResultSet().getRelationRows().getHoldRelations().isEmpty()) {
22266                                                impactRelation = modelFactory.createImpactRelation();
22267                                                impactRelation.addSource(new RelationRowsRelationshipElement<ResultSetRelationRows>(
22268                                                                ((ResultColumn) source).getResultSet().getRelationRows()));
22269                                                impactRelation.setEffectType(effectType);
22270                                        } else if (source instanceof TableColumn
22271                                                        && !((TableColumn) source).getTable().getRelationRows().getHoldRelations().isEmpty()) {
22272                                                impactRelation = modelFactory.createImpactRelation();
22273                                                impactRelation.addSource(new RelationRowsRelationshipElement<TableRelationRows>(
22274                                                                ((TableColumn) source).getTable().getRelationRows()));
22275                                                impactRelation.setEffectType(effectType);;
22276                                        }
22277
22278                                        if (impactRelation == null) {
22279                                                continue;
22280                                        }
22281
22282                                        Object target = relation.getTarget().getElement();
22283                                        if (target instanceof ResultColumn) {
22284                                                impactRelation.setTarget(new RelationRowsRelationshipElement<ResultSetRelationRows>(
22285                                                                ((ResultColumn) target).getResultSet().getRelationRows()));
22286                                        } else if (target instanceof TableColumn) {
22287                                                impactRelation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(
22288                                                                ((TableColumn) target).getTable().getRelationRows()));
22289                                        }
22290
22291                                        if (impactRelation.getSources().iterator().next().getElement() == impactRelation.getTarget().getElement()) {
22292                                                modelManager.removeRelation(impactRelation);
22293                                        }
22294                                }
22295                        }
22296                }
22297                return relation;
22298        }
22299
22300        private boolean isNotInProcedure(Table table) {
22301        TStoredProcedureSqlStatement stmt = getProcedureParent(stmtStack.peek());
22302                Procedure procedure = this.modelFactory.createProcedure(stmt);
22303                if(procedure!=null && procedure.getName().equals(table.getParent())){
22304                        return false;
22305                }
22306                return true;
22307        }
22308
22309        private boolean hasJoin(TCustomSqlStatement stmt) {
22310                if (stmt.getJoins() == null || stmt.getJoins().size() == 0)
22311                        return false;
22312                if (stmt.getJoins().size() > 1) {
22313                        return true;
22314                }
22315                TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems();
22316                if (joinItems == null || joinItems.size() == 0) {
22317                        return false;
22318                }
22319                return true;
22320        }
22321
22322        private boolean isInQuery(TSelectSqlStatement query, TResultColumn column) {
22323                if(query == null)
22324                        return false;
22325                TResultColumnList columns = query.getResultColumnList();
22326                if (columns != null) {
22327                        for (int i = 0; i < columns.size(); i++) {
22328                                if (columns.getResultColumn(i).equals(column)) {
22329                                        return true;
22330                                }
22331                        }
22332                }
22333                return false;
22334        }
22335
22336        private void appendResultColumnRelationSource(Object modelObject, DataFlowRelationship relation, int columnIndex,
22337                        TObjectName columnName, Object tableModel) {
22338                if (tableModel instanceof Table) {
22339                        Object model = modelManager.getModel(new Pair<Table, TObjectName>((Table) tableModel, columnName));
22340                        if (model instanceof TableColumn) {
22341                                relation.addSource(new TableColumnRelationshipElement((TableColumn) model));
22342                        }
22343                } else if (tableModel instanceof ResultSet) {
22344                        List<ResultColumn> queryColumns = ((ResultSet) tableModel).getColumns();
22345                        boolean flag = false;
22346                        for (int l = 0; l < queryColumns.size(); l++) {
22347                                ResultColumn column = queryColumns.get(l);
22348                                if (DlineageUtil.compareColumnIdentifier(getColumnName(columnName),
22349                                                DlineageUtil.getIdentifierNormalColumnName(column.getName()))) {
22350                                        if (!column.equals(modelObject)) {
22351                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
22352                                                flag = true;
22353                                        }
22354                                        break;
22355                                }
22356                        }
22357                        if (!flag) {
22358                                for (int l = 0; l < queryColumns.size(); l++) {
22359                                        ResultColumn column = queryColumns.get(l);
22360                                        if ("*".equals(column.getName())) {
22361                                                if (!containsStarColumn(column, columnName)) {
22362                                                        column.bindStarLinkColumn(columnName);
22363                                                }
22364                                                relation.addSource(new ResultColumnRelationshipElement(column, columnName));
22365                                                flag = true;
22366                                                break;
22367                                        }
22368                                }
22369                        }
22370                        if (!flag && columnIndex < queryColumns.size() && columnIndex != -1) {
22371                                relation.addSource(new ResultColumnRelationshipElement(queryColumns.get(columnIndex), columnName));
22372                        }
22373                }
22374        }
22375
22376        private boolean isApplyJoin(TCustomSqlStatement stmt) {
22377                if (stmt.getJoins() == null || stmt.getJoins().size() == 0)
22378                        return false;
22379                TJoinItemList joinItems = stmt.getJoins().getJoin(0).getJoinItems();
22380                if (joinItems == null || joinItems.size() == 0) {
22381                        return false;
22382                }
22383                if (joinItems.getJoinItem(0).getJoinType() == EJoinType.crossapply
22384                                || joinItems.getJoinItem(0).getJoinType() == EJoinType.outerapply)
22385                        return true;
22386                return false;
22387        }
22388
22389        private boolean containsStarColumn(ResultColumn resultColumn, TObjectName columnName) {
22390                String targetColumnName = getColumnName(columnName);
22391                if (resultColumn.hasStarLinkColumn()) {
22392                        return resultColumn.getStarLinkColumns().containsKey(targetColumnName);
22393                }
22394                return false;
22395        }
22396
22397        private void analyzeAggregate(TFunctionCall function, TExpression expr) {
22398                TCustomSqlStatement stmt = stmtStack.peek();
22399                ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
22400                if (resultSet == null) {
22401                        return;
22402                }
22403
22404                if (expr != null) {
22405                        columnsInExpr visitor = new columnsInExpr();
22406                        expr.inOrderTraverse(visitor);
22407                        List<TObjectName> objectNames = visitor.getObjectNames();
22408                        for (int j = 0; j < objectNames.size(); j++) {
22409                                TObjectName columnName = objectNames.get(j);
22410
22411                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
22412                                        continue;
22413                                }
22414
22415                                if (columnName.getColumnNameOnly().startsWith("@")
22416                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
22417                                        continue;
22418                                }
22419
22420                                if (columnName.getColumnNameOnly().startsWith(":")
22421                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
22422                                        continue;
22423                                }
22424
22425                                if(modelManager.getModel(function.getFunctionName()) == null) {
22426                                        continue;
22427                                }
22428                                AbstractRelationship relation = modelFactory.createRecordSetRelation();
22429                                relation.setEffectType(EffectType.function);
22430                                relation.setFunction(function.getFunctionName().toString());
22431                                relation.setTarget(new ResultColumnRelationshipElement(
22432                                                (ResultColumn) modelManager.getModel(function.getFunctionName())));
22433                                TTable table = modelManager.getTable(stmt, columnName);
22434                                if (table != null) {
22435                                        if (modelManager.getModel(table) instanceof Table) {
22436                                                Table tableModel = (Table) modelManager.getModel(table);
22437                                                if (tableModel != null) {
22438                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
22439                                                        if (columnModel != null) {
22440                                                                relation.addSource(
22441                                                                                new TableColumnRelationshipElement(columnModel, columnName.getLocation()));
22442                                                        }
22443                                                }
22444                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
22445                                                Object model = modelManager.getModel(columnName.getSourceColumn());
22446                                                if (model instanceof ResultColumn) {
22447                                                        ResultColumn resultColumn = (ResultColumn) model;
22448                                                        if (resultColumn != null) {
22449                                                                relation.addSource(
22450                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
22451                                                        }
22452                                                }
22453                                        }
22454                                }
22455                        }
22456
22457                        List<TParseTreeNode> functions = visitor.getFunctions();
22458                        for (int j = 0; j < functions.size(); j++) {
22459                                TParseTreeNode functionObj = functions.get(j);
22460                                Object functionModel = modelManager.getModel(functionObj);
22461                                if (functionModel == null) {
22462                                        functionModel = createFunction(functionObj);
22463                                }
22464                                if (functionModel instanceof Function) {
22465                                        AbstractRelationship relation;
22466                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22467                                                // relation = modelFactory.createDataFlowRelation();
22468                                                relation = modelFactory.createRecordSetRelation();
22469                                        } else {
22470                                                relation = modelFactory.createRecordSetRelation();
22471                                        }
22472                                        relation.setEffectType(EffectType.function);
22473                                        relation.setFunction(function.getFunctionName().toString());
22474                                        relation.setTarget(new ResultColumnRelationshipElement(
22475                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22476
22477                                        if (functionObj instanceof TFunctionCall) {
22478                                                ResultColumn resultColumn = (ResultColumn) modelManager
22479                                                                .getModel(((TFunctionCall) functionObj).getFunctionName());
22480                                                if (resultColumn != null) {
22481                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn,
22482                                                                        ((TFunctionCall) functionObj).getFunctionName().getLocation());
22483                                                        relation.addSource(element);
22484                                                }
22485                                        }
22486                                        if (functionObj instanceof TCaseExpression) {
22487                                                ResultColumn resultColumn = (ResultColumn) modelManager
22488                                                                .getModel(((TCaseExpression) functionObj).getWhenClauseItemList());
22489                                                if (resultColumn != null) {
22490                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn);
22491                                                        relation.addSource(element);
22492                                                }
22493                                        }
22494                                } else if (functionModel instanceof Table) {
22495                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
22496                                                        function.getFunctionName(), false);
22497                                        AbstractRelationship relation;
22498                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22499                                                // relation = modelFactory.createDataFlowRelation();
22500                                                relation = modelFactory.createRecordSetRelation();
22501                                        } else {
22502                                                relation = modelFactory.createRecordSetRelation();
22503                                        }
22504                                        relation.setEffectType(EffectType.function);
22505                                        relation.setFunction(function.getFunctionName().toString());
22506                                        relation.setTarget(new ResultColumnRelationshipElement(
22507                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22508                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
22509                                        relation.addSource(element);
22510                                }
22511                        }
22512                }
22513
22514                if (expr == null || "COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22515                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())
22516                                        // https://e.gitee.com/gudusoft/issues/list?issue=I4L5EO
22517                                        // 对于非 count() 函数,当有group by clause时, RelationRows 不参与indirect dataflow,
22518                                        // 让位与group by clause中的column.
22519                                        || ((TSelectSqlStatement) stmt).getGroupByClause() == null) {
22520                                TTableList tables = stmt.getTables();
22521                                if (tables != null) {
22522                                        for (int i = 0; i < tables.size(); i++) {
22523                                                TTable table = tables.getTable(i);
22524                                                if (modelManager.getModel(table) == null && table.getSubquery() == null) {
22525                                                        modelFactory.createTable(table);
22526                                                }
22527                                                if (modelManager.getModel(table) instanceof Table) {
22528                                                        Table tableModel = (Table) modelManager.getModel(table);
22529                                                        AbstractRelationship relation;
22530                                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22531                                                                // relation = modelFactory.createDataFlowRelation();
22532                                                                relation = modelFactory.createRecordSetRelation();
22533                                                        } else {
22534                                                                relation = modelFactory.createRecordSetRelation();
22535                                                        }
22536                                                        relation.setEffectType(EffectType.function);
22537                                                        relation.setFunction(function.getFunctionName().toString());
22538                                                        relation.setTarget(new ResultColumnRelationshipElement(
22539                                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22540
22541                                                        if (relation instanceof DataFlowRelationship && option.isShowCountTableColumn()) {
22542                                                                List<TExpression> expressions = new ArrayList<TExpression>();
22543                                                                getFunctionExpressions(expressions, new ArrayList<TExpression>(), function);
22544                                                                for (int j = 0; j < expressions.size(); j++) {
22545                                                                        columnsInExpr visitor = new columnsInExpr();
22546                                                                        expressions.get(j).inOrderTraverse(visitor);
22547                                                                        List<TObjectName> objectNames = visitor.getObjectNames();
22548                                                                        if (objectNames != null) {
22549                                                                                for (TObjectName columnName : objectNames) {
22550                                                                                        TTable tempTable = modelManager.getTable(stmt, columnName);
22551                                                                                        if (table.equals(tempTable)) {
22552                                                                                                TableColumn tableColumn = modelFactory.createTableColumn(tableModel,
22553                                                                                                                columnName, false);
22554                                                                                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(
22555                                                                                                                tableColumn);
22556                                                                                                relation.addSource(element);
22557                                                                                        }
22558                                                                                }
22559                                                                        }
22560                                                                }
22561                                                        }
22562                                                        if (relation.getSources().size() == 0) {
22563                                                                RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<TableRelationRows>(
22564                                                                                tableModel.getRelationRows());
22565                                                                relation.addSource(element);
22566                                                        }
22567                                                } else if (modelManager.getModel(table) instanceof QueryTable) {
22568                                                        QueryTable tableModel = (QueryTable) modelManager.getModel(table);
22569                                                        AbstractRelationship relation;
22570                                                        if ("COUNT".equalsIgnoreCase(function.getFunctionName().toString())) {
22571                                                                // relation = modelFactory.createDataFlowRelation();
22572                                                                relation = modelFactory.createRecordSetRelation();
22573                                                        } else {
22574                                                                relation = modelFactory.createRecordSetRelation();
22575                                                        }
22576                                                        relation.setEffectType(EffectType.function);
22577                                                        relation.setFunction(function.getFunctionName().toString());
22578                                                        relation.setTarget(new ResultColumnRelationshipElement(
22579                                                                        (ResultColumn) modelManager.getModel(function.getFunctionName())));
22580                                                        RelationRowsRelationshipElement element = new RelationRowsRelationshipElement<ResultSetRelationRows>(
22581                                                                        tableModel.getRelationRows());
22582                                                        relation.addSource(element);
22583                                                }
22584                                        }
22585                                }
22586                        }
22587
22588                        if (stmt.getWhereClause() == null || stmt.getWhereClause().getCondition() == null) {
22589                                return;
22590                        }
22591
22592                        columnsInExpr visitor = new columnsInExpr();
22593                        stmt.getWhereClause().getCondition().inOrderTraverse(visitor);
22594                        List<TObjectName> objectNames = visitor.getObjectNames();
22595                        for (int j = 0; j < objectNames.size(); j++) {
22596                                TObjectName columnName = objectNames.get(j);
22597                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
22598                                        Variable tableModel;
22599                                        if (columnName.toString().indexOf(".") != -1) {
22600                                                List<String> splits = SQLUtil.parseNames(columnName.toString());
22601                                                tableModel = modelFactory.createVariable(splits.get(splits.size() - 2));
22602                                        } else {
22603                                                tableModel = modelFactory.createVariable(columnName);
22604                                        }
22605                                        tableModel.setCreateTable(true);
22606                                        tableModel.setSubType(SubType.record);
22607                                        TObjectName variableProperties = new TObjectName();
22608                                        variableProperties.setString("*");
22609                                        modelFactory.createTableColumn(tableModel, variableProperties, true);
22610                                }
22611
22612//                              if (columnName.getColumnNameOnly().startsWith("@")
22613//                                              && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
22614//                                      continue;
22615//                              }
22616//
22617//                              if (columnName.getColumnNameOnly().startsWith(":") && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
22618//                                      continue;
22619//                              }
22620
22621                                AbstractRelationship relation = modelFactory.createRecordSetRelation();
22622                                relation.setEffectType(EffectType.function);
22623                                relation.setFunction(function.getFunctionName().toString());
22624                                relation.setTarget(new ResultColumnRelationshipElement(
22625                                                (ResultColumn) modelManager.getModel(function.getFunctionName())));
22626
22627                                TTable table = modelManager.getTable(stmt, columnName);
22628                                if (table != null) {
22629                                        if (modelManager.getModel(table) instanceof Table) {
22630                                                Table tableModel = (Table) modelManager.getModel(table);
22631                                                if (tableModel != null) {
22632                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
22633                                                        if(columnModel == null) {
22634                                                                continue;
22635                                                        }
22636                                                        relation.addSource(
22637                                                                        new TableColumnRelationshipElement(columnModel, columnName.getLocation()));
22638                                                }
22639                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
22640                                                Object model = modelManager.getModel(columnName.getSourceColumn());
22641                                                if (model instanceof ResultColumn) {
22642                                                        ResultColumn resultColumn = (ResultColumn) model;
22643                                                        if (resultColumn != null) {
22644                                                                relation.addSource(
22645                                                                                new ResultColumnRelationshipElement(resultColumn, columnName.getLocation()));
22646                                                        }
22647                                                }
22648                                        }
22649                                }
22650                        }
22651                }
22652        }
22653
22654        private void analyzeFilterCondition(Object modelObject, TExpression expr, EJoinType joinType,
22655                        JoinClauseType joinClauseType, EffectType effectType) {
22656                if (expr == null) {
22657                        return;
22658                }
22659
22660                TCustomSqlStatement stmt = stmtStack.peek();
22661
22662                columnsInExpr visitor = new columnsInExpr();
22663                expr.inOrderTraverse(visitor);
22664
22665                List<TObjectName> objectNames = visitor.getObjectNames();
22666                List<TParseTreeNode> functions = visitor.getFunctions();
22667                List<TResultColumn> resultColumns = visitor.getResultColumns();
22668                List<TParseTreeNode> constants = visitor.getConstants();
22669
22670                ImpactRelationship relation = modelFactory.createImpactRelation();
22671                relation.setEffectType(effectType);
22672                relation.setJoinClauseType(joinClauseType);
22673                if (modelObject instanceof ResultColumn) {
22674                        relation.setTarget(new ResultColumnRelationshipElement((ResultColumn) modelObject));
22675                } else {
22676                        ResultSet resultSet = (ResultSet) modelManager.getModel(stmt.getResultColumnList());
22677                        if (resultSet == null && stmt instanceof TUpdateSqlStatement) {
22678                                resultSet = (ResultSet) modelManager.getModel(stmt);
22679                        }
22680                        if (resultSet == null && stmt instanceof TMergeSqlStatement) {
22681                                TSelectSqlStatement subquery = ((TMergeSqlStatement) stmt).getUsingTable().getSubquery();
22682                                if (subquery != null) {
22683                                        resultSet = (ResultSet) modelManager.getModel(((TMergeSqlStatement) stmt).getUsingTable());
22684                                }
22685                                else {
22686                                        resultSet = modelFactory.createQueryTable(((TMergeSqlStatement) stmt).getUsingTable());
22687                                }
22688                        }
22689                        if (resultSet != null) {
22690                                relation.setTarget(
22691                                                new RelationRowsRelationshipElement<ResultSetRelationRows>(resultSet.getRelationRows()));
22692                        }
22693                        if (stmt instanceof TDeleteSqlStatement) {
22694                                Table table = (Table) modelManager.getModel(((TDeleteSqlStatement) stmt).getTargetTable());
22695                                if (table != null) {
22696                                        relation.setTarget(new RelationRowsRelationshipElement<TableRelationRows>(table.getRelationRows()));
22697                                }
22698                        }
22699                }
22700                if (relation.getTarget() != null) {
22701
22702                        if (constants != null && constants.size() > 0) {
22703                                if (option.isShowConstantTable()) {
22704                                        Table constantTable = modelFactory.createConstantsTable(stmtStack.peek());
22705                                        for (int i = 0; i < constants.size(); i++) {
22706                                                TParseTreeNode constant = constants.get(i);
22707                                                if (constant instanceof TConstant) {
22708                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
22709                                                                        (TConstant) constant);
22710                                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
22711                                                } else if (constant instanceof TObjectName) {
22712                                                        TableColumn constantColumn = modelFactory.createTableColumn(constantTable,
22713                                                                        (TObjectName) constant, false);
22714                                                        if(constantColumn == null) {
22715                                                                continue;
22716                                                        }
22717                                                        relation.addSource(new ConstantRelationshipElement(constantColumn));
22718                                                }
22719                                        }
22720                                }
22721                        }
22722
22723                        for (int j = 0; j < objectNames.size(); j++) {
22724                                TObjectName columnName = objectNames.get(j);
22725                                if (columnName.getDbObjectType() == EDbObjectType.variable) {
22726                                        Variable variable = modelFactory.createVariable(columnName);
22727                                        variable.setSubType(SubType.record);
22728                                        if (variable.getColumns().isEmpty()) {
22729                                                TObjectName variableProperties = new TObjectName();
22730                                                variableProperties.setString("*");
22731                                                modelFactory.createTableColumn(variable, variableProperties, true);
22732                                        }
22733                                        relation.addSource(new TableColumnRelationshipElement(variable.getColumns().get(0), columnName.getLocation()));
22734                                        continue;
22735                                }
22736
22737                                if (columnName.getColumnNameOnly().startsWith("@")
22738                                                && (option.getVendor() == EDbVendor.dbvmssql || option.getVendor() == EDbVendor.dbvazuresql)) {
22739                                        continue;
22740                                }
22741
22742                                if (columnName.getColumnNameOnly().startsWith(":")
22743                                                && (option.getVendor() == EDbVendor.dbvhana || option.getVendor() == EDbVendor.dbvteradata)) {
22744                                        continue;
22745                                }
22746
22747                                TTable table = modelManager.getTable(stmt, columnName);
22748
22749                                if (table == null) {
22750                                        table = columnName.getSourceTable();
22751                                }
22752
22753                                if (table == null && stmt.tables != null) {
22754                                        for (int k = 0; k < stmt.tables.size(); k++) {
22755                                                if (table != null)
22756                                                        break;
22757
22758                                                TTable tTable = stmt.tables.getTable(k);
22759                                                if (tTable.getTableType().name().startsWith("open")) {
22760                                                        continue;
22761                                                } else if (getTableLinkedColumns(tTable) != null && getTableLinkedColumns(tTable).size() > 0) {
22762                                                        for (int z = 0; z < getTableLinkedColumns(tTable).size(); z++) {
22763                                                                TObjectName refer = getTableLinkedColumns(tTable).getObjectName(z);
22764                                                                if ("*".equals(getColumnName(refer)))
22765                                                                        continue;
22766                                                                if (getColumnName(refer).equals(getColumnName(columnName))) {
22767                                                                        table = tTable;
22768                                                                        break;
22769                                                                }
22770                                                        }
22771                                                } else if (columnName.getTableToken() != null
22772                                                                && (columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getName())
22773                                                                                || columnName.getTableToken().getAstext().equalsIgnoreCase(tTable.getAliasName()))) {
22774                                                        table = tTable;
22775                                                        break;
22776                                                }
22777                                        }
22778
22779                                        if (table == null) {
22780                                                for (int k = 0; k < stmt.tables.size(); k++) {
22781                                                        if (table != null)
22782                                                                break;
22783
22784                                                        TTable tTable = stmt.tables.getTable(k);
22785                                                        Object model = ModelBindingManager.get().getModel(tTable);
22786                                                        if (model instanceof Table) {
22787                                                                Table tableModel = (Table) model;
22788                                                                for (int z = 0; tableModel.getColumns() != null
22789                                                                                && z < tableModel.getColumns().size(); z++) {
22790                                                                        TableColumn refer = tableModel.getColumns().get(z);
22791                                                                        if (getColumnName(refer.getName()).equals(getColumnName(columnName))) {
22792                                                                                table = tTable;
22793                                                                                break;
22794                                                                        }
22795                                                                        if (refer.hasStarLinkColumn()) {
22796                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
22797                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
22798                                                                                                table = tTable;
22799                                                                                                break;
22800                                                                                        }
22801                                                                                }
22802                                                                        }
22803                                                                }
22804                                                        } else if (model instanceof QueryTable) {
22805                                                                QueryTable tableModel = (QueryTable) model;
22806                                                                for (int z = 0; tableModel.getColumns() != null
22807                                                                                && z < tableModel.getColumns().size(); z++) {
22808                                                                        ResultColumn refer = tableModel.getColumns().get(z);
22809                                                                        if (DlineageUtil.getIdentifierNormalColumnName(refer.getName()).equals(
22810                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
22811                                                                                table = tTable;
22812                                                                                break;
22813                                                                        }
22814                                                                        if (refer.hasStarLinkColumn()) {
22815                                                                                for (TObjectName linkColumn : refer.getStarLinkColumnList()) {
22816                                                                                        if (getColumnName(linkColumn).equals(getColumnName(columnName))) {
22817                                                                                                table = tTable;
22818                                                                                                break;
22819                                                                                        }
22820                                                                                }
22821                                                                        }
22822                                                                }
22823                                                        }
22824                                                }
22825                                        }
22826                                }
22827
22828                                if (table == null && stmt.tables != null && stmt.tables.size() != 0
22829                                                && !(isBuiltInFunctionName(columnName) && isFromFunction(columnName))) {
22830                                        
22831                                        if (modelManager.getModel(stmt) instanceof ResultSet) {
22832                                                ResultSet resultSetModel = (ResultSet) modelManager.getModel(stmt);
22833                                                boolean find = false;
22834                                                for (ResultColumn resultColumn : resultSetModel.getColumns()) {
22835                                                        if(resultColumn.equals(modelObject)) {
22836                                                                continue;
22837                                                        }
22838                                                        if (!TSQLEnv.isAliasReferenceForbidden.get(option.getVendor())) {
22839                                                                if (getColumnName(columnName).equals(getColumnName(resultColumn.getName()))) {
22840                                                                        if (resultColumn.getColumnObject() != null) {
22841                                                                                int startToken = resultColumn.getColumnObject().getStartToken().posinlist;
22842                                                                                int endToken = resultColumn.getColumnObject().getEndToken().posinlist;
22843                                                                                if (columnName.getStartToken().posinlist >= startToken
22844                                                                                                && columnName.getEndToken().posinlist <= endToken) {
22845                                                                                        continue;
22846                                                                                }
22847                                                                        }
22848                                                                        relation.addSource(new ResultColumnRelationshipElement(resultColumn));
22849                                                                        find = true;
22850                                                                        break;
22851                                                                }
22852                                                        }
22853                                                }
22854                                                if (find) {
22855                                                        continue;
22856                                                }
22857                                        }
22858
22859                                        TObjectName pseudoTableName = new TObjectName();
22860                                        // Use qualified prefix from column name if available (e.g., sch.pk_constv2 from sch.pk_constv2.c_cdsl)
22861                                        // Otherwise fall back to default pseudo table name
22862                                        String qualifiedPrefix = getQualifiedPrefixFromColumn(columnName);
22863                                        pseudoTableName.setString(qualifiedPrefix != null ? qualifiedPrefix : "pseudo_table_include_orphan_column");
22864                                        Table pseudoTable = modelFactory.createTableByName(pseudoTableName);
22865                                        pseudoTable.setPseudo(true);
22866                                        TableColumn pseudoTableColumn = modelFactory.createTableColumn(pseudoTable, columnName, true);
22867
22868                                        // If not linking to first table and column has qualified prefix (3-part name like sch.pkg.col),
22869                                        // add the pseudo table column as source
22870                                        if (!isLinkOrphanColumnToFirstTable() && pseudoTableColumn != null && qualifiedPrefix != null) {
22871                                                relation.addSource(new TableColumnRelationshipElement(pseudoTableColumn));
22872                                        }
22873
22874                                        if (isLinkOrphanColumnToFirstTable()) {
22875                                                TTable orphanTable = stmt.tables.getTable(0);
22876                                                table = stmt.tables.getTable(0);
22877                                                Object tableModel = modelManager.getModel(table);
22878                                                if (tableModel == null) {
22879                                                        tableModel = modelFactory.createTable(orphanTable);
22880                                                }
22881                                                if (tableModel instanceof Table) {
22882                                                        modelFactory.createTableColumn((Table) tableModel, columnName, false);
22883                                                        ErrorInfo errorInfo = new ErrorInfo();
22884                                                        errorInfo.setErrorType(ErrorInfo.LINK_ORPHAN_COLUMN);
22885                                                        errorInfo.setErrorMessage("Link orphan column [" + columnName.toString()
22886                                                                        + "] to the first table [" + orphanTable.getFullNameWithAliasString() + "]");
22887                                                        errorInfo.setStartPosition(new Pair3<Long, Long, String>(columnName.getStartToken().lineNo,
22888                                                                        columnName.getStartToken().columnNo, ModelBindingManager.getGlobalHash()));
22889                                                        errorInfo.setEndPosition(new Pair3<Long, Long, String>(columnName.getEndToken().lineNo,
22890                                                                        columnName.getEndToken().columnNo + columnName.getEndToken().getAstext().length(),
22891                                                                        ModelBindingManager.getGlobalHash()));
22892                                                        errorInfo.fillInfo(this);
22893                                                        errorInfos.add(errorInfo);
22894                                                }
22895                                        }
22896                                }
22897
22898                                if (table != null) {
22899                                        if (modelManager.getModel(table) instanceof Table) {
22900                                                Table tableModel = (Table) modelManager.getModel(table);
22901                                                if (tableModel != null) {
22902                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel, columnName, false);
22903                                                        if(columnModel!=null) {
22904                                                                TableColumnRelationshipElement element = new TableColumnRelationshipElement(columnModel,
22905                                                                                columnName.getLocation());
22906                                                                relation.addSource(element);
22907                                                        }
22908                                                }
22909                                        } else if (modelManager.getModel(table) instanceof QueryTable) {
22910                                                QueryTable tableModel = (QueryTable)modelManager.getModel(table);
22911                                                if (table.getSubquery() != null && table.getSubquery().isCombinedQuery()) {
22912                                                        TSelectSqlStatement subquery = table.getSubquery();
22913                                                        List<ResultSet> resultSets = new ArrayList<ResultSet>();
22914                                                        if (!subquery.getLeftStmt().isCombinedQuery()) {
22915                                                                ResultSet sourceResultSet = (ResultSet) modelManager
22916                                                                                .getModel(subquery.getLeftStmt().getResultColumnList());
22917                                                                resultSets.add(sourceResultSet);
22918                                                        } else {
22919                                                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getLeftStmt());
22920                                                                resultSets.add(sourceResultSet);
22921                                                        }
22922
22923                                                        if (!subquery.getRightStmt().isCombinedQuery()) {
22924                                                                ResultSet sourceResultSet = (ResultSet) modelManager
22925                                                                                .getModel(subquery.getRightStmt().getResultColumnList());
22926                                                                resultSets.add(sourceResultSet);
22927                                                        } else {
22928                                                                ResultSet sourceResultSet = (ResultSet) modelManager.getModel(subquery.getRightStmt());
22929                                                                resultSets.add(sourceResultSet);
22930                                                        }
22931
22932                                                        for (ResultSet sourceResultSet : resultSets) {
22933                                                                if (sourceResultSet != null && columnName.getSourceColumn() != null) {
22934                                                                        for (int k = 0; k < sourceResultSet.getColumns().size(); k++) {
22935                                                                                if (getColumnName(sourceResultSet.getColumns().get(k).getName()).equals(
22936                                                                                                getColumnName(columnName.getSourceColumn().getColumnNameOnly()))) {
22937                                                                                        Set<TObjectName> starLinkColumnSet = sourceResultSet.getColumns().get(k)
22938                                                                                                        .getStarLinkColumns().get(getColumnName(columnName));
22939                                                                                        if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) {
22940                                                                                                ResultColumn column = modelFactory.createResultColumn(sourceResultSet,
22941                                                                                                                starLinkColumnSet.iterator().next(), true);
22942                                                                                                relation.addSource(new ResultColumnRelationshipElement(column));
22943                                                                                        } else {
22944                                                                                                relation.addSource(new ResultColumnRelationshipElement(
22945                                                                                                                sourceResultSet.getColumns().get(k)));
22946                                                                                        }
22947                                                                                }
22948                                                                        }
22949                                                                }
22950                                                        }
22951                                                } else {
22952                                                        Object model = modelManager.getModel(columnName.getSourceColumn());
22953                                                        if (model instanceof ResultColumn) {
22954                                                                ResultColumn resultColumn = (ResultColumn) model;
22955                                                                if (resultColumn != null) {
22956                                                                        if (resultColumn.hasStarLinkColumn()) {
22957                                                                                Set<TObjectName> starLinkColumnSet = resultColumn.getStarLinkColumns()
22958                                                                                                .get(getColumnName(columnName));
22959                                                                                if (starLinkColumnSet != null && !starLinkColumnSet.isEmpty()) {
22960                                                                                        ResultColumn column = modelFactory.createResultColumn(
22961                                                                                                        resultColumn.getResultSet(), starLinkColumnSet.iterator().next(), true);
22962                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
22963                                                                                } else {
22964                                                                                        resultColumn.bindStarLinkColumn(columnName);
22965                                                                                        ResultColumn column = modelFactory
22966                                                                                                        .createResultColumn(resultColumn.getResultSet(), columnName, true);
22967                                                                                        relation.addSource(new ResultColumnRelationshipElement(column));
22968                                                                                }
22969                                                                        } else {
22970                                                                                ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
22971                                                                                                resultColumn, columnName.getLocation());
22972                                                                                relation.addSource(element);
22973                                                                        }
22974                                                                }
22975                                                        }
22976                                                        else{
22977                                                                boolean find = false;
22978                                                                for (int i = 0; i < tableModel.getColumns().size(); i++) {
22979                                                                        ResultColumn resultColumn = tableModel.getColumns().get(i);
22980                                                                        if (DlineageUtil.getIdentifierNormalColumnName(resultColumn.getName()).equals(
22981                                                                                        DlineageUtil.getIdentifierNormalColumnName(getColumnName(columnName)))) {
22982                                                                                ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
22983                                                                                                resultColumn, columnName.getLocation());
22984                                                                                relation.addSource(element);
22985                                                                                find = true;
22986                                                                                break;
22987                                                                        }
22988                                                                        else if (resultColumn.getName().endsWith("*")) {
22989                                                                                resultColumn.bindStarLinkColumn(columnName);
22990                                                                        }
22991                                                                }
22992                                                                if(!find){
22993                                                                        ResultColumn resultColumn = new ResultColumn(tableModel, columnName);
22994                                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(
22995                                                                                                resultColumn, columnName.getLocation());
22996                                                                                relation.addSource(element);
22997                                                                }
22998                                                        }
22999                                                }
23000                                        }
23001                                }
23002                        }
23003
23004                        for (int j = 0; j < functions.size(); j++) {
23005                                TParseTreeNode functionObj = functions.get(j);
23006                                Object functionModel = modelManager.getModel(functionObj);
23007                                if (functionModel == null) {
23008                                        functionModel = createFunction(functionObj);
23009                                }
23010                                if (functionModel instanceof Function) {
23011                                        if (functionObj instanceof TFunctionCall) {
23012                                                ResultColumn resultColumn = (ResultColumn) modelManager
23013                                                                .getModel(((TFunctionCall) functionObj).getFunctionName());
23014                                                if (resultColumn != null) {
23015                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn,
23016                                                                        ((TFunctionCall) functionObj).getFunctionName().getLocation());
23017                                                        relation.addSource(element);
23018                                                }
23019                                        }
23020                                        if (functionObj instanceof TCaseExpression) {
23021                                                ResultColumn resultColumn = (ResultColumn) modelManager
23022                                                                .getModel(((TCaseExpression) functionObj).getWhenClauseItemList());
23023                                                if (resultColumn != null) {
23024                                                        ResultColumnRelationshipElement element = new ResultColumnRelationshipElement(resultColumn);
23025                                                        relation.addSource(element);
23026                                                }
23027                                        }
23028                                } else if (functionModel instanceof Table) {
23029                                        TableColumn tableColumn = modelFactory.createTableColumn((Table) functionModel,
23030                                                        ((TFunctionCall) functionObj).getFunctionName(), false);
23031                                        TableColumnRelationshipElement element = new TableColumnRelationshipElement(tableColumn);
23032                                        relation.addSource(element);
23033                                }
23034                        }
23035
23036                        for (int j = 0; j < resultColumns.size(); j++) {
23037                                TResultColumn resultColumn = resultColumns.get(j);
23038                                if (modelManager.getModel(resultColumn) instanceof ResultColumn) {
23039                                        ResultColumn resultColumnModel = (ResultColumn) modelManager.getModel(resultColumn);
23040                                        relation.addSource(new ResultColumnRelationshipElement(resultColumnModel, ESqlClause.selectList));
23041                                }
23042                        }
23043                }
23044
23045                if (isShowJoin() && joinClauseType != null) {
23046                        joinInExpr joinVisitor = new joinInExpr(joinType, joinClauseType, effectType);
23047                        expr.inOrderTraverse(joinVisitor);
23048                }
23049        }
23050
23051        public void dispose() {
23052                accessedSubqueries.clear();
23053                accessedStatements.clear();
23054                stmtStack.clear();
23055                viewDDLMap.clear();
23056                procedureDDLMap.clear();
23057                structObjectMap.clear();
23058                appendResultSets.clear();
23059                appendStarColumns.clear();
23060                appendTableStarColumns.clear();
23061                modelManager.DISPLAY_ID.clear();
23062                modelManager.DISPLAY_NAME.clear();
23063                tableIds.clear();
23064                ModelBindingManager.remove();
23065        }
23066
23067        class joinTreatColumnsInExpr implements IExpressionVisitor {
23068
23069                private List<TObjectName> objectNames = new ArrayList<TObjectName>();
23070                
23071                private TTable table;
23072
23073                public joinTreatColumnsInExpr(TTable table) {
23074                        this.table = table;
23075                }
23076
23077                public List<TObjectName> getObjectNames() {
23078                        return objectNames;
23079                }
23080
23081                boolean is_compare_condition(EExpressionType t) {
23082                        return t == EExpressionType.simple_comparison_t;
23083                }
23084
23085                @Override
23086                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
23087                        TExpression expr = (TExpression) pNode;
23088                        if (is_compare_condition(expr.getExpressionType())) {
23089                                TExpression leftExpr = expr.getLeftOperand();
23090                                columnsInExpr leftVisitor = new columnsInExpr();
23091                                leftExpr.inOrderTraverse(leftVisitor);
23092                                List<TObjectName> leftObjectNames = leftVisitor.getObjectNames();
23093
23094                                TExpression rightExpr = expr.getRightOperand();
23095                                columnsInExpr rightVisitor = new columnsInExpr();
23096                                rightExpr.inOrderTraverse(rightVisitor);
23097                                List<TObjectName> rightObjectNames = rightVisitor.getObjectNames();
23098
23099                                if (!leftObjectNames.isEmpty() && !rightObjectNames.isEmpty()) {
23100                                        for (TObjectName column : leftObjectNames) {
23101                                                if (column.getSourceTable() != null && column.getSourceTable().equals(table)) {
23102                                                        objectNames.add(column);
23103                                                        return false;
23104                                                }
23105                                        }
23106                                        for (TObjectName column : rightObjectNames) {
23107                                                if (column.getSourceTable() != null && column.getSourceTable().equals(table)) {
23108                                                        objectNames.add(column);
23109                                                        return false;
23110                                                }
23111                                        }
23112                                }
23113                                return false;
23114                        }
23115                        return true;
23116                }
23117        }
23118        
23119        class columnsInExpr implements IExpressionVisitor {
23120
23121                private List<TParseTreeNode> constants = new ArrayList<TParseTreeNode>();
23122                private List<TObjectName> objectNames = new ArrayList<TObjectName>();
23123                private List<TParseTreeNode> functions = new ArrayList<TParseTreeNode>();
23124                private List<TResultColumn> resultColumns = new ArrayList<TResultColumn>();
23125                private List<TSelectSqlStatement> subquerys = new ArrayList<TSelectSqlStatement>();
23126                private boolean skipFunction = false;
23127
23128                public void setSkipFunction(boolean skipFunction) {
23129                        this.skipFunction = skipFunction;
23130                }
23131
23132                public List<TParseTreeNode> getFunctions() {
23133                        return functions;
23134                }
23135
23136                public List<TSelectSqlStatement> getSubquerys() {
23137                        return subquerys;
23138                }
23139
23140                public List<TParseTreeNode> getConstants() {
23141                        return constants;
23142                }
23143
23144                public List<TObjectName> getObjectNames() {
23145                        return objectNames;
23146                }
23147
23148                public List<TResultColumn> getResultColumns() {
23149                        return resultColumns;
23150                }
23151
23152                @Override
23153                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
23154                        TExpression lcexpr = (TExpression) pNode;
23155                        // Handle named argument expressions (e.g., "INPUT => value" in Snowflake FLATTEN)
23156                        // The left operand is the parameter name, NOT a column reference.
23157                        // Only traverse the right operand (the value).
23158                        if (lcexpr.getExpressionType() == EExpressionType.assignment_t) {
23159                                // Skip left operand (parameter name) - only traverse right operand (value)
23160                                if (lcexpr.getRightOperand() != null) {
23161                                        lcexpr.getRightOperand().inOrderTraverse(this);
23162                                }
23163                                return false; // Don't continue default traversal
23164                        }
23165                        if (lcexpr.getExpressionType() == EExpressionType.simple_constant_t) {
23166                                if (lcexpr.getConstantOperand() != null) {
23167                                        if(lcexpr.getConstantOperand().getInt64_expression()!=null 
23168                                                        && lcexpr.getConstantOperand().getInt64_expression().getExpressionType() == EExpressionType.function_t) {
23169                                                lcexpr.getConstantOperand().getInt64_expression().inOrderTraverse(this);
23170                                        }
23171                                        else {
23172                                                constants.add(lcexpr.getConstantOperand());
23173                                        }
23174                                }
23175                        } else if (lcexpr.getExpressionType() == EExpressionType.array_t) {
23176                                if(lcexpr.getObjectOperand()!=null) {
23177                                        TObjectName object = lcexpr.getObjectOperand();
23178                                        objectNames.add(object);
23179                                } else if (lcexpr.getExprList() != null) {
23180                                        for (int j = 0; j < lcexpr.getExprList().size(); j++) {
23181                                                TExpression expr = lcexpr.getExprList().getExpression(j);
23182                                                if (expr != null)
23183                                                        expr.inOrderTraverse(this);
23184                                        }
23185                                }
23186                        } else if (lcexpr.getExpressionType() == EExpressionType.simple_object_name_t) {
23187                                if (lcexpr.getObjectOperand() != null && !(isBuiltInFunctionName(lcexpr.getObjectOperand())
23188                                                && isFromFunction(lcexpr.getObjectOperand()))) {
23189                                        TObjectName object = lcexpr.getObjectOperand();
23190                                        // Skip named argument parameter names (e.g., INPUT in "INPUT => value")
23191                                        // These are function parameter names, NOT column references
23192                                        if (object.getObjectType() == TObjectName.ttobjNamedArgParameter) {
23193                                                // Skip - this is a named argument parameter name
23194                                        } else if (object.getDbObjectType() == EDbObjectType.column
23195                                                        || object.getDbObjectType() == EDbObjectType.column_alias
23196                                                        || object.getDbObjectType() == EDbObjectType.alias
23197                                                        || object.getDbObjectType() == EDbObjectType.unknown
23198                                                        || object.getDbObjectType() == EDbObjectType.variable) {
23199                                                objectNames.add(object);
23200                                        } else if (object.getDbObjectType() == EDbObjectType.notAColumn
23201                                                        || object.getDbObjectType() == EDbObjectType.date_time_part ) {
23202                                                constants.add(object);
23203                                        }
23204                                }
23205                        } else if (lcexpr.getExpressionType() == EExpressionType.between_t) {
23206                                if (lcexpr.getBetweenOperand() != null && lcexpr.getBetweenOperand().getObjectOperand() != null) {
23207                                        TObjectName object = lcexpr.getBetweenOperand().getObjectOperand();
23208                                        if (object.getDbObjectType() == EDbObjectType.column
23209                                                        || object.getDbObjectType() == EDbObjectType.column_alias
23210                                                        || object.getDbObjectType() == EDbObjectType.alias
23211                                                        || object.getDbObjectType() == EDbObjectType.unknown
23212                                                        || object.getDbObjectType() == EDbObjectType.variable) {
23213                                                objectNames.add(object);
23214                                        }
23215                                }
23216                        } else if (lcexpr.getExpressionType() == EExpressionType.object_access_t) {
23217                                if (lcexpr.getObjectAccess() != null) {
23218                                        TObjectNameList objects = lcexpr.getObjectAccess().getAttributes();
23219                                        TFunctionCall function = lcexpr.getObjectAccess().getObjectExpr().getFunctionCall();
23220                                        if (objects != null && function != null) {
23221                                                for (TObjectName object : objects) {
23222                                                        TGSqlParser sqlparser = new TGSqlParser(option.getVendor());
23223                                                        sqlparser.sqltext = "select " + function.getFunctionName().toString() + "."
23224                                                                        + object.getColumnNameOnly() + " from " + function.getFunctionName().toString();
23225                                                        if (sqlparser.parse() == 0) {
23226                                                                TObjectName objectName = sqlparser.sqlstatements.get(0).getResultColumnList()
23227                                                                                .getResultColumn(0).getFieldAttr();
23228                                                                objectNames.add(objectName);
23229                                                        }
23230                                                }
23231                                        }
23232                                }
23233                        } else if (lcexpr.getExpressionType() == EExpressionType.function_t || lcexpr.getExpressionType() == EExpressionType.fieldselection_t) {
23234                                TFunctionCall func = lcexpr.getFunctionCall();
23235                                if (func == null) {
23236                                        return true;
23237                                }
23238                                if (skipFunction) {
23239                                        if (func.getArgs() != null) {
23240                                                for (int k = 0; k < func.getArgs().size(); k++) {
23241                                                        TExpression expr = func.getArgs().getExpression(k);
23242                                                        if (expr != null)
23243                                                                expr.inOrderTraverse(this);
23244                                                }
23245                                        }
23246
23247                                        if (func.getTrimArgument() != null) {
23248                                                TTrimArgument args = func.getTrimArgument();
23249                                                TExpression expr = args.getStringExpression();
23250                                                if (expr != null) {
23251                                                        expr.inOrderTraverse(this);
23252                                                }
23253                                                expr = args.getTrimCharacter();
23254                                                if (expr != null) {
23255                                                        expr.inOrderTraverse(this);
23256                                                }
23257                                        }
23258
23259                                        if (func.getAgainstExpr() != null) {
23260                                                func.getAgainstExpr().inOrderTraverse(this);
23261                                        }
23262//                                      if (func.getBetweenExpr() != null) {
23263//                                              func.getBetweenExpr().inOrderTraverse(this);
23264//                                      }
23265                                        if (func.getExpr1() != null) {
23266                                                func.getExpr1().inOrderTraverse(this);
23267                                        }
23268                                        if (func.getExpr2() != null) {
23269                                                func.getExpr2().inOrderTraverse(this);
23270                                        }
23271                                        if (func.getExpr3() != null) {
23272                                                func.getExpr3().inOrderTraverse(this);
23273                                        }
23274                                        if (func.getParameter() != null) {
23275                                                func.getParameter().inOrderTraverse(this);
23276                                        }
23277                                } else {
23278                                        functions.add(func);
23279                                }
23280
23281                        } else if (lcexpr.getExpressionType() == EExpressionType.case_t) {
23282                                TCaseExpression expr = lcexpr.getCaseExpression();
23283                                if (skipFunction) {
23284                                        TExpression defaultExpr = expr.getElse_expr();
23285                                        if (defaultExpr != null) {
23286                                                defaultExpr.inOrderTraverse(this);
23287                                        }
23288                                        TWhenClauseItemList list = expr.getWhenClauseItemList();
23289                                        for (int i = 0; i < list.size(); i++) {
23290                                                TWhenClauseItem element = (TWhenClauseItem) list.getElement(i);
23291                                                (((TWhenClauseItem) element).getReturn_expr()).inOrderTraverse(this);
23292
23293                                        }
23294                                } else {
23295                                        functions.add(expr);
23296                                }
23297                        } else if (lcexpr.getSubQuery() != null) {
23298                                TSelectSqlStatement select = lcexpr.getSubQuery();
23299                                analyzeSelectStmt(select);
23300                                subquerys.add(select);
23301                                if (select.getResultColumnList() != null && select.getResultColumnList().size() > 0) {
23302                                        for (TResultColumn column : select.getResultColumnList()) {
23303                                                resultColumns.add(column);
23304                                        }
23305                                }
23306                        }
23307                        return true;
23308                }
23309        }
23310
23311        class joinInExpr implements IExpressionVisitor {
23312
23313                private EJoinType joinType;
23314                private JoinClauseType joinClauseType;
23315                private EffectType effectType;
23316
23317                public joinInExpr(EJoinType joinType, JoinClauseType joinClauseType, EffectType effectType) {
23318                        this.joinType = joinType;
23319                        this.joinClauseType = joinClauseType;
23320                        this.effectType = effectType;
23321                }
23322
23323                boolean is_compare_condition(EExpressionType t) {
23324                        return ((t == EExpressionType.simple_comparison_t) || (t == EExpressionType.group_comparison_t)
23325                                        || (t == EExpressionType.in_t) || (t == EExpressionType.pattern_matching_t)
23326                                        || (t == EExpressionType.left_join_t) || (t == EExpressionType.right_join_t));
23327                }
23328
23329                @Override
23330                public boolean exprVisit(TParseTreeNode pNode, boolean isLeafNode) {
23331                        TExpression expr = (TExpression) pNode;
23332                        if (is_compare_condition(expr.getExpressionType())) {
23333                                TExpression leftExpr = expr.getLeftOperand();
23334                                columnsInExpr leftVisitor = new columnsInExpr();
23335                                leftExpr.inOrderTraverse(leftVisitor);
23336                                List<TObjectName> leftObjectNames = leftVisitor.getObjectNames();
23337                                List<TParseTreeNode> leftObjects = leftVisitor.getFunctions();
23338                                leftObjects.addAll(leftObjectNames);
23339                                
23340                                TExpression rightExpr = expr.getRightOperand();
23341                                columnsInExpr rightVisitor = new columnsInExpr();
23342                                rightExpr.inOrderTraverse(rightVisitor);
23343                                List<TObjectName> rightObjectNames = rightVisitor.getObjectNames();
23344                                List<TParseTreeNode> rightObjects = rightVisitor.getFunctions();
23345                                rightObjects.addAll(rightObjectNames);
23346
23347                                if (!leftObjects.isEmpty() && !rightObjects.isEmpty()) {
23348                                        TCustomSqlStatement stmt = stmtStack.peek();
23349
23350                                        for (int i = 0; i < leftObjects.size(); i++) {
23351                                                TParseTreeNode leftObject = leftObjects.get(i);
23352                                                TTable leftTable = null;
23353                                                TFunctionCall leftFunction = null;
23354                                                TObjectName leftObjectName = null;
23355                                                if (leftObject instanceof TObjectName) {
23356                                                        leftObjectName = (TObjectName)leftObject;
23357
23358                                                        if (leftObjectName.getDbObjectType() == EDbObjectType.variable) {
23359                                                                continue;
23360                                                        }
23361
23362                                                        if (leftObjectName.getColumnNameOnly().startsWith("@")
23363                                                                        && (option.getVendor() == EDbVendor.dbvmssql
23364                                                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
23365                                                                continue;
23366                                                        }
23367
23368                                                        if (leftObjectName.getColumnNameOnly().startsWith(":")
23369                                                                        && (option.getVendor() == EDbVendor.dbvhana
23370                                                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
23371                                                                continue;
23372                                                        }
23373
23374                                                        leftTable = modelManager.getTable(stmt, leftObjectName);
23375
23376                                                        if (leftTable == null) {
23377                                                                leftTable = leftObjectName.getSourceTable();
23378                                                        }
23379
23380                                                        if (leftTable == null) {
23381                                                                leftTable = modelManager.guessTable(stmt, leftObjectName);
23382                                                        }
23383                                                }
23384                                                else if(leftObject instanceof TFunctionCall){
23385                                                        leftFunction = (TFunctionCall)leftObject;
23386                                                }
23387
23388                                                if (leftTable != null || leftFunction != null) {
23389                                                        for (int j = 0; j < rightObjects.size(); j++) {
23390                                                                JoinRelationship joinRelation = modelFactory.createJoinRelation();
23391                                                                joinRelation.setEffectType(effectType);
23392                                                                if (joinType != null) {
23393                                                                        joinRelation.setJoinType(joinType);
23394                                                                } else {
23395                                                                        if (expr.getLeftOperand().isOracleOuterJoin()) {
23396                                                                                joinRelation.setJoinType(right);
23397                                                                        } else if (expr.getRightOperand().isOracleOuterJoin()) {
23398                                                                                joinRelation.setJoinType(EJoinType.left);
23399                                                                        } else if (expr.getExpressionType() == EExpressionType.left_join_t) {
23400                                                                                joinRelation.setJoinType(EJoinType.left);
23401                                                                        } else if (expr.getExpressionType() == EExpressionType.right_join_t) {
23402                                                                                joinRelation.setJoinType(right);
23403                                                                        } else {
23404                                                                                joinRelation.setJoinType(EJoinType.inner);
23405                                                                        }
23406                                                                }
23407
23408                                                                joinRelation.setJoinClauseType(joinClauseType);
23409                                                                joinRelation.setJoinCondition(expr.toString());
23410
23411
23412                                                                if (leftTable != null) {
23413                                                                        if (modelManager.getModel(leftTable) instanceof Table) {
23414                                                                                Table tableModel = (Table) modelManager.getModel(leftTable);
23415                                                                                if (tableModel != null) {
23416                                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel,
23417                                                                                                        leftObjectName, false);
23418                                                                                        if (columnModel != null) {
23419                                                                                                joinRelation.addSource(new TableColumnRelationshipElement(columnModel));
23420                                                                                        }
23421                                                                                }
23422                                                                        } else if (modelManager.getModel(leftTable) instanceof QueryTable) {
23423                                                                                QueryTable table = (QueryTable) modelManager.getModel(leftTable);
23424                                                                                TSelectSqlStatement subquery = table.getTableObject().getSubquery();
23425                                                                                if (subquery != null && subquery.isCombinedQuery()) {
23426                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
23427                                                                                                        leftObjectName);
23428                                                                                        if (resultColumn != null) {
23429                                                                                                joinRelation
23430                                                                                                                .addSource(new ResultColumnRelationshipElement(resultColumn));
23431                                                                                        }
23432                                                                                } else if (leftObjectName.getSourceColumn() != null) {
23433                                                                                        Object model = modelManager.getModel(leftObjectName);
23434                                                                                        if (model == null) {
23435                                                                                                model = modelFactory.createResultColumn(table, leftObjectName);
23436                                                                                        }
23437                                                                                        if (model instanceof ResultColumn) {
23438                                                                                                ResultColumn resultColumn = (ResultColumn) model;
23439                                                                                                if (resultColumn != null) {
23440                                                                                                        joinRelation.addSource(
23441                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
23442                                                                                                }
23443                                                                                        } else if (model instanceof LinkedHashMap) {
23444                                                                                                String columnName = getColumnNameOnly(leftObjectName.toString());
23445                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>) model;
23446                                                                                                if (resultColumns.containsKey(columnName)) {
23447                                                                                                        ResultColumn resultColumn = resultColumns.get(columnName);
23448                                                                                                        joinRelation.addSource(
23449                                                                                                                        new ResultColumnRelationshipElement(resultColumn));
23450                                                                                                }
23451                                                                                        }
23452                                                                                } else {
23453                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
23454                                                                                                        leftObjectName);
23455                                                                                        if (resultColumn != null) {
23456                                                                                                joinRelation
23457                                                                                                                .addSource(new ResultColumnRelationshipElement(resultColumn));
23458                                                                                        }
23459                                                                                }
23460                                                                        }
23461                                                                }
23462                                                                else if(leftFunction!=null) {
23463                                                                        Object functionObj = createFunction(leftFunction);
23464                                                                        if(functionObj instanceof Function) {
23465                                                                                Function function = (Function)functionObj;
23466                                                                                joinRelation.addSource(new ResultColumnRelationshipElement(function.getColumns().get(0)));
23467                                                                        }
23468                                                                }
23469
23470                                                                TParseTreeNode rightObject = rightObjects.get(j);
23471                                                                if(rightObject instanceof TObjectName) {
23472                                                                        TObjectName rightObjectName = (TObjectName)rightObject;
23473
23474                                                                        if (rightObjectName.getDbObjectType() == EDbObjectType.variable) {
23475                                                                                continue;
23476                                                                        }
23477
23478                                                                        if (rightObjectName.getColumnNameOnly().startsWith("@")
23479                                                                                        && (option.getVendor() == EDbVendor.dbvmssql
23480                                                                                                        || option.getVendor() == EDbVendor.dbvazuresql)) {
23481                                                                                continue;
23482                                                                        }
23483
23484                                                                        if (rightObjectName.getColumnNameOnly().startsWith(":")
23485                                                                                        && (option.getVendor() == EDbVendor.dbvhana
23486                                                                                                        || option.getVendor() == EDbVendor.dbvteradata)) {
23487                                                                                continue;
23488                                                                        }
23489
23490                                                                        TTable rightTable = modelManager.getTable(stmt, rightObjectName);
23491                                                                        if (rightTable == null) {
23492                                                                                rightTable = rightObjectName.getSourceTable();
23493                                                                        }
23494
23495                                                                        if (rightTable == null) {
23496                                                                                rightTable = modelManager.guessTable(stmt, rightObjectName);
23497                                                                        }
23498
23499                                                                        if (modelManager.getModel(rightTable) instanceof Table) {
23500                                                                                Table tableModel = (Table) modelManager.getModel(rightTable);
23501                                                                                if (tableModel != null) {
23502                                                                                        TableColumn columnModel = modelFactory.createTableColumn(tableModel,
23503                                                                                                        rightObjectName, false);
23504                                                                                        if(columnModel != null) {
23505                                                                                                joinRelation.setTarget(new TableColumnRelationshipElement(columnModel));
23506                                                                                        }
23507                                                                                }
23508                                                                        } else if (modelManager.getModel(rightTable) instanceof QueryTable) {
23509                                                                                QueryTable table = (QueryTable) modelManager.getModel(rightTable);
23510                                                                                TSelectSqlStatement subquery = table.getTableObject().getSubquery();
23511                                                                                if (subquery != null && subquery.isCombinedQuery()) {
23512                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
23513                                                                                                        rightObjectName);
23514                                                                                        if (resultColumn != null) {
23515                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
23516                                                                                        }
23517                                                                                } else if (rightObjectName.getSourceColumn() != null) {
23518                                                                                        Object model = modelManager.getModel(rightObjectName);
23519                                                                                        if (model == null) {
23520                                                                                                model = modelManager
23521                                                                                                                .getModel(rightObjectName.getSourceColumn());
23522                                                                                        }
23523                                                                                        if (model instanceof ResultColumn) {
23524                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement((ResultColumn)model));
23525                                                                                        }
23526                                                                                        else if (model instanceof LinkedHashMap) {
23527                                                                                                String columnName = getColumnNameOnly(rightObjectName.toString());
23528                                                                                                LinkedHashMap<String, ResultColumn> resultColumns = (LinkedHashMap<String, ResultColumn>)model;
23529                                                                                                if (resultColumns.containsKey(columnName)) {
23530                                                                                                        ResultColumn resultColumn = resultColumns.get(columnName);
23531                                                                                                        joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
23532                                                                                                }
23533                                                                                        }
23534                                                                                } else {
23535                                                                                        ResultColumn resultColumn = matchResultColumn(table.getColumns(),
23536                                                                                                        rightObjectName);
23537                                                                                        if (resultColumn != null) {
23538                                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(resultColumn));
23539                                                                                        }
23540                                                                                }
23541                                                                        }
23542                                                                }
23543                                                                else if(rightObject instanceof TFunctionCall) {
23544                                                                        Object functionObj = createFunction(rightObject);
23545                                                                        if(functionObj instanceof Function) {
23546                                                                                Function function = (Function)functionObj;
23547                                                                                joinRelation.setTarget(new ResultColumnRelationshipElement(function.getColumns().get(0)));
23548                                                                        }
23549                                                                }
23550                                                        }
23551                                                }
23552                                        }
23553                                }
23554                        }
23555                        return true;
23556                }
23557        }
23558
23559        @Deprecated
23560        public static Dataflow getSqlflowJSONModel(dataflow dataflow) {
23561                EDbVendor vendor = ModelBindingManager.getGlobalVendor();
23562                if(vendor == null) {
23563                        throw new IllegalArgumentException("getSqlflowJSONModel(dataflow dataflow) is deprecated, please call method getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor).");
23564                }
23565                return getSqlflowJSONModel(vendor, dataflow, false);
23566        }
23567
23568        public static Dataflow getSqlflowJSONModel(dataflow dataflow, EDbVendor vendor) {
23569                return getSqlflowJSONModel(vendor, dataflow, false);
23570        }
23571
23572        public static Dataflow getSqlflowJSONModel(EDbVendor vendor, dataflow dataflow, boolean normalizeIdentifier) {
23573                Dataflow model = new Dataflow();
23574                
23575                if (dataflow.getErrors() != null && !dataflow.getErrors().isEmpty()) {
23576                        List<Error> errorList = new ArrayList<Error>();
23577                        for (error error : dataflow.getErrors()) {
23578                                Error err = new Error();
23579                                err.setErrorMessage(error.getErrorMessage());
23580                                err.setErrorType(error.getErrorType());
23581                                err.setCoordinates(Coordinate.parse(error.getCoordinate()));
23582                                err.setFile(err.getFile());
23583                                err.setOriginCoordinates(Coordinate.parse(error.getOriginCoordinate()));
23584                                errorList.add(err);
23585                        }
23586                        model.setErrors(errorList.toArray(new Error[0]));
23587                }
23588
23589                Sqlflow sqlflow = MetadataUtil.convertDataflowToMetadata(vendor, dataflow);
23590                sqlflow.setErrorMessages(null);
23591                model.setDbobjs(sqlflow);
23592                model.setOrientation(dataflow.getOrientation());
23593
23594
23595                List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process> processes = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Process>();
23596                if(dataflow.getProcesses()!=null){
23597                        for(process process: dataflow.getProcesses()){
23598                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Process processModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process();
23599                                processModel.setId(process.getId());
23600                                processModel.setName(process.getName());
23601                                processModel.setProcedureId(process.getProcedureId());
23602                                processModel.setProcedureName(process.getProcedureName());
23603                                processModel.setType(process.getType());
23604                                processModel.setCoordinate(process.getCoordinate());
23605                                processModel.setDatabase(process.getDatabase());
23606                                processModel.setSchema(process.getSchema());
23607                                processModel.setServer(process.getServer());
23608                                processModel.setQueryHashId(process.getQueryHashId());
23609                                if (process.getTransforms() != null && !process.getTransforms().isEmpty()) {
23610                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>();
23611                                        for (transform transform : process.getTransforms()) {
23612                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform();
23613                                                item.setCode(transform.getCode());
23614                                                item.setType(transform.getType());
23615                                                item.setCoordinate(transform.getCoordinate(true));
23616                                                transforms.add(item);
23617                                        }
23618                                        processModel.setTransforms(transforms
23619                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0]));
23620                                }
23621                                processes.add(processModel);
23622                        }
23623                }
23624                model.setProcesses(processes.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Process[0]));
23625
23626                List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship> relations = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship>();
23627                if (dataflow.getRelationships() != null) {
23628                        for (relationship relation : dataflow.getRelationships()) {
23629                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship relationModel;
23630                                if (relation.getType().equals("join")) {
23631                                        gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship joinRelationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.JoinRelationship();
23632                                        joinRelationModel.setCondition(relation.getCondition());
23633                                        joinRelationModel.setJoinType(relation.getJoinType());
23634                                        joinRelationModel.setClause(relation.getClause());
23635                                        relationModel = joinRelationModel;
23636                                } else {
23637                                        relationModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship();
23638                                }
23639
23640                                relationModel.setId(relation.getId());
23641                                relationModel.setProcessId(relation.getProcessId());
23642                                relationModel.setProcessType(relation.getProcessType());
23643                                relationModel.setType(relation.getType());
23644                                relationModel.setEffectType(relation.getEffectType());
23645                                relationModel.setPartition(relation.getPartition());
23646                                relationModel.setFunction(relation.getFunction());
23647                                relationModel.setProcedureId(relation.getProcedureId());
23648                                relationModel.setSqlHash(relation.getSqlHash());
23649                                relationModel.setCondition(relation.getCondition());
23650                                relationModel.setSqlComment(relation.getSqlComment());
23651                                relationModel.setTimestampMax(relation.getTimestampMax());
23652                                relationModel.setTimestampMin(relation.getTimestampMin());
23653                                if (Boolean.TRUE.equals(relation.getBuiltIn())) {
23654                                        relationModel.setBuiltIn(relation.getBuiltIn());
23655                                }
23656                                relationModel.setCallStmt(relation.getCallStmt());
23657                                relationModel.setCallCoordinate(relation.getCallCoordinate());
23658                                
23659                                if (relation.getTarget() != null && relation.getSources() != null && !relation.getSources().isEmpty()) {
23660                                        {
23661                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23662                                                targetColumn target = relation.getTarget();
23663                                                if (normalizeIdentifier) {
23664                                                        targetModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, target.getColumn()));
23665                                                        targetModel.setParentName(
23666                                                                        SQLUtil.getIdentifierNormalTableName(vendor, target.getParent_name()));
23667                                                        targetModel.setTargetName(
23668                                                                        SQLUtil.getIdentifierNormalColumnName(vendor, target.getTarget_name()));
23669                                                } else {
23670                                                        targetModel.setColumn(target.getColumn());
23671                                                        targetModel.setParentName(target.getParent_name());
23672                                                        targetModel.setTargetName(target.getTarget_name());
23673                                                }
23674                                                targetModel.setId(target.getId());
23675                                                targetModel.setTargetId(target.getTarget_id());
23676                                                targetModel.setParentId(target.getParent_id());
23677                                                targetModel.setCoordinates(Coordinate.parse(target.getCoordinate()));
23678                                                targetModel.setFunction(target.getFunction());
23679                                                targetModel.setType(target.getType());
23680                                                relationModel.setTarget(targetModel);
23681                                        }
23682
23683                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>();
23684                                        for (sourceColumn source : relation.getSources()) {
23685                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23686                                                if (normalizeIdentifier) {
23687                                                        sourceModel.setColumn(SQLUtil.getIdentifierNormalColumnName(vendor, source.getColumn()));
23688                                                        sourceModel.setParentName(
23689                                                                        SQLUtil.getIdentifierNormalTableName(vendor, source.getParent_name()));
23690                                                        sourceModel.setSourceName(
23691                                                                        SQLUtil.getIdentifierNormalColumnName(vendor, source.getSource_name()));
23692                                                } else {
23693                                                        sourceModel.setColumn(source.getColumn());
23694                                                        sourceModel.setParentName(source.getParent_name());
23695                                                        sourceModel.setSourceName(source.getSource_name());
23696                                                }
23697                                                sourceModel.setColumnType(source.getColumn_type());
23698                                                sourceModel.setId(source.getId());
23699                                                sourceModel.setParentId(source.getParent_id());
23700                                                sourceModel.setSourceId(source.getSource_id());
23701                                                sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate()));
23702                                                sourceModel.setClauseType(source.getClauseType());
23703                                                sourceModel.setType(source.getType());
23704                                                sourceModels.add(sourceModel);
23705                                                if (source.getTransforms() != null && !source.getTransforms().isEmpty()) {
23706                                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform> transforms = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform>();
23707                                                        for (transform transform : source.getTransforms()) {
23708                                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform();
23709                                                                item.setCode(transform.getCode());
23710                                                                item.setType(transform.getType());
23711                                                                item.setCoordinate(transform.getCoordinate(true));
23712                                                                transforms.add(item);
23713                                                        }
23714                                                        sourceModel.setTransforms(transforms
23715                                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Transform[0]));
23716                                                }
23717                                                
23718                                                if (source.getCandidateParents() != null && !source.getCandidateParents().isEmpty()) {
23719                                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable> candidateParents = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable>();
23720                                                        for (candidateTable candidateTable : source.getCandidateParents()) {
23721                                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable item = new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable();
23722                                                                item.setId(candidateTable.getId());
23723                                                                if (normalizeIdentifier) {
23724                                                                        item.setName(
23725                                                                                        SQLUtil.getIdentifierNormalTableName(vendor, candidateTable.getName()));
23726                                                                } else {
23727                                                                        item.setName(candidateTable.getName());
23728                                                                }
23729                                                                candidateParents.add(item);
23730                                                        }
23731                                                        sourceModel.setCandidateParents(candidateParents
23732                                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.CandidateTable[0]));
23733                                                }
23734                                        }
23735                                        relationModel.setSources(sourceModels
23736                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0]));
23737                                        relations.add(relationModel);
23738                                } else if (relation.getCaller() != null && relation.getCallees() != null
23739                                                && !relation.getCallees().isEmpty()) {
23740                                        {
23741                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement targetModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23742                                                targetColumn target = relation.getCaller();
23743                                                if (normalizeIdentifier) {
23744                                                        targetModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, target.getName()));
23745                                                } else {
23746                                                        targetModel.setName(target.getName());
23747                                                }
23748                                                targetModel.setId(target.getId());
23749                                                targetModel.setCoordinates(Coordinate.parse(target.getCoordinate()));
23750                                                targetModel.setType(target.getType());
23751                                                relationModel.setCaller(targetModel);
23752                                        }
23753
23754                                        List<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement> sourceModels = new ArrayList<gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement>();
23755                                        for (sourceColumn source : relation.getCallees()) {
23756                                                gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement sourceModel = new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement();
23757                                                if (normalizeIdentifier) {
23758                                                        sourceModel.setName(SQLUtil.getIdentifierNormalColumnName(vendor, source.getName()));
23759                                                } else {
23760                                                        sourceModel.setName(source.getName());
23761                                                }
23762                                                sourceModel.setId(source.getId());
23763                                                sourceModel.setCoordinates(Coordinate.parse(source.getCoordinate()));
23764                                                sourceModel.setType(source.getType());
23765                                                sourceModels.add(sourceModel);
23766                                        }
23767                                        relationModel.setCallees(sourceModels
23768                                                        .toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.RelationshipElement[0]));
23769                                        relations.add(relationModel);
23770                                }
23771                        }
23772                }
23773                model.setRelationships(relations.toArray(new gudusoft.gsqlparser.dlineage.dataflow.model.json.Relationship[0]));
23774                return model;
23775        }
23776
23777        public static String getVersion() {
23778                return "3.1.4";
23779        }
23780
23781        public static String getReleaseDate() {
23782                return "2023-03-04";
23783        }
23784
23785        public static void main(String[] args) {
23786                if (args.length < 1) {
23787                        System.out.println(
23788                                        "Usage: java DataFlowAnalyzer [/f <path_to_sql_file>] [/d <path_to_directory_includes_sql_files>] [/s [/text]] [/json] [/traceView] [/t <database type>] [/o <output file path>][/version]");
23789                        System.out.println("/f: Option, specify the sql file path to analyze fdd relation.");
23790                        System.out.println("/d: Option, specify the sql directory path to analyze fdd relation.");
23791                        System.out.println("/j: Option, analyze the join relation.");
23792                        System.out.println("/s: Option, simple output, ignore the intermediate results.");
23793                        System.out.println("/i: Option, ignore all result sets.");
23794                        System.out.println("/traceView: Option, analyze the source tables of views.");
23795                        System.out.println("/text: Option, print the plain text format output.");
23796                        System.out.println("/json: Option, print the json format output.");
23797                        System.out.println(
23798                                        "/t: Option, set the database type. Support oracle, mysql, mssql, db2, netezza, teradata, informix, sybase, postgresql, hive, greenplum and redshift, the default type is oracle");
23799                        System.out.println("/o: Option, write the output stream to the specified file.");
23800                        System.out.println("/log: Option, generate a dataflow.log file to log information.");
23801                        return;
23802                }
23803
23804                File sqlFiles = null;
23805
23806                List<String> argList = Arrays.asList(args);
23807
23808                if (argList.indexOf("/version") != -1) {
23809                        System.out.println("Version: " + DataFlowAnalyzer.getVersion());
23810                        System.out.println("Release Date: " + DataFlowAnalyzer.getReleaseDate());
23811                        return;
23812                }
23813
23814                if (argList.indexOf("/f") != -1 && argList.size() > argList.indexOf("/f") + 1) {
23815                        sqlFiles = new File(args[argList.indexOf("/f") + 1]);
23816                        if (!sqlFiles.exists() || !sqlFiles.isFile()) {
23817                                System.out.println(sqlFiles + " is not a valid file.");
23818                                return;
23819                        }
23820                } else if (argList.indexOf("/d") != -1 && argList.size() > argList.indexOf("/d") + 1) {
23821                        sqlFiles = new File(args[argList.indexOf("/d") + 1]);
23822                        if (!sqlFiles.exists() || !sqlFiles.isDirectory()) {
23823                                System.out.println(sqlFiles + " is not a valid directory.");
23824                                return;
23825                        }
23826                } else {
23827                        System.out.println("Please specify a sql file path or directory path to analyze dlineage.");
23828                        return;
23829                }
23830
23831                EDbVendor vendor = EDbVendor.dbvoracle;
23832
23833                int index = argList.indexOf("/t");
23834
23835                if (index != -1 && args.length > index + 1) {
23836                        vendor = TGSqlParser.getDBVendorByName(args[index + 1]);
23837                }
23838
23839                String outputFile = null;
23840
23841                index = argList.indexOf("/o");
23842
23843                if (index != -1 && args.length > index + 1) {
23844                        outputFile = args[index + 1];
23845                }
23846
23847                FileOutputStream writer = null;
23848                if (outputFile != null) {
23849                        try {
23850                                writer = new FileOutputStream(outputFile);
23851                                System.setOut(new PrintStream(writer));
23852                        } catch (FileNotFoundException e) {
23853                                logger.error("output file is not found.", e);
23854                        }
23855                }
23856
23857                boolean simple = argList.indexOf("/s") != -1;
23858                boolean ignoreResultSets = argList.indexOf("/i") != -1;
23859                boolean showJoin = argList.indexOf("/j") != -1;
23860                boolean textFormat = false;
23861                boolean jsonFormat = false;
23862                if (simple) {
23863                        textFormat = argList.indexOf("/text") != -1;
23864                }
23865
23866                boolean traceView = argList.indexOf("/traceView") != -1;
23867                if (traceView) {
23868                        simple = true;
23869                }
23870
23871                jsonFormat = argList.indexOf("/json") != -1;
23872
23873                DataFlowAnalyzer dlineage = new DataFlowAnalyzer(sqlFiles, vendor, simple);
23874
23875                dlineage.setShowJoin(showJoin);
23876                dlineage.setIgnoreRecordSet(ignoreResultSets);
23877                // dlineage.setShowImplicitSchema(true);
23878
23879                if (simple && !jsonFormat) {
23880                        dlineage.setTextFormat(textFormat);
23881                }
23882
23883                String result = dlineage.generateDataFlow();
23884
23885//              dataflow dataflow = ProcessUtility.generateTableLevelLineage(dlineage, dlineage.getDataFlow());
23886//              System.out.println(result);
23887
23888                if (jsonFormat) {
23889                        // Map jsonResult = new LinkedHashMap();
23890                        Dataflow model = getSqlflowJSONModel(vendor, dlineage.getDataFlow(), true);
23891                        // jsonResult.put("data", BeanUtils.bean2Map(model));
23892                        result = JSON.toJSONString(model);
23893                } else if (traceView) {
23894                        result = dlineage.traceView();
23895                }
23896
23897                if (result != null) {
23898                        System.out.println(result);
23899
23900                        if (writer != null && result.length() < 1024 * 1024) {
23901                                System.err.println(result);
23902                        }
23903                }
23904
23905                try {
23906                        if (writer != null) {
23907                                writer.close();
23908                        }
23909                } catch (IOException e) {
23910                        logger.error("close writer failed.", e);
23911                }
23912
23913                boolean log = argList.indexOf("/log") != -1;
23914
23915                PrintStream systemSteam = System.err;
23916                ByteArrayOutputStream sw = new ByteArrayOutputStream();
23917                PrintStream pw = new PrintStream(sw);
23918                System.setErr(pw);
23919
23920
23921                List<ErrorInfo> errors = dlineage.getErrorMessages();
23922                if (!errors.isEmpty()) {
23923                        System.err.println("Error log:\n");
23924                        for (int i = 0; i < errors.size(); i++) {
23925                                System.err.println(errors.get(i).getErrorMessage());
23926                        }
23927                }
23928
23929                if (sw != null) {
23930                        String errorMessage = sw.toString().trim();
23931                        if (errorMessage.length() > 0) {
23932                                if (log) {
23933                                        try {
23934                                                pw = new PrintStream(new File(".", "dataflow.log"));
23935                                                pw.print(errorMessage);
23936                                        } catch (FileNotFoundException e) {
23937                                                logger.error("error log file is not found.", e);
23938                                        }
23939                                }
23940
23941                                System.setErr(systemSteam);
23942                                System.err.println(errorMessage);
23943                        }
23944                }
23945        }
23946
23947        public List<ErrorInfo> getErrorMessages() {
23948                return errorInfos;
23949        }
23950
23951        public String traceView() {
23952                StringBuilder buffer = new StringBuilder();
23953                dataflow dataflow = this.getDataFlow();
23954                Map<table, Set<table>> traceViewMap = new LinkedHashMap<table, Set<table>>();
23955                if (dataflow != null && dataflow.getViews() != null) {
23956                        List<relationship> relations = dataflow.getRelationships();
23957                        Map<String, table> viewMap = new HashMap<String, table>();
23958                        Map<String, table> tableMap = new HashMap<String, table>();
23959                        for (table view : dataflow.getViews()) {
23960                                viewMap.put(view.getId(), view);
23961                                tableMap.put(view.getId(), view);
23962                        }
23963                        for (table table : dataflow.getTables()) {
23964                                tableMap.put(table.getId(), table);
23965                        }
23966                        for (relationship relation : relations) {
23967                                if (!RelationshipType.fdd.name().equals(relation.getType())) {
23968                                        continue;
23969                                }
23970                                String parentId = relation.getTarget().getParent_id();
23971                                if (viewMap.containsKey(parentId)) {
23972                                        if (!traceViewMap.containsKey(viewMap.get(parentId))) {
23973                                                traceViewMap.put(viewMap.get(parentId), new LinkedHashSet<table>());
23974                                        }
23975
23976                                        for (sourceColumn sourceColumn : relation.getSources()) {
23977                                                traceViewMap.get(viewMap.get(parentId)).add(tableMap.get(sourceColumn.getParent_id()));
23978                                        }
23979                                }
23980                        }
23981
23982                        Map<table, Set<table>> viewTableMap = new LinkedHashMap<table, Set<table>>();
23983                        for (table view : traceViewMap.keySet()) {
23984                                Set<table> tables = new LinkedHashSet<table>();
23985                                traverseViewSourceTables(tables, view, traceViewMap);
23986                                viewTableMap.put(view, tables);
23987                        }
23988
23989                        for (table view : viewTableMap.keySet()) {
23990                                buffer.append(view.getFullName());
23991                                for (table table : viewTableMap.get(view)) {
23992                                        buffer.append(",").append(table.getFullName());
23993                                }
23994                                buffer.append(System.getProperty("line.separator"));
23995                        }
23996                }
23997                return buffer.toString().trim();
23998        }
23999
24000        private void traverseViewSourceTables(Set<table> tables, table view, Map<table, Set<table>> traceViewMap) {
24001                Set<table> sourceTables = traceViewMap.get(view);
24002                for (table sourceTable : sourceTables) {
24003                        if (sourceTable.isTable()) {
24004                                tables.add(sourceTable);
24005                        } else if (sourceTable.isView()) {
24006                                traverseViewSourceTables(tables, sourceTable, traceViewMap);
24007                        }
24008                }
24009        }
24010
24011        protected List<SqlInfo> convertSQL(EDbVendor vendor, String json) {
24012                List<SqlInfo> sqlInfos = new ArrayList<SqlInfo>();
24013                List sqlContents = (List) JSON.parseObject(json);
24014                for (int j = 0; j < sqlContents.size(); j++) {
24015                        Map sqlContent = (Map) sqlContents.get(j);
24016                        String sql = (String) sqlContent.get("sql");
24017                        String fileName = (String) sqlContent.get("fileName");
24018                        String filePath = (String) sqlContent.get("filePath");
24019                        if (sql != null && sql.trim().startsWith("{")) {
24020                                if (sql.indexOf("createdBy") != -1) {
24021                                        if (this.sqlenv == null) {
24022                                                TSQLEnv[] sqlenvs = new TJSONSQLEnvParser(option.getDefaultServer(),
24023                                                                option.getDefaultDatabase(), option.getDefaultSchema()).parseSQLEnv(vendor, sql);
24024                                                if (sqlenvs != null && sqlenvs.length > 0) {
24025                                                        this.sqlenv = sqlenvs[0];
24026                                                }
24027                                        }
24028                                        if (sql.toLowerCase().indexOf("sqldep") != -1 || sql.toLowerCase().indexOf("grabit") != -1) {
24029                                                Map queryObject = (Map) JSON.parseObject(sql);
24030                                                List querys = (List) queryObject.get("queries");
24031                                                if (querys != null) {
24032                                                        for (int i = 0; i < querys.size(); i++) {
24033                                                                Map object = (Map) querys.get(i);
24034                                                                SqlInfo info = new SqlInfo();
24035                                                                info.setSql(JSON.toJSONString(object));
24036                                                                info.setFileName(fileName);
24037                                                                info.setFilePath(filePath);
24038                                                                info.setOriginIndex(i);
24039                                                                sqlInfos.add(info);
24040                                                        }
24041                                                        queryObject.remove("queries");
24042                                                        SqlInfo info = new SqlInfo();
24043                                                        info.setSql(JSON.toJSONString(queryObject));
24044                                                        info.setFileName(fileName);
24045                                                        info.setFilePath(filePath);
24046                                                        info.setOriginIndex(querys.size());
24047                                                        sqlInfos.add(info);
24048                                                } else {
24049                                                        SqlInfo info = new SqlInfo();
24050                                                        info.setSql(JSON.toJSONString(queryObject));
24051                                                        info.setFileName(fileName);
24052                                                        info.setFilePath(filePath);
24053                                                        info.setOriginIndex(0);
24054                                                        sqlInfos.add(info);
24055                                                }
24056                                        } else if (sql.toLowerCase().indexOf("sqlflow") != -1) {
24057                                                Map sqlflow = (Map) JSON.parseObject(sql);
24058                                                List<Map> servers = (List<Map>) sqlflow.get("servers");
24059                                                if (servers != null) {
24060                                                        for (Map queryObject : servers) {
24061                                                                String name = (String) queryObject.get("name");
24062                                                                String dbVendor = (String) queryObject.get("dbVendor");
24063                                                                List querys = (List) queryObject.get("queries");
24064                                                                if (querys != null) {
24065                                                                        for (int i = 0; i < querys.size(); i++) {
24066                                                                                Map object = (Map) querys.get(i);
24067                                                                                SqlInfo info = new SqlInfo();
24068                                                                                info.setSql(JSON.toJSONString(object));
24069                                                                                info.setFileName(fileName);
24070                                                                                info.setFilePath(filePath);
24071                                                                                info.setOriginIndex(i);
24072                                                                                info.setDbVendor(dbVendor);
24073                                                                                info.setServer(name);
24074                                                                                sqlInfos.add(info);
24075                                                                        }
24076                                                                        queryObject.remove("queries");
24077                                                                        Map serverObject = new IndexedLinkedHashMap();
24078                                                                        serverObject.put("createdBy", sqlflow.get("createdBy"));
24079                                                                        serverObject.put("servers", Arrays.asList(queryObject));
24080                                                                        SqlInfo info = new SqlInfo();
24081                                                                        info.setSql(JSON.toJSONString(serverObject));
24082                                                                        info.setFileName(fileName);
24083                                                                        info.setFilePath(filePath);
24084                                                                        info.setOriginIndex(querys.size());
24085                                                                        info.setDbVendor(dbVendor);
24086                                                                        info.setServer(filePath);
24087                                                                        sqlInfos.add(info);
24088                                                                } else {
24089                                                                        SqlInfo info = new SqlInfo();
24090                                                                        info.setSql(JSON.toJSONString(queryObject));
24091                                                                        info.setFileName(fileName);
24092                                                                        info.setFilePath(filePath);
24093                                                                        info.setOriginIndex(0);
24094                                                                        sqlInfos.add(info);
24095                                                                }
24096                                                        }
24097                                                }
24098                                                
24099                                                List<Map> errorMessages =  (List<Map>) sqlflow.get("errorMessages");
24100                                                if(errorMessages!=null && !errorMessages.isEmpty()) {
24101                                                        for(Map error: errorMessages){
24102                                                                ErrorInfo errorInfo = new ErrorInfo();
24103                                                                errorInfo.setErrorType(ErrorInfo.METADATA_ERROR);
24104                                                                errorInfo.setErrorMessage((String)error.get("errorMessage"));
24105                                                                errorInfo.setFileName(fileName);
24106                                                                errorInfo.setFilePath(filePath);
24107                                                                errorInfo.setStartPosition(new Pair3<Long, Long, String>(-1L, -1L,
24108                                                                                ModelBindingManager.getGlobalHash()));
24109                                                                errorInfo.setEndPosition(new Pair3<Long, Long, String>(-1L, -1L,
24110                                                                                ModelBindingManager.getGlobalHash()));
24111                                                                errorInfo.setOriginStartPosition(new Pair<Long, Long>(-1L, -1L));
24112                                                                errorInfo.setOriginEndPosition(new Pair<Long, Long>(-1L, -1L));
24113                                                                metadataErrors.add(errorInfo);
24114                                                        }
24115                                                }
24116                                        }
24117                                }
24118                        } else if (sql != null) {
24119                                SqlInfo info = new SqlInfo();
24120                                info.setSql(sql);
24121                                info.setFileName(fileName);
24122                                info.setFilePath(filePath);
24123                                info.setOriginIndex(0);
24124                                sqlInfos.add(info);
24125                        }
24126                }
24127                return sqlInfos;
24128        }
24129
24130        public void setTextFormat(boolean textFormat) {
24131                option.setTextFormat(textFormat);
24132        }
24133
24134        public boolean isBuiltInFunctionName(TObjectName object) {
24135                if (object == null || object.getGsqlparser() == null)
24136                        return false;
24137                try {
24138                        EDbVendor vendor = object.getGsqlparser().getDbVendor();
24139                        if (vendor == EDbVendor.dbvteradata) {
24140                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(object.toString().toUpperCase());
24141                                if (result) {
24142                                        return true;
24143                                }
24144                        }
24145
24146                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
24147                        if (versions != null && versions.size() > 0) {
24148                                for (int i = 0; i < versions.size(); i++) {
24149                                        boolean result = functionChecker.isBuiltInFunction(object.toString(),
24150                                                        object.getGsqlparser().getDbVendor(), versions.get(i));
24151                                        if (result) {
24152                                                return result;
24153                                        }
24154                                }
24155
24156                                // boolean result =
24157                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
24158                                // if (result) {
24159                                // return true;
24160                                // }
24161                        }
24162                } catch (Exception e) {
24163                }
24164
24165                return false;
24166        }
24167        
24168        public boolean isBuiltInFunctionName(String functionName) {
24169                if (functionName == null)
24170                        return false;
24171                try {
24172                        EDbVendor vendor = getOption().getVendor();
24173                        if (vendor == EDbVendor.dbvteradata) {
24174                                boolean result = TERADATA_BUILTIN_FUNCTIONS.contains(functionName.toUpperCase());
24175                                if (result) {
24176                                        return true;
24177                                }
24178                        }
24179
24180                        List<String> versions = functionChecker.getAvailableDbVersions(vendor);
24181                        if (versions != null && versions.size() > 0) {
24182                                for (int i = 0; i < versions.size(); i++) {
24183                                        boolean result = functionChecker.isBuiltInFunction(functionName.toUpperCase(),
24184                                                        vendor, versions.get(i));
24185                                        if (result) {
24186                                                return result;
24187                                        }
24188                                }
24189
24190                                // boolean result =
24191                                // TERADATA_BUILTIN_FUNCTIONS.contains(object.toString());
24192                                // if (result) {
24193                                // return true;
24194                                // }
24195                        }
24196                } catch (Exception e) {
24197                }
24198
24199                return false;
24200        }
24201
24202        public boolean isKeyword(TObjectName object) {
24203                if (object == null || object.getGsqlparser() == null)
24204                        return false;
24205                try {
24206                        EDbVendor vendor = object.getGsqlparser().getDbVendor();
24207
24208                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
24209                        if (versions != null && versions.size() > 0) {
24210                                for (int i = 0; i < versions.size(); i++) {
24211                                        List<String> segments = SQLUtil.parseNames(object.toString());
24212                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
24213                                                        object.getGsqlparser().getDbVendor(), versions.get(i), true);
24214                                        if (result) {
24215                                                return result;
24216                                        }
24217                                }
24218                        }
24219                } catch (Exception e) {
24220                }
24221
24222                return false;
24223        }
24224        
24225        public boolean isKeyword(String objectName) {
24226                if (objectName == null)
24227                        return false;
24228                try {
24229                        EDbVendor vendor = getOption().getVendor();
24230
24231                        List<String> versions = keywordChecker.getAvailableDbVersions(vendor);
24232                        if (versions != null && versions.size() > 0) {
24233                                for (int i = 0; i < versions.size(); i++) {
24234                                        List<String> segments = SQLUtil.parseNames(objectName);
24235                                        boolean result = keywordChecker.isKeyword(segments.get(segments.size() - 1),
24236                                                        vendor, versions.get(i), false);
24237                                        if (result) {
24238                                                return result;
24239                                        }
24240                                }
24241                        }
24242                } catch (Exception e) {
24243                }
24244
24245                return false;
24246        }
24247
24248        public boolean isAggregateFunction(TFunctionCall func) {
24249                if (func == null)
24250                        return false;
24251                return Arrays
24252                                .asList(new String[] { "AVG", "COUNT", "MAX", "MIN", "SUM", "COLLECT", "CORR", "COVAR_POP",
24253                                                "COVAR_SAMP", "CUME_DIST", "DENSE_RANK", "FIRST", "GROUP_ID", "GROUPING", "GROUPING_ID", "LAST",
24254                                                "LISTAGG", "MEDIAN", "PERCENT_RANK", "PERCENTILE_CONT", "PERCENTILE_DISC", "RANK",
24255                                                "STATS_BINOMIAL_TEST", "STATS_CROSSTAB", "STATS_F_TEST", "STATS_KS_TEST", "STATS_MODE",
24256                                                "STATS_MW_TEST", "STATS_ONE_WAY_ANOVA", "STATS_WSR_TEST", "STDDEV", "STDDEV_POP", "STDDEV_SAMP",
24257                                                "SYS_XMLAGG", "VAR_ POP", "VAR_ SAMP", "VARI ANCE", "XMLAGG", "ARRAY_AGG" })
24258                                .contains(func.getFunctionName().toString().toUpperCase());
24259        }
24260
24261        public boolean isConstant(TObjectName object) {
24262                if (object == null || object.getGsqlparser() == null)
24263                        return false;
24264                List<String> constants = Arrays.asList(new String[] { "NEXTVAL", "CURRVAL", "SYSDATE", "CENTURY", "YEAR",
24265                                "MONTH", "DAY", "HOUR", "MINUTE", "SECOND" });
24266                List<String> segments = SQLUtil.parseNames(object.toString());
24267                // sequence.NEXTVAL or sequence.CURRVAL is a sequence reference, not a constant
24268                // This syntax is used by Oracle, Snowflake, and accepted by other vendors for compatibility
24269                String columnNameOnly = object.getColumnNameOnly();
24270                if (segments.size() > 1 && ("NEXTVAL".equalsIgnoreCase(columnNameOnly) || "CURRVAL".equalsIgnoreCase(columnNameOnly))) {
24271                        return false;
24272                }
24273                boolean result = constants.indexOf(segments.get(segments.size() - 1).toUpperCase()) != -1;
24274                if (result) {
24275                        return result;
24276                }
24277                if (isKeyword(object)) {
24278                        return true;
24279                }
24280                return false;
24281        }
24282
24283        private Pair3<Long, Long, Integer> convertCoordinate(Pair3<Long, Long, String> position) {
24284//              if (ModelBindingManager.getGlobalOption()!=null && ModelBindingManager.getGlobalOption().isIgnoreCoordinate()) {
24285//                      return new Pair3<>(-1L, -1L, -1);
24286//              }
24287                return new Pair3<Long, Long, Integer>(position.first, position.second,
24288                                ModelBindingManager.getGlobalSqlInfo().getIndexOf(position.third));
24289        }
24290
24291}